version 1.139, 2015/02/08 04:40:50 |
version 1.140, 2015/02/12 01:49:02 |
|
|
#include <sys/domain.h> |
#include <sys/domain.h> |
#include <sys/protosw.h> |
#include <sys/protosw.h> |
#include <sys/sysctl.h> |
#include <sys/sysctl.h> |
|
#define _KERNEL |
|
#include <sys/ucred.h> |
|
#include <sys/file.h> |
|
#undef _KERNEL |
|
|
#include <net/route.h> |
#include <net/route.h> |
#include <netinet/in.h> |
#include <netinet/in.h> |
|
|
struct socket sockb; |
struct socket sockb; |
|
|
char *inetname(struct in_addr *); |
char *inetname(struct in_addr *); |
void inetprint(struct in_addr *, in_port_t, char *, int); |
void inetprint(struct in_addr *, in_port_t, const char *, int); |
char *inet6name(struct in6_addr *); |
char *inet6name(struct in6_addr *); |
void inet6print(struct in6_addr *, int, char *); |
|
void sosplice_dump(u_long); |
void sosplice_dump(u_long); |
void sockbuf_dump(struct sockbuf *, const char *); |
void sockbuf_dump(struct sockbuf *, const char *); |
void protosw_dump(u_long, u_long); |
void protosw_dump(u_long, u_long); |
|
|
void inpcb_dump(u_long, short, int); |
void inpcb_dump(u_long, short, int); |
void tcpcb_dump(u_long); |
void tcpcb_dump(u_long); |
|
|
|
int type_map[] = { -1, 2, 3, 1, 4, 5 }; |
|
|
|
int |
|
kf_comp(const void *a, const void *b) |
|
{ |
|
const struct kinfo_file *ka = a, *kb = b; |
|
|
|
if (ka->so_family != kb->so_family) { |
|
/* AF_INET < AF_INET6 < AF_LOCAL */ |
|
if (ka->so_family == AF_INET) |
|
return (-1); |
|
if (ka->so_family == AF_LOCAL) |
|
return (1); |
|
if (kb->so_family == AF_LOCAL) |
|
return (-1); |
|
return (1); |
|
} |
|
if (ka->so_family == AF_LOCAL) { |
|
if (type_map[ka->so_type] < type_map[kb->so_type]) |
|
return (-1); |
|
if (type_map[ka->so_type] > type_map[kb->so_type]) |
|
return (1); |
|
} else if (ka->so_family == AF_INET || ka->so_family == AF_INET6) { |
|
if (ka->so_protocol < kb->so_protocol) |
|
return (-1); |
|
if (ka->so_protocol > kb->so_protocol) |
|
return (1); |
|
if (ka->so_type == SOCK_DGRAM || ka->so_type == SOCK_STREAM) { |
|
/* order sockets by remote port desc */ |
|
if (ka->inp_fport > kb->inp_fport) |
|
return (-1); |
|
if (ka->inp_fport < kb->inp_fport) |
|
return (1); |
|
} else if (ka->so_type == SOCK_RAW) { |
|
if (ka->inp_proto > kb->inp_proto) |
|
return (-1); |
|
if (ka->inp_proto < kb->inp_proto) |
|
return (1); |
|
} |
|
} |
|
return (0); |
|
} |
|
|
|
void |
|
protopr(kvm_t *kvmd, u_long pcbaddr, u_int tableid, int proto) |
|
{ |
|
struct kinfo_file *kf; |
|
int i, fcnt; |
|
|
|
kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET, |
|
sizeof(*kf), &fcnt); |
|
if (kf == NULL) { |
|
printf("Out of memory (file table).\n"); |
|
return; |
|
} |
|
|
|
/* sort sockets by AF and type */ |
|
qsort(kf, fcnt, sizeof(*kf), kf_comp); |
|
|
|
for (i = 0; i < fcnt; i++) { |
|
if (Pflag) { |
|
switch (kf[i].so_family) { |
|
case AF_INET: |
|
case AF_INET6: |
|
/* |
|
* XXX at the moment fstat returns the pointer |
|
* to the so_pcb or for tcp sockets the tcpcb |
|
* pointer (inp_ppcb) so check both. |
|
*/ |
|
if (pcbaddr == kf[i].so_pcb) { |
|
inpcb_dump(pcbaddr, kf[i].so_protocol, |
|
kf[i].so_family); |
|
return; |
|
} else if (pcbaddr == kf[i].inp_ppcb && |
|
kf[i].so_protocol == IPPROTO_TCP) { |
|
tcpcb_dump(pcbaddr); |
|
return; |
|
} |
|
break; |
|
case AF_UNIX: |
|
if (pcbaddr == kf[i].so_pcb) { |
|
unpcb_dump(pcbaddr); |
|
return; |
|
} |
|
break; |
|
} |
|
continue; |
|
} |
|
if (kf[i].so_family == AF_LOCAL && (kf[i].so_pcb != 0 || |
|
kf[i].unp_path[0] != '\0')) |
|
if ((af == AF_LOCAL || af == AF_UNSPEC) && !proto) |
|
unixdomainpr(&kf[i]); |
|
if (kf[i].so_family == AF_INET && kf[i].so_pcb != 0 && |
|
kf[i].inp_rtableid == tableid) |
|
if (af == AF_INET || af == AF_UNSPEC) |
|
netdomainpr(&kf[i], proto); |
|
if (kf[i].so_family == AF_INET6 && kf[i].so_pcb != 0 && |
|
kf[i].inp_rtableid == tableid) |
|
if (af == AF_INET6 || af == AF_UNSPEC) |
|
netdomainpr(&kf[i], proto); |
|
} |
|
} |
|
|
/* |
/* |
* Print a summary of connections related to an Internet |
* Print a summary of connections related to an Internet |
* protocol. For TCP, also give state of connection. |
* protocol. For TCP, also give state of connection. |
|
|
* -a (all) flag is specified. |
* -a (all) flag is specified. |
*/ |
*/ |
void |
void |
protopr(u_long off, char *name, int af, u_int tableid, u_long pcbaddr) |
netdomainpr(struct kinfo_file *kf, int proto) |
{ |
{ |
struct inpcbtable table; |
static int af = 0, type = 0; |
struct inpcb *prev, *next; |
struct in_addr laddr, faddr; |
struct inpcb inpcb, prevpcb; |
struct in6_addr laddr6, faddr6; |
int istcp, israw, isany; |
const char *name, *name6; |
int addrlen = 22; |
int addrlen = 22; |
int first = 1; |
int isany = 0; |
char *name0; |
int istcp = 0; |
char namebuf[20]; |
int isip6 = 0; |
|
|
name0 = name; |
/* XXX should fix kinfo_file instead but not now */ |
if (off == 0) |
if (kf->so_pcb == -1) |
return; |
kf->so_pcb = 0; |
istcp = strcmp(name, "tcp") == 0; |
|
israw = strncmp(name, "ip", 2) == 0; |
|
kread(off, &table, sizeof table); |
|
prev = NULL; |
|
next = TAILQ_FIRST(&table.inpt_queue); |
|
|
|
while (next != NULL) { |
switch (proto) { |
kread((u_long)next, &inpcb, sizeof inpcb); |
case IPPROTO_TCP: |
if (prev != NULL) { |
case IPPROTO_UDP: |
kread((u_long)prev, &prevpcb, sizeof prevpcb); |
case IPPROTO_DIVERT: |
if (TAILQ_NEXT(&prevpcb, inp_queue) != next) { |
if (kf->so_protocol != proto) |
printf("PCB list changed\n"); |
return; |
break; |
break; |
} |
case IPPROTO_IPV4: |
} |
if (kf->so_type != SOCK_RAW || kf->so_family != AF_INET) |
prev = next; |
return; |
next = TAILQ_NEXT(&inpcb, inp_queue); |
break; |
|
case IPPROTO_IPV6: |
|
if (kf->so_type != SOCK_RAW || kf->so_family != AF_INET6) |
|
return; |
|
break; |
|
} |
|
|
switch (af) { |
/* make in_addr6 access a bit easier */ |
case AF_INET: |
#define s6_addr32 __u6_addr.__u6_addr32 |
if ((inpcb.inp_flags & INP_IPV6) != 0) |
laddr.s_addr = kf->inp_laddru[0]; |
continue; |
laddr6.s6_addr32[0] = kf->inp_laddru[0]; |
isany = inet_lnaof(inpcb.inp_faddr) == INADDR_ANY; |
laddr6.s6_addr32[1] = kf->inp_laddru[1]; |
break; |
laddr6.s6_addr32[2] = kf->inp_laddru[2]; |
case AF_INET6: |
laddr6.s6_addr32[3] = kf->inp_laddru[3]; |
if ((inpcb.inp_flags & INP_IPV6) == 0) |
|
continue; |
|
isany = IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_faddr6); |
|
break; |
|
default: |
|
isany = 0; |
|
break; |
|
} |
|
|
|
if (Pflag) { |
faddr.s_addr = kf->inp_faddru[0]; |
if (istcp && pcbaddr == (u_long)inpcb.inp_ppcb) { |
faddr6.s6_addr32[0] = kf->inp_faddru[0]; |
if (vflag) |
faddr6.s6_addr32[1] = kf->inp_faddru[1]; |
socket_dump((u_long)inpcb.inp_socket); |
faddr6.s6_addr32[2] = kf->inp_faddru[2]; |
else |
faddr6.s6_addr32[3] = kf->inp_faddru[3]; |
tcpcb_dump(pcbaddr); |
#undef s6_addr32 |
} else if (pcbaddr == (u_long)prev) { |
|
if (vflag) |
|
socket_dump((u_long)inpcb.inp_socket); |
|
else |
|
inpcb_dump(pcbaddr, 0, af); |
|
} |
|
continue; |
|
} |
|
|
|
if (inpcb.inp_rtableid != tableid) |
switch (kf->so_family) { |
continue; |
case AF_INET: |
|
isany = faddr.s_addr == INADDR_ANY; |
|
break; |
|
case AF_INET6: |
|
isany = IN6_IS_ADDR_UNSPECIFIED(&faddr6); |
|
isip6 = 1; |
|
break; |
|
} |
|
|
kread((u_long)inpcb.inp_socket, &sockb, sizeof (sockb)); |
switch (kf->so_protocol) { |
if (istcp) { |
case IPPROTO_TCP: |
kread((u_long)inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb)); |
name = "tcp"; |
if (!aflag && tcpcb.t_state <= TCPS_LISTEN) |
name6 = "tcp6"; |
continue; |
istcp = 1; |
} else if (!aflag && isany) |
break; |
continue; |
case IPPROTO_UDP: |
if (first) { |
name = "udp"; |
printf("Active Internet connections"); |
name6 = "udp6"; |
if (aflag) |
break; |
printf(" (including servers)"); |
case IPPROTO_DIVERT: |
putchar('\n'); |
name = "divert"; |
if (Aflag) { |
name6 = "divert6"; |
addrlen = 18; |
break; |
printf("%-*.*s ", PLEN, PLEN, "PCB"); |
default: |
} |
name = "ip"; |
printf("%-7.7s %-6.6s %-6.6s ", |
name6 = "ip6"; |
"Proto", "Recv-Q", "Send-Q"); |
break; |
if (Bflag && istcp) |
} |
printf("%-6.6s %-6.6s %-6.6s ", |
|
"Recv-W", "Send-W", "Cgst-W"); |
/* filter listening sockets out unless -a is set */ |
printf(" %-*.*s %-*.*s %s\n", |
if (!aflag && istcp && kf->t_state <= TCPS_LISTEN) |
addrlen, addrlen, "Local Address", |
return; |
addrlen, addrlen, "Foreign Address", "(state)"); |
else if (!aflag && isany) |
first = 0; |
return; |
} |
|
|
if (af != kf->so_family || type != kf->so_type) { |
|
af = kf->so_family; |
|
type = kf->so_type; |
|
printf("Active Internet connections"); |
|
if (aflag) |
|
printf(" (including servers)"); |
|
putchar('\n'); |
if (Aflag) { |
if (Aflag) { |
if (istcp) |
addrlen = 18; |
printf("%*p ", PLEN, hideroot ? 0 : inpcb.inp_ppcb); |
printf("%-*.*s ", PLEN, PLEN, "PCB"); |
else |
|
printf("%*p ", PLEN, hideroot ? 0 : prev); |
|
} |
} |
if (inpcb.inp_flags & INP_IPV6 && !israw) { |
printf("%-7.7s %-6.6s %-6.6s ", |
strlcpy(namebuf, name0, sizeof namebuf); |
"Proto", "Recv-Q", "Send-Q"); |
strlcat(namebuf, "6", sizeof namebuf); |
|
name = namebuf; |
|
} else |
|
name = name0; |
|
printf("%-7.7s %6lu %6lu ", |
|
name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); |
|
if (Bflag && istcp) |
if (Bflag && istcp) |
printf("%6lu %6lu %6lu ", tcpcb.rcv_wnd, tcpcb.snd_wnd, |
printf("%-6.6s %-6.6s %-6.6s ", |
(tcpcb.t_state == TCPS_ESTABLISHED) ? |
"Recv-W", "Send-W", "Cgst-W"); |
tcpcb.snd_cwnd : 0); |
printf(" %-*.*s %-*.*s %s\n", |
|
addrlen, addrlen, "Local Address", |
|
addrlen, addrlen, "Foreign Address", "(state)"); |
|
} |
|
|
if (inpcb.inp_flags & INP_IPV6) { |
if (Aflag) |
inet6print(&inpcb.inp_laddr6, (int)inpcb.inp_lport, |
printf("%#*llx%s ", FAKE_PTR(kf->so_pcb)); |
name); |
|
inet6print(&inpcb.inp_faddr6, (int)inpcb.inp_fport, |
|
name); |
|
} else { |
|
inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport, |
|
name, 1); |
|
inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport, |
|
name, 0); |
|
} |
|
if (istcp) { |
|
if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES) |
|
printf(" %d", tcpcb.t_state); |
|
else |
|
printf(" %s", tcpstates[tcpcb.t_state]); |
|
} else if (israw) { |
|
u_int8_t proto; |
|
|
|
if (inpcb.inp_flags & INP_IPV6) |
printf("%-7.7s %6llu %6llu ", |
proto = inpcb.inp_ipv6.ip6_nxt; |
isip6 ? name6: name, kf->so_rcv_cc, kf->so_snd_cc); |
else |
if (Bflag && istcp) |
proto = inpcb.inp_ip.ip_p; |
printf("%6llu %6llu %6llu ", kf->t_rcv_wnd, kf->t_snd_wnd, |
printf(" %u", proto); |
(kf->t_state == TCPS_ESTABLISHED) ? |
} |
kf->t_snd_cwnd : 0); |
putchar('\n'); |
|
|
if (isip6) { |
|
inet6print(&laddr6, kf->inp_lport, name); |
|
inet6print(&faddr6, kf->inp_fport, name); |
|
} else { |
|
inetprint(&laddr, kf->inp_lport, name, 1); |
|
inetprint(&faddr, kf->inp_fport, name, 0); |
} |
} |
|
if (istcp) { |
|
if (kf->t_state < 0 || kf->t_state >= TCP_NSTATES) |
|
printf(" %d", kf->t_state); |
|
else |
|
printf(" %s", tcpstates[kf->t_state]); |
|
} else if (kf->so_type == SOCK_RAW) { |
|
printf(" %u", kf->inp_proto); |
|
} |
|
putchar('\n'); |
} |
} |
|
|
/* |
/* |
|
|
* If the nflag was specified, use numbers instead of names. |
* If the nflag was specified, use numbers instead of names. |
*/ |
*/ |
void |
void |
inetprint(struct in_addr *in, in_port_t port, char *proto, int local) |
inetprint(struct in_addr *in, in_port_t port, const char *proto, int local) |
{ |
{ |
struct servent *sp = 0; |
struct servent *sp = 0; |
char line[80], *cp, *nam; |
char line[80], *cp, *nam; |
|
|
kread(off, &so, sizeof(so)); |
kread(off, &so, sizeof(so)); |
|
|
#define p(fmt, v, sep) printf(#v " " fmt sep, so.v); |
#define p(fmt, v, sep) printf(#v " " fmt sep, so.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : so.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, so.v); |
printf("socket %#lx\n ", hideroot ? 0 : off); |
printf("socket %#lx\n ", off); |
p("%#.4x", so_type, "\n "); |
p("%#.4x", so_type, "\n "); |
p("%#.4x", so_options, "\n "); |
p("%#.4x", so_options, "\n "); |
p("%d", so_linger, "\n "); |
p("%d", so_linger, "\n "); |
|
|
#undef p |
#undef p |
#undef pp |
#undef pp |
|
|
if (!vflag) |
|
return; |
|
protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb); |
protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb); |
} |
} |
|
|
|
|
|
|
#define p(fmt, v, sep) printf(#v " " fmt sep, ssp.v); |
#define p(fmt, v, sep) printf(#v " " fmt sep, ssp.v); |
#define pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v); |
#define pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : ssp.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, ssp.v); |
pp("%p", ssp_socket, ", "); |
pp("%p", ssp_socket, ", "); |
pp("%p", ssp_soback, "\n "); |
pp("%p", ssp_soback, "\n "); |
p("%lld", ssp_len, ", "); |
p("%lld", ssp_len, ", "); |
|
|
kread(off, &proto, sizeof(proto)); |
kread(off, &proto, sizeof(proto)); |
|
|
#define p(fmt, v, sep) printf(#v " " fmt sep, proto.v); |
#define p(fmt, v, sep) printf(#v " " fmt sep, proto.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : proto.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, proto.v); |
printf("protosw %#lx\n ", hideroot ? 0 : off); |
printf("protosw %#lx\n ", off); |
p("%#.4x", pr_type, "\n "); |
p("%#.4x", pr_type, "\n "); |
pp("%p", pr_domain, "\n "); |
pp("%p", pr_domain, "\n "); |
p("%d", pr_protocol, "\n "); |
p("%d", pr_protocol, "\n "); |
|
|
kread((u_long)dom.dom_name, name, sizeof(name)); |
kread((u_long)dom.dom_name, name, sizeof(name)); |
|
|
#define p(fmt, v, sep) printf(#v " " fmt sep, dom.v); |
#define p(fmt, v, sep) printf(#v " " fmt sep, dom.v); |
printf("domain %#lx\n ", hideroot ? 0 : off); |
printf("domain %#lx\n ", off); |
p("%d", dom_family, "\n "); |
p("%d", dom_family, "\n "); |
printf("dom_name %.*s\n", (int)sizeof(name), name); |
printf("dom_name %.*s\n", (int)sizeof(name), name); |
#undef p |
#undef p |
|
|
switch (dom.dom_family) { |
|
case AF_INET: |
|
case AF_INET6: |
|
inpcb_dump(pcb, protocol, dom.dom_family); |
|
break; |
|
case AF_UNIX: |
|
unpcb_dump(pcb); |
|
break; |
|
} |
|
} |
} |
|
|
/* |
/* |
|
|
if (off == 0) |
if (off == 0) |
return; |
return; |
kread(off, &inp, sizeof(inp)); |
kread(off, &inp, sizeof(inp)); |
|
|
|
if (vflag) |
|
socket_dump((u_long)inp.inp_socket); |
|
|
switch (af) { |
switch (af) { |
case AF_INET: |
case AF_INET: |
inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr)); |
inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr)); |
|
|
} |
} |
|
|
#define p(fmt, v, sep) printf(#v " " fmt sep, inp.v); |
#define p(fmt, v, sep) printf(#v " " fmt sep, inp.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : inp.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, inp.v); |
printf("inpcb %#lx\n ", hideroot ? 0 : off); |
printf("inpcb %#lx\n ", off); |
pp("%p", inp_table, "\n "); |
pp("%p", inp_table, "\n "); |
printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr); |
printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr); |
HTONS(inp.inp_fport); |
HTONS(inp.inp_fport); |
|
|
kread(off, (char *)&tcpcb, sizeof (tcpcb)); |
kread(off, (char *)&tcpcb, sizeof (tcpcb)); |
|
|
#define p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v); |
#define p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, hideroot ? 0 : tcpcb.v); |
#define pp(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v); |
printf("tcpcb %#lx\n ", hideroot ? 0 : off); |
printf("tcpcb %#lx\n ", off); |
pp("%p", t_inpcb, "\n "); |
pp("%p", t_inpcb, "\n "); |
p("%d", t_state, ""); |
p("%d", t_state, ""); |
if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES) |
if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES) |