xref: /xnu-11417.140.69/tools/lldbmacros/net.py (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
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    if cmd_args is None or len(cmd_args) == 0:
1356        raise ArgumentError()
1357
1358    out_string = ""
1359    rt = kern.GetValueFromAddress(cmd_args[0], 'rtentry *')
1360    out_string += GetRtEntryPrDetailsAsString(rt) + "\n"
1361    print(out_string)
1362# EndMacro: show_rtentry
1363
1364# Macro: inm_trash
1365@lldb_command('inm_trash')
1366def InmTrash(cmd_args=None):
1367    """ Walk the list of trash in_multi entries
1368    """
1369    out_string = ""
1370    inm_trash_head = kern.globals.inm_trash_head
1371    inm = Cast(inm_trash_head.tqh_first, 'in_multi_dbg *')
1372    inm_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1373    cnt = 0
1374    while (int(inm) != 0):
1375        if (cnt == 0):
1376            if (kern.ptrsize == 8):
1377                print("                     inm  ref   hold   rele")
1378                print("      ------------------  --- ------ ------")
1379            else:
1380                print("             inm  ref   hold   rele")
1381                print("      ----------  --- ------ ------")
1382        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) + "   "
1383        out_string += GetInAddrAsString(addressof(inm.inm.inm_addr)) + "\n"
1384        inm = inm.inm_trash_link.tqe_next
1385        cnt += 1
1386    print(out_string)
1387# EndMacro: inm_trash
1388
1389# Macro: in6m_trash
1390@lldb_command('in6m_trash')
1391def In6mTrash(cmd_args=None):
1392    """ Walk the list of trash in6_multi entries
1393    """
1394    out_string = ""
1395    in6m_trash_head = kern.globals.in6m_trash_head
1396    in6m = Cast(in6m_trash_head.tqh_first, 'in6_multi_dbg *')
1397    in6m_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1398    cnt = 0
1399    while (int(in6m) != 0):
1400        if (cnt == 0):
1401            if (kern.ptrsize == 8):
1402                print("                    in6m  ref   hold   rele")
1403                print("      ------------------  --- ------ ------")
1404            else:
1405                print("            in6m  ref   hold   rele")
1406                print("      ----------  --- ------ ------")
1407        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) + "   "
1408        out_string += GetIn6AddrAsString(addressof(in6m.in6m.in6m_addr)) + "\n"
1409        in6m = in6m.in6m_trash_link.tqe_next
1410        cnt += 1
1411    print(out_string)
1412# EndMacro: in6m_trash
1413
1414# Macro: ifma_trash
1415@lldb_command('ifma_trash')
1416def IfmaTrash(cmd_args=None):
1417    """ Walk the list of trash ifmultiaddr entries
1418    """
1419    out_string = ""
1420    ifma_trash_head = kern.globals.ifma_trash_head
1421    ifma = Cast(ifma_trash_head.tqh_first, 'ifmultiaddr_dbg *')
1422    ifma_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1423    cnt = 0
1424    while (int(ifma) != 0):
1425        if (cnt == 0):
1426            if (kern.ptrsize == 8):
1427                print("                    ifma  ref   hold   rele")
1428                print("      ------------------  --- ------ ------")
1429            else:
1430                print("            ifma  ref   hold   rele")
1431                print("      ----------  --- ------ ------")
1432        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) + "   "
1433        out_string += GetSocketAddrAsString(ifma.ifma.ifma_addr) + "\n"
1434        out_string += " @ " + ifma.ifma.ifma_ifp.if_xname
1435        ifma = ifma.ifma_trash_link.tqe_next
1436        cnt += 1
1437    print(out_string)
1438# EndMacro: ifma_trash
1439
1440def GetInPcb(pcb, proto):
1441    out_string = ""
1442    out_string += hex(pcb)
1443
1444    if (proto == IPPROTO_TCP):
1445        out_string +=  " tcp"
1446    elif (proto == IPPROTO_UDP):
1447        out_string += " udp"
1448    elif (proto == IPPROTO_RAW):
1449        out_string += " raw"
1450    else:
1451        out_string += str(proto) +  "."
1452
1453    if (pcb.inp_vflag & INP_IPV4):
1454        out_string += "4 "
1455    if (pcb.inp_vflag & INP_IPV6):
1456        out_string += "6 "
1457
1458    if (pcb.inp_vflag & INP_IPV4):
1459        out_string += "                                       "
1460        out_string += GetInAddrAsString(addressof(pcb.inp_dependladdr.inp46_local.ia46_addr4))
1461    else:
1462        out_string += "  "
1463        out_string += GetIn6AddrAsString((pcb.inp_dependladdr.inp6_local.__u6_addr.__u6_addr8))
1464
1465    out_string += " "
1466    out_string += Getntohs(pcb.inp_lport)
1467    out_string += " "
1468
1469    if (pcb.inp_vflag & INP_IPV4):
1470        out_string += "                                 "
1471        out_string += GetInAddrAsString(addressof(pcb.inp_dependfaddr.inp46_foreign.ia46_addr4))
1472    else:
1473        out_string += GetIn6AddrAsString((pcb.inp_dependfaddr.inp6_foreign.__u6_addr.__u6_addr8))
1474
1475    out_string += " "
1476    out_string += Getntohs(pcb.inp_fport)
1477    out_string += " "
1478
1479    if (proto == IPPROTO_TCP):
1480        out_string += GetTcpState(pcb.inp_ppcb)
1481
1482    out_string += "\n\t"
1483    if (pcb.inp_flags & INP_RECVOPTS):
1484        out_string += "recvopts "
1485    if (pcb.inp_flags & INP_RECVRETOPTS):
1486        out_string += "recvretopts "
1487    if (pcb.inp_flags & INP_RECVDSTADDR):
1488        out_string += "recvdstaddr "
1489    if (pcb.inp_flags & INP_HDRINCL):
1490        out_string += "hdrincl "
1491    if (pcb.inp_flags & INP_HIGHPORT):
1492        out_string += "highport "
1493    if (pcb.inp_flags & INP_LOWPORT):
1494        out_string += "lowport "
1495    if (pcb.inp_flags & INP_ANONPORT):
1496        out_string += "anonport "
1497    if (pcb.inp_flags & INP_RECVIF):
1498        out_string += "recvif "
1499    if (pcb.inp_flags & INP_MTUDISC):
1500        out_string += "mtudisc "
1501    if (pcb.inp_flags & INP_STRIPHDR):
1502        out_string += "striphdr "
1503    if (pcb.inp_flags & INP_RECV_ANYIF):
1504        out_string += "recv_anyif "
1505    if (pcb.inp_flags & INP_INADDR_ANY):
1506        out_string += "inaddr_any "
1507    if (pcb.inp_flags & INP_RECVTTL):
1508        out_string += "recvttl "
1509    if (pcb.inp_flags & INP_UDP_NOCKSUM):
1510        out_string += "nocksum "
1511    if (pcb.inp_flags & INP_BOUND_IF):
1512        out_string += "boundif "
1513    if (pcb.inp_flags & IN6P_IPV6_V6ONLY):
1514        out_string += "v6only "
1515    if (pcb.inp_flags & IN6P_PKTINFO):
1516        out_string += "pktinfo "
1517    if (pcb.inp_flags & IN6P_HOPLIMIT):
1518        out_string += "hoplimit "
1519    if (pcb.inp_flags & IN6P_HOPOPTS):
1520        out_string += "hopopts "
1521    if (pcb.inp_flags & IN6P_DSTOPTS):
1522        out_string += "dstopts "
1523    if (pcb.inp_flags & IN6P_RTHDR):
1524        out_string += "rthdr "
1525    if (pcb.inp_flags & IN6P_RTHDRDSTOPTS):
1526        out_string += "rthdrdstopts "
1527    if (pcb.inp_flags & IN6P_TCLASS):
1528        out_string += "rcv_tclass "
1529    if (pcb.inp_flags & IN6P_AUTOFLOWLABEL):
1530        out_string += "autoflowlabel "
1531    if (pcb.inp_flags & IN6P_BINDV6ONLY):
1532        out_string += "bindv6only "
1533    if (pcb.inp_flags & IN6P_RFC2292):
1534        out_string += "RFC2292 "
1535    if (pcb.inp_flags & IN6P_MTU):
1536        out_string += "rcv_pmtu "
1537    if (pcb.inp_flags & INP_PKTINFO):
1538        out_string += "pktinfo "
1539    if (pcb.inp_flags & INP_FLOW_SUSPENDED):
1540        out_string += "suspended "
1541    if (pcb.inp_flags & INP_NO_IFT_CELLULAR):
1542        out_string += "nocellular "
1543    if (pcb.inp_flags & INP_FLOW_CONTROLLED):
1544        out_string += "flowctld "
1545    if (pcb.inp_flags & INP_FC_FEEDBACK):
1546        out_string += "fcfeedback "
1547    if (pcb.inp_flags2 & INP2_TIMEWAIT):
1548        out_string += "timewait "
1549    if (pcb.inp_flags2 & INP2_IN_FCTREE):
1550        out_string += "in_fctree "
1551    if (pcb.inp_flags2 & INP2_WANT_APP_POLICY):
1552        out_string += "want_app_policy "
1553
1554    out_string += "\n\t"
1555    so = pcb.inp_socket
1556    if (so != 0):
1557        out_string += "so=" + str(so) + " s=" + str(int(so.so_snd.sb_cc)) + " r=" + str(int(so.so_rcv.sb_cc))
1558        if proto == IPPROTO_TCP :
1559            tcpcb = cast(pcb.inp_ppcb, 'tcpcb *')
1560            out_string += " reass=" + str(int(tcpcb.t_reassqlen))
1561
1562        out_string += " usecnt=" + str(int(so.so_usecount)) + ", "
1563
1564    if (pcb.inp_state == 0 or pcb.inp_state == INPCB_STATE_INUSE):
1565        out_string += "inuse"
1566    else:
1567        if (pcb.inp_state == INPCB_STATE_DEAD):
1568            out_string += "dead"
1569        else:
1570            out_string += "unknown (" + str(int(pcb.inp_state)) + ")"
1571
1572    return out_string
1573
1574def CalcMbufInList(mpkt, pkt_cnt, buf_byte_cnt, mbuf_cnt, mbuf_cluster_cnt):
1575    while (mpkt != 0):
1576        mp = mpkt
1577        if kern.globals.mb_uses_mcache == 1:
1578            mpkt = mp.m_hdr.mh_nextpkt
1579        else:
1580            mpkt = mp.M_hdr_common.M_hdr.mh_nextpkt
1581        pkt_cnt[0] +=1
1582        while (mp != 0):
1583            if kern.globals.mb_uses_mcache == 1:
1584                mnext = mp.m_hdr.mh_next
1585                mflags = mp.m_hdr.mh_flags
1586                mtype = mp.m_hdr.mh_type
1587            else:
1588                mnext = mp.M_hdr_common.M_hdr.mh_next
1589                mflags = mp.M_hdr_common.M_hdr.mh_flags
1590                mtype = mp.M_hdr_common.M_hdr.mh_type
1591            mbuf_cnt[0] += 1
1592            buf_byte_cnt[int(mtype)] += 256
1593            buf_byte_cnt[Mbuf_Type.MT_LAST] += 256
1594            if (mflags & 0x01):
1595                mbuf_cluster_cnt[0] += 1
1596                if kern.globals.mb_uses_mcache == 1:
1597                    extsize = mp.M_dat.MH.MH_dat.MH_ext.ext_size
1598                else:
1599                    extsize = mp.M_hdr_common.M_ext.ext_size
1600                buf_byte_cnt[int(mtype)] += extsize
1601                buf_byte_cnt[Mbuf_Type.MT_LAST] += extsize
1602            mp = mnext
1603
1604def 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):
1605    snd_cc[0] += so.so_snd.sb_cc
1606    mpkt = so.so_snd.sb_mb
1607    CalcMbufInList(mpkt, snd_record_cnt, snd_buf, snd_mbuf_cnt, snd_mbuf_cluster_cnt)
1608    rcv_cc[0] += so.so_rcv.sb_cc
1609    mpkt = so.so_rcv.sb_mb
1610    CalcMbufInList(mpkt, rcv_record_cnt, rcv_buf, rcv_mbuf_cnt, rcv_mbuf_cluster_cnt)
1611
1612# Macro: show_socket_sb_mbuf_usage
1613@lldb_command('show_socket_sb_mbuf_usage')
1614def ShowSocketSbMbufUsage(cmd_args=None):
1615    """ Display for a socket the mbuf usage of the send and receive socket buffers
1616    """
1617    if cmd_args is None or len(cmd_args) == 0:
1618            print("Missing argument 0 in user function.")
1619            return
1620    so = kern.GetValueFromAddress(cmd_args[0], 'socket *')
1621    out_string = ""
1622    if (so != 0):
1623        snd_mbuf_cnt = [0]
1624        snd_mbuf_cluster_cnt = [0]
1625        snd_record_cnt = [0]
1626        snd_cc = [0]
1627        snd_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1628        rcv_mbuf_cnt = [0]
1629        rcv_mbuf_cluster_cnt = [0]
1630        rcv_record_cnt = [0]
1631        rcv_cc = [0]
1632        rcv_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1633        total_mbuf_bytes = 0
1634        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)
1635        out_string += "total send mbuf count: " + str(int(snd_mbuf_cnt[0])) + " receive mbuf count: " + str(int(rcv_mbuf_cnt[0])) + "\n"
1636        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"
1637        out_string += "total send record count: " + str(int(snd_record_cnt[0])) + " receive record count: " + str(int(rcv_record_cnt[0])) + "\n"
1638        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"
1639        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"
1640        for x in range(Mbuf_Type.MT_LAST):
1641            if (snd_buf[x] != 0 or rcv_buf[x] != 0):
1642                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"
1643                total_mbuf_bytes += snd_buf[x] + rcv_buf[x]
1644    print(out_string)
1645# EndMacro:  show_socket_sb_mbuf_usage
1646
1647
1648def GetMptcpInfo():
1649    mptcp = kern.globals.mtcbinfo
1650
1651    mppcb = cast(mptcp.mppi_pcbs.tqh_first, 'mppcb *')
1652    pcbseen = 0
1653    reinject_cnt=[0]
1654    reinject_byte_cnt=[0] * (Mbuf_Type.MT_LAST + 1)
1655    reinject_mbuf_cnt=[0]
1656    reinject_mbuf_cluster_cnt=[0]
1657
1658    snd_mbuf_cnt = [0]
1659    snd_mbuf_cluster_cnt = [0]
1660    snd_record_cnt = [0]
1661    snd_cc = [0]
1662    snd_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1663    rcv_mbuf_cnt = [0]
1664    rcv_mbuf_cluster_cnt = [0]
1665    rcv_record_cnt = [0]
1666    rcv_cc = [0]
1667    rcv_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1668    total_mbuf_bytes = 0
1669    while mppcb != 0:
1670        mpte = mppcb.mpp_pcbe
1671        pcbseen += 1
1672        CalcMbufInList(mpte.mpte_reinjectq, reinject_cnt, reinject_byte_cnt, reinject_mbuf_cnt, reinject_mbuf_cluster_cnt)
1673
1674        socket = mppcb.mpp_socket
1675        if socket != 0:
1676            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)
1677
1678        mppcb = cast(mppcb.mpp_entry.tqe_next, 'mppcb *')
1679
1680    out_string = ""
1681    out_string += "total pcbs seen: " + str(int(pcbseen)) + "\n"
1682    out_string += "total reinject mbuf count: " + str(int(reinject_mbuf_cnt[0])) + "\n"
1683    out_string += "total reinject mbuf cluster count: " + str(int(reinject_mbuf_cluster_cnt[0])) + "\n"
1684    out_string += "total reinject record count: " + str(int(reinject_cnt[0])) + "\n"
1685    for x in range(Mbuf_Type.MT_LAST):
1686        if (reinject_byte_cnt[x] != 0):
1687            out_string += "total reinject bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(reinject_byte_cnt[x])) + "\n"
1688            total_mbuf_bytes += reinject_byte_cnt[x]
1689
1690
1691    out_string += "total send mbuf count: " + str(int(snd_mbuf_cnt[0])) + " receive mbuf count: " + str(int(rcv_mbuf_cnt[0])) + "\n"
1692    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"
1693    out_string += "total send record count: " + str(int(snd_record_cnt[0])) + " receive record count: " + str(int(rcv_record_cnt[0])) + "\n"
1694    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"
1695    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"
1696    for x in range(Mbuf_Type.MT_LAST):
1697        if (snd_buf[x] != 0 or rcv_buf[x] != 0):
1698            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"
1699            total_mbuf_bytes += snd_buf[x] + rcv_buf[x]
1700
1701    out_string += "total mbuf bytes used by MPTCP: "+ str(total_mbuf_bytes) + "\n"
1702    print(out_string)
1703
1704def GetPcbInfo(pcbi, proto):
1705    tcp_reassqlen = [0]
1706    tcp_reassq_bytes = 0
1707    mbuf_reassq_cnt = [0]
1708    mbuf_reassq_bytes = [0] * (Mbuf_Type.MT_LAST + 1)
1709    mbuf_reassq_cluster = [0]
1710    out_string = ""
1711    snd_mbuf_cnt = [0]
1712    snd_mbuf_cluster_cnt = [0]
1713    snd_record_cnt = [0]
1714    snd_cc = [0]
1715    snd_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1716    rcv_mbuf_cnt = [0]
1717    rcv_mbuf_cluster_cnt = [0]
1718    rcv_record_cnt = [0]
1719    rcv_cc = [0]
1720    rcv_buf = [0] * (Mbuf_Type.MT_LAST + 1)
1721    pcbseen = 0
1722    out_string += "lastport " + str(int(pcbi.ipi_lastport)) + " lastlow " + str(int(pcbi.ipi_lastlow)) + " lasthi " + str(int(pcbi.ipi_lasthi)) + "\n"
1723    out_string += "active pcb count is " + str(int(pcbi.ipi_count)) + "\n"
1724    hashsize = pcbi.ipi_hashmask + 1
1725    out_string += "hash size is " + str(int(hashsize)) + "\n"
1726    out_string += str(pcbi.ipi_hashbase) + " has the following inpcb(s):\n"
1727    if (kern.ptrsize == 8):
1728        out_string += "pcb                proto  source                                        port  destination                                 port\n"
1729    else:
1730        out_string += "pcb            proto  source           address  port  destination         address  port\n\n"
1731
1732    if proto == IPPROTO_RAW:
1733        head = cast(pcbi.ipi_listhead, 'inpcbhead *')
1734        pcb = cast(head.lh_first, 'inpcb *')
1735        while pcb != 0:
1736            pcbseen += 1
1737            out_string += GetInPcb(pcb, proto) + "\n"
1738            so = pcb.inp_socket
1739            if so != 0:
1740                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)
1741            pcb = cast(pcb.inp_list.le_next, 'inpcb *')
1742    else:
1743        i = 0
1744        hashbase = pcbi.ipi_hashbase
1745        while (i < hashsize):
1746            head = hashbase[i]
1747            pcb = cast(head.lh_first, 'inpcb *')
1748            while pcb != 0:
1749                pcbseen += 1
1750                out_string += GetInPcb(pcb, proto) + "\n"
1751                so = pcb.inp_socket
1752                if so != 0:
1753                    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)
1754                if proto == IPPROTO_TCP and pcb.inp_ppcb:
1755                    tcpcb = cast(pcb.inp_ppcb, 'tcpcb *')
1756                    reass_entry = cast(tcpcb.t_segq.lh_first, 'tseg_qent *')
1757                    curr_reass = 0
1758                    while reass_entry != 0:
1759                        CalcMbufInList(reass_entry.tqe_m, tcp_reassqlen, mbuf_reassq_bytes, mbuf_reassq_cnt, mbuf_reassq_cluster)
1760                        tcp_reassq_bytes += reass_entry.tqe_len
1761                        curr_reass += reass_entry.tqe_len
1762
1763                        reass_entry = reass_entry.tqe_q.le_next
1764
1765                pcb = cast(pcb.inp_hash.le_next, 'inpcb *')
1766            i += 1
1767
1768    out_string += "total pcbs seen: " + str(int(pcbseen)) + "\n"
1769    out_string += "total send mbuf count: " + str(int(snd_mbuf_cnt[0])) + " receive mbuf count: " + str(int(rcv_mbuf_cnt[0])) + "\n"
1770    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"
1771    out_string += "total send record count: " + str(int(snd_record_cnt[0])) + " receive record count: " + str(int(rcv_record_cnt[0])) + "\n"
1772    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"
1773    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"
1774    for x in range(Mbuf_Type.MT_LAST):
1775        if (snd_buf[x] != 0 or rcv_buf[x] != 0):
1776            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"
1777    out_string += "port hash base is " + hex(pcbi.ipi_porthashbase) + "\n"
1778    if proto == IPPROTO_TCP:
1779        out_string += "TCP reassembly queue length: " + str(tcp_reassqlen[0]) + " TCP-payload bytes: " + str(tcp_reassq_bytes) + "\n"
1780
1781        for x in range(Mbuf_Type.MT_LAST):
1782            if mbuf_reassq_bytes[x] != 0:
1783                out_string += "total reassq bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(mbuf_reassq_bytes[x]) + "\n"
1784
1785    i = 0
1786    hashbase = pcbi.ipi_porthashbase
1787    while (i < hashsize):
1788        head = hashbase[i]
1789        pcb = cast(head.lh_first, 'inpcbport *')
1790        while pcb != 0:
1791            out_string += "\t"
1792            out_string += GetInPcbPort(pcb)
1793            out_string += "\n"
1794            pcb = cast(pcb.phd_hash.le_next, 'inpcbport *')
1795        i += 1
1796
1797    return out_string
1798
1799def GetInPcbPort(ppcb):
1800    out_string = ""
1801    out_string += hex(ppcb) + ": lport "
1802    out_string += Getntohs(ppcb.phd_port)
1803    return out_string
1804
1805
1806def Getntohs(port):
1807    out_string = ""
1808    #p = unsigned(int(port) & 0x0000ffff)
1809    p = ((port & 0x0000ff00) >> 8)
1810    p |= ((port & 0x000000ff) << 8)
1811    return str(p)
1812
1813
1814# Macro: mbuf_list_usage_summary
1815@lldb_command('mbuf_list_usage_summary')
1816def ShowMbufListUsageSummary(cmd_args=None):
1817    """ Print mbuf list usage summary
1818    Usage: mbuf_list_usage_summary [mbuf_addr]
1819    """
1820    if cmd_args is None or len(cmd_args) == 0:
1821        raise ArgumentError()
1822
1823    out_string = ""
1824    pkt_cnt = [0]
1825    buf_byte_cnt = [0] * (Mbuf_Type.MT_LAST + 1)
1826    mbuf_cnt = [0]
1827    mbuf_cluster_cnt = [0]
1828
1829    mpkt = kern.GetValueFromAddress(cmd_args[0], 'struct mbuf *')
1830    CalcMbufInList(mpkt, pkt_cnt, buf_byte_cnt, mbuf_cnt, mbuf_cluster_cnt)
1831
1832    out_string += "Total packet count is " + str(int(pkt_cnt[0])) + "\n"
1833    for x in range(Mbuf_Type.MT_LAST):
1834        if (buf_byte_cnt[x] != 0):
1835            out_string += "Total buf bytes of type " + Mbuf_Type.reverse_mapping[x] + " : " + str(int(buf_byte_cnt[x])) + "\n"
1836    out_string += "Total mbuf count " + str(int(mbuf_cnt[0])) + "\n"
1837    out_string += "Total mbuf cluster count " + str(int(mbuf_cluster_cnt[0])) + "\n"
1838    print(out_string)
1839
1840# Macro: show_kern_event_pcbinfo
1841def GetKernEventPcbInfo(kev_pcb_head):
1842    out_string = ""
1843    pcb = Cast(kev_pcb_head.lh_first, 'kern_event_pcb *')
1844    if (kern.ptrsize == 8):
1845        kev_pcb_format_string = "0x{0:<16x} {1:12d} {2:16d} {3:16d} {4:16d} {5:16d}"
1846        out_string += "  evp socket         vendor code      class filter      subclass filter     so_rcv.sb_cc      so_rcv.sb_mbcnt\n"
1847        out_string += "--------------       -----------      ------------      ---------------     ------------      ---------------\n"
1848    else:
1849        kev_pcb_format_string = "0x{0:<8x} {1:12d} {2:16d} {3:16d} {4:16d} {5:16d}"
1850        out_string += "evp socket       vendor code      class filter      subclass filter     so_rcv.sb_cc      so_rcv.sb_mbcnt\n"
1851        out_string += "----------       -----------      ------------      ---------------     ------------      ---------------\n"
1852    while (pcb != 0):
1853        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)
1854        out_string += "\n"
1855        pcb = pcb.evp_link.le_next
1856    return out_string
1857
1858@lldb_command('show_kern_event_pcbinfo')
1859def ShowKernEventPcbInfo(cmd_args=None):
1860    """ Display the list of Kernel Event protocol control block information
1861    """
1862    print(GetKernEventPcbInfo(addressof(kern.globals.kern_event_head)))
1863# EndMacro:  show_kern_event_pcbinfo
1864
1865# Macro: show_kern_control_pcbinfo
1866def GetKernControlPcbInfo(ctl_head):
1867    out_string = ""
1868    kctl = Cast(ctl_head.tqh_first, 'kctl *')
1869    if (kern.ptrsize == 8):
1870        kcb_format_string = "0x{0:<16x} {1:10d} {2:10d} {3:10d}\n"
1871    else:
1872        kcb_format_string = "0x{0:<8x} {1:10d} {2:10d} {3:10d}\n"
1873    while unsigned(kctl) != 0:
1874        kctl_name = "controller: " + str(kctl.name) + "\n"
1875        out_string += kctl_name
1876        kcb = Cast(kctl.kcb_head.tqh_first, 'ctl_cb *')
1877        if unsigned(kcb) != 0:
1878            if (kern.ptrsize == 8):
1879                out_string += "socket               usecount     snd_cc     rcv_cc\n"
1880                out_string += "------               --------     ------     ------\n"
1881            else:
1882                out_string += "socket       usecount     snd_cc     rcv_cc\n"
1883                out_string += "------       --------     ------     ------\n"
1884        while unsigned(kcb) != 0:
1885            so = Cast(kcb.so, 'socket *')
1886            snd_cc = so.so_snd.sb_cc
1887            rcv_cc = so.so_rcv.sb_cc
1888            out_string += kcb_format_string.format(kcb.so, kcb.usecount, snd_cc, rcv_cc)
1889            kcb = kcb.next.tqe_next
1890        out_string += "\n"
1891        kctl = kctl.next.tqe_next
1892    return out_string
1893
1894@lldb_command('show_kern_control_pcbinfo')
1895def ShowKernControlPcbInfo(cmd_args=None):
1896    """ Display the list of Kernel Control protocol control block information
1897    """
1898    print(GetKernControlPcbInfo(addressof(kern.globals.ctl_head)))
1899# EndMacro:  show_kern_control_pcbinfo
1900
1901# Macro: show_unix_domain_pcbinfo
1902def GetUnixDomainPCBAsString(unp, type) :
1903    out_string = ""
1904    pcb = Cast(unp, 'unpcb *')
1905    out_string += "unpcb: " + hex(pcb)  + " " + str(type)
1906    out_string += " unp_socket: " + hex(pcb.unp_socket)
1907    out_string += " unp_vnode: " + hex(pcb.unp_vnode)
1908    out_string += " unp_conn: " + hex(pcb.unp_conn)
1909    out_string += " unp_addr: " + GetSocketAddrAsStringUnix(pcb.unp_addr)
1910    out_string += " unp_gencnt: " + str(int(pcb.unp_gencnt))
1911    out_string += " unp_flags: " + hex(pcb.unp_flags)
1912    if pcb.unp_socket != 0:
1913        so = Cast(pcb.unp_socket, 'socket *')
1914        out_string += " s=" + str(int(so.so_snd.sb_cc)) + " r=" + str(int(so.so_rcv.sb_cc)) + " usecnt=" + str(int(so.so_usecount))
1915    return out_string
1916
1917def GetUnixDomainPcbInfo(unp_head, type):
1918    out_string = ""
1919    unp = Cast(unp_head.lh_first, 'unpcb *')
1920    while unsigned(unp) != 0:
1921        out_string += GetUnixDomainPCBAsString(unp, type)
1922        out_string += "\n"
1923        unp = unp.unp_link.le_next
1924    return out_string
1925
1926@lldb_command('show_unix_domain_pcbinfo')
1927def ShowUnixDomainPcbInfo(cmd_args=None):
1928    """ Display the list of unix domain pcb
1929    """
1930    print(GetUnixDomainPcbInfo(addressof(kern.globals.unp_dhead), "dgram"))
1931    print(GetUnixDomainPcbInfo(addressof(kern.globals.unp_shead), "stream"))
1932# EndMacro:  show_kern_control_pcbinfo
1933
1934# Macro: show_tcp_pcbinfo
1935@lldb_command('show_tcp_pcbinfo')
1936def ShowTcpPcbInfo(cmd_args=None):
1937    """ Display the list of TCP protocol control block information
1938    """
1939    print(GetPcbInfo(addressof(kern.globals.tcbinfo), IPPROTO_TCP))
1940# EndMacro:  show_tcp_pcbinfo
1941
1942# Macro: show_udp_pcbinfo
1943@lldb_command('show_udp_pcbinfo')
1944def ShowUdpPcbInfo(cmd_args=None):
1945    """ Display the list of UDP protocol control block information
1946    """
1947    print(GetPcbInfo(addressof(kern.globals.udbinfo), IPPROTO_UDP))
1948# EndMacro:  show_udp_pcbinfo
1949
1950# Macro: show_udp_pcbinfo
1951@lldb_command('show_udb_info')
1952def ShowUdb(cmd_args=None):
1953    """ Display the list of UDP PCBs from udb.
1954    """
1955    head = kern.globals.udb
1956    pcb = cast(head.lh_first, 'inpcb *')
1957    pcbseen = 0
1958    while pcb != 0:
1959        pcbseen += 1
1960        so = pcb.inp_socket
1961        pcb = cast(pcb.inp_list.le_next, 'inpcb *')
1962        #print(pcb.inp_last_proc_name)
1963        print(GetInPcb(pcb, IPPROTO_UDP))
1964        #print(pcb.inp_start_timestamp)
1965# EndMacro: show_udb_pcbinfo
1966
1967# Macro: show_rip_pcbinfo
1968@lldb_command('show_rip_pcbinfo')
1969def ShowRipPcbInfo(cmd_args=None):
1970    """ Display the list of Raw IP protocol control block information
1971    """
1972    print(GetPcbInfo(addressof(kern.globals.ripcbinfo), IPPROTO_RAW))
1973# EndMacro:  show_rip_pcbinfo
1974
1975# Macro: show_mptcp_pcbinfo
1976@lldb_command('show_mptcp_pcbinfo')
1977def ShowMptcpPcbInfo(cmd_args=None):
1978    """ Display the list of MPTCP protocol control block information
1979    """
1980    GetMptcpInfo()
1981# EndMacro:  show_mptcp_pcbinfo
1982
1983# Macro: show_domains
1984@lldb_command('show_domains')
1985def ShowDomains(cmd_args=None):
1986    """ Display the list of the domains
1987    """
1988    out_string = ""
1989    domains = kern.globals.domains
1990    dp = Cast(domains.tqh_first, 'domain *')
1991    ifma_trash_format_string = "{0:4d}: {1:x} {2:3d} {3:6d} {4:6d}"
1992    cnt = 0
1993    while (dp != 0):
1994        out_string += "\"" + str(dp.dom_name) + "\"" + "[" + str(int(dp.dom_refs)) + " refs] domain " + hex(dp) + "\n"
1995        out_string += "    family:\t" + str(int(dp.dom_family)) + "\n"
1996        out_string += "    flags:0x\t" + str(int(dp.dom_flags)) + "\n"
1997        out_string += "    rtparams:\toff=" + str(int(dp.dom_rtoffset)) + ", maxrtkey=" + str(int(dp.dom_maxrtkey)) + "\n"
1998
1999        if (dp.dom_init):
2000            out_string += "    init:\t"
2001            out_string += GetSourceInformationForAddress(dp.dom_init) + "\n"
2002        if (dp.dom_externalize):
2003            out_string += "    externalize:\t"
2004            out_string += GetSourceInformationForAddress(dp.dom_externalize) + "\n"
2005        if (dp.dom_dispose):
2006            out_string += "    dispose:\t"
2007            out_string += GetSourceInformationForAddress(dp.dom_dispose) + "\n"
2008        if (dp.dom_rtattach):
2009            out_string += "    rtattach:\t"
2010            out_string += GetSourceInformationForAddress(dp.dom_rtattach) + "\n"
2011        if (dp.dom_old):
2012            out_string += "    old:\t"
2013            out_string += GetSourceInformationForAddress(dp.dom_old) + "\n"
2014
2015        pr = Cast(dp.dom_protosw.tqh_first, 'protosw *')
2016        while pr != 0:
2017            pru = pr.pr_usrreqs
2018            out_string += "\ttype " + str(int(pr.pr_type)) + ", protocol " + str(int(pr.pr_protocol)) + ", protosw " + hex(pr) + "\n"
2019            out_string += "\t    flags:0x\t" + hex(pr.pr_flags) + "\n"
2020            if (pr.pr_input):
2021                out_string += "\t    input:\t"
2022                out_string += GetSourceInformationForAddress(pr.pr_input) + "\n"
2023            if (pr.pr_output):
2024                out_string += "\t    output:\t"
2025                out_string += GetSourceInformationForAddress(pr.pr_output) + "\n"
2026            if (pr.pr_ctlinput):
2027                out_string += "\t    ctlinput:\t"
2028                out_string += GetSourceInformationForAddress(pr.pr_ctlinput) + "\n"
2029            if (pr.pr_ctloutput):
2030                out_string += "\t    ctloutput:\t"
2031                out_string += GetSourceInformationForAddress(pr.pr_ctloutput) + "\n"
2032            if (pr.pr_init):
2033                out_string += "\t    init:\t"
2034                out_string += GetSourceInformationForAddress(pr.pr_init) + "\n"
2035            if (pr.pr_drain):
2036                out_string += "\t    drain:\t"
2037                out_string += GetSourceInformationForAddress(pr.pr_drain) + "\n"
2038            if (pr.pr_sysctl):
2039                out_string += "\t    sysctl:\t"
2040                out_string += GetSourceInformationForAddress(pr.pr_sysctl) + "\n"
2041            if (pr.pr_lock):
2042                out_string += "\t    lock:\t"
2043                out_string += GetSourceInformationForAddress(pr.pr_lock) + "\n"
2044            if (pr.pr_unlock):
2045                out_string += "\t    unlock:\t"
2046                out_string += GetSourceInformationForAddress(pr.pr_unlock) + "\n"
2047            if (pr.pr_getlock):
2048                out_string += "\t    getlock:\t"
2049                out_string += GetSourceInformationForAddress(pr.pr_getlock) + "\n"
2050            if (pr.pr_old):
2051                out_string += "\t    old:\t"
2052                out_string += GetSourceInformationForAddress(pr.pr_old) + "\n"
2053
2054            out_string += "\t    pru_flags:0x\t" + hex(pru.pru_flags) + "\n"
2055            out_string += "\t    abort:\t"
2056            out_string += GetSourceInformationForAddress(pru.pru_abort) + "\n"
2057            out_string += "\t    accept:\t"
2058            out_string += GetSourceInformationForAddress(pru.pru_accept) + "\n"
2059            out_string += "\t    attach:\t"
2060            out_string += GetSourceInformationForAddress(pru.pru_attach) + "\n"
2061            out_string += "\t    bind:\t"
2062            out_string += GetSourceInformationForAddress(pru.pru_bind) + "\n"
2063            out_string += "\t    connect:\t"
2064            out_string += GetSourceInformationForAddress(pru.pru_connect) + "\n"
2065            out_string += "\t    connect2:\t"
2066            out_string += GetSourceInformationForAddress(pru.pru_connect2) + "\n"
2067            out_string += "\t    connectx:\t"
2068            out_string += GetSourceInformationForAddress(pru.pru_connectx) + "\n"
2069            out_string += "\t    control:\t"
2070            out_string += GetSourceInformationForAddress(pru.pru_control) + "\n"
2071            out_string += "\t    detach:\t"
2072            out_string += GetSourceInformationForAddress(pru.pru_detach) + "\n"
2073            out_string += "\t    disconnect:\t"
2074            out_string += GetSourceInformationForAddress(pru.pru_disconnect) + "\n"
2075            out_string += "\t    listen:\t"
2076            out_string += GetSourceInformationForAddress(pru.pru_listen) + "\n"
2077            out_string += "\t    peeraddr:\t"
2078            out_string += GetSourceInformationForAddress(pru.pru_peeraddr) + "\n"
2079            out_string += "\t    rcvd:\t"
2080            out_string += GetSourceInformationForAddress(pru.pru_rcvd) + "\n"
2081            out_string += "\t    rcvoob:\t"
2082            out_string += GetSourceInformationForAddress(pru.pru_rcvoob) + "\n"
2083            out_string += "\t    send:\t"
2084            out_string += GetSourceInformationForAddress(pru.pru_send) + "\n"
2085            out_string += "\t    sense:\t"
2086            out_string += GetSourceInformationForAddress(pru.pru_sense) + "\n"
2087            out_string += "\t    shutdown:\t"
2088            out_string += GetSourceInformationForAddress(pru.pru_shutdown) + "\n"
2089            out_string += "\t    sockaddr:\t"
2090            out_string += GetSourceInformationForAddress(pru.pru_sockaddr) + "\n"
2091            out_string += "\t    sopoll:\t"
2092            out_string += GetSourceInformationForAddress(pru.pru_sopoll) + "\n"
2093            out_string += "\t    soreceive:\t"
2094            out_string += GetSourceInformationForAddress(pru.pru_soreceive) + "\n"
2095            out_string += "\t    sosend:\t"
2096            out_string += GetSourceInformationForAddress(pru.pru_sosend) + "\n"
2097            pr = pr.pr_entry.tqe_next
2098        dp = dp.dom_entry.tqe_next
2099
2100        print(out_string)
2101# EndMacro: show_domains
2102
2103# Macro: tcp_count_rxt_segments
2104@lldb_command('tcp_count_rxt_segments')
2105def TCPCountRxtSegments(cmd_args=None):
2106    """ Size of the t_rxt_segments chain
2107    """
2108    if cmd_args is None or len(cmd_args) == 0:
2109        raise ArgumentError("Missing argument 0 in user function.")
2110
2111    tp = kern.GetValueFromAddress(cmd_args[0], 'tcpcb *')
2112    rxseg = cast(tp.t_rxt_segments.slh_first, 'tcp_rxt_seg *')
2113    cnt = 0
2114    while rxseg != 0:
2115        cnt += 1
2116        rxseg = rxseg.rx_link.sle_next
2117        if (cnt % 1000 == 0):
2118            print(" running count: {:d}".format(cnt))
2119    print(" total count: {:d}".format(cnt))
2120# EndMacro: tcp_count_rxt_segments
2121
2122# Macro: tcp_walk_rxt_segments
2123@lldb_command('tcp_walk_rxt_segments')
2124def TCPWalkRxtSegments(cmd_args=None):
2125    """ Walk the t_rxt_segments chain
2126    """
2127    if cmd_args is None or len(cmd_args) == 0:
2128        raise ArgumentError("Missing argument 0 in user function.")
2129
2130    tp = kern.GetValueFromAddress(cmd_args[0], 'tcpcb *')
2131    rxseg = cast(tp.t_rxt_segments.slh_first, 'tcp_rxt_seg *')
2132    cnt = 0
2133    while rxseg != 0:
2134        cnt += 1
2135        rxseg = rxseg.rx_link.sle_next
2136        if (cnt % 1000 == 0):
2137            print(" running count: {:d}".format(cnt))
2138    print(" total count: {:d}".format(cnt))
2139    rxseg = cast(tp.t_rxt_segments.slh_first, 'tcp_rxt_seg *')
2140    cnt = 0
2141    while rxseg != 0:
2142        cnt += 1
2143        out_string = ""
2144        span = rxseg.rx_end - rxseg.rx_start
2145        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}"
2146        out_string += rxseg_format.format(cnt, rxseg, rxseg.rx_start, rxseg.rx_end, rxseg.rx_count, rxseg.rx_flags, abs(span))
2147        print(out_string)
2148        rxseg = rxseg.rx_link.sle_next
2149# EndMacro: tcp_walk_rxt_segments
2150