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