Exemplo n.º 1
0
static void
sctp_process_tcb(struct xsctp_tcb *xstcb,
    char *buf, const size_t buflen, size_t *offset, int *indent)
{
	int i, xl_total = 0, xr_total = 0, x_max;
	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;

	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("%-12s ", " ");

		if (xl != NULL) {
			sctp_print_address(&(xl->xladdr->address),
			    htons(xstcb->local_port), numeric_port);
		} else {
			if (Wflag) {
				printf("%-45s ", " ");
			} else {
				printf("%-22s ", " ");
			}
		}

		if (xr != NULL && !Lflag) {
			sctp_print_address(&(xr->xraddr->address),
			    htons(xstcb->remote_port), numeric_port);
		}

		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;
	}
}
Exemplo n.º 2
0
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);
	}
}
Exemplo n.º 3
0
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");
}