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