static void sctp_process_inpcb(struct xsctp_inpcb *xinpcb, char *buf, const size_t buflen, size_t *offset) { int indent = 0, xladdr_total = 0, is_listening = 0; static int first = 1; const char *tname, *pname; struct xsctp_tcb *xstcb; struct xsctp_laddr *xladdr; size_t offset_laddr; int process_closed; if (xinpcb->maxqlen > 0) is_listening = 1; if (first) { if (!Lflag) { xo_emit("Active SCTP associations"); if (aflag) xo_emit(" (including servers)"); } else xo_emit("Current listen queue sizes (qlen/maxqlen)"); xo_emit("\n"); if (Lflag) xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-8.8s} " "{T:/%-22.22s}\n", "Proto", "Type", "Listen", "Local Address"); else if (Wflag) xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-45.45s} " "{T:/%-45.45s} {T:/%s}\n", "Proto", "Type", "Local Address", "Foreign Address", "(state)"); else xo_emit("{T:/%-6.6s} {T:/%-5.5s} {T:/%-22.22s} " "{T:/%-22.22s} {T:/%s}\n", "Proto", "Type", "Local Address", "Foreign Address", "(state)"); first = 0; } xladdr = (struct xsctp_laddr *)(buf + *offset); if (Lflag && !is_listening) { sctp_skip_xinpcb_ifneed(buf, buflen, offset); return; } if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { /* Can't distinguish between sctp46 and sctp6 */ pname = "sctp46"; } else { pname = "sctp4"; } if (xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE) tname = "1to1"; else if (xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) tname = "1toN"; else tname = "????"; if (Lflag) { char buf1[22]; snprintf(buf1, sizeof buf1, "%u/%u", xinpcb->qlen, xinpcb->maxqlen); xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ", pname, tname); xo_emit("{d:queues/%-8.8s}{e:queue-len/%hu}" "{e:max-queue-len/%hu} ", buf1, xinpcb->qlen, xinpcb->maxqlen); } offset_laddr = *offset; process_closed = 0; xo_open_list("local-address"); retry: while (*offset < buflen) { xladdr = (struct xsctp_laddr *)(buf + *offset); *offset += sizeof(struct xsctp_laddr); if (xladdr->last) { if (aflag && !Lflag && (xladdr_total == 0) && process_closed) { xo_open_instance("local-address"); xo_emit("{:protocol/%-6.6s/%s} " "{:type/%-5.5s/%s} ", pname, tname); if (Wflag) { xo_emit("{P:/%-91.91s/%s} " "{:state/CLOSED}", " "); } else { xo_emit("{P:/%-45.45s/%s} " "{:state/CLOSED}", " "); } xo_close_instance("local-address"); } if (process_closed || is_listening) { xo_emit("\n"); } break; } if (!Lflag && !is_listening && !process_closed) continue; xo_open_instance("local-address"); if (xladdr_total == 0) { xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ", pname, tname); } else { xo_emit("\n"); xo_emit(Lflag ? "{P:/%-21.21s} " : "{P:/%-12.12s} ", " "); } sctp_print_address("local", &(xladdr->address), htons(xinpcb->local_port), numeric_port); if (aflag && !Lflag && xladdr_total == 0) { if (Wflag) { if (process_closed) { xo_emit("{P:/%-45.45s} " "{:state/CLOSED}", " "); } else { xo_emit("{P:/%-45.45s} " "{:state:LISTEN}", " "); } } else { if (process_closed) { xo_emit("{P:/%-22.22s} " "{:state/CLOSED}", " "); } else { xo_emit("{P:/%-22.22s} " "{:state/LISTEN}", " "); } } } xladdr_total++; xo_close_instance("local-address"); } xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); if (aflag && (xladdr_total == 0) && xstcb->last && !process_closed) { process_closed = 1; *offset = offset_laddr; goto retry; } while (xstcb->last == 0 && *offset < buflen) { xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ", pname, tname); sctp_process_tcb(xstcb, buf, buflen, offset, &indent); indent++; xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); } xo_close_list("local-address"); }
static void sctp_process_inpcb(struct xsctp_inpcb *xinpcb, char *buf, const size_t buflen, size_t *offset) { int indent = 0, xladdr_total = 0, is_listening = 0; static int first = 1; const char *tname, *pname; struct xsctp_tcb *xstcb; struct xsctp_laddr *xladdr; size_t offset_laddr; int process_closed; if (xinpcb->maxqlen > 0) is_listening = 1; if (first) { if (!Lflag) { printf("Active SCTP associations"); if (aflag) printf(" (including servers)"); } else printf("Current listen queue sizes (qlen/maxqlen)"); putchar('\n'); if (Lflag) printf("%-6.6s %-5.5s %-8.8s %-22.22s\n", "Proto", "Type", "Listen", "Local Address"); else if (Wflag) printf("%-6.6s %-5.5s %-45.45s %-45.45s %s\n", "Proto", "Type", "Local Address", "Foreign Address", "(state)"); else printf("%-6.6s %-5.5s %-22.22s %-22.22s %s\n", "Proto", "Type", "Local Address", "Foreign Address", "(state)"); first = 0; } xladdr = (struct xsctp_laddr *)(buf + *offset); if (Lflag && !is_listening) { sctp_skip_xinpcb_ifneed(buf, buflen, offset); return; } if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) { /* Can't distinguish between sctp46 and sctp6 */ pname = "sctp46"; } else { pname = "sctp4"; } if (xinpcb->flags & SCTP_PCB_FLAGS_TCPTYPE) tname = "1to1"; else if (xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) tname = "1toN"; else tname = "????"; if (Lflag) { char buf1[9]; snprintf(buf1, 9, "%hu/%hu", xinpcb->qlen, xinpcb->maxqlen); printf("%-6.6s %-5.5s ", pname, tname); printf("%-8.8s ", buf1); } offset_laddr = *offset; process_closed = 0; retry: while (*offset < buflen) { xladdr = (struct xsctp_laddr *)(buf + *offset); *offset += sizeof(struct xsctp_laddr); if (xladdr->last) { if (aflag && !Lflag && (xladdr_total == 0) && process_closed) { printf("%-6.6s %-5.5s ", pname, tname); if (Wflag) { printf("%-91.91s CLOSED", " "); } else { printf("%-45.45s CLOSED", " "); } } if (process_closed || is_listening) { putchar('\n'); } break; } if (!Lflag && !is_listening && !process_closed) continue; if (xladdr_total == 0) { printf("%-6.6s %-5.5s ", pname, tname); } else { putchar('\n'); printf((Lflag) ? "%-21.21s " : "%-12.12s ", " "); } sctp_print_address(&(xladdr->address), htons(xinpcb->local_port), numeric_port); if (aflag && !Lflag && xladdr_total == 0) { if (Wflag) { if (process_closed) { printf("%-45.45s CLOSED", " "); } else { printf("%-45.45s LISTEN", " "); } } else { if (process_closed) { printf("%-22.22s CLOSED", " "); } else { printf("%-22.22s LISTEN", " "); } } } xladdr_total++; } xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); if (aflag && (xladdr_total == 0) && xstcb->last && !process_closed) { process_closed = 1; *offset = offset_laddr; goto retry; } while (xstcb->last == 0 && *offset < buflen) { printf("%-6.6s %-5.5s ", pname, tname); sctp_process_tcb(xstcb, buf, buflen, offset, &indent); indent++; xstcb = (struct xsctp_tcb *)(buf + *offset); *offset += sizeof(struct xsctp_tcb); } }
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'); }