xref: /xnu-12377.81.4/tools/lldbmacros/net.py (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1
2""" Please make sure you read the README COMPLETELY BEFORE reading anything below.
3    It is very critical that you read coding guidelines in Section E in README file.
4"""
5from xnu import *
6from utils import *
7from string import *
8from socket import *
9import tempfile
10
11import xnudefines
12from netdefines import *
13from routedefines import *
14from mbufdefines import *
15
16def GetDlilIfFlagsAsString(dlil_if_flags):
17    """ Return a formatted string description of the dlil interface flags
18    """
19    out_string = ""
20    flags = (unsigned)(dlil_if_flags & 0xffff)
21    i = 0
22    num = 1
23    while num <= flags:
24        if flags & num:
25            out_string += dlil_if_flags_strings[i] + ","
26        i += 1
27        num = num << 1
28    return out_string.rstrip(",")
29
30def GetIfFlagsAsString(if_flags):
31    """ Return a formatted string description of the interface flags
32    """
33    out_string = ""
34    flags = (unsigned)(if_flags & 0xffff)
35    i = 0
36    num = 1
37    while num <= flags:
38        if flags & num:
39            out_string += if_flags_strings[i] + ","
40        i += 1
41        num = num << 1
42    return out_string.rstrip(",")
43
44def GetIfEflagsAsString(if_eflags):
45    """ Return a formatted string description of the interface extra flags
46    """
47    out_string = ""
48    flags = unsigned(if_eflags)
49    i = 0
50    num = 1
51    while num <= flags:
52        if flags & num:
53            out_string += if_eflags_strings[i] + ","
54        i += 1
55        num = num << 1
56    return out_string.rstrip(",")
57
58def GetIfXflagsAsString(if_xflags):
59    """ Return a formatted string description of the interface extended flags
60    """
61    out_string = ""
62    flags = unsigned(if_xflags)
63    i = 0
64    num = 1
65    while num <= flags:
66        if flags & num:
67            out_string += if_xflags_strings[i] + ","
68        i += 1
69        num = num << 1
70    return out_string.rstrip(",")
71
72
73def ShowIfConfiguration(ifnet):
74    """ Display ifconfig-like output for the ifnet
75    """
76    iface = Cast(ifnet, 'ifnet *')
77    dlifnet = Cast(ifnet, 'dlil_ifnet *')
78    out_string = ""
79    format_string = "{0: <s}: flags={1: <x} <{2: <s}> index {3: <d} mtu {4: <d}"
80    extended_flags_format_string = "\n\teflags={0: <x} <{1: <s}>"
81    extra_flags_format_string = "\n\txflags={0: <x} <{1: <s}>"
82    capenabled_format_string = "\n\toptions={0: <x} <{1: <s}>"
83    if iface :
84        out_string += format_string.format(iface.if_xname, (iface.if_flags & 0xffff), GetIfFlagsAsString(iface.if_flags), iface.if_index, iface.if_data.ifi_mtu)
85        out_string += "\n\tdlil flags=" + hex(dlifnet.dl_if_flags)+ " <" + GetDlilIfFlagsAsString(dlifnet.dl_if_flags) + ">"
86        if (iface.if_eflags) :
87            out_string += extended_flags_format_string.format(iface.if_eflags, GetIfEflagsAsString(iface.if_eflags))
88        if (iface.if_xflags) :
89            out_string += extra_flags_format_string.format(iface.if_xflags, GetIfXflagsAsString(iface.if_xflags))
90        if (iface.if_capenable) :
91            out_string += capenabled_format_string.format(iface.if_capenable, GetCapabilitiesAsString(iface.if_capenable))
92        out_string += "\n\t(struct ifnet *)" + hex(ifnet)
93        if iface.if_snd and iface.if_snd.ifcq_len :
94            out_string += "\n\t" + str(iface.if_snd.ifcq_len)
95        if dlifnet.dl_if_inpstorage.dlth_pkts.qlen :
96            out_string += "\n\t" + str(dlifnet.dl_if_inpstorage.dlth_pkts.qlen)
97    print(out_string)
98
99def GetIfConfiguration(ifname):
100    """ Return ifnet structure corresponding to the ifname passed in
101    """
102    global kern
103    ifnets = kern.globals.ifnet_head
104    for ifnet in IterateTAILQ_HEAD(ifnets, "if_link") :
105        if str(ifnet.if_xname) == ifname :
106            return ifnet
107    return None
108
109#Macro: ifconfig_dlil
110@lldb_command('ifconfig_dlil')
111def ShowIfconfigDlil(cmd_args=None) :
112    """ Display ifconfig-like output for DLIL interface list, print (struct ifnet *) pointer and dlil info for further inspection
113    """
114    dlil_ifnets = kern.globals.dlil_ifnet_head
115    for dlil_ifnet in IterateTAILQ_HEAD(dlil_ifnets, "dl_if_link"):
116        ShowIfConfiguration(dlil_ifnet)
117        print(GetIfaddrs(Cast(dlil_ifnet, 'ifnet *')))
118# EndMacro: ifconfig_dlil
119
120def GetAddressAsStringColonHex(addr, count):
121    out_string = ""
122    i = 0
123    addr_format_string = "{0:02x}"
124    while (i < count):
125        if (i == 0):
126            out_string += addr_format_string.format(unsigned(addr[i]))[-2:]
127        else:
128            out_string += ":" + addr_format_string.format(unsigned(addr[i]))[-2:]
129        i += 1
130    return out_string
131
132def GetSocketAddrAsStringUnspec(sockaddr):
133    out_string = ""
134    out_string += GetAddressAsStringColonHex(sockaddr.sa_data, sockaddr.sa_len - 2)
135    return out_string
136
137def GetSocketAddrAsStringUnix(sockaddr):
138    sock_unix = Cast(sockaddr, 'sockaddr_un *')
139    if (sock_unix == 0):
140        return "(null)"
141    else:
142        if (len(str(sock_unix.sun_path)) > 0):
143            return str(sock_unix.sun_path)
144        else:
145            return "\"\""
146
147def GetInAddrAsString(ia):
148    out_string = ""
149    inaddr = Cast(ia, 'in_addr *')
150
151    packed_value = struct.pack('I', unsigned(ia.s_addr))
152    out_string = inet_ntoa(packed_value)
153    return out_string
154
155def GetIn6AddrAsString(ia):
156    addr_raw_string = ":".join(["{0:02x}{1:02x}".format(unsigned(ia[i]),
157        unsigned(ia[i+1])) for i in range(0, 16, 2)])
158    return inet_ntop(AF_INET6, inet_pton(AF_INET6, addr_raw_string))
159
160def GetSocketAddrAsStringInet(sockaddr):
161    sock_in = Cast(sockaddr, 'sockaddr_in *')
162    return GetInAddrAsString(addressof(sock_in.sin_addr))
163
164def GetSocketAddrAsStringInet6(sockaddr):
165    sock_in6 = Cast(sockaddr, 'sockaddr_in6 *')
166    return GetIn6AddrAsString(sock_in6.sin6_addr.__u6_addr.__u6_addr8)
167
168def GetSocketAddrAsStringLink(sockaddr):
169    sock_link = Cast(sockaddr, 'sockaddr_dl *')
170    if sock_link is None:
171        return "(null)"
172    else:
173        out_string = ""
174        if (sock_link.sdl_nlen == 0 and sock_link.sdl_alen == 0 and sock_link.sdl_slen == 0):
175            out_string = "link#" + str(int(sock_link.sdl_index))
176        else:
177            out_string += GetAddressAsStringColonHex(addressof(sock_link.sdl_data[sock_link.sdl_nlen]), sock_link.sdl_alen)
178    return out_string
179
180def GetSocketAddrAsStringAT(sockaddr):
181    out_string = ""
182    sock_addr = Cast(sockaddr, 'sockaddr *')
183    out_string += GetAddressAsStringColonHex(sockaddr.sa_data, sockaddr.sa_len - 2)
184    return out_string
185
186def GetSocketAddrAsString(sockaddr):
187    if sockaddr is None :
188        return "(null)"
189    out_string = ""
190    if (sockaddr.sa_family == 0):
191        out_string += "UNSPC "
192        GetSocketAddrAsStringUnspec(sockaddr)
193    elif (sockaddr.sa_family == 1):
194        out_string += "UNIX "
195        out_string += GetSocketAddrAsStringUnix(sockaddr)
196    elif (sockaddr.sa_family == 2):
197        out_string += "INET "
198        out_string += GetSocketAddrAsStringInet(sockaddr)
199    elif (sockaddr.sa_family == 30):
200        out_string += "INET6 "
201        out_string += GetSocketAddrAsStringInet6(sockaddr)
202    elif (sockaddr.sa_family == 18):
203        out_string += "LINK "
204        out_string += GetSocketAddrAsStringLink(sockaddr)
205    elif (sockaddr.sa_family == 16):
206        out_string += "ATLK "
207        out_string += GetSocketAddrAsStringAT(sockaddr)
208    else:
209        out_string += "FAM " + str(sockaddr.sa_family)
210        out_string += GetAddressAsStringColonHex(sockaddr.sa_data, sockaddr.sa_len)
211    return out_string
212
213# Macro: showifaddrs
214@lldb_command('showifaddrs')
215def ShowIfaddrs(cmd_args=None):
216    """ Show the (struct ifnet).if_addrhead list of addresses for the given ifp
217    """
218    if cmd_args != None and len(cmd_args) > 0 :
219        ifp = kern.GetValueFromAddress(cmd_args[0], 'ifnet *')
220        if not ifp:
221            print("Unknown value passed as argument.")
222            return
223        i = 1
224        for ifaddr in IterateTAILQ_HEAD(ifp.if_addrhead, "ifa_link"):
225            format_string = "\t{0: <d}: 0x{1: <x} {2: <s} [{3: <d}]"
226            print(format_string.format(i, ifaddr, GetSocketAddrAsString(ifaddr.ifa_addr), ifaddr.ifa_refcnt))
227            i += 1
228    else :
229        print("Missing argument 0 in user function.")
230# EndMacro: showifaddrs
231
232def GetIfaddrs(ifp):
233    out_string = ""
234    if (ifp != 0):
235        i = 1
236        for ifaddr in IterateTAILQ_HEAD(ifp.if_addrhead, "ifa_link"):
237            format_string = "\t{0: <d}: 0x{1: <x} {2: <s}"
238            out_string += format_string.format(i, ifaddr, GetSocketAddrAsString(ifaddr.ifa_addr)) + "\n"
239            i += 1
240    else:
241        out_string += "Missing argument 0 in user function."
242    return out_string
243
244
245def GetCapabilitiesAsString(flags):
246    """ Return a formatted string description of the interface flags
247    """
248    out_string = ""
249    i = 0
250    num = 1
251    while num <= flags:
252        if flags & num:
253            out_string += if_capenable_strings[i] + ","
254        i += 1
255        num = num << 1
256    return out_string.rstrip(",")
257
258def ShowDlilIfnetConfiguration(dlil_ifnet, show_all) :
259    """ Formatted display of dlil_ifnet structures
260    """
261    DLIF_INUSE = 0x1
262    DLIF_REUSE = 0x2
263
264    if dlil_ifnet is None :
265        return
266
267    dlil_iface = Cast(dlil_ifnet, 'dlil_ifnet *')
268    iface = Cast(dlil_ifnet, 'ifnet *')
269    out_string = ""
270    if (dlil_iface.dl_if_flags & DLIF_REUSE) :
271        out_string  += "*"
272    format_string = "{0: <s}: flags={1: <x} <{2: <s}> index {3: <d} mtu {4: <d}"
273    extended_flags_format_string = "\n\teflags={0: <x} <{1: <s}>"
274    extra_flags_format_string = "\n\txflags={0: <x} <{1: <s}>"
275    capenabled_format_string = "\n\toptions={0: <x} <{1: <s}>"
276    if (dlil_iface.dl_if_flags & DLIF_INUSE) :
277        out_string += format_string.format(iface.if_xname, (iface.if_flags & 0xffff), GetIfFlagsAsString(iface.if_flags), iface.if_index, iface.if_data.ifi_mtu)
278    else :
279        out_string += format_string.format("[" + str(iface.if_name) + str(int(iface.if_unit)) + "]", (iface.if_flags & 0xffff), GetIfFlagsAsString(iface.if_flags), iface.if_index, iface.if_data.ifi_mtu)
280    if (iface.if_eflags) :
281        out_string += extended_flags_format_string.format(iface.if_eflags, GetIfEflagsAsString(iface.if_eflags))
282    if (iface.if_xflags) :
283        out_string += extra_flags_format_string.format(iface.if_xflags, GetIfXflagsAsString(iface.if_xflags))
284    if (iface.if_capenable) :
285        out_string += capenabled_format_string.format(iface.if_capenable, GetCapabilitiesAsString(iface.if_capenable))
286    out_string += "\n\t(struct ifnet *)" + hex(dlil_ifnet) + "\n"
287    if show_all :
288        out_string += GetIfaddrs(iface)
289        out_string += "\n"
290    print(out_string)
291
292# Macro: ifconfig
293@lldb_command('ifconfig')
294def ShowIfconfig(cmd_args=None) :
295    """ Display ifconfig-like output, and print the (struct ifnet *) pointers for further inspection
296    """
297    if cmd_args != None and len(cmd_args) > 0:
298        showall = 1
299    else:
300        showall = 0
301
302    ifnets = kern.globals.ifnet_head
303    for ifnet in IterateTAILQ_HEAD(ifnets, "if_link"):
304        ShowIfConfiguration(ifnet)
305        if (showall == 1):
306            print(GetIfaddrs(ifnet))
307# EndMacro: ifconfig
308
309# Macro: showifnets
310@lldb_command('showifnets')
311def ShowIfnets(cmd_args=None) :
312    """ Display ifconfig-like output for all attached and detached interfaces
313    """
314    showall = 0
315    if cmd_args != None and len(cmd_args) > 0 :
316        showall = 1
317    dlil_ifnets = kern.globals.dlil_ifnet_head
318    for dlil_ifnet in IterateTAILQ_HEAD(dlil_ifnets, "dl_if_link"):
319        ShowDlilIfnetConfiguration(dlil_ifnet, showall)
320# EndMacro: showifnets
321
322# Macro: showdetachingifnets
323@lldb_command('showdetachingifnets')
324def ShowDetachingIfnets(cmd_args=None) :
325    """ Display ifconfig-like output for all detaching interfaces
326    """
327    if cmd_args != None and len(cmd_args) > 0:
328        showall = 1
329    else:
330        showall = 0
331    ifnets = kern.globals.ifnet_detaching_head
332    for ifnet in IterateTAILQ_HEAD(ifnets, "if_detaching_link"):
333        ShowIfConfiguration(ifnet)
334        if (showall == 1):
335            print(GetIfaddrs(ifnet))
336# EndMacro: showdetachingifnets
337
338# Macro: showorderedifnets
339@lldb_command('showorderedifnets')
340def ShowOrderedIfnets(cmd_args=None) :
341    """ Display ifconfig-like output for ordered interfaces
342    """
343    if cmd_args != None and len(cmd_args) > 0:
344        showall = 1
345    else:
346        showall = 0
347    ifnets = kern.globals.ifnet_ordered_head
348    for ifnet in IterateTAILQ_HEAD(ifnets, "if_ordered_link"):
349        ShowIfConfiguration(ifnet)
350        if (showall == 1):
351            print(GetIfaddrs(ifnet))
352# EndMacro: showorderedifnets
353
354# Macro: showifmultiaddrs
355@lldb_command('showifmultiaddrs')
356def ShowIfMultiAddrs(cmd_args=None) :
357    """ Show the list of multicast addresses for the given ifp
358    """
359    out_string = ""
360    if cmd_args != None and len(cmd_args) > 0 :
361        ifp = kern.GetValueFromAddress(cmd_args[0], 'ifnet *')
362        if not ifp:
363            print("Unknown value passed as argument.")
364            return
365        ifmulti = cast(ifp.if_multiaddrs.lh_first, 'ifmultiaddr *')
366        i = 0
367        while ifmulti != 0:
368            ifma_format_string = "\t{0: <d}: 0x{1: <x} "
369            out_string += (ifma_format_string.format(i + 1, ifmulti))
370            if (ifmulti.ifma_addr.sa_family == 2):
371                if (ifmulti.ifma_ll != 0):
372                    out_string += GetSocketAddrAsStringLink(ifmulti.ifma_ll.ifma_addr) + " "
373                out_string += GetSocketAddrAsStringInet(ifmulti.ifma_addr)
374            if (ifmulti.ifma_addr.sa_family == 30):
375                if (ifmulti.ifma_ll != 0):
376                    out_string += GetSocketAddrAsStringLink(ifmulti.ifma_ll.ifma_addr) + " "
377                out_string += GetSocketAddrAsStringInet6(ifmulti.ifma_addr) + " "
378            if (ifmulti.ifma_addr.sa_family == 18):
379                out_string += GetSocketAddrAsStringLink(ifmulti.ifma_addr) + " "
380            if (ifmulti.ifma_addr.sa_family == 0):
381                out_string += GetSocketAddrAsStringUnspec(ifmulti.ifma_addr) + " "
382            out_string += "[" + str(int(ifmulti.ifma_refcount)) + "]\n"
383            ifmulti = cast(ifmulti.ifma_link.le_next, 'ifmultiaddr *')
384            i += 1
385        print(out_string)
386    else :
387        print("Missing argument 0 in user function.")
388# EndMacro: showifmultiaddrs
389
390# Macro: showinmultiaddrs
391@lldb_command('showinmultiaddrs')
392def ShowInMultiAddrs(cmd_args=None) :
393    """ Show the contents of IPv4 multicast address records
394    """
395    out_string = ""
396    inmultihead = kern.globals.in_multihead
397    inmulti = cast(inmultihead.lh_first, 'in_multi *')
398    i = 0
399    while inmulti != 0:
400        ifp = inmulti.inm_ifp
401        inma_format_string = "\t{0: <d}: 0x{1: <x} "
402        out_string += inma_format_string.format(i + 1, inmulti) + " "
403        out_string += GetInAddrAsString(addressof(inmulti.inm_addr)) + " "
404        ifma_format_string = "(ifp 0x{0: <x} [{1: <s}] ifma {2: <x})"
405        out_string += ifma_format_string.format(ifp, ifp.if_xname, inmulti.inm_ifma) + "\n"
406        inmulti = cast(inmulti.inm_link.le_next, 'in_multi *')
407        i += 1
408    print(out_string)
409# EndMacro: showinmultiaddrs
410
411# Macro: showin6multiaddrs
412@lldb_command('showin6multiaddrs')
413def ShowIn6MultiAddrs(cmd_args=None) :
414    """ Show the contents of IPv6 multicast address records
415    """
416    out_string = ""
417    in6multihead = kern.globals.in6_multihead
418    in6multi = cast(in6multihead.lh_first, 'in6_multi *')
419    i = 0
420    while in6multi != 0:
421        ifp = in6multi.in6m_ifp
422        inma_format_string = "\t{0: <d}: 0x{1: <x} "
423        out_string += inma_format_string.format(i + 1, in6multi) + " "
424        out_string += GetIn6AddrAsString((in6multi.in6m_addr.__u6_addr.__u6_addr8)) + " "
425        ifma_format_string = "(ifp 0x{0: <x} [{1: <s}] ifma {2: <x})"
426        out_string += ifma_format_string.format(ifp, ifp.if_xname, in6multi.in6m_ifma) + "\n"
427        in6multi = cast(in6multi.in6m_entry.le_next, 'in6_multi *')
428        i += 1
429    print(out_string)
430# EndMacro: showin6multiaddrs
431
432def GetTcpState(tcpcb):
433    out_string = ""
434    tp = Cast(tcpcb, 'tcpcb *')
435    if (int(tp) != 0):
436        if tp.t_state == 0:
437            out_string += "CLOSED\t"
438        if tp.t_state == 1:
439            out_string += "LISTEN\t"
440        if tp.t_state == 2:
441            out_string += "SYN_SENT\t"
442        if tp.t_state == 3:
443            out_string += "SYN_RCVD\t"
444        if tp.t_state == 4:
445            out_string += "ESTABLISHED\t"
446        if tp.t_state == 5:
447            out_string += "CLOSE_WAIT\t"
448        if tp.t_state == 6:
449            out_string += "FIN_WAIT_1\t"
450        if tp.t_state == 7:
451            out_string += "CLOSING\t"
452        if tp.t_state == 8:
453            out_string += "LAST_ACK\t"
454        if tp.t_state == 9:
455            out_string += "FIN_WAIT_2\t"
456        if tp.t_state == 10:
457            out_string += "TIME_WAIT\t"
458    return out_string
459
460def GetSocketProtocolAsString(sock):
461    out_string = ""
462    inpcb = Cast(sock.so_pcb, 'inpcb *')
463    if sock.so_proto.pr_protocol == 6:
464        out_string += " TCP "
465        out_string += GetTcpState(inpcb.inp_ppcb)
466    if sock.so_proto.pr_protocol == 17:
467        out_string += " UDP "
468    if sock.so_proto.pr_protocol == 1:
469        out_string += " ICMP "
470    if sock.so_proto.pr_protocol == 254:
471        out_string += " DIVERT "
472    if sock.so_proto.pr_protocol == 255:
473        out_string += " RAW "
474    return out_string
475
476def GetInAddr4to6AsString(inaddr):
477    out_string = ""
478    if (inaddr is not None):
479        ia = Cast(inaddr, 'unsigned char *')
480        inaddr_format_string = "{0:d}:{1:d}:{2:d}:{3:d}"
481        out_string += inaddr_format_string.format(unsigned(ia[0]), unsigned(ia[1]), unsigned(ia[2]), unsigned(ia[3]))
482    return out_string
483
484def GetInPortAsString(port):
485    out_string = ""
486    port_string = Cast(port, 'char *')
487    port_unsigned = dereference(Cast(port, 'unsigned short *'))
488
489    if ((((port_unsigned & 0xff00) >> 8) == port_string[0])) and (((port_unsigned & 0x00ff) == port_string[1])):
490        out_string += ":" + str(int(port_unsigned))
491    else:
492        out_string += ":" + str(int(((port_unsigned & 0xff00) >> 8) | ((port_unsigned & 0x00ff) << 8)))
493
494    return out_string
495
496def GetIPv4SocketAsString(sock) :
497    out_string = ""
498    pcb = Cast(sock.so_pcb, 'inpcb *')
499    if (pcb == 0):
500        out_string += "inpcb: (null) "
501    else:
502        out_string += "inpcb: " + hex(pcb)
503        out_string += GetSocketProtocolAsString(sock)
504
505        out_string += GetInAddr4to6AsString(addressof(pcb.inp_dependladdr.inp46_local.ia46_addr4))
506        out_string += GetInPortAsString(addressof(pcb.inp_lport))
507        out_string += " -> "
508        out_string += GetInAddr4to6AsString(addressof(pcb.inp_dependfaddr.inp46_foreign.ia46_addr4))
509        out_string += GetInPortAsString(addressof(pcb.inp_fport))
510    return out_string
511
512def GetIPv6SocketAsString(sock) :
513    out_string = ""
514    pcb = Cast(sock.so_pcb, 'inpcb *')
515    if (pcb == 0):
516        out_string += "inpcb: (null) "
517    else:
518        out_string += "inpcb: " + hex(pcb) + " "
519        out_string += GetSocketProtocolAsString(sock)
520
521        out_string += GetIn6AddrAsString((pcb.inp_dependladdr.inp6_local.__u6_addr.__u6_addr8))
522        out_string += GetInPortAsString(addressof(pcb.inp_lport))
523        out_string += " -> "
524        out_string += GetIn6AddrAsString((pcb.inp_dependfaddr.inp6_foreign.__u6_addr.__u6_addr8))
525        out_string += GetInPortAsString(addressof(pcb.inp_fport))
526    return out_string
527
528def GetUnixDomainSocketAsString(sock) :
529    out_string = ""
530    pcb = Cast(sock.so_pcb, 'unpcb *')
531    if (pcb == 0):
532        out_string += "unpcb: (null) "
533    else:
534        out_string += "unpcb: " + hex(pcb)  + " "
535        out_string += "unp_vnode: " + hex(pcb.unp_vnode) + " "
536        out_string += "unp_conn: " + hex(pcb.unp_conn) + " "
537        out_string += "unp_addr: " + GetSocketAddrAsStringUnix(pcb.unp_addr)
538    return out_string
539
540def GetVsockSocketAsString(sock) :
541    out_string = ""
542    pcb = Cast(sock.so_pcb, 'vsockpcb *')
543    if (pcb == 0):
544        out_string += "vsockpcb: (null) "
545    else:
546        out_string += "vsockpcb: " + hex(pcb) + " "
547        out_string += str(pcb.local_address) + " "
548        out_string += str(pcb.remote_address)
549    return out_string
550
551def GetSocket(socket) :
552    """ Show the contents of a socket
553    """
554    so = kern.GetValueFromAddress(unsigned(socket), 'socket *')
555    if (so):
556        out_string = ""
557        sock_format_string = "so: 0x{0:<x} options 0x{1:<x} state 0x{2:<x}"
558        out_string += sock_format_string.format(so, so.so_options, so.so_state)
559        domain = so.so_proto.pr_domain
560        domain_name_format_string = " {0:<s} "
561        out_string += domain_name_format_string.format(domain.dom_name)
562        if (domain.dom_family == 1):
563            out_string += GetUnixDomainSocketAsString(so)
564        if (domain.dom_family == 2):
565            out_string += GetIPv4SocketAsString(so)
566        if (domain.dom_family == 30):
567            out_string += GetIPv6SocketAsString(so)
568        if (domain.dom_family == 40):
569            out_string += GetVsockSocketAsString(so)
570        out_string += " s=" + str(int(so.so_snd.sb_cc)) + " r=" + str(int(so.so_rcv.sb_cc)) + " usecnt=" + str(int(so.so_usecount))
571    else:
572        out_string += "(null)"
573    return out_string
574# EndMacro: showsocket
575
576
577# Macro: showsocket
578@lldb_command('showsocket')
579def ShowSocket(cmd_args=None) :
580    """ Show the contents of a socket
581    """
582    if cmd_args is None or len(cmd_args) == 0:
583            print("Missing argument 0 in user function.")
584            return
585    so = kern.GetValueFromAddress(cmd_args[0], 'socket *')
586    if (len(str(cmd_args[0])) > 0):
587        out_string = ""
588        sock_format_string = "so: 0x{0:<x} options 0x{1:<x} state 0x{2:<x}"
589        out_string += sock_format_string.format(so, so.so_options, so.so_state)
590        domain = so.so_proto.pr_domain
591        domain_name_format_string = " {0:<s} "
592        out_string += domain_name_format_string.format(domain.dom_name)
593        if (domain.dom_family == 1):
594            out_string += GetUnixDomainSocketAsString(so)
595        if (domain.dom_family == 2):
596            out_string += GetIPv4SocketAsString(so)
597        if (domain.dom_family == 30):
598            out_string += GetIPv6SocketAsString(so)
599        if (domain.dom_family == 40):
600            out_string += GetVsockSocketAsString(so)
601        print(out_string)
602    else:
603        print("Unknown value passed as argument.")
604        return
605# EndMacro: showsocket
606
607def GetProcSockets(proc, total_snd_cc, total_rcv_cc, total_sock_fd):
608    """ Given a proc_t pointer, display information about its sockets
609    """
610    out_string = ""
611
612    if proc is None:
613        out_string += "Unknown value passed as argument."
614    else:
615        snd_cc = 0
616        rcv_cc = 0
617        sock_fd_seen = 0
618        """struct  filedesc *"""
619        proc_filedesc = addressof(proc.p_fd)
620        """struct  fileproc **"""
621        proc_ofiles = proc_filedesc.fd_ofiles
622        """ high-water mark of fd_ofiles """
623        if proc_filedesc.fd_nfiles != 0:
624            for fd in range(0, unsigned(proc_filedesc.fd_afterlast)):
625                if (unsigned(proc_ofiles[fd]) != 0 and proc_ofiles[fd].fp_glob != 0):
626                        fg = proc_ofiles[fd].fp_glob
627                        fg_data = Cast(fg.fg_data, 'void *')
628                        if (int(fg.fg_ops.fo_type) == 2):
629                            if (proc_filedesc.fd_ofileflags[fd] & 4):
630                                out_string += "U: "
631                            else:
632                                out_string += " "
633                            out_string += "fd = " + str(fd) + " "
634                            if (fg_data != 0):
635                                out_string += GetSocket(fg_data)
636                                out_string += "\n"
637
638                                so = Cast(fg_data, 'socket *')
639                                snd_cc += int(so.so_snd.sb_cc)
640                                total_snd_cc[0] += int(so.so_snd.sb_cc)
641                                rcv_cc += int(so.so_rcv.sb_cc)
642                                total_rcv_cc[0] += int(so.so_rcv.sb_cc)
643                                sock_fd_seen += 1
644                            else:
645                                out_string += ""
646        out_string += "total sockets " + str(int(sock_fd_seen)) + " snd_cc " + str(int(snd_cc)) + " rcv_cc " + str(int(rcv_cc)) + "\n"
647        total_sock_fd[0] = sock_fd_seen
648    return out_string
649
650
651# Macro: showprocsockets
652@lldb_command('showprocsockets')
653def ShowProcSockets(cmd_args=None):
654    """ Given a proc_t pointer, display information about its sockets
655    """
656    total_snd_cc = [0]
657    total_rcv_cc = [0]
658    sock_fd_seen = [0]
659    out_string = ""
660    if cmd_args != None and len(cmd_args) > 0 :
661        proc = kern.GetValueFromAddress(cmd_args[0], 'proc *')
662
663        if not proc:
664            print("Unknown value passed as argument.")
665            return
666        else:
667            print(GetProcInfo(proc))
668            print(GetProcSockets(proc, total_snd_cc, total_rcv_cc, sock_fd_seen))
669    else:
670        print("Missing argument 0 in user function.")
671# EndMacro: showprocsockets
672
673# Macro: showallprocsockets
674@lldb_command('showallprocsockets')
675def ShowAllProcSockets(cmd_args=None):
676    """Display information about the sockets of all the processes
677    """
678    total_snd_cc = [0]
679    total_rcv_cc = [0]
680    for proc in kern.procs:
681        sock_fd_seen = [0]
682        out_str = ""
683        out_str += GetProcSockets(proc, total_snd_cc, total_rcv_cc, sock_fd_seen)
684        if sock_fd_seen[0] != 0:
685            print("================================================================================")
686            print(GetProcInfo(proc))
687            print(out_str)
688    print ("total_snd_cc: " + str(int(total_snd_cc[0])) + " total_rcv_cc: " + str(int(total_rcv_cc[0])) + "\n")
689# EndMacro: showallprocsockets
690
691
692def GetRtEntryPrDetailsAsString(rte):
693    out_string = ""
694    rt = Cast(rte, 'rtentry *')
695    dst = Cast(rt.rt_nodes[0].rn_u.rn_leaf.rn_Key, 'sockaddr *')
696    isv6 = 0
697    dst_string_format = "{0:<18s}"
698    if (dst.sa_family == AF_INET):
699        out_string += dst_string_format.format(GetSocketAddrAsStringInet(dst)) + " "
700    else:
701        if (dst.sa_family == AF_INET6):
702            out_string += dst_string_format.format(GetSocketAddrAsStringInet6(dst)) + " "
703            isv6 = 1
704        else:
705            if (dst.sa_family == AF_LINK):
706                out_string += dst_string_format.format(GetSocketAddrAsStringLink(dst))
707                if (isv6 == 1):
708                    out_string += "                       "
709                else:
710                    out_string += " "
711            else:
712                out_string += dst_string_format.format(GetSocketAddrAsStringUnspec(dst)) + " "
713
714    gw = Cast(rt.rt_gateway, 'sockaddr *')
715    if (gw.sa_family == AF_INET):
716        out_string += dst_string_format.format(GetSocketAddrAsStringInet(gw)) + " "
717    else:
718        if (gw.sa_family == 30):
719            out_string += dst_string_format.format(GetSocketAddrAsStringInet6(gw)) + " "
720            isv6 = 1
721        else:
722            if (gw.sa_family == 18):
723                out_string += dst_string_format.format(GetSocketAddrAsStringLink(gw)) + " "
724                if (isv6 == 1):
725                    out_string += "                       "
726                else:
727                    out_string += " "
728            else:
729                dst_string_format.format(GetSocketAddrAsStringUnspec(gw))
730
731    if (rt.rt_flags & RTF_WASCLONED):
732        if (kern.ptrsize == 8):
733            rt_flags_string_format = "0x{0:<16x}"
734            out_string += rt_flags_string_format.format(rt.rt_parent) + " "
735        else:
736            rt_flags_string_format = "0x{0:<8x}"
737            out_string += rt_flags_string_format.format(rt.rt_parent) + " "
738    else:
739        if (kern.ptrsize == 8):
740            out_string += "                   "
741        else:
742            out_string += "           "
743
744    rt_refcnt_rmx_string_format = "{0:<d} {1:>10d}  "
745    out_string += rt_refcnt_rmx_string_format.format(rt.rt_refcnt, rt.rt_rmx.rmx_pksent) + "   "
746
747    rtf_string_format = "{0:>s}"
748    if (rt.rt_flags & RTF_UP):
749        out_string += rtf_string_format.format("U")
750    if (rt.rt_flags & RTF_GATEWAY):
751        out_string += rtf_string_format.format("G")
752    if (rt.rt_flags & RTF_HOST):
753        out_string += rtf_string_format.format("H")
754    if (rt.rt_flags & RTF_REJECT):
755        out_string += rtf_string_format.format("R")
756    if (rt.rt_flags & RTF_DYNAMIC):
757        out_string += rtf_string_format.format("D")
758    if (rt.rt_flags & RTF_MODIFIED):
759        out_string += rtf_string_format.format("M")
760    if (rt.rt_flags & RTF_CLONING):
761        out_string += rtf_string_format.format("C")
762    if (rt.rt_flags & RTF_PRCLONING):
763        out_string += rtf_string_format.format("c")
764    if (rt.rt_flags & RTF_LLINFO):
765        out_string += rtf_string_format.format("L")
766    if (rt.rt_flags & RTF_STATIC):
767        out_string += rtf_string_format.format("S")
768    if (rt.rt_flags & RTF_PROTO1):
769        out_string += rtf_string_format.format("1")
770    if (rt.rt_flags & RTF_PROTO2):
771        out_string += rtf_string_format.format("2")
772    if (rt.rt_flags & RTF_PROTO3):
773        out_string += rtf_string_format.format("3")
774    if (rt.rt_flags & RTF_WASCLONED):
775        out_string += rtf_string_format.format("W")
776    if (rt.rt_flags & RTF_BROADCAST):
777        out_string += rtf_string_format.format("b")
778    if (rt.rt_flags & RTF_MULTICAST):
779        out_string += rtf_string_format.format("m")
780    if (rt.rt_flags & RTF_XRESOLVE):
781        out_string += rtf_string_format.format("X")
782    if (rt.rt_flags & RTF_BLACKHOLE):
783        out_string += rtf_string_format.format("B")
784    if (rt.rt_flags & RTF_IFSCOPE):
785        out_string += rtf_string_format.format("I")
786    if (rt.rt_flags & RTF_CONDEMNED):
787        out_string += rtf_string_format.format("Z")
788    if (rt.rt_flags & RTF_IFREF):
789        out_string += rtf_string_format.format("i")
790    if (rt.rt_flags & RTF_PROXY):
791        out_string += rtf_string_format.format("Y")
792    if (rt.rt_flags & RTF_ROUTER):
793        out_string += rtf_string_format.format("r")
794
795    out_string +=  "/"
796    out_string += str(rt.rt_ifp.if_name)
797    out_string += str(int(rt.rt_ifp.if_unit))
798    out_string += "\n"
799    return out_string
800
801
802RNF_ROOT = 2
803def GetRtTableAsString(rt_tables):
804    out_string = ""
805    rn = Cast(rt_tables.rnh_treetop, 'radix_node *')
806    rnh_cnt = rt_tables.rnh_cnt
807
808    while (rn.rn_bit >= 0):
809        rn = rn.rn_u.rn_node.rn_L
810
811    while 1:
812        base = Cast(rn, 'radix_node *')
813        while ((rn.rn_parent.rn_u.rn_node.rn_R == rn) and (rn.rn_flags & RNF_ROOT == 0)):
814            rn = rn.rn_parent
815        rn = rn.rn_parent.rn_u.rn_node.rn_R
816        while (rn.rn_bit >= 0):
817            rn = rn.rn_u.rn_node.rn_L
818        next_rn = rn
819        while (base != 0):
820            rn = base
821            base = rn.rn_u.rn_leaf.rn_Dupedkey
822            if ((rn.rn_flags & RNF_ROOT) == 0):
823                rt = Cast(rn, 'rtentry *')
824                if (kern.ptrsize == 8):
825                    rtentry_string_format = "0x{0:<18x}"
826                    out_string += rtentry_string_format.format(rt) + " "
827                else:
828                    rtentry_string_format = "0x{0:<10x}"
829                    out_string += rtentry_string_format.format(rt) + " "
830                out_string += GetRtEntryPrDetailsAsString(rt) + " "
831
832        rn = next_rn
833        if ((rn.rn_flags & RNF_ROOT) != 0):
834            break
835    return out_string
836
837def GetRtInetAsString():
838    rt_tables = kern.globals.rt_tables[2]
839    if (kern.ptrsize == 8):
840        rt_table_header_format_string = "{0:<18s} {1: <16s} {2:<20s} {3:<16s} {4:<8s} {5:<8s} {6:<8s}"
841        print(rt_table_header_format_string.format("rtentry", " dst", "gw", "parent", "Refs", "Use", "flags/if"))
842        print(rt_table_header_format_string.format("-" * 18, "-" * 16, "-" * 16, "-" * 16, "-" * 8, "-" * 8, "-" * 8))
843        print(GetRtTableAsString(rt_tables))
844    else:
845        rt_table_header_format_string = "{0:<8s} {1:<16s} {2:<18s} {3:<8s} {4:<8s} {5:<8s} {6:<8s}"
846        print(rt_table_header_format_string.format("rtentry", "dst", "gw", "parent", "Refs", "Use", "flags/if"))
847        print(rt_table_header_format_string.format("-" * 8, "-" * 16, "-" * 16, "-" * 8, "-" * 8, "-" * 8, "-" * 8))
848        print(GetRtTableAsString(rt_tables))
849
850def GetRtInet6AsString():
851    rt_tables = kern.globals.rt_tables[30]
852    if (kern.ptrsize == 8):
853        rt_table_header_format_string = "{0:<18s} {1: <16s} {2:<20s} {3:<16s} {4:<8s} {5:<8s} {6:<8s}"
854        print(rt_table_header_format_string.format("rtentry", " dst", "gw", "parent", "Refs", "Use", "flags/if"))
855        print(rt_table_header_format_string.format("-" * 18, "-" * 16, "-" * 16, "-" * 16, "-" * 8, "-" * 8, "-" * 8))
856        print(GetRtTableAsString(rt_tables))
857    else:
858        rt_table_header_format_string = "{0:<8s} {1:<16s} {2:<18s} {3:<8s} {4:<8s} {5:<8s} {6:<8s}"
859        print(rt_table_header_format_string.format("rtentry", "dst", "gw", "parent", "Refs", "Use", "flags/if"))
860        print(rt_table_header_format_string.format("-" * 8, "-" * 16, "-" * 18, "-" * 8, "-" * 8, "-" * 8, "-" * 8))
861        print(GetRtTableAsString(rt_tables))
862
863# Macro: show_rt_inet
864@lldb_command('show_rt_inet')
865def ShowRtInet(cmd_args=None):
866    """ Display the IPv4 routing table
867    """
868    print(GetRtInetAsString())
869# EndMacro: show_rt_inet
870
871# Macro: show_rt_inet6
872@lldb_command('show_rt_inet6')
873def ShowRtInet6(cmd_args=None):
874    """ Display the IPv6 routing table
875    """
876    print(GetRtInet6AsString())
877# EndMacro: show_rt_inet6
878
879# Macro: rtentry_showdbg
880@lldb_command('rtentry_showdbg')
881def ShowRtEntryDebug(cmd_args=None):
882    """ Print the debug information of a route entry
883    """
884    if cmd_args is None or len(cmd_args) == 0:
885            print("Missing argument 0 in user function.")
886            return
887    out_string = ""
888    cnt = 0
889    rtd = kern.GetValueFromAddress(cmd_args[0], 'rtentry_dbg *')
890    rtd_summary_format_string = "{0:s} {1:d}"
891    out_string += rtd_summary_format_string.format("Total holds : ", rtd.rtd_refhold_cnt) + "\n"
892    out_string += rtd_summary_format_string.format("Total releases : ", rtd.rtd_refrele_cnt) + "\n"
893
894    ix = 0
895    while (ix < CTRACE_STACK_SIZE):
896        kgm_pc = rtd.rtd_alloc.pc[ix]
897        if (kgm_pc != 0):
898            if (ix == 0):
899                out_string += "\nAlloc: (thread " + hex(rtd.rtd_alloc.th) + "):\n"
900            out_string += str(int(ix + 1)) + ": "
901            out_string += GetSourceInformationForAddress(kgm_pc)
902            out_string += "\n"
903        ix += 1
904
905    ix = 0
906    while (ix < CTRACE_STACK_SIZE):
907        kgm_pc = rtd.rtd_free.pc[ix]
908        if (kgm_pc != 0):
909            if (ix == 0):
910                out_string += "\nFree: (thread " + hex(rtd.rtd_free.th) + "):\n"
911            out_string += str(int(ix + 1)) + ": "
912            out_string += GetSourceInformationForAddress(kgm_pc)
913            out_string += "\n"
914        ix += 1
915
916    while (cnt < RTD_TRACE_HIST_SIZE):
917        ix = 0
918        while (ix < CTRACE_STACK_SIZE):
919            kgm_pc = rtd.rtd_refhold[cnt].pc[ix]
920            if (kgm_pc != 0):
921                if (ix == 0):
922                    out_string += "\nHold [" + str(int(cnt)) + "] (thread " + hex(rtd.rtd_refhold[cnt].th) + "):\n"
923                out_string += str(int(ix + 1)) + ": "
924                out_string += GetSourceInformationForAddress(kgm_pc)
925                out_string += "\n"
926            ix += 1
927        cnt += 1
928
929    cnt = 0
930    while (cnt < RTD_TRACE_HIST_SIZE):
931        ix = 0
932        while (ix < CTRACE_STACK_SIZE):
933            kgm_pc = rtd.rtd_refrele[cnt].pc[ix]
934            if (kgm_pc != 0):
935                if (ix == 0):
936                    out_string += "\nRelease [" + str(int(cnt)) + "] (thread " + hex(rtd.rtd_refrele[cnt].th) + "):\n"
937                out_string += str(int(ix + 1)) + ": "
938                out_string += GetSourceInformationForAddress(kgm_pc)
939                out_string += "\n"
940            ix += 1
941        cnt += 1
942
943    out_string += "\nTotal locks : " + str(int(rtd.rtd_lock_cnt))
944    out_string += "\nTotal unlocks : " + str(int(rtd.rtd_unlock_cnt))
945
946    cnt = 0
947    while (cnt < RTD_TRACE_HIST_SIZE):
948        ix = 0
949        while (ix < CTRACE_STACK_SIZE):
950            kgm_pc = rtd.rtd_lock[cnt].pc[ix]
951            if (kgm_pc != 0):
952                if (ix == 0):
953                    out_string += "\nLock [" + str(int(cnt)) + "] (thread " + hex(rtd.rtd_lock[cnt].th) + "):\n"
954                out_string += str(int(ix + 1)) + ": "
955                out_string += GetSourceInformationForAddress(kgm_pc)
956                out_string += "\n"
957            ix += 1
958        cnt += 1
959
960    cnt = 0
961    while (cnt < RTD_TRACE_HIST_SIZE):
962        ix = 0
963        while (ix < CTRACE_STACK_SIZE):
964            kgm_pc = rtd.rtd_unlock[cnt].pc[ix]
965            if (kgm_pc != 0):
966                if (ix == 0):
967                    out_string += "\nUnlock [" + str(int(cnt)) + "] (thread " + hex(rtd.rtd_unlock[cnt].th) + "):\n"
968                out_string += str(int(ix + 1)) + ": "
969                out_string += GetSourceInformationForAddress(kgm_pc)
970                out_string += "\n"
971            ix += 1
972        cnt += 1
973
974    print(out_string)
975# EndMacro: rtentry_showdbg
976
977# Macro: inm_showdbg
978@lldb_command('inm_showdbg')
979def InmShowDebug(cmd_args=None):
980    """ Print the debug information of an IPv4 multicast address
981    """
982    if cmd_args is None or len(cmd_args) == 0:
983            print("Missing argument 0 in user function.")
984            return
985    out_string = ""
986    cnt = 0
987    inm = kern.GetValueFromAddress(cmd_args[0], 'in_multi_dbg *')
988    in_multi_summary_format_string = "{0:s} {1:d}"
989    out_string += in_multi_summary_format_string.format("Total holds : ", inm.inm_refhold_cnt)
990    out_string += in_multi_summary_format_string.format("Total releases : ", inm.inm_refrele_cnt)
991
992    while (cnt < INM_TRACE_HIST_SIZE):
993        ix = 0
994        while (ix < CTRACE_STACK_SIZE):
995            kgm_pc = inm.inm_refhold[cnt].pc[ix]
996            if (kgm_pc != 0):
997                if (ix == 0):
998                    out_string += "\nHold [" + str(int(cnt)) + "] (thread " + hex(inm.inm_refhold[cnt].th) + "):\n"
999                out_string += str(int(ix + 1)) + ": "
1000                out_string += GetSourceInformationForAddress(kgm_pc)
1001                out_string += "\n"
1002            ix += 1
1003        cnt += 1
1004    cnt = 0
1005    while (cnt < INM_TRACE_HIST_SIZE):
1006        ix = 0
1007        while (ix < CTRACE_STACK_SIZE):
1008            kgm_pc = inm.inm_refrele[cnt].pc[ix]
1009            if (kgm_pc != 0):
1010                if (ix == 0):
1011                    out_string += "\nRelease [" + str(int(cnt)) + "] (thread " + hex(inm.inm_refrele[cnt].th) + "):\n"
1012                out_string += str(int(ix + 1)) + ": "
1013                out_string += GetSourceInformationForAddress(kgm_pc)
1014                out_string += "\n"
1015            ix += 1
1016        cnt += 1
1017    print(out_string)
1018# EndMacro: inm_showdbg
1019
1020# Macro: ifma_showdbg
1021@lldb_command('ifma_showdbg')
1022def IfmaShowDebug(cmd_args=None):
1023    """ Print the debug information of a link multicast address
1024    """
1025    if cmd_args is None or len(cmd_args) == 0:
1026            print("Missing argument 0 in user function.")
1027            return
1028    out_string = ""
1029    cnt = 0
1030    ifma = kern.GetValueFromAddress(cmd_args[0], 'ifmultiaddr_dbg *')
1031    link_multi_summary_format_string = "{0:s} {1:d}"
1032    out_string += link_multi_summary_format_string.format("Total holds : ", ifma.ifma_refhold_cnt) + "\n"
1033    out_string += link_multi_summary_format_string.format("Total releases : ", ifma.ifma_refrele_cnt) + "\n"
1034
1035    while (cnt < IFMA_TRACE_HIST_SIZE):
1036        ix = 0
1037        while (ix < CTRACE_STACK_SIZE):
1038            kgm_pc = ifma.ifma_refhold[cnt].pc[ix]
1039            if (kgm_pc != 0):
1040                if (ix == 0):
1041                    out_string += "\nHold [" + str(int(cnt)) + "] (thread " + hex(ifma.ifma_refhold[cnt].th) + "):\n"
1042                out_string += str(int(ix + 1)) + ": "
1043                out_string += GetSourceInformationForAddress(kgm_pc)
1044                out_string += "\n"
1045            ix += 1
1046        cnt += 1
1047    cnt = 0
1048    while (cnt < IFMA_TRACE_HIST_SIZE):
1049        ix = 0
1050        while (ix < CTRACE_STACK_SIZE):
1051            kgm_pc = ifma.ifma_refrele[cnt].pc[ix]
1052            if (kgm_pc != 0):
1053                if (ix == 0):
1054                    out_string += "\nRelease [" + str(int(cnt)) + "] (thread " + hex(ifma.ifma_refrele[cnt].th) + "):\n"
1055                out_string += str(int(ix + 1)) + ": "
1056                out_string += GetSourceInformationForAddress(kgm_pc)
1057                out_string += "\n"
1058            ix += 1
1059        cnt += 1
1060    print(out_string)
1061# EndMacro: ifma_showdbg
1062
1063# Macro: ifpref_showdbg
1064@lldb_command('ifpref_showdbg')
1065def IfpRefShowDebug(cmd_args=None):
1066    """ Print the debug information of an interface ref count
1067    """
1068    if cmd_args is None or len(cmd_args) == 0:
1069            print("Missing argument 0 in user function.")
1070            return
1071    out_string = ""
1072    cnt = 0
1073    dl_if = kern.GetValueFromAddress(cmd_args[0], 'dlil_ifnet_dbg *')
1074    dl_if_summary_format_string = "{0:s} {1:d}"
1075    out_string +=  dl_if_summary_format_string.format("Total holds : ", dl_if.dldbg_if_refhold_cnt)
1076    out_string += dl_if_summary_format_string.format("Total releases : ", dl_if.dldbg_if_refrele_cnt)
1077
1078    while (cnt < IF_REF_TRACE_HIST_SIZE):
1079        ix = 0
1080        while (ix < CTRACE_STACK_SIZE):
1081            kgm_pc = dl_if.dldbg_if_refhold[cnt].pc[ix]
1082            if (kgm_pc != 0):
1083                if (ix == 0):
1084                    out_string += "\nHold [" + str(int(cnt)) + "] (thread " + hex(dl_if.dldbg_if_refhold[cnt].th) + "):\n"
1085                out_string += str(int(ix + 1)) + ": "
1086                out_string += GetSourceInformationForAddress(kgm_pc)
1087                out_string += "\n"
1088            ix += 1
1089        cnt += 1
1090    cnt = 0
1091    while (cnt < IF_REF_TRACE_HIST_SIZE):
1092        ix = 0
1093        while (ix < CTRACE_STACK_SIZE):
1094            kgm_pc = dl_if.dldbg_if_refrele[cnt].pc[ix]
1095            if (kgm_pc != 0):
1096                if (ix == 0):
1097                    out_string += "\nRelease [" + str(int(cnt)) + "] (thread " + hex(dl_if.dldbg_if_refrele[cnt].th) + "):\n"
1098                out_string += str(int(ix + 1)) + ": "
1099                out_string += GetSourceInformationForAddress(kgm_pc)
1100                out_string += "\n"
1101            ix += 1
1102        cnt += 1
1103    print(out_string)
1104# EndMacro: ifpref_showdbg
1105
1106# Macro: ndpr_showdbg
1107@lldb_command('ndpr_showdbg')
1108def ndprShowDebug(cmd_args=None):
1109    """ Print the debug information of a nd_prefix structure
1110    """
1111    if cmd_args is None or len(cmd_args) == 0:
1112            print("Missing argument 0 in user function.")
1113            return
1114    out_string = ""
1115    cnt = 0
1116    ndpr = kern.GetValueFromAddress(cmd_args[0], 'nd_prefix_dbg *')
1117    ndpr_summary_format_string = "{0:s} {1:d}"
1118    out_string += ndpr_summary_format_string.format("Total holds : ", ndpr.ndpr_refhold_cnt)
1119    out_string += ndpr_summary_format_string.format("Total releases : ", ndpr.ndpr_refrele_cnt)
1120
1121    while (cnt < NDPR_TRACE_HIST_SIZE):
1122        ix = 0
1123        while (ix < CTRACE_STACK_SIZE):
1124            kgm_pc = ndpr.ndpr_refhold[cnt].pc[ix]
1125            if (kgm_pc != 0):
1126                if (ix == 0):
1127                    out_string += "\nHold [" + str(int(cnt)) + "] (thread " + hex(ndpr.ndpr_refhold[cnt].th) + "):\n"
1128                out_string += str(int(ix + 1)) + ": "
1129                out_string += GetSourceInformationForAddress(kgm_pc)
1130                out_string += "\n"
1131            ix += 1
1132        cnt += 1
1133    cnt = 0
1134    while (cnt < NDPR_TRACE_HIST_SIZE):
1135        ix = 0
1136        while (ix < CTRACE_STACK_SIZE):
1137            kgm_pc = ndpr.ndpr_refrele[cnt].pc[ix]
1138            if (kgm_pc != 0):
1139                if (ix == 0):
1140                    out_string += "\nRelease [" + str(int(cnt)) + "] (thread " + hex(ndpr.ndpr_refrele[cnt].th) + "):\n"
1141                out_string += str(int(ix + 1)) + ": "
1142                out_string += GetSourceInformationForAddress(kgm_pc)
1143                out_string += "\n"
1144            ix += 1
1145        cnt += 1
1146    print(out_string)
1147# EndMacro: ndpr_showdbg
1148
1149# Macro: nddr_showdbg
1150@lldb_command('nddr_showdbg')
1151def nddrShowDebug(cmd_args=None):
1152    """ Print the debug information of a nd_defrouter structure
1153    """
1154    if cmd_args is None or len(cmd_args) == 0:
1155            print("Missing argument 0 in user function.")
1156            return
1157    out_string = ""
1158    cnt = 0
1159    nddr = kern.GetValueFromAddress(cmd_args[0], 'nd_defrouter_dbg *')
1160    nddr_summary_format_string = "{0:s} {1:d}"
1161    out_string += nddr_summary_format_string.format("Total holds : ", nddr.nddr_refhold_cnt)
1162    out_string += nddr_summary_format_string.format("Total releases : ", nddr.nddr_refrele_cnt)
1163
1164    while (cnt < NDDR_TRACE_HIST_SIZE):
1165        ix = 0
1166        while (ix < CTRACE_STACK_SIZE):
1167            kgm_pc = nddr.nddr_refhold[cnt].pc[ix]
1168            if (kgm_pc != 0):
1169                if (ix == 0):
1170                    out_string += "\nHold [" + str(int(cnt)) + "] (thread " + hex(nddr.nddr_refhold[cnt].th) + "):\n"
1171                out_string += str(int(ix + 1)) + ": "
1172                out_string += GetSourceInformationForAddress(kgm_pc)
1173                out_string += "\n"
1174            ix += 1
1175        cnt += 1
1176    cnt = 0
1177    while (cnt < NDDR_TRACE_HIST_SIZE):
1178        ix = 0
1179        while (ix < CTRACE_STACK_SIZE):
1180            kgm_pc = nddr.nddr_refrele[cnt].pc[ix]
1181            if (kgm_pc != 0):
1182                if (ix == 0):
1183                    out_string += "\nRelease [" + str(int(cnt)) + "] (thread " + hex(nddr.nddr_refrele[cnt].th) + "):\n"
1184                out_string += str(int(ix + 1)) + ": "
1185                out_string += GetSourceInformationForAddress(kgm_pc)
1186                out_string += "\n"
1187            ix += 1
1188        cnt += 1
1189    print(out_string)
1190# EndMacro: nddr_showdbg
1191
1192# Macro: imo_showdbg
1193@lldb_command('imo_showdbg')
1194def IpmOptions(cmd_args=None):
1195    """ Print the debug information of a ip_moptions structure
1196    """
1197    if cmd_args is None or len(cmd_args) == 0:
1198            print("Missing argument 0 in user function.")
1199            return
1200    out_string = ""
1201    cnt = 0
1202    imo = kern.GetValueFromAddress(cmd_args[0], 'ip_moptions_dbg *')
1203    imo_summary_format_string = "{0:s} {1:d}"
1204    out_string += imo_summary_format_string.format("Total holds : ", imo.imo_refhold_cnt)
1205    out_string += imo_summary_format_string.format("Total releases : ", imo.imo_refrele_cnt)
1206
1207    while (cnt < IMO_TRACE_HIST_SIZE):
1208        ix = 0
1209        while (ix < CTRACE_STACK_SIZE):
1210            kgm_pc = imo.imo_refhold[cnt].pc[ix]
1211            if (kgm_pc != 0):
1212                if (ix == 0):
1213                    out_string += "\nHold [" + str(int(cnt)) + "] (thread " + hex(imo.imo_refhold[cnt].th) + "):\n"
1214                out_string += str(int(ix + 1)) + ": "
1215                out_string += GetSourceInformationForAddress(kgm_pc)
1216                out_string += "\n"
1217            ix += 1
1218        cnt += 1
1219    cnt = 0
1220    while (cnt < IMO_TRACE_HIST_SIZE):
1221        ix = 0
1222        while (ix < CTRACE_STACK_SIZE):
1223            kgm_pc = imo.imo_refrele[cnt].pc[ix]
1224            if (kgm_pc != 0):
1225                if (ix == 0):
1226                    out_string += "\nRelease [" + str(int(cnt)) + "] (thread " + hex(imo.imo_refrele[cnt].th) + "):\n"
1227                out_string += str(int(ix + 1)) + ": "
1228                out_string += GetSourceInformationForAddress(kgm_pc)
1229                out_string += "\n"
1230            ix += 1
1231        cnt += 1
1232    print(out_string)
1233# EndMacro: imo_showdbg
1234
1235# Macro: im6o_showdbg
1236@lldb_command('im6o_showdbg')
1237def IpmOptions(cmd_args=None):
1238    """ Print the debug information of a ip6_moptions structure
1239    """
1240    if cmd_args is None or len(cmd_args) == 0:
1241            print("Missing argument 0 in user function.")
1242            return
1243    out_string = ""
1244    cnt = 0
1245    im6o = kern.GetValueFromAddress(cmd_args[0], 'ip6_moptions_dbg *')
1246    im6o_summary_format_string = "{0:s} {1:d}"
1247    out_string += im6o_summary_format_string.format("Total holds : ", im6o.im6o_refhold_cnt)
1248    out_string += im6o_summary_format_string.format("Total releases : ", im6o.im6o_refrele_cnt)
1249
1250    while (cnt < IM6O_TRACE_HIST_SIZE):
1251        ix = 0
1252        while (ix < CTRACE_STACK_SIZE):
1253            kgm_pc = im6o.im6o_refhold[cnt].pc[ix]
1254            if (kgm_pc != 0):
1255                if (ix == 0):
1256                    out_string += "\nHold [" + str(int(cnt)) + "] (thread " + hex(im6o.im6o_refhold[cnt].th) + "):\n"
1257                out_string += str(int(ix + 1)) + ": "
1258                out_string += GetSourceInformationForAddress(kgm_pc)
1259                out_string += "\n"
1260            ix += 1
1261        cnt += 1
1262    cnt = 0
1263    while (cnt < IM6O_TRACE_HIST_SIZE):
1264        ix = 0
1265        while (ix < CTRACE_STACK_SIZE):
1266            kgm_pc = im6o.im6o_refrele[cnt].pc[ix]
1267            if (kgm_pc != 0):
1268                if (ix == 0):
1269                    out_string += "\nRelease [" + str(int(cnt)) + "] (thread " + hex(im6o.im6o_refrele[cnt].th) + "):\n"
1270                out_string += str(int(ix + 1)) + ": "
1271                out_string += GetSourceInformationForAddress(kgm_pc)
1272                out_string += "\n"
1273            ix += 1
1274        cnt += 1
1275    print(out_string)
1276# EndMacro: im6o_showdbg
1277
1278# Macro: rtentry_trash
1279@lldb_command('rtentry_trash')
1280def RtEntryTrash(cmd_args=None):
1281    """ Walk the list of trash route entries
1282    """
1283    out_string = ""
1284    rt_trash_head = kern.globals.rttrash_head
1285    rtd = Cast(rt_trash_head.tqh_first, 'rtentry_dbg *')
1286    rt_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1287    cnt = 0
1288    while (int(rtd) != 0):
1289        if (cnt == 0):
1290            if (kern.ptrsize == 8):
1291                print("                rtentry ref   hold   rele             dst    gw             parent flags/if\n")
1292                print("      ----------------- --- ------ ------ --------------- ----- ------------------ -----------\n")
1293            else:
1294                print("        rtentry ref   hold   rele             dst    gw     parent flags/if\n")
1295                print("      --------- --- ------ ------ --------------- ----- ---------- -----------\n")
1296        out_string += rt_trash_format_string.format(cnt, rtd, rtd.rtd_refhold_cnt - rtd.rtd_refrele_cnt, rtd.rtd_refhold_cnt, rtd.rtd_refrele_cnt) + "   "
1297        out_string += GetRtEntryPrDetailsAsString(rtd) + "\n"
1298        rtd = rtd.rtd_trash_link.tqe_next
1299        cnt += 1
1300    print(out_string)
1301# EndMacro: rtentry_trash
1302
1303# Macro: show_rtentry
1304@lldb_command('show_rtentry')
1305def ShRtEntry(cmd_args=None):
1306    """ Print rtentry.
1307    """
1308    if cmd_args is None or len(cmd_args) == 0:
1309        raise ArgumentError()
1310
1311    out_string = ""
1312    rt = kern.GetValueFromAddress(cmd_args[0], 'rtentry *')
1313    out_string += GetRtEntryPrDetailsAsString(rt) + "\n"
1314    print(out_string)
1315# EndMacro: show_rtentry
1316
1317# Macro: inm_trash
1318@lldb_command('inm_trash')
1319def InmTrash(cmd_args=None):
1320    """ Walk the list of trash in_multi entries
1321    """
1322    out_string = ""
1323    inm_trash_head = kern.globals.inm_trash_head
1324    inm = Cast(inm_trash_head.tqh_first, 'in_multi_dbg *')
1325    inm_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1326    cnt = 0
1327    while (int(inm) != 0):
1328        if (cnt == 0):
1329            if (kern.ptrsize == 8):
1330                print("                     inm  ref   hold   rele")
1331                print("      ------------------  --- ------ ------")
1332            else:
1333                print("             inm  ref   hold   rele")
1334                print("      ----------  --- ------ ------")
1335        out_string += inm_trash_format_string.format(cnt + 1, inm, inm.inm_refhold_cnt - inm.inm_refrele_cnt, inm.inm_refhold_cnt, inm.inm_refrele_cnt) + "   "
1336        out_string += GetInAddrAsString(addressof(inm.inm.inm_addr)) + "\n"
1337        inm = inm.inm_trash_link.tqe_next
1338        cnt += 1
1339    print(out_string)
1340# EndMacro: inm_trash
1341
1342# Macro: in6m_trash
1343@lldb_command('in6m_trash')
1344def In6mTrash(cmd_args=None):
1345    """ Walk the list of trash in6_multi entries
1346    """
1347    out_string = ""
1348    in6m_trash_head = kern.globals.in6m_trash_head
1349    in6m = Cast(in6m_trash_head.tqh_first, 'in6_multi_dbg *')
1350    in6m_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1351    cnt = 0
1352    while (int(in6m) != 0):
1353        if (cnt == 0):
1354            if (kern.ptrsize == 8):
1355                print("                    in6m  ref   hold   rele")
1356                print("      ------------------  --- ------ ------")
1357            else:
1358                print("            in6m  ref   hold   rele")
1359                print("      ----------  --- ------ ------")
1360        out_string += in6m_trash_format_string.format(cnt + 1, in6m, in6m.in6m_refhold_cnt - in6m.in6m_refrele_cnt, in6m.in6m_refhold_cnt, in6m.in6m_refrele_cnt) + "   "
1361        out_string += GetIn6AddrAsString(addressof(in6m.in6m.in6m_addr)) + "\n"
1362        in6m = in6m.in6m_trash_link.tqe_next
1363        cnt += 1
1364    print(out_string)
1365# EndMacro: in6m_trash
1366
1367# Macro: ifma_trash
1368@lldb_command('ifma_trash')
1369def IfmaTrash(cmd_args=None):
1370    """ Walk the list of trash ifmultiaddr entries
1371    """
1372    out_string = ""
1373    ifma_trash_head = kern.globals.ifma_trash_head
1374    ifma = Cast(ifma_trash_head.tqh_first, 'ifmultiaddr_dbg *')
1375    ifma_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1376    cnt = 0
1377    while (int(ifma) != 0):
1378        if (cnt == 0):
1379            if (kern.ptrsize == 8):
1380                print("                    ifma  ref   hold   rele")
1381                print("      ------------------  --- ------ ------")
1382            else:
1383                print("            ifma  ref   hold   rele")
1384                print("      ----------  --- ------ ------")
1385        out_string += ifma_trash_format_string.format(cnt + 1, ifma, ifma.ifma_refhold_cnt - ifma.ifma_refrele_cnt, ifma.ifma_refhold_cnt, ifma.ifma_refrele_cnt) + "   "
1386        out_string += GetSocketAddrAsString(ifma.ifma.ifma_addr) + "\n"
1387        out_string += " @ " + ifma.ifma.ifma_ifp.if_xname
1388        ifma = ifma.ifma_trash_link.tqe_next
1389        cnt += 1
1390    print(out_string)
1391# EndMacro: ifma_trash
1392
1393def GetInPcb(pcb, proto):
1394    out_string = ""
1395    out_string += hex(pcb)
1396
1397    if (proto == IPPROTO_TCP):
1398        out_string +=  " tcp"
1399    elif (proto == IPPROTO_UDP):
1400        out_string += " udp"
1401    elif (proto == IPPROTO_RAW):
1402        out_string += " raw"
1403    else:
1404        out_string += str(proto) +  "."
1405
1406    if (pcb.inp_vflag & INP_IPV4):
1407        out_string += "4 "
1408    if (pcb.inp_vflag & INP_IPV6):
1409        out_string += "6 "
1410
1411    if (pcb.inp_vflag & INP_IPV4):
1412        out_string += "                                       "
1413        out_string += GetInAddrAsString(addressof(pcb.inp_dependladdr.inp46_local.ia46_addr4))
1414    else:
1415        out_string += "  "
1416        out_string += GetIn6AddrAsString((pcb.inp_dependladdr.inp6_local.__u6_addr.__u6_addr8))
1417
1418    out_string += " "
1419    out_string += Getntohs(pcb.inp_lport)
1420    out_string += " "
1421
1422    if (pcb.inp_vflag & INP_IPV4):
1423        out_string += "                                 "
1424        out_string += GetInAddrAsString(addressof(pcb.inp_dependfaddr.inp46_foreign.ia46_addr4))
1425    else:
1426        out_string += GetIn6AddrAsString((pcb.inp_dependfaddr.inp6_foreign.__u6_addr.__u6_addr8))
1427
1428    out_string += " "
1429    out_string += Getntohs(pcb.inp_fport)
1430    out_string += " "
1431
1432    if (proto == IPPROTO_TCP):
1433        out_string += GetTcpState(pcb.inp_ppcb)
1434
1435    out_string += "\n\t"
1436    if (pcb.inp_flags & INP_RECVOPTS):
1437        out_string += "recvopts "
1438    if (pcb.inp_flags & INP_RECVRETOPTS):
1439        out_string += "recvretopts "
1440    if (pcb.inp_flags & INP_RECVDSTADDR):
1441        out_string += "recvdstaddr "
1442    if (pcb.inp_flags & INP_HDRINCL):
1443        out_string += "hdrincl "
1444    if (pcb.inp_flags & INP_HIGHPORT):
1445        out_string += "highport "
1446    if (pcb.inp_flags & INP_LOWPORT):
1447        out_string += "lowport "
1448    if (pcb.inp_flags & INP_ANONPORT):
1449        out_string += "anonport "
1450    if (pcb.inp_flags & INP_RECVIF):
1451        out_string += "recvif "
1452    if (pcb.inp_flags & INP_MTUDISC):
1453        out_string += "mtudisc "
1454    if (pcb.inp_flags & INP_STRIPHDR):
1455        out_string += "striphdr "
1456    if (pcb.inp_flags & INP_RECV_ANYIF):
1457        out_string += "recv_anyif "
1458    if (pcb.inp_flags & INP_INADDR_ANY):
1459        out_string += "inaddr_any "
1460    if (pcb.inp_flags & INP_RECVTTL):
1461        out_string += "recvttl "
1462    if (pcb.inp_flags & INP_UDP_NOCKSUM):
1463        out_string += "nocksum "
1464    if (pcb.inp_flags & INP_BOUND_IF):
1465        out_string += "boundif "
1466    if (pcb.inp_flags & IN6P_IPV6_V6ONLY):
1467        out_string += "v6only "
1468    if (pcb.inp_flags & IN6P_PKTINFO):
1469        out_string += "pktinfo "
1470    if (pcb.inp_flags & IN6P_HOPLIMIT):
1471        out_string += "hoplimit "
1472    if (pcb.inp_flags & IN6P_HOPOPTS):
1473        out_string += "hopopts "
1474    if (pcb.inp_flags & IN6P_DSTOPTS):
1475        out_string += "dstopts "
1476    if (pcb.inp_flags & IN6P_RTHDR):
1477        out_string += "rthdr "
1478    if (pcb.inp_flags & IN6P_RTHDRDSTOPTS):
1479        out_string += "rthdrdstopts "
1480    if (pcb.inp_flags & IN6P_TCLASS):
1481        out_string += "rcv_tclass "
1482    if (pcb.inp_flags & IN6P_AUTOFLOWLABEL):
1483        out_string += "autoflowlabel "
1484    if (pcb.inp_flags & IN6P_BINDV6ONLY):
1485        out_string += "bindv6only "
1486    if (pcb.inp_flags & IN6P_RFC2292):
1487        out_string += "RFC2292 "
1488    if (pcb.inp_flags & IN6P_MTU):
1489        out_string += "rcv_pmtu "
1490    if (pcb.inp_flags & INP_PKTINFO):
1491        out_string += "pktinfo "
1492    if (pcb.inp_flags & INP_FLOW_SUSPENDED):
1493        out_string += "suspended "
1494    if (pcb.inp_flags & INP_NO_IFT_CELLULAR):
1495        out_string += "nocellular "
1496    if (pcb.inp_flags & INP_FLOW_CONTROLLED):
1497        out_string += "flowctld "
1498    if (pcb.inp_flags & INP_FC_FEEDBACK):
1499        out_string += "fcfeedback "
1500    if (pcb.inp_flags2 & INP2_TIMEWAIT):
1501        out_string += "timewait "
1502    if (pcb.inp_flags2 & INP2_IN_FCTREE):
1503        out_string += "in_fctree "
1504    if (pcb.inp_flags2 & INP2_WANT_APP_POLICY):
1505        out_string += "want_app_policy "
1506
1507    out_string += "\n\t"
1508    so = pcb.inp_socket
1509    if (so != 0):
1510        out_string += "so=" + str(so) + " s=" + str(int(so.so_snd.sb_cc)) + " r=" + str(int(so.so_rcv.sb_cc))
1511        if proto == IPPROTO_TCP :
1512            tcpcb = cast(pcb.inp_ppcb, 'tcpcb *')
1513            out_string += " reass=" + str(int(tcpcb.t_reassqlen))
1514
1515        out_string += " usecnt=" + str(int(so.so_usecount))
1516
1517    if (pcb.inp_state == 0 or pcb.inp_state == INPCB_STATE_INUSE):
1518        out_string += " inuse"
1519    else:
1520        if (pcb.inp_state == INPCB_STATE_DEAD):
1521            out_string += " dead"
1522        else:
1523            out_string += " unknown (" + str(int(pcb.inp_state)) + ")"
1524
1525    ifname = ""
1526    if (pcb.inp_flags & INP_BOUND_IF):
1527        ifp = pcb.inp_boundifp
1528    else:
1529        ifp = pcb.inp_last_outifp
1530    if (ifp != 0):
1531        ifname = ifp.if_xname
1532    out_string += " ifp=" + str(ifname)
1533
1534    out_string += " last_proc=" + str(pcb.inp_last_proc_name) + ":" + str(int(so.last_pid))
1535
1536    return out_string
1537
1538def CalcMbufInList(mpkt, pkt_cnt, buf_byte_cnt, mbuf_cnt, mbuf_cluster_cnt):
1539    while (mpkt != 0):
1540        mp = mpkt
1541        if kern.arch == 'x86_64':
1542            mpkt = mp.m_hdr.mh_nextpkt
1543        else:
1544            mpkt = mp.M_hdr_common.M_hdr.mh_nextpkt
1545        pkt_cnt[0] +=1
1546        while (mp != 0):
1547            if kern.arch == 'x86_64':
1548                mnext = mp.m_hdr.mh_next
1549                mflags = mp.m_hdr.mh_flags
1550                mtype = mp.m_hdr.mh_type
1551            else:
1552                mnext = mp.M_hdr_common.M_hdr.mh_next
1553                mflags = mp.M_hdr_common.M_hdr.mh_flags
1554                mtype = mp.M_hdr_common.M_hdr.mh_type
1555            mbuf_cnt[0] += 1
1556            buf_byte_cnt[int(mtype)] += 256
1557            buf_byte_cnt[Mbuf_Type.MT_LAST] += 256
1558            if (mflags & 0x01):
1559                mbuf_cluster_cnt[0] += 1
1560                if kern.arch == 'x86_64':
1561                    extsize = mp.M_dat.MH.MH_dat.MH_ext.ext_size
1562                else:
1563                    extsize = mp.M_hdr_common.M_ext.ext_size
1564                buf_byte_cnt[int(mtype)] += extsize
1565                buf_byte_cnt[Mbuf_Type.MT_LAST] += extsize
1566            mp = mnext
1567
1568def CalcMbufInSB(so, snd_cc, snd_buf, rcv_cc, rcv_buf, snd_record_cnt, rcv_record_cnt, snd_mbuf_cnt, rcv_mbuf_cnt, snd_mbuf_cluster_cnt, rcv_mbuf_cluster_cnt):
1569    snd_cc[0] += so.so_snd.sb_cc
1570    mpkt = so.so_snd.sb_mb
1571    CalcMbufInList(mpkt, snd_record_cnt, snd_buf, snd_mbuf_cnt, snd_mbuf_cluster_cnt)
1572    rcv_cc[0] += so.so_rcv.sb_cc
1573    mpkt = so.so_rcv.sb_mb
1574    CalcMbufInList(mpkt, rcv_record_cnt, rcv_buf, rcv_mbuf_cnt, rcv_mbuf_cluster_cnt)
1575
1576# Macro: show_socket_sb_mbuf_usage
1577@lldb_command('show_socket_sb_mbuf_usage')
1578def ShowSocketSbMbufUsage(cmd_args=None):
1579    """ Display for a socket the mbuf usage of the send and receive socket buffers
1580    """
1581    if cmd_args is None or len(cmd_args) == 0:
1582            print("Missing argument 0 in user function.")
1583            return
1584    so = kern.GetValueFromAddress(cmd_args[0], 'socket *')
1585    out_string = ""
1586    if (so != 0):
1587        snd_mbuf_cnt = [0]
1588        snd_mbuf_cluster_cnt = [0]
1589        snd_record_cnt = [0]
1590        snd_cc = [0]
1591        snd_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1592        rcv_mbuf_cnt = [0]
1593        rcv_mbuf_cluster_cnt = [0]
1594        rcv_record_cnt = [0]
1595        rcv_cc = [0]
1596        rcv_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1597        total_mbuf_bytes = 0
1598        CalcMbufInSB(so, snd_cc, snd_buf, rcv_cc, rcv_buf, snd_record_cnt, rcv_record_cnt, snd_mbuf_cnt, rcv_mbuf_cnt, snd_mbuf_cluster_cnt, rcv_mbuf_cluster_cnt)
1599        out_string += "total send mbuf count: " + str(int(snd_mbuf_cnt[0])) + " receive mbuf count: " + str(int(rcv_mbuf_cnt[0])) + "\n"
1600        out_string += "total send mbuf cluster count: " + str(int(snd_mbuf_cluster_cnt[0])) + " receive mbuf cluster count: " + str(int(rcv_mbuf_cluster_cnt[0])) + "\n"
1601        out_string += "total send record count: " + str(int(snd_record_cnt[0])) + " receive record count: " + str(int(rcv_record_cnt[0])) + "\n"
1602        out_string += "total snd_cc (total bytes in send buffers): " + str(int(snd_cc[0])) + " rcv_cc (total bytes in receive buffers): " + str(int(rcv_cc[0])) + "\n"
1603        out_string += "total snd_buf bytes " + str(int(snd_buf[Mbuf_Type.MT_LAST])) + " rcv_buf bytes " + str(int(rcv_buf[Mbuf_Type.MT_LAST])) + "\n"
1604        for x in range(Mbuf_Type.MT_LAST):
1605            if (snd_buf[x] != 0 or rcv_buf[x] != 0):
1606                out_string += "total snd_buf bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(snd_buf[x])) + " total recv_buf bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(rcv_buf[x])) + "\n"
1607                total_mbuf_bytes += snd_buf[x] + rcv_buf[x]
1608    print(out_string)
1609# EndMacro:  show_socket_sb_mbuf_usage
1610
1611
1612def GetMptcpInfo():
1613    mptcp = kern.globals.mtcbinfo
1614
1615    mppcb = cast(mptcp.mppi_pcbs.tqh_first, 'mppcb *')
1616    pcbseen = 0
1617    reinject_cnt=[0]
1618    reinject_byte_cnt=[0] * (Mbuf_Type.MT_LAST + 1)
1619    reinject_mbuf_cnt=[0]
1620    reinject_mbuf_cluster_cnt=[0]
1621
1622    snd_mbuf_cnt = [0]
1623    snd_mbuf_cluster_cnt = [0]
1624    snd_record_cnt = [0]
1625    snd_cc = [0]
1626    snd_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1627    rcv_mbuf_cnt = [0]
1628    rcv_mbuf_cluster_cnt = [0]
1629    rcv_record_cnt = [0]
1630    rcv_cc = [0]
1631    rcv_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1632    total_mbuf_bytes = 0
1633    while mppcb != 0:
1634        mpte = mppcb.mpp_pcbe
1635        pcbseen += 1
1636        CalcMbufInList(mpte.mpte_reinjectq, reinject_cnt, reinject_byte_cnt, reinject_mbuf_cnt, reinject_mbuf_cluster_cnt)
1637
1638        socket = mppcb.mpp_socket
1639        if socket != 0:
1640            CalcMbufInSB(socket, snd_cc, snd_buf, rcv_cc, rcv_buf, snd_record_cnt, rcv_record_cnt, snd_mbuf_cnt, rcv_mbuf_cnt, snd_mbuf_cluster_cnt, rcv_mbuf_cluster_cnt)
1641
1642        mppcb = cast(mppcb.mpp_entry.tqe_next, 'mppcb *')
1643
1644    out_string = ""
1645    out_string += "total pcbs seen: " + str(int(pcbseen)) + "\n"
1646    out_string += "total reinject mbuf count: " + str(int(reinject_mbuf_cnt[0])) + "\n"
1647    out_string += "total reinject mbuf cluster count: " + str(int(reinject_mbuf_cluster_cnt[0])) + "\n"
1648    out_string += "total reinject record count: " + str(int(reinject_cnt[0])) + "\n"
1649    for x in range(Mbuf_Type.MT_LAST):
1650        if (reinject_byte_cnt[x] != 0):
1651            out_string += "total reinject bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(reinject_byte_cnt[x])) + "\n"
1652            total_mbuf_bytes += reinject_byte_cnt[x]
1653
1654
1655    out_string += "total send mbuf count: " + str(int(snd_mbuf_cnt[0])) + " receive mbuf count: " + str(int(rcv_mbuf_cnt[0])) + "\n"
1656    out_string += "total send mbuf cluster count: " + str(int(snd_mbuf_cluster_cnt[0])) + " receive mbuf cluster count: " + str(int(rcv_mbuf_cluster_cnt[0])) + "\n"
1657    out_string += "total send record count: " + str(int(snd_record_cnt[0])) + " receive record count: " + str(int(rcv_record_cnt[0])) + "\n"
1658    out_string += "total snd_cc (total bytes in send buffers): " + str(int(snd_cc[0])) + " rcv_cc (total bytes in receive buffers): " + str(int(rcv_cc[0])) + "\n"
1659    out_string += "total snd_buf bytes " + str(int(snd_buf[Mbuf_Type.MT_LAST])) + " rcv_buf bytes " + str(int(rcv_buf[Mbuf_Type.MT_LAST])) + "\n"
1660    for x in range(Mbuf_Type.MT_LAST):
1661        if (snd_buf[x] != 0 or rcv_buf[x] != 0):
1662            out_string += "total snd_buf bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(snd_buf[x])) + " total recv_buf bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(rcv_buf[x])) + "\n"
1663            total_mbuf_bytes += snd_buf[x] + rcv_buf[x]
1664
1665    out_string += "total mbuf bytes used by MPTCP: "+ str(total_mbuf_bytes) + "\n"
1666    print(out_string)
1667
1668def GetPcbInfo(pcbi, proto):
1669    tcp_reassqlen = [0]
1670    tcp_reassq_bytes = 0
1671    mbuf_reassq_cnt = [0]
1672    mbuf_reassq_bytes = [0] * (Mbuf_Type.MT_LAST + 1)
1673    mbuf_reassq_cluster = [0]
1674    out_string = ""
1675    snd_mbuf_cnt = [0]
1676    snd_mbuf_cluster_cnt = [0]
1677    snd_record_cnt = [0]
1678    snd_cc = [0]
1679    snd_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1680    rcv_mbuf_cnt = [0]
1681    rcv_mbuf_cluster_cnt = [0]
1682    rcv_record_cnt = [0]
1683    rcv_cc = [0]
1684    rcv_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1685    pcbseen = 0
1686    out_string += "lastport " + str(int(pcbi.ipi_lastport)) + " lastlow " + str(int(pcbi.ipi_lastlow)) + " lasthi " + str(int(pcbi.ipi_lasthi)) + "\n"
1687    out_string += "active pcb count is " + str(int(pcbi.ipi_count)) + "\n"
1688    hashsize = pcbi.ipi_hashmask + 1
1689    out_string += "hash size is " + str(int(hashsize)) + "\n"
1690    out_string += str(pcbi.ipi_hashbase) + " has the following inpcb(s):\n"
1691    if (kern.ptrsize == 8):
1692        out_string += "pcb                proto  source                                        port  destination                                 port\n"
1693    else:
1694        out_string += "pcb            proto  source           address  port  destination         address  port\n\n"
1695
1696    if proto == IPPROTO_RAW:
1697        head = cast(pcbi.ipi_listhead, 'inpcbhead *')
1698        pcb = cast(head.lh_first, 'inpcb *')
1699        while pcb != 0:
1700            pcbseen += 1
1701            out_string += GetInPcb(pcb, proto) + "\n"
1702            so = pcb.inp_socket
1703            if so != 0:
1704                CalcMbufInSB(so, snd_cc, snd_buf, rcv_cc, rcv_buf, snd_record_cnt, rcv_record_cnt, snd_mbuf_cnt, rcv_mbuf_cnt, snd_mbuf_cluster_cnt, rcv_mbuf_cluster_cnt)
1705            pcb = cast(pcb.inp_list.le_next, 'inpcb *')
1706    else:
1707        i = 0
1708        hashbase = pcbi.ipi_hashbase
1709        while (i < hashsize):
1710            head = hashbase[i]
1711            pcb = cast(head.lh_first, 'inpcb *')
1712            while pcb != 0:
1713                pcbseen += 1
1714                out_string += GetInPcb(pcb, proto) + "\n"
1715                so = pcb.inp_socket
1716                if so != 0:
1717                    CalcMbufInSB(so, snd_cc, snd_buf, rcv_cc, rcv_buf, snd_record_cnt, rcv_record_cnt, snd_mbuf_cnt, rcv_mbuf_cnt, snd_mbuf_cluster_cnt, rcv_mbuf_cluster_cnt)
1718                if proto == IPPROTO_TCP and pcb.inp_ppcb:
1719                    tcpcb = cast(pcb.inp_ppcb, 'tcpcb *')
1720                    reass_entry = cast(tcpcb.t_segq.lh_first, 'tseg_qent *')
1721                    curr_reass = 0
1722                    while reass_entry != 0:
1723                        CalcMbufInList(reass_entry.tqe_m, tcp_reassqlen, mbuf_reassq_bytes, mbuf_reassq_cnt, mbuf_reassq_cluster)
1724                        tcp_reassq_bytes += reass_entry.tqe_len
1725                        curr_reass += reass_entry.tqe_len
1726
1727                        reass_entry = reass_entry.tqe_q.le_next
1728
1729                pcb = cast(pcb.inp_hash.le_next, 'inpcb *')
1730            i += 1
1731
1732    out_string += "total pcbs seen: " + str(int(pcbseen)) + "\n"
1733    out_string += "total send mbuf count: " + str(int(snd_mbuf_cnt[0])) + " receive mbuf count: " + str(int(rcv_mbuf_cnt[0])) + "\n"
1734    out_string += "total send mbuf cluster count: " + str(int(snd_mbuf_cluster_cnt[0])) + " receive mbuf cluster count: " + str(int(rcv_mbuf_cluster_cnt[0])) + "\n"
1735    out_string += "total send record count: " + str(int(snd_record_cnt[0])) + " receive record count: " + str(int(rcv_record_cnt[0])) + "\n"
1736    out_string += "total snd_cc (total bytes in send buffers): " + str(int(snd_cc[0])) + " rcv_cc (total bytes in receive buffers): " + str(int(rcv_cc[0])) + "\n"
1737    out_string += "total snd_buf bytes " + str(int(snd_buf[Mbuf_Type.MT_LAST])) + " rcv_buf bytes " + str(int(rcv_buf[Mbuf_Type.MT_LAST])) + "\n"
1738    for x in range(Mbuf_Type.MT_LAST):
1739        if (snd_buf[x] != 0 or rcv_buf[x] != 0):
1740            out_string += "total snd_buf bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(snd_buf[x])) + " total recv_buf bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(rcv_buf[x])) + "\n"
1741    out_string += "port hash base is " + hex(pcbi.ipi_porthashbase) + "\n"
1742    if proto == IPPROTO_TCP:
1743        out_string += "TCP reassembly queue length: " + str(tcp_reassqlen[0]) + " TCP-payload bytes: " + str(tcp_reassq_bytes) + "\n"
1744
1745        for x in range(Mbuf_Type.MT_LAST):
1746            if mbuf_reassq_bytes[x] != 0:
1747                out_string += "total reassq bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(mbuf_reassq_bytes[x]) + "\n"
1748
1749    i = 0
1750    hashbase = pcbi.ipi_porthashbase
1751    while (i < hashsize):
1752        head = hashbase[i]
1753        pcb = cast(head.lh_first, 'inpcbport *')
1754        while pcb != 0:
1755            out_string += "\t"
1756            out_string += GetInPcbPort(pcb)
1757            out_string += "\n"
1758            pcb = cast(pcb.phd_hash.le_next, 'inpcbport *')
1759        i += 1
1760
1761    return out_string
1762
1763def GetInPcbPort(ppcb):
1764    out_string = ""
1765    out_string += hex(ppcb) + ": lport "
1766    out_string += Getntohs(ppcb.phd_port)
1767    return out_string
1768
1769
1770def Getntohs(port):
1771    out_string = ""
1772    #p = unsigned(int(port) & 0x0000ffff)
1773    p = ((port & 0x0000ff00) >> 8)
1774    p |= ((port & 0x000000ff) << 8)
1775    return str(p)
1776
1777
1778# Macro: mbuf_list_usage_summary
1779@lldb_command('mbuf_list_usage_summary')
1780def ShowMbufListUsageSummary(cmd_args=None):
1781    """ Print mbuf list usage summary
1782    Usage: mbuf_list_usage_summary [mbuf_addr]
1783    """
1784    if cmd_args is None or len(cmd_args) == 0:
1785        raise ArgumentError()
1786
1787    out_string = ""
1788    pkt_cnt = [0]
1789    buf_byte_cnt = [0] * (Mbuf_Type.MT_LAST + 1)
1790    mbuf_cnt = [0]
1791    mbuf_cluster_cnt = [0]
1792
1793    mpkt = kern.GetValueFromAddress(cmd_args[0], 'struct mbuf *')
1794    CalcMbufInList(mpkt, pkt_cnt, buf_byte_cnt, mbuf_cnt, mbuf_cluster_cnt)
1795
1796    out_string += "Total packet count is " + str(int(pkt_cnt[0])) + "\n"
1797    for x in range(Mbuf_Type.MT_LAST):
1798        if (buf_byte_cnt[x] != 0):
1799            out_string += "Total buf bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(buf_byte_cnt[x])) + "\n"
1800    out_string += "Total mbuf count " + str(int(mbuf_cnt[0])) + "\n"
1801    out_string += "Total mbuf cluster count " + str(int(mbuf_cluster_cnt[0])) + "\n"
1802    print(out_string)
1803
1804# Macro: show_kern_event_pcbinfo
1805def GetKernEventPcbInfo(kev_pcb_head):
1806    out_string = ""
1807    pcb = Cast(kev_pcb_head.lh_first, 'kern_event_pcb *')
1808    if (kern.ptrsize == 8):
1809        kev_pcb_format_string = "0x{0:<16x} {1:12d} {2:16d} {3:16d} {4:16d} {5:16d}"
1810        out_string += "  evp socket         vendor code      class filter      subclass filter     so_rcv.sb_cc      so_rcv.sb_mbcnt\n"
1811        out_string += "--------------       -----------      ------------      ---------------     ------------      ---------------\n"
1812    else:
1813        kev_pcb_format_string = "0x{0:<8x} {1:12d} {2:16d} {3:16d} {4:16d} {5:16d}"
1814        out_string += "evp socket       vendor code      class filter      subclass filter     so_rcv.sb_cc      so_rcv.sb_mbcnt\n"
1815        out_string += "----------       -----------      ------------      ---------------     ------------      ---------------\n"
1816    while (pcb != 0):
1817        out_string += kev_pcb_format_string.format(pcb.evp_socket, pcb.evp_vendor_code_filter, pcb.evp_class_filter, pcb.evp_subclass_filter, pcb.evp_socket.so_rcv.sb_cc, pcb.evp_socket.so_rcv.sb_mbcnt)
1818        out_string += "\n"
1819        pcb = pcb.evp_link.le_next
1820    return out_string
1821
1822@lldb_command('show_kern_event_pcbinfo')
1823def ShowKernEventPcbInfo(cmd_args=None):
1824    """ Display the list of Kernel Event protocol control block information
1825    """
1826    print(GetKernEventPcbInfo(addressof(kern.globals.kern_event_head)))
1827# EndMacro:  show_kern_event_pcbinfo
1828
1829# Macro: show_kern_control_pcbinfo
1830def GetKernControlPcbInfo(ctl_head):
1831    out_string = ""
1832    kctl = Cast(ctl_head.tqh_first, 'kctl *')
1833    if (kern.ptrsize == 8):
1834        kcb_format_string = "0x{0:<16x} {1:10d} {2:10d} {3:10d}\n"
1835    else:
1836        kcb_format_string = "0x{0:<8x} {1:10d} {2:10d} {3:10d}\n"
1837    while unsigned(kctl) != 0:
1838        kctl_name = "controller: " + str(kctl.name) + "\n"
1839        out_string += kctl_name
1840        kcb = Cast(kctl.kcb_head.tqh_first, 'ctl_cb *')
1841        if unsigned(kcb) != 0:
1842            if (kern.ptrsize == 8):
1843                out_string += "socket               usecount     snd_cc     rcv_cc\n"
1844                out_string += "------               --------     ------     ------\n"
1845            else:
1846                out_string += "socket       usecount     snd_cc     rcv_cc\n"
1847                out_string += "------       --------     ------     ------\n"
1848        while unsigned(kcb) != 0:
1849            so = Cast(kcb.so, 'socket *')
1850            snd_cc = so.so_snd.sb_cc
1851            rcv_cc = so.so_rcv.sb_cc
1852            out_string += kcb_format_string.format(kcb.so, kcb.usecount, snd_cc, rcv_cc)
1853            kcb = kcb.next.tqe_next
1854        out_string += "\n"
1855        kctl = kctl.next.tqe_next
1856    return out_string
1857
1858@lldb_command('show_kern_control_pcbinfo')
1859def ShowKernControlPcbInfo(cmd_args=None):
1860    """ Display the list of Kernel Control protocol control block information
1861    """
1862    print(GetKernControlPcbInfo(addressof(kern.globals.ctl_head)))
1863# EndMacro:  show_kern_control_pcbinfo
1864
1865# Macro: show_unix_domain_pcbinfo
1866def GetUnixDomainPCBAsString(unp, type) :
1867    out_string = ""
1868    pcb = Cast(unp, 'unpcb *')
1869    out_string += "unpcb: " + hex(pcb)  + " " + str(type)
1870    out_string += " unp_socket: " + hex(pcb.unp_socket)
1871    out_string += " unp_vnode: " + hex(pcb.unp_vnode)
1872    out_string += " unp_conn: " + hex(pcb.unp_conn)
1873    out_string += " unp_addr: " + GetSocketAddrAsStringUnix(pcb.unp_addr)
1874    out_string += " unp_gencnt: " + str(int(pcb.unp_gencnt))
1875    out_string += " unp_flags: " + hex(pcb.unp_flags)
1876    if pcb.unp_socket != 0:
1877        so = Cast(pcb.unp_socket, 'socket *')
1878        out_string += " s=" + str(int(so.so_snd.sb_cc)) + " r=" + str(int(so.so_rcv.sb_cc)) + " usecnt=" + str(int(so.so_usecount))
1879    return out_string
1880
1881def GetUnixDomainPcbInfo(unp_head, type):
1882    out_string = ""
1883    unp = Cast(unp_head.lh_first, 'unpcb *')
1884    while unsigned(unp) != 0:
1885        out_string += GetUnixDomainPCBAsString(unp, type)
1886        out_string += "\n"
1887        unp = unp.unp_link.le_next
1888    return out_string
1889
1890@lldb_command('show_unix_domain_pcbinfo')
1891def ShowUnixDomainPcbInfo(cmd_args=None):
1892    """ Display the list of unix domain pcb
1893    """
1894    print(GetUnixDomainPcbInfo(addressof(kern.globals.unp_dhead), "dgram"))
1895    print(GetUnixDomainPcbInfo(addressof(kern.globals.unp_shead), "stream"))
1896# EndMacro:  show_kern_control_pcbinfo
1897
1898# Macro: show_tcp_pcbinfo
1899@lldb_command('show_tcp_pcbinfo')
1900def ShowTcpPcbInfo(cmd_args=None):
1901    """ Display the list of TCP protocol control block information
1902    """
1903    print(GetPcbInfo(addressof(kern.globals.tcbinfo), IPPROTO_TCP))
1904# EndMacro:  show_tcp_pcbinfo
1905
1906# Macro: show_udp_pcbinfo
1907@lldb_command('show_udp_pcbinfo')
1908def ShowUdpPcbInfo(cmd_args=None):
1909    """ Display the list of UDP protocol control block information
1910    """
1911    print(GetPcbInfo(addressof(kern.globals.udbinfo), IPPROTO_UDP))
1912# EndMacro:  show_udp_pcbinfo
1913
1914# Macro: show_rip_pcbinfo
1915@lldb_command('show_rip_pcbinfo')
1916def ShowRipPcbInfo(cmd_args=None):
1917    """ Display the list of Raw IP protocol control block information
1918    """
1919    print(GetPcbInfo(addressof(kern.globals.ripcbinfo), IPPROTO_RAW))
1920# EndMacro:  show_rip_pcbinfo
1921
1922# Macro: show_mptcp_pcbinfo
1923@lldb_command('show_mptcp_pcbinfo')
1924def ShowMptcpPcbInfo(cmd_args=None):
1925    """ Display the list of MPTCP protocol control block information
1926    """
1927    GetMptcpInfo()
1928# EndMacro:  show_mptcp_pcbinfo
1929
1930# Macro: show_domains
1931@lldb_command('show_domains')
1932def ShowDomains(cmd_args=None):
1933    """ Display the list of the domains
1934    """
1935    out_string = ""
1936    domains = kern.globals.domains
1937    dp = Cast(domains.tqh_first, 'domain *')
1938    ifma_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1939    cnt = 0
1940    while (dp != 0):
1941        out_string += "\"" + str(dp.dom_name) + "\"" + "[" + str(int(dp.dom_refs)) + " refs] domain " + hex(dp) + "\n"
1942        out_string += "    family:\t" + str(int(dp.dom_family)) + "\n"
1943        out_string += "    flags:0x\t" + str(int(dp.dom_flags)) + "\n"
1944        out_string += "    rtparams:\toff=" + str(int(dp.dom_rtoffset)) + ", maxrtkey=" + str(int(dp.dom_maxrtkey)) + "\n"
1945
1946        if (dp.dom_init):
1947            out_string += "    init:\t"
1948            out_string += GetSourceInformationForAddress(dp.dom_init) + "\n"
1949        if (dp.dom_externalize):
1950            out_string += "    externalize:\t"
1951            out_string += GetSourceInformationForAddress(dp.dom_externalize) + "\n"
1952        if (dp.dom_dispose):
1953            out_string += "    dispose:\t"
1954            out_string += GetSourceInformationForAddress(dp.dom_dispose) + "\n"
1955        if (dp.dom_rtattach):
1956            out_string += "    rtattach:\t"
1957            out_string += GetSourceInformationForAddress(dp.dom_rtattach) + "\n"
1958        if (dp.dom_old):
1959            out_string += "    old:\t"
1960            out_string += GetSourceInformationForAddress(dp.dom_old) + "\n"
1961
1962        pr = Cast(dp.dom_protosw.tqh_first, 'protosw *')
1963        while pr != 0:
1964            pru = pr.pr_usrreqs
1965            out_string += "\ttype " + str(int(pr.pr_type)) + ", protocol " + str(int(pr.pr_protocol)) + ", protosw " + hex(pr) + "\n"
1966            out_string += "\t    flags:0x\t" + hex(pr.pr_flags) + "\n"
1967            if (pr.pr_input):
1968                out_string += "\t    input:\t"
1969                out_string += GetSourceInformationForAddress(pr.pr_input) + "\n"
1970            if (pr.pr_output):
1971                out_string += "\t    output:\t"
1972                out_string += GetSourceInformationForAddress(pr.pr_output) + "\n"
1973            if (pr.pr_ctlinput):
1974                out_string += "\t    ctlinput:\t"
1975                out_string += GetSourceInformationForAddress(pr.pr_ctlinput) + "\n"
1976            if (pr.pr_ctloutput):
1977                out_string += "\t    ctloutput:\t"
1978                out_string += GetSourceInformationForAddress(pr.pr_ctloutput) + "\n"
1979            if (pr.pr_init):
1980                out_string += "\t    init:\t"
1981                out_string += GetSourceInformationForAddress(pr.pr_init) + "\n"
1982            if (pr.pr_drain):
1983                out_string += "\t    drain:\t"
1984                out_string += GetSourceInformationForAddress(pr.pr_drain) + "\n"
1985            if (pr.pr_sysctl):
1986                out_string += "\t    sysctl:\t"
1987                out_string += GetSourceInformationForAddress(pr.pr_sysctl) + "\n"
1988            if (pr.pr_lock):
1989                out_string += "\t    lock:\t"
1990                out_string += GetSourceInformationForAddress(pr.pr_lock) + "\n"
1991            if (pr.pr_unlock):
1992                out_string += "\t    unlock:\t"
1993                out_string += GetSourceInformationForAddress(pr.pr_unlock) + "\n"
1994            if (pr.pr_getlock):
1995                out_string += "\t    getlock:\t"
1996                out_string += GetSourceInformationForAddress(pr.pr_getlock) + "\n"
1997            if (pr.pr_old):
1998                out_string += "\t    old:\t"
1999                out_string += GetSourceInformationForAddress(pr.pr_old) + "\n"
2000
2001            out_string += "\t    pru_flags:0x\t" + hex(pru.pru_flags) + "\n"
2002            out_string += "\t    abort:\t"
2003            out_string += GetSourceInformationForAddress(pru.pru_abort) + "\n"
2004            out_string += "\t    accept:\t"
2005            out_string += GetSourceInformationForAddress(pru.pru_accept) + "\n"
2006            out_string += "\t    attach:\t"
2007            out_string += GetSourceInformationForAddress(pru.pru_attach) + "\n"
2008            out_string += "\t    bind:\t"
2009            out_string += GetSourceInformationForAddress(pru.pru_bind) + "\n"
2010            out_string += "\t    connect:\t"
2011            out_string += GetSourceInformationForAddress(pru.pru_connect) + "\n"
2012            out_string += "\t    connect2:\t"
2013            out_string += GetSourceInformationForAddress(pru.pru_connect2) + "\n"
2014            out_string += "\t    connectx:\t"
2015            out_string += GetSourceInformationForAddress(pru.pru_connectx) + "\n"
2016            out_string += "\t    control:\t"
2017            out_string += GetSourceInformationForAddress(pru.pru_control) + "\n"
2018            out_string += "\t    detach:\t"
2019            out_string += GetSourceInformationForAddress(pru.pru_detach) + "\n"
2020            out_string += "\t    disconnect:\t"
2021            out_string += GetSourceInformationForAddress(pru.pru_disconnect) + "\n"
2022            out_string += "\t    listen:\t"
2023            out_string += GetSourceInformationForAddress(pru.pru_listen) + "\n"
2024            out_string += "\t    peeraddr:\t"
2025            out_string += GetSourceInformationForAddress(pru.pru_peeraddr) + "\n"
2026            out_string += "\t    rcvd:\t"
2027            out_string += GetSourceInformationForAddress(pru.pru_rcvd) + "\n"
2028            out_string += "\t    rcvoob:\t"
2029            out_string += GetSourceInformationForAddress(pru.pru_rcvoob) + "\n"
2030            out_string += "\t    send:\t"
2031            out_string += GetSourceInformationForAddress(pru.pru_send) + "\n"
2032            out_string += "\t    sense:\t"
2033            out_string += GetSourceInformationForAddress(pru.pru_sense) + "\n"
2034            out_string += "\t    shutdown:\t"
2035            out_string += GetSourceInformationForAddress(pru.pru_shutdown) + "\n"
2036            out_string += "\t    sockaddr:\t"
2037            out_string += GetSourceInformationForAddress(pru.pru_sockaddr) + "\n"
2038            out_string += "\t    sopoll:\t"
2039            out_string += GetSourceInformationForAddress(pru.pru_sopoll) + "\n"
2040            out_string += "\t    soreceive:\t"
2041            out_string += GetSourceInformationForAddress(pru.pru_soreceive) + "\n"
2042            out_string += "\t    sosend:\t"
2043            out_string += GetSourceInformationForAddress(pru.pru_sosend) + "\n"
2044            pr = pr.pr_entry.tqe_next
2045        dp = dp.dom_entry.tqe_next
2046
2047        print(out_string)
2048# EndMacro: show_domains
2049
2050# Macro: tcp_count_rxt_segments
2051@lldb_command('tcp_count_rxt_segments')
2052def TCPCountRxtSegments(cmd_args=None):
2053    """ Size of the t_rxt_segments chain
2054    """
2055    if cmd_args is None or len(cmd_args) == 0:
2056        raise ArgumentError("Missing argument 0 in user function.")
2057
2058    tp = kern.GetValueFromAddress(cmd_args[0], 'tcpcb *')
2059    rxseg = cast(tp.t_rxt_segments.slh_first, 'tcp_rxt_seg *')
2060    cnt = 0
2061    while rxseg != 0:
2062        cnt += 1
2063        rxseg = rxseg.rx_link.sle_next
2064        if (cnt % 1000 == 0):
2065            print(" running count: {:d}".format(cnt))
2066    print(" total count: {:d}".format(cnt))
2067# EndMacro: tcp_count_rxt_segments
2068
2069# Macro: tcp_walk_rxt_segments
2070@lldb_command('tcp_walk_rxt_segments')
2071def TCPWalkRxtSegments(cmd_args=None):
2072    """ Walk the t_rxt_segments chain
2073    """
2074    if cmd_args is None or len(cmd_args) == 0:
2075        raise ArgumentError("Missing argument 0 in user function.")
2076
2077    tp = kern.GetValueFromAddress(cmd_args[0], 'tcpcb *')
2078    rxseg = cast(tp.t_rxt_segments.slh_first, 'tcp_rxt_seg *')
2079    cnt = 0
2080    while rxseg != 0:
2081        cnt += 1
2082        rxseg = rxseg.rx_link.sle_next
2083        if (cnt % 1000 == 0):
2084            print(" running count: {:d}".format(cnt))
2085    print(" total count: {:d}".format(cnt))
2086    rxseg = cast(tp.t_rxt_segments.slh_first, 'tcp_rxt_seg *')
2087    cnt = 0
2088    while rxseg != 0:
2089        cnt += 1
2090        out_string = ""
2091        span = rxseg.rx_end - rxseg.rx_start
2092        rxseg_format = "{0:4d} 0x{1:x} rx_start 0x{2:x} rx_end 0x{3:x} rx_count {4:4d} rx_flags 0x{5:x} span {6:d}"
2093        out_string += rxseg_format.format(cnt, rxseg, rxseg.rx_start, rxseg.rx_end, rxseg.rx_count, rxseg.rx_flags, abs(span))
2094        print(out_string)
2095        rxseg = rxseg.rx_link.sle_next
2096# EndMacro: tcp_walk_rxt_segments
2097
2098def GetTCPTimerAsString(value):
2099    """ Return a formatted string description of the timer index
2100    """
2101    index = unsigned(value)
2102    if index <= TCPT_MAX:
2103        out_string = tcp_timer_strings[index]
2104    else:
2105        out_string = printf("<{d}>".format(value))
2106    return out_string
2107
2108# Macro: tcp_walk_timer_list
2109@lldb_command('tcp_walk_timer_list', 'V')
2110def TCPWalkTimerList(cmd_args=None, cmd_options={}):
2111    """ Walk the list of tcptimerentry from tcp_timer_list lhead field
2112        Usage: tcp_walk_timer_list [-V]
2113                -V show detail of the TCP control block
2114    """
2115    verbose = False
2116    if "-V" in cmd_options:
2117        verbose = True
2118
2119    field_offset = getfieldoffset("struct tcpcb", "tentry.te_le.le_next")
2120
2121    timer_list = addressof(kern.globals.tcp_timer_list)
2122
2123    timer_entry = Cast(timer_list.lhead.lh_first, 'tcptimerentry *')
2124    cnt = 0
2125
2126    print("Walking entries of tcp_timer_list at 0x{:x}".format(unsigned(timer_list)))
2127
2128    timer_header_format = "{0:6s} {1:>18s} {2:>12s} {3:>14s} {4:>6s} {5:>12s} {6:>18s} {7:>18s} {8:>18s}"
2129    out_string = timer_header_format.format("Entry#", "(tcptimerentry *)", "timer_start", "index", "mode", "runtime", "le_next", "(tcpcb *)", "(inpcb *)")
2130    print(out_string)
2131
2132    while timer_entry != 0:
2133        cnt += 1
2134        next_entry = timer_entry.te_le.le_next
2135        tp = Cast(kern.GetValueFromAddress(Cast(timer_entry, 'char *') - field_offset), 'tcpcb *')
2136        timer_entry_format = "{0:6d} 0x{1:<16x} {2:>12d} {3:>14s} {4:>6d} {5:>12d} 0x{6:<16x} 0x{7:<16x} 0x{8:<16x}"
2137        out_string = timer_entry_format.format(
2138            cnt,
2139            unsigned(timer_entry),
2140            unsigned(timer_entry.te_timer_start),
2141            GetTCPTimerAsString(timer_entry.te_index),
2142            unsigned(timer_entry.te_mode),
2143            unsigned(timer_entry.te_runtime),
2144            unsigned(next_entry) if next_entry else 0,
2145            unsigned(tp),
2146            unsigned(tp.t_inpcb)
2147        )
2148        print(out_string)
2149
2150        if verbose:
2151            print(GetInPcb(tp.t_inpcb, IPPROTO_TCP))
2152
2153        timer_entry = Cast(next_entry, 'tcptimerentry *')
2154
2155        # Safety check to prevent infinite loops
2156        if cnt > 10000:
2157            print("Warning: Stopped after 10000 entries to prevent infinite loop")
2158            break
2159
2160    print("Total timer entries: {:d}".format(cnt))
2161# EndMacro: tcp_walk_timer_list
2162
2163def ShowBPFDevice(i, bpf_d):
2164    out_string = ""
2165    if bpf_d != 0:
2166        bd_sbuf = cast(bpf_d.bd_sbuf, 'char *')
2167        bd_hbuf = cast(bpf_d.bd_hbuf, 'char *')
2168        ifname = ""
2169        bd_bif = cast(bpf_d.bd_bif, 'struct bpf_if *')
2170        if bd_bif != 0:
2171            bif_ifp = cast(bd_bif.bif_ifp, 'struct ifnet *')
2172            if bif_ifp != 0:
2173                ifname = bif_ifp.if_xname
2174        format_string = "bpf{0:<3d} (struct bpf_d *)0x{1:16x} {2:7d} 0x{3:<16x} {4:7d} 0x{5:<16x} {6:16s}"
2175        out_string += format_string.format(i, bpf_d, bpf_d.bd_slen, bd_sbuf, bpf_d.bd_hlen, bd_hbuf, ifname)
2176    return out_string
2177
2178# Macro: show_bpf_devices
2179@lldb_command('show_bpf_devices')
2180def ShowBPFDevices(cmd_args=None):
2181    """ Walk the bpf device array
2182    """
2183    format_string = "{0:6s} {1:34s} {2:>7s} {3:18s} {4:>7s} {5:18s} {6:16s}"
2184    out_string = format_string.format("device", "address", "bd_slen", "bd_sbuf", "bd_hlen", "bd_hbuf", "bif_ifp")
2185    print(out_string)
2186
2187    bpf_dtab_size = int(kern.globals.bpf_dtab_size)
2188    for i in range(0, bpf_dtab_size):
2189        bpf_d = cast(kern.globals.bpf_dtab[i], 'struct bpf_d *')
2190        if bpf_d == 0:
2191            continue
2192        out_string = ShowBPFDevice(i, bpf_d)
2193        print(out_string)
2194# EndMacro: show_bpf_devices
2195
2196def DumpBPFToFile(bpf_d):
2197    bd_bif = cast(bpf_d.bd_bif, 'struct bpf_if *')
2198    if bd_bif == 0:
2199        print("bd_bif is NULL")
2200        return
2201
2202    bif_ifp = Cast(bd_bif.bif_ifp, 'struct ifnet *')
2203    if bif_ifp == 0:
2204        print("bd_bif.bif_ifp is NULL")
2205        return
2206
2207    ifname = cast(bif_ifp.if_xname, 'char *')
2208    print("ifname: ", ifname);
2209
2210    dlt = bd_bif.bif_dlt
2211    if dlt == 149:
2212        suffix = ".pktap"
2213    else:
2214        suffix = ".bpf"
2215
2216    format_string = "{0:s}-dlt-{1:d}-"
2217    prefix = format_string.format(ifname, dlt)
2218
2219    f = tempfile.NamedTemporaryFile(prefix=prefix, suffix=suffix, dir="/tmp/", mode="wb", delete=False)
2220
2221    err = lldb.SBError()
2222
2223    if bpf_d.bd_hlen != 0:
2224        addr = bpf_d.bd_hbuf[0].GetSBValue().GetLoadAddress()
2225        hlen = (unsigned(bpf_d.bd_hlen)+(4-1))&~(4-1)
2226        if hlen != 0:
2227            buf = LazyTarget.GetProcess().ReadMemory(addr, hlen, err)
2228            if err.fail:
2229                print("Error, getting sbuf")
2230            f.write(buf)
2231
2232    if bpf_d.bd_slen != 0:
2233        addr = bpf_d.bd_sbuf[0].GetSBValue().GetLoadAddress()
2234        slen = (unsigned(bpf_d.bd_slen)+(4-1))&~(4-1)
2235        if slen != 0:
2236            buf = LazyTarget.GetProcess().ReadMemory(addr, slen, err)
2237            if err.fail:
2238                print("Error, getting sbuf")
2239                f.write(buf)
2240
2241    print(f.name)
2242    f.close()
2243
2244# Macro: net_get_always_on_pktap
2245@lldb_command('save_bfp_buffers')
2246def SaveBPFBuffer(cmd_args=None):
2247    """ Dump the buffers of a BPF to a file in /tmp/
2248    """
2249    if cmd_args is None or len(cmd_args) == 0:
2250        raise ArgumentError()
2251
2252    bpf_d = kern.GetValueFromAddress(cmd_args[0], 'struct bpf_d *')
2253
2254    DumpBPFToFile(bpf_d)
2255
2256# Macro: net_get_always_on_pktap
2257@lldb_command('net_get_always_on_pktap')
2258def NetGetAlwaysOnPktap(cmd_args=None):
2259    """ Dump the always-on packet capture to a file in /tmp/
2260    """
2261    for i in range(0, 10):
2262        ifnet = GetIfConfiguration("pktap"+str(i))
2263        if not ifnet:
2264            continue
2265        if ifnet.if_bpf == 0:
2266            ifnet = None
2267            continue
2268        if ifnet.if_bpf.bif_dlist.bd_headdrop == 0:
2269            ifnet = None
2270            continue
2271        break
2272
2273    if not ifnet:
2274        print("Could not find a pktap interface")
2275        return
2276
2277    bpf_d = ifnet.if_bpf.bif_dlist
2278
2279    DumpBPFToFile(bpf_d)
2280# EndMacro: net_get_always_on_pktap
2281