예제 #1
0
파일: sctp.c 프로젝트: 2asoft/freebsd
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");
}
예제 #2
0
파일: sctp.c 프로젝트: coyizumi/cs111
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);
	}
}
예제 #3
0
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');
}