void tcp6protopr(const char *name) { netsnmp_variable_list *var, *vp; oid ipv6TcpConnState_oid[] = { 1,3,6,1,2,1,6,16,1,6 }; size_t ipv6TcpConnState_len = OID_LENGTH( ipv6TcpConnState_oid ); int state, i; unsigned char localAddr[16], remoteAddr[16]; int localPort, remotePort, ifIndex; int first = 1; /* * Walking the v6 tcpConnState column will provide all * the necessary information. */ var = NULL; snmp_varlist_add_variable( &var, ipv6TcpConnState_oid, ipv6TcpConnState_len, ASN_NULL, NULL, 0); if (netsnmp_query_walk( var, ss ) != SNMP_ERR_NOERROR) return; if (var->type == ASN_NULL) /* No entries */ return; for (vp = var; vp ; vp=vp->next_variable) { state = *vp->val.integer; if (!aflag && state == MIB_TCPCONNSTATE_LISTEN) continue; if (first) { printf("Active Internet Connections"); if (aflag) printf(" (including servers)"); putchar('\n'); printf("%-5.5s %-28.28s %-28.28s %4s %s\n", "Proto", "Local Address", "Remote Address", "I/F", "(state)"); first = 0; } /* Extract the local/remote information from the index values */ for (i=0; i<16; i++) localAddr[i] = vp->name[ 10+i ]; localPort = vp->name[ 26 ]; for (i=0; i<16; i++) remoteAddr[i] = vp->name[ 27+i ]; remotePort = vp->name[ 43 ]; ifIndex = vp->name[ 44 ]; printf("%-5.5s", name); inet6print(localAddr, localPort, name, 1); inet6print(remoteAddr, remotePort, name, 0); if ( state < 1 || state > TCP_NSTATES ) printf(" %4d %d\n", ifIndex, state ); else printf(" %4d %s\n", ifIndex, tcp6states[ state ]); } snmp_free_varbind( var ); }
static void shownetstat(struct netinfo *p) { switch (p->nif_family) { case AF_INET: inetprint(&p->nif_laddr, p->nif_lport, p->nif_proto, FLD_NS_LOCAL); inetprint(&p->nif_faddr, p->nif_fport, p->nif_proto, FLD_NS_FOREIGN); break; case AF_INET6: inet6print(&p->nif_laddr6, p->nif_lport, p->nif_proto, FLD_NS_LOCAL); inet6print(&p->nif_faddr6, p->nif_fport, p->nif_proto, FLD_NS_FOREIGN); break; } tb_start(); tbprintf("%s", p->nif_proto); if (p->nif_family == AF_INET6) tbprintf("6"); print_fld_tb(FLD_NS_PROTO); print_fld_size(FLD_NS_RECV_Q, p->nif_rcvcc); print_fld_size(FLD_NS_SEND_Q, p->nif_sndcc); if (streq(p->nif_proto, "tcp")) { if (p->nif_state < 0 || p->nif_state >= TCP_NSTATES) print_fld_uint(FLD_NS_STATE, p->nif_state); else print_fld_str(FLD_NS_STATE, tcpstates[p->nif_state]); } end_line(); }
/* * Print a summary of UDPv6 "connections" * XXX - what about "listening" services ?? */ void udp6protopr(const char *name) { netsnmp_variable_list *var, *vp; oid ipv6UdpLocalAddress_oid[] = { 1,3,6,1,2,1,7,6,1,1 }; size_t ipv6UdpLocalAddress_len = OID_LENGTH( ipv6UdpLocalAddress_oid ); int localPort, ifIndex; /* * Walking a single column of the udpTable will provide * all the necessary information from the index values. */ var = NULL; snmp_varlist_add_variable( &var, ipv6UdpLocalAddress_oid, ipv6UdpLocalAddress_len, ASN_NULL, NULL, 0); if (netsnmp_query_walk( var, ss ) != SNMP_ERR_NOERROR) return; if (var->type == ASN_NULL) /* No entries */ return; printf("Active Internet Connections\n"); printf("%-5.5s %-28.28s %4s\n", "Proto", "Local Address", "I/F"); for (vp = var; vp ; vp=vp->next_variable) { printf("%-5.5s", name); /* * Extract the local port from the index values, but take * the IP address from the varbind value, (which is why * we walked udpLocalAddress rather than udpLocalPort) */ localPort = vp->name[ vp->name_length-2 ]; ifIndex = vp->name[ vp->name_length-1 ]; inet6print(vp->val.string, localPort, name, 1); printf(" %4d\n", ifIndex ); } snmp_free_varbind( var ); }
/* * Print a summary of connections related to an Internet * protocol. For TCP, also give state of connection. * Listening processes (aflag) are suppressed unless the * -a (all) flag is specified. */ void protopr(u_long off, char *name, int af, u_int tableid, u_long pcbaddr) { struct inpcbtable table; struct inpcb *prev, *next; struct inpcb inpcb, prevpcb; int istcp, israw, isany; int addrlen = 22; int first = 1; char *name0; char namebuf[20]; name0 = name; if (off == 0) return; 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) { kread((u_long)next, &inpcb, sizeof inpcb); if (prev != NULL) { kread((u_long)prev, &prevpcb, sizeof prevpcb); if (TAILQ_NEXT(&prevpcb, inp_queue) != next) { printf("PCB list changed\n"); break; } } prev = next; next = TAILQ_NEXT(&inpcb, inp_queue); switch (af) { case AF_INET: if ((inpcb.inp_flags & INP_IPV6) != 0) continue; isany = inet_lnaof(inpcb.inp_faddr) == INADDR_ANY; break; case AF_INET6: if ((inpcb.inp_flags & INP_IPV6) == 0) continue; isany = IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_faddr6); break; default: isany = 0; break; } if (Pflag) { if (istcp && pcbaddr == (u_long)inpcb.inp_ppcb) { if (vflag) socket_dump((u_long)inpcb.inp_socket); else tcpcb_dump(pcbaddr); } 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) continue; kread((u_long)inpcb.inp_socket, &sockb, sizeof (sockb)); if (istcp) { kread((u_long)inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb)); if (!aflag && tcpcb.t_state <= TCPS_LISTEN) continue; } else if (!aflag && isany) continue; if (first) { printf("Active Internet connections"); if (aflag) printf(" (including servers)"); putchar('\n'); if (Aflag) { addrlen = 18; printf("%-*.*s ", PLEN, PLEN, "PCB"); } printf("%-7.7s %-6.6s %-6.6s ", "Proto", "Recv-Q", "Send-Q"); if (Bflag && istcp) printf("%-6.6s %-6.6s %-6.6s ", "Recv-W", "Send-W", "Cgst-W"); printf(" %-*.*s %-*.*s %s\n", addrlen, addrlen, "Local Address", addrlen, addrlen, "Foreign Address", "(state)"); first = 0; } if (Aflag) { if (istcp) printf("%*p ", PLEN, hideroot ? 0 : inpcb.inp_ppcb); else printf("%*p ", PLEN, hideroot ? 0 : prev); } if (inpcb.inp_flags & INP_IPV6 && !israw) { strlcpy(namebuf, name0, sizeof namebuf); 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) printf("%6lu %6lu %6lu ", tcpcb.rcv_wnd, tcpcb.snd_wnd, (tcpcb.t_state == TCPS_ESTABLISHED) ? tcpcb.snd_cwnd : 0); if (inpcb.inp_flags & INP_IPV6) { inet6print(&inpcb.inp_laddr6, (int)inpcb.inp_lport, 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) proto = inpcb.inp_ipv6.ip6_nxt; else proto = inpcb.inp_ip.ip_p; printf(" %u", proto); } putchar('\n'); } }
/* * Print a summary of connections related to an Internet * protocol. For TCP, also give state of connection. * Listening processes (aflag) are suppressed unless the * -a (all) flag is specified. */ void protopr(u_long off, const char *name, int af1, int proto) { static int first = 1; int istcp; char *buf; const char *vchar; struct xtcpcb *tp; struct xinpcb *inp; struct xinpgen *xig, *oxig; struct xsocket *so; istcp = 0; switch (proto) { case IPPROTO_TCP: #ifdef INET6 if (strncmp(name, "sdp", 3) != 0) { if (tcp_done != 0) return; else tcp_done = 1; } else { if (sdp_done != 0) return; else sdp_done = 1; } #endif istcp = 1; break; case IPPROTO_UDP: #ifdef INET6 if (udp_done != 0) return; else udp_done = 1; #endif break; } if (!pcblist_sysctl(proto, name, &buf)) return; oxig = xig = (struct xinpgen *)buf; for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); xig->xig_len > sizeof(struct xinpgen); xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { if (istcp) { tp = (struct xtcpcb *)xig; inp = &tp->xt_inp; } else { inp = (struct xinpcb *)xig; } so = &inp->xi_socket; /* Ignore sockets for protocols other than the desired one. */ if (so->xso_protocol != proto) continue; /* Ignore PCBs which were freed during copyout. */ if (inp->inp_gencnt > oxig->xig_gen) continue; if ((af1 == AF_INET && (inp->inp_vflag & INP_IPV4) == 0) #ifdef INET6 || (af1 == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0) #endif /* INET6 */ || (af1 == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0 #ifdef INET6 && (inp->inp_vflag & INP_IPV6) == 0 #endif /* INET6 */ )) ) continue; if (!aflag && ( (istcp && tp->t_state == TCPS_LISTEN) || (af1 == AF_INET && inet_lnaof(inp->inp_laddr) == INADDR_ANY) #ifdef INET6 || (af1 == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) #endif /* INET6 */ || (af1 == AF_UNSPEC && (((inp->inp_vflag & INP_IPV4) != 0 && inet_lnaof(inp->inp_laddr) == INADDR_ANY) #ifdef INET6 || ((inp->inp_vflag & INP_IPV6) != 0 && IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) #endif )) )) continue; if (first) { if (!Lflag) { xo_emit("Active Internet connections"); if (aflag) xo_emit(" (including servers)"); } else xo_emit( "Current listen queue sizes (qlen/incqlen/maxqlen)"); xo_emit("\n"); if (Aflag) xo_emit("{T:/%-*s} ", 2 * (int)sizeof(void *), "Tcpcb"); if (Lflag) xo_emit((Aflag && !Wflag) ? "{T:/%-5.5s} {T:/%-32.32s} {T:/%-18.18s}" : ((!Wflag || af1 == AF_INET) ? "{T:/%-5.5s} {T:/%-32.32s} {T:/%-22.22s}" : "{T:/%-5.5s} {T:/%-32.32s} {T:/%-45.45s}"), "Proto", "Listen", "Local Address"); else if (Tflag) xo_emit((Aflag && !Wflag) ? "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%s}" : ((!Wflag || af1 == AF_INET) ? "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%s}" : "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%s}"), "Proto", "Rexmit", "OOORcv", "0-win", "Local Address", "Foreign Address"); else { xo_emit((Aflag && !Wflag) ? "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-18.18s} {T:/%-18.18s}" : ((!Wflag || af1 == AF_INET) ? "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-22.22s} {T:/%-22.22s}" : "{T:/%-5.5s} {T:/%-6.6s} {T:/%-6.6s} {T:/%-45.45s} {T:/%-45.45s}"), "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address"); if (!xflag && !Rflag) xo_emit(" (state)"); } if (xflag) { xo_emit(" {T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} " "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} " "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s} " "{T:/%-6.6s} {T:/%-6.6s} {T:/%-6.6s}", "R-MBUF", "S-MBUF", "R-CLUS", "S-CLUS", "R-HIWA", "S-HIWA", "R-LOWA", "S-LOWA", "R-BCNT", "S-BCNT", "R-BMAX", "S-BMAX"); xo_emit(" {T:/%7.7s} {T:/%7.7s} {T:/%7.7s} " "{T:/%7.7s} {T:/%7.7s} {T:/%7.7s}", "rexmt", "persist", "keep", "2msl", "delack", "rcvtime"); } else if (Rflag) { xo_emit(" {T:/%8.8s} {T:/%5.5s}", "flowid", "ftype"); } xo_emit("\n"); first = 0; } if (Lflag && so->so_qlimit == 0) continue; xo_open_instance("socket"); if (Aflag) { if (istcp) xo_emit("{q:address/%*lx} ", 2 * (int)sizeof(void *), (u_long)inp->inp_ppcb); else xo_emit("{q:address/%*lx} ", 2 * (int)sizeof(void *), (u_long)so->so_pcb); } #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? "46" : "6"; else #endif vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? "4" : ""; if (istcp && (tp->t_flags & TF_TOE) != 0) xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", "toe", vchar); else xo_emit("{:protocol/%-3.3s%-2.2s/%s%s} ", name, vchar); if (Lflag) { char buf1[33]; snprintf(buf1, sizeof buf1, "%u/%u/%u", so->so_qlen, so->so_incqlen, so->so_qlimit); xo_emit("{:listen-queue-sizes/%-32.32s} ", buf1); } else if (Tflag) { if (istcp) xo_emit("{:sent-retransmit-packets/%6u} " "{:received-out-of-order-packets/%6u} " "{:sent-zero-window/%6u} ", tp->t_sndrexmitpack, tp->t_rcvoopack, tp->t_sndzerowin); else xo_emit("{P:/%21s}", ""); } else { xo_emit("{:receive-bytes-waiting/%6u} " "{:send-bytes-waiting/%6u} ", so->so_rcv.sb_cc, so->so_snd.sb_cc); } if (numeric_port) { if (inp->inp_vflag & INP_IPV4) { inetprint("local", &inp->inp_laddr, (int)inp->inp_lport, name, 1, af1); if (!Lflag) inetprint("remote", &inp->inp_faddr, (int)inp->inp_fport, name, 1, af1); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { inet6print("local", &inp->in6p_laddr, (int)inp->inp_lport, name, 1); if (!Lflag) inet6print("remote", &inp->in6p_faddr, (int)inp->inp_fport, name, 1); } /* else nothing printed now */ #endif /* INET6 */ } else if (inp->inp_flags & INP_ANONPORT) { if (inp->inp_vflag & INP_IPV4) { inetprint("local", &inp->inp_laddr, (int)inp->inp_lport, name, 1, af1); if (!Lflag) inetprint("remote", &inp->inp_faddr, (int)inp->inp_fport, name, 0, af1); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { inet6print("local", &inp->in6p_laddr, (int)inp->inp_lport, name, 1); if (!Lflag) inet6print("remote", &inp->in6p_faddr, (int)inp->inp_fport, name, 0); } /* else nothing printed now */ #endif /* INET6 */ } else { if (inp->inp_vflag & INP_IPV4) { inetprint("local", &inp->inp_laddr, (int)inp->inp_lport, name, 0, af1); if (!Lflag) inetprint("remote", &inp->inp_faddr, (int)inp->inp_fport, name, inp->inp_lport != inp->inp_fport, af1); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { inet6print("local", &inp->in6p_laddr, (int)inp->inp_lport, name, 0); if (!Lflag) inet6print("remote", &inp->in6p_faddr, (int)inp->inp_fport, name, inp->inp_lport != inp->inp_fport); } /* else nothing printed now */ #endif /* INET6 */ } if (xflag) { xo_emit("{:receive-mbufs/%6u} {:send-mbufs/%6u} " "{:receive-clusters/%6u} {:send-clusters/%6u} " "{:receive-high-water/%6u} {:send-high-water/%6u} " "{:receive-low-water/%6u} {:send-low-water/%6u} " "{:receive-mbuf-bytes/%6u} {:send-mbuf-bytes/%6u} " "{:receive-mbuf-bytes-max/%6u} " "{:send-mbuf-bytes-max/%6u}", so->so_rcv.sb_mcnt, so->so_snd.sb_mcnt, so->so_rcv.sb_ccnt, so->so_snd.sb_ccnt, so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat, so->so_rcv.sb_lowat, so->so_snd.sb_lowat, so->so_rcv.sb_mbcnt, so->so_snd.sb_mbcnt, so->so_rcv.sb_mbmax, so->so_snd.sb_mbmax); if (istcp) xo_emit(" {:retransmit-timer/%4d.%02d} " "{:persist-timer/%4d.%02d} " "{:keepalive-timer/%4d.%02d} " "{:msl2-timer/%4d.%02d} " "{:delay-ack-timer/%4d.%02d} " "{:inactivity-timer/%4d.%02d}", tp->tt_rexmt / 1000, (tp->tt_rexmt % 1000) / 10, tp->tt_persist / 1000, (tp->tt_persist % 1000) / 10, tp->tt_keep / 1000, (tp->tt_keep % 1000) / 10, tp->tt_2msl / 1000, (tp->tt_2msl % 1000) / 10, tp->tt_delack / 1000, (tp->tt_delack % 1000) / 10, tp->t_rcvtime / 1000, (tp->t_rcvtime % 1000) / 10); } if (istcp && !Lflag && !xflag && !Tflag && !Rflag) { if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES) xo_emit("{:tcp-state/%d}", tp->t_state); else { xo_emit("{:tcp-state/%s}", tcpstates[tp->t_state]); #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN) /* Show T/TCP `hidden state' */ if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) xo_emit("{:need-syn-or-fin/*}"); #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ } } if (Rflag) { /* XXX: is this right Alfred */ xo_emit(" {:flow-id/%08x} {:flow-type/%5d}", inp->inp_flowid, inp->inp_flowtype); } xo_emit("\n"); xo_close_instance("socket"); } if (xig != oxig && xig->xig_gen != oxig->xig_gen) { if (oxig->xig_count > xig->xig_count) { xo_emit("Some {d:lost/%s} sockets may have been " "deleted.\n", name); } else if (oxig->xig_count < xig->xig_count) { xo_emit("Some {d:created/%s} sockets may have been " "created.\n", name); } else { xo_emit("Some {d:changed/%s} sockets may have been " "created or deleted.\n", name); } } free(buf); }
/* * Print a summary of connections related to an Internet * protocol (currently only TCP). For TCP, also give state of connection. */ void protopr6(const char *name) { struct tcpconn_entry *tcpconn = NULL, *tcplast = NULL, *tp, *newtp; struct udp_entry *udpconn = NULL, *udplast = NULL, *up, *newup; netsnmp_pdu *request = NULL, *response = NULL; netsnmp_variable_list *vp; oid *instance; int first, status; response = NULL; if (strncmp(name, "tcp", 3) == 0) { request = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(request, oid_tcpconntable, sizeof(oid_tcpconntable) / sizeof(oid)); status = STAT_SUCCESS; } else status = STAT_TIMEOUT; while (status == STAT_SUCCESS) { if (response) snmp_free_pdu(response); response = NULL; status = snmp_synch_response(Session, request, &response); if (status != STAT_SUCCESS || response->errstat != SNMP_ERR_NOERROR) { snmp_perror("SNMP request failed"); break; } vp = response->variables; if (!vp) break; if (vp->name_length != 46 || memcmp(vp->name, oid_tcpconntable, sizeof(oid_tcpconntable))) { break; } request = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(request, vp->name, vp->name_length); instance = vp->name + 10; for (tp = tcpconn; tp != NULL; tp = tp->next) { if (!memcmp(instance, tp->instance, sizeof(tp->instance))) break; } if (tp == NULL) { tp = (struct tcpconn_entry *) calloc(1, sizeof(struct tcpconn_entry)); if (tp == NULL) break; if (tcplast != NULL) tcplast->next = tp; tcplast = tp; if (tcpconn == NULL) tcpconn = tp; memmove(tp->instance, instance, sizeof(tp->instance)); } if (vp->name[TCP_ENTRY] == TCPCONN_STATE) { tp->state = *vp->val.integer; tp->stateSet = 1; } if (vp->name[TCP_ENTRY] == TCPCONN_LOCADDR) { memmove(&tp->localAddress, vp->val.string, sizeof(struct in6_addr)); tp->locAddrSet = 1; } if (vp->name[TCP_ENTRY] == TCPCONN_LOCPORT) { if (validUShortAssign(&tp->localPort, *vp->val.integer, "TCPCONN_LOCPORT")) tp->locPortSet = 1; } if (vp->name[TCP_ENTRY] == TCPCONN_REMADDR) { memmove(&tp->remoteAddress, vp->val.string, sizeof(struct in6_addr)); tp->remAddrSet = 1; } if (vp->name[TCP_ENTRY] == TCPCONN_REMPORT) { if (validUShortAssign(&tp->remotePort, *vp->val.integer, "TCPCONN_REMPORT")) tp->remPortSet = 1; } } if (response) snmp_free_pdu(response); response = NULL; for (first = 1, tp = tcpconn, newtp = NULL; tp != NULL; tp = tp->next) { if (newtp) free(newtp); newtp = tp; if (!(tp->stateSet && tp->locAddrSet && tp->locPortSet && tp->remAddrSet && tp->remPortSet)) { printf("incomplete entry\n"); continue; } if (!aflag && tp->state == MIB_TCPCONNSTATE_LISTEN) continue; if (first) { printf("Active Internet (%s) Connections", name); if (aflag) printf(" (including servers)"); putchar('\n'); printf("%-5.5s %-28.28s %-28.28s %s\n", "Proto", "Local Address", "Foreign Address", "(state)"); first = 0; } printf("%-5.5s ", name); inet6print(&tp->localAddress, tp->localPort, name); inet6print(&tp->remoteAddress, tp->remotePort, name); if (tp->state < 1 || tp->state > TCP_NSTATES) printf(" %d", tp->state); else printf(" %s", tcpstates[tp->state]); putchar('\n'); } if (newtp) free(newtp); response = NULL; if (strncmp(name, "udp", 3) == 0) { request = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(request, oid_udptable, sizeof(oid_udptable) / sizeof(oid)); status = STAT_SUCCESS; } else status = STAT_TIMEOUT; while (status == STAT_SUCCESS) { if (response) snmp_free_pdu(response); response = NULL; status = snmp_synch_response(Session, request, &response); if (status != STAT_SUCCESS || response->errstat != SNMP_ERR_NOERROR) { fprintf(stderr, "SNMP request failed\n"); break; } vp = response->variables; if (!vp) break; if (vp->name_length != 28 || memcmp(vp->name, oid_udptable, sizeof(oid_udptable))) { break; } request = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(request, vp->name, vp->name_length); instance = vp->name + 10; for (up = udpconn; up != NULL; up = up->next) { if (!memcmp(instance, up->instance, sizeof(up->instance))) break; } if (up == NULL) { up = (struct udp_entry *) calloc(1, sizeof(struct udp_entry)); if (up == NULL) break; if (udplast != NULL) udplast->next = up; udplast = up; if (udpconn == NULL) udpconn = up; memmove(up->instance, instance, sizeof(up->instance)); } if (vp->name[UDP_ENTRY] == UDP_LOCADDR) { memmove(&up->localAddress, vp->val.string, sizeof(struct in6_addr)); up->locAddrSet = 1; } if (vp->name[UDP_ENTRY] == UDP_LOCPORT) { if (validUShortAssign(&up->localPort, *vp->val.integer, "UDP_LOCPORT")) up->locPortSet = 1; } } if (response) snmp_free_pdu(response); response = NULL; for (first = 1, up = udpconn, newup = NULL; up != NULL; up = up->next) { if (newup) free(newup); newup = up; if (!(up->locAddrSet && up->locPortSet)) { printf("incomplete entry\n"); continue; } if (first) { printf("Active Internet (%s) Connections", name); putchar('\n'); printf("%-5.5s %-28.28s\n", "Proto", "Local Address"); first = 0; } printf("%-5.5s ", name); inet6print(&up->localAddress, up->localPort, name); putchar('\n'); } if (newup) free(newup); }
static void outputpcb(int proto, const char *name, struct inpcb *inp, struct xsocket *so, struct tcpcb *tp) { const char *vchar; static struct clockinfo clockinfo; if (clockinfo.hz == 0) { size_t size = sizeof(clockinfo); sysctlbyname("kern.clockrate", &clockinfo, &size, NULL, 0); if (clockinfo.hz == 0) clockinfo.hz = 100; } /* Ignore sockets for protocols other than the desired one. */ if (so->xso_protocol != (int)proto) return; if ((af == AF_INET && (inp->inp_vflag & INP_IPV4) == 0) #ifdef INET6 || (af == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0) #endif /* INET6 */ || (af == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0 #ifdef INET6 && (inp->inp_vflag & INP_IPV6) == 0 #endif /* INET6 */ )) ) { return; } if (!aflag && ( (proto == IPPROTO_TCP && tp->t_state == TCPS_LISTEN) || (af == AF_INET && inet_lnaof(inp->inp_laddr) == INADDR_ANY) #ifdef INET6 || (af == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) #endif /* INET6 */ || (af == AF_UNSPEC && (((inp->inp_vflag & INP_IPV4) != 0 && inet_lnaof(inp->inp_laddr) == INADDR_ANY) #ifdef INET6 || ((inp->inp_vflag & INP_IPV6) != 0 && IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) #endif )) )) { return; } if (ppr_first) { if (!Lflag) { printf("Active Internet connections"); if (aflag) printf(" (including servers)"); } else { printf("Current listen queue sizes " "(qlen/incqlen/maxqlen)"); } putchar('\n'); if (Aflag) printf("%-8.8s ", "Socket"); if (Pflag) printf("%8.8s %8.8s %8.8s ", "TxWin", "Unacked", "RTT/ms"); if (Lflag) { printf("%-5.5s %-14.14s %-22.22s\n", "Proto", "Listen", "Local Address"); } else { printf((Aflag && !Wflag) ? "%-5.5s %-6.6s %-6.6s %-17.17s %-17.17s %s\n" : "%-5.5s %-6.6s %-6.6s %-21.21s %-21.21s %s\n", "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address", "(state)"); } ppr_first = 0; } if (Lflag && so->so_qlimit == 0) return; if (Aflag) { if (tp) printf("%8lx ", (u_long)inp->inp_ppcb); else printf("%8lx ", (u_long)so->so_pcb); } if (Pflag) { if (tp) { int window = MIN(tp->snd_cwnd, tp->snd_bwnd); if (window == 1073725440) printf("%8s ", "max"); else printf("%8d ", (int)MIN(tp->snd_cwnd, tp->snd_bwnd)); printf("%8d ", (int)(tp->snd_max - tp->snd_una)); if (tp->t_srtt == 0) printf("%8s ", "-"); else printf("%8.3f ", (double)tp->t_srtt * 1000.0 / TCP_RTT_SCALE / clockinfo.hz); } else { printf("%8s %8s %8s ", "-", "-", "-"); } } #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? "46" : "6 "; else #endif vchar = ((inp->inp_vflag & INP_IPV4) != 0) ? "4 " : " "; printf("%-3.3s%-2.2s ", name, vchar); if (Lflag) { char buf[15]; snprintf(buf, sizeof(buf), "%d/%d/%d", so->so_qlen, so->so_incqlen, so->so_qlimit); printf("%-13.13s ", buf); } else if (Bflag) { printf("%6ld %6ld ", so->so_rcv.sb_hiwat, so->so_snd.sb_hiwat); } else { printf("%6ld %6ld ", so->so_rcv.sb_cc, so->so_snd.sb_cc); } if (numeric_port) { if (inp->inp_vflag & INP_IPV4) { inetprint(&inp->inp_laddr, (int)inp->inp_lport, name, 1); if (!Lflag) inetprint(&inp->inp_faddr, (int)inp->inp_fport, name, 1); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { inet6print(&inp->in6p_laddr, (int)inp->inp_lport, name, 1); if (!Lflag) inet6print(&inp->in6p_faddr, (int)inp->inp_fport, name, 1); } /* else nothing printed now */ #endif /* INET6 */ } else if (inp->inp_flags & INP_ANONPORT) { if (inp->inp_vflag & INP_IPV4) { inetprint(&inp->inp_laddr, (int)inp->inp_lport, name, 1); if (!Lflag) inetprint(&inp->inp_faddr, (int)inp->inp_fport, name, 0); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { inet6print(&inp->in6p_laddr, (int)inp->inp_lport, name, 1); if (!Lflag) inet6print(&inp->in6p_faddr, (int)inp->inp_fport, name, 0); } /* else nothing printed now */ #endif /* INET6 */ } else { if (inp->inp_vflag & INP_IPV4) { inetprint(&inp->inp_laddr, (int)inp->inp_lport, name, 0); if (!Lflag) inetprint(&inp->inp_faddr, (int)inp->inp_fport, name, inp->inp_lport != inp->inp_fport); } #ifdef INET6 else if (inp->inp_vflag & INP_IPV6) { inet6print(&inp->in6p_laddr, (int)inp->inp_lport, name, 0); if (!Lflag) inet6print(&inp->in6p_faddr, (int)inp->inp_fport, name, inp->inp_lport != inp->inp_fport); } /* else nothing printed now */ #endif /* INET6 */ } if (tp && !Lflag) { if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES) printf("%d", tp->t_state); else { printf("%s", tcpstates[tp->t_state]); #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN) /* Show T/TCP `hidden state' */ if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) putchar('*'); #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ } } putchar('\n'); }
static void protopr0(u_long off, char *name, int af) { struct inpcbtable table; struct inpcb *head, *next, *prev; struct inpcb inpcb; int istcp, israw; #ifdef DCCP int isdccp; #endif int first = 1; char *name0; char namebuf[20]; name0 = name; if (off == 0) return; istcp = strcmp(name, "tcp") == 0; israw = strncmp(name, "ip", 2) == 0; #ifdef DCCP isdccp = strcmp(name, "dccp") == 0; #endif kread(off, (char *)&table, sizeof table); prev = head = (struct inpcb *)&((struct inpcbtable *)off)->inpt_queue.cqh_first; next = table.inpt_queue.cqh_first; while (next != head) { kread((u_long)next, (char *)&inpcb, sizeof inpcb); if (inpcb.inp_queue.cqe_prev != prev) { printf("???\n"); break; } prev = next; next = inpcb.inp_queue.cqe_next; switch (af) { case AF_INET: if ((inpcb.inp_flags & INP_IPV6) != 0) continue; break; case AF_INET6: if ((inpcb.inp_flags & INP_IPV6) == 0) continue; break; default: break; } if (!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) continue; kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb)); if (istcp) { kread((u_long)inpcb.inp_ppcb, (char *)&tcpcb, sizeof (tcpcb)); } #ifdef DCCP if (isdccp) { kread((u_long)inpcb.inp_ppcb, (char *)&dccpcb, sizeof (dccpcb)); } #endif if (first) { printf("Active Internet connections"); if (aflag) printf(" (including servers)"); putchar('\n'); if (Aflag) printf("%-*.*s %-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n", PLEN, PLEN, "PCB", "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address", "(state)"); else printf("%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address", "(state)"); first = 0; } if (Aflag) { #ifdef DCCP if (istcp || isdccp) #else if (istcp) #endif printf("%*p ", PLEN, inpcb.inp_ppcb); else printf("%*p ", PLEN, prev); } #ifdef INET6 if (inpcb.inp_flags & INP_IPV6 && !israw) { strlcpy(namebuf, name0, sizeof namebuf); strlcat(namebuf, "6", sizeof namebuf); name = namebuf; } else name = name0; #endif printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); #ifdef INET6 if (inpcb.inp_flags & INP_IPV6) { inet6print(&inpcb.inp_laddr6, (int)inpcb.inp_lport, name, 1); inet6print(&inpcb.inp_faddr6, (int)inpcb.inp_fport, name, 0); } else #endif { 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) { struct protoent *pe = NULL; u_int8_t proto; #ifdef INET6 if (inpcb.inp_flags & INP_IPV6) proto = inpcb.inp_ipv6.ip6_nxt; else #endif proto = inpcb.inp_ip.ip_p; if (!nflag) pe = getprotobynumber(proto); if (pe) printf(" %s", pe->p_name); else printf(" %u", proto); } #ifdef DCCP if (isdccp) { if (dccpcb.state >= DCCP_NSTATES) printf(" %d", dccpcb.state); else printf(" %s", dccpstates[dccpcb.state]); } #endif putchar('\n'); } }
static void sctp_process_inpcb(struct xsctp_inpcb *xinpcb, const char *name, char *buf, const size_t buflen, size_t *offset) { int offset_backup, indent = 0, xladdr_total = 0, is_listening = 0; static int first = 1; char *tname; struct xsctp_tcb *xstcb; struct xsctp_laddr *xladdr; struct sockaddr *sa; #ifdef INET6 struct sockaddr_in6 *in6; #endif if ((xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE) == SCTP_PCB_FLAGS_TCPTYPE && xinpcb->maxqlen > 0) is_listening = 1; if (!Lflag && !is_listening && !(xinpcb->flags & SCTP_PCB_FLAGS_CONNECTED)) { #ifdef SCTP_DEBUG int i, found = 0; for (i = 0; i < sctp_pcnt; i++) { if (sctp_pdup[i] == xinpcb->flags) { found = 1; break; } } if (!found) { sctp_pdup[sctp_pcnt++] = xinpcb->flags; if (sctp_pcnt >= 64) sctp_pcnt = 0; printf("[0x%08x]", xinpcb->flags); } #endif offset_backup = *offset; if (!sctp_skip_xinpcb_ifneed(buf, buflen, offset)) return; *offset = offset_backup; } if (first) { if (!Lflag) { printf("Active SCTP associations"); if (aflag) printf(" (including servers)"); } else printf("Current listen queue sizes (qlen/maxqlen)"); putchar('\n'); if (Aflag) printf("%-8.8s ", "Socket"); if (Lflag) printf("%-5.5s %-5.5s %-8.8s %-22.22s\n", "Proto", "Type", "Listen", "Local Address"); else printf((Aflag && !Wflag) ? "%-5.5s %-5.5s %-18.18s %-18.18s %s\n" : "%-5.5s %-5.5s %-22.22s %-22.22s %s\n", "Proto", "Type", "Local Address", "Foreign Address", "(state)"); first = 0; } if (Lflag && xinpcb->maxqlen == 0) { (int)sctp_skip_xinpcb_ifneed(buf, buflen, offset); return; } if (Aflag) printf("%8lx ", (u_long)xinpcb); printf("%-5.5s ", name); if (xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE) tname = "1to1"; else if (xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) tname = "1toN"; else return; printf("%-5.5s ", tname); if (Lflag) { char buf1[9]; snprintf(buf1, 9, "%hu/%hu", xinpcb->qlen, xinpcb->maxqlen); printf("%-8.8s ", buf1); } /* * process the local address. This routine are used for Lflag. */ while (*offset < buflen) { xladdr = (struct xsctp_laddr *)(buf + *offset); *offset += sizeof(struct xsctp_laddr); if (xladdr->last == 1) break; if (!Lflag && !is_listening) continue; if (xladdr_total != 0) putchar('\n'); if (xladdr_total > 0) printf((Lflag) ? "%-20.20s " : "%-11.11s ", " "); sa = &(xladdr->address.sa); if ((sa->sa_family) == AF_INET) inetprint(&((struct sockaddr_in *)sa)->sin_addr, htons(xinpcb->local_port), name, numeric_port); #ifdef INET6 else { in6 = (struct sockaddr_in6 *)sa; inet6print(&in6->sin6_addr, htons(xinpcb->local_port), name, numeric_port); } #endif if (!Lflag && xladdr_total == 0 && is_listening == 1) printf("%-22.22s LISTEN", " "); xladdr_total++; } xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); while (xstcb->last == 0 && *offset < buflen) { sctp_process_tcb(xstcb, name, buf, buflen, offset, &indent); indent++; xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); } putchar('\n'); }
static void sctp_process_tcb(struct xsctp_tcb *xstcb, const char *name, char *buf, const size_t buflen, size_t *offset, int *indent) { int i, xl_total = 0, xr_total = 0, x_max; struct sockaddr *sa; struct xsctp_raddr *xraddr; struct xsctp_laddr *xladdr; struct xladdr_entry *prev_xl = NULL, *xl = NULL, *xl_tmp; struct xraddr_entry *prev_xr = NULL, *xr = NULL, *xr_tmp; #ifdef INET6 struct sockaddr_in6 *in6; #endif LIST_INIT(&xladdr_head); LIST_INIT(&xraddr_head); /* * Make `struct xladdr_list' list and `struct xraddr_list' list * to handle the address flexibly. */ while (*offset < buflen) { xladdr = (struct xsctp_laddr *)(buf + *offset); *offset += sizeof(struct xsctp_laddr); if (xladdr->last == 1) break; prev_xl = xl; xl = malloc(sizeof(struct xladdr_entry)); if (xl == NULL) { warnx("malloc %lu bytes", (u_long)sizeof(struct xladdr_entry)); goto out; } xl->xladdr = xladdr; if (prev_xl == NULL) LIST_INSERT_HEAD(&xladdr_head, xl, xladdr_entries); else LIST_INSERT_AFTER(prev_xl, xl, xladdr_entries); xl_total++; } while (*offset < buflen) { xraddr = (struct xsctp_raddr *)(buf + *offset); *offset += sizeof(struct xsctp_raddr); if (xraddr->last == 1) break; prev_xr = xr; xr = malloc(sizeof(struct xraddr_entry)); if (xr == NULL) { warnx("malloc %lu bytes", (u_long)sizeof(struct xraddr_entry)); goto out; } xr->xraddr = xraddr; if (prev_xr == NULL) LIST_INSERT_HEAD(&xraddr_head, xr, xraddr_entries); else LIST_INSERT_AFTER(prev_xr, xr, xraddr_entries); xr_total++; } /* * Let's print the address infos. */ xl = LIST_FIRST(&xladdr_head); xr = LIST_FIRST(&xraddr_head); x_max = (xl_total > xr_total) ? xl_total : xr_total; for (i = 0; i < x_max; i++) { if (((*indent == 0) && i > 0) || *indent > 0) printf("%-11s ", " "); if (xl != NULL) { sa = &(xl->xladdr->address.sa); if ((sa->sa_family) == AF_INET) inetprint(&((struct sockaddr_in *)sa)->sin_addr, htons(xstcb->local_port), name, numeric_port); #ifdef INET6 else { in6 = (struct sockaddr_in6 *)sa; inet6print(&in6->sin6_addr, htons(xstcb->local_port), name, numeric_port); } #endif } if (xr != NULL && !Lflag) { sa = &(xr->xraddr->address.sa); if ((sa->sa_family) == AF_INET) inetprint(&((struct sockaddr_in *)sa)->sin_addr, htons(xstcb->remote_port), name, numeric_port); #ifdef INET6 else { in6 = (struct sockaddr_in6 *)sa; inet6print(&in6->sin6_addr, htons(xstcb->remote_port), name, numeric_port); } #endif } if (xl != NULL) xl = LIST_NEXT(xl, xladdr_entries); if (xr != NULL) xr = LIST_NEXT(xr, xraddr_entries); if (i == 0 && !Lflag) sctp_statesprint(xstcb->state); if (i < x_max) putchar('\n'); } out: /* * Free the list which be used to handle the address. */ xl = LIST_FIRST(&xladdr_head); while (xl != NULL) { xl_tmp = LIST_NEXT(xl, xladdr_entries); free(xl); xl = xl_tmp; } xr = LIST_FIRST(&xraddr_head); while (xr != NULL) { xr_tmp = LIST_NEXT(xr, xraddr_entries); free(xr); xr = xr_tmp; } }