File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / trafshow / cisco_netflow.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:55:18 2012 UTC (12 years, 4 months ago) by misho
Branches: trafshow, MAIN
CVS tags: v5_2_3p0, v5_2_3, HEAD
trafshow

    1: /*
    2:  *	Copyright (c) 2004 Rinet Corp., Novosibirsk, Russia
    3:  *
    4:  * Redistribution and use in source forms, with and without modification,
    5:  * are permitted provided that this entire comment appears intact.
    6:  *
    7:  * THIS SOURCE CODE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND.
    8:  */
    9: 
   10: #ifdef	HAVE_CONFIG_H
   11: #include <config.h>
   12: #endif
   13: 
   14: #include <sys/param.h>
   15: #include <sys/types.h>
   16: #include <sys/socket.h>
   17: #include <netinet/in.h>
   18: #include <netinet/in_systm.h>
   19: #include <netinet/ip.h>
   20: #include <netinet/ip_icmp.h>
   21: #include <netinet/udp.h>
   22: #include <netinet/tcp.h>
   23: #ifdef INET6
   24: #include <netinet/ip6.h>
   25: #include <netinet/icmp6.h>
   26: #endif
   27: #include <stdio.h>
   28: #include <stdlib.h>
   29: #include <string.h>
   30: #include <time.h>
   31: #include <netdb.h>
   32: #include <pthread.h>
   33: 
   34: #include "cisco_netflow.h"
   35: #include "trafshow.h"
   36: #include "session.h"
   37: #include "netstat.h"
   38: #include "show_dump.h"
   39: #include "addrtoname.h"
   40: 
   41: 
   42: static void read_netflow(SESSION *sd, const unsigned char *data, int len);
   43: static PCAP_HANDLER *match_feeder(PCAP_HANDLER *ph_list, const struct sockaddr *sa);
   44: static void parse_netflow(PCAP_HANDLER *ph, const unsigned char *data, int len);
   45: static char *get_name(const struct sockaddr *sa, char *dst, int size);
   46: static void fprint_tcpflags(FILE *fp, int flags);
   47: static void fprint_tos(FILE *fp, int tos);
   48: static void dump_netflow_v1(const CNF_DATA_V1 *data);
   49: static void dump_netflow_v5(const CNF_DATA_V5 *data);
   50: static void dump_netflow_v7(const CNF_DATA_V7 *data);
   51: 
   52: int
   53: cisco_netflow_init(ph_list, port)
   54: 	PCAP_HANDLER **ph_list;
   55: 	int port;
   56: {
   57: 	SESSION *sd;
   58: 	int sock, on = 1;
   59: 	socklen_t slen;
   60: 	static struct sockaddr_in sin; /* why static? */
   61: 
   62: 	if (!ph_list) return -1;
   63: 
   64: 	memset(&sin, 0, sizeof(sin));
   65: 	sin.sin_family = AF_INET;
   66: 	sin.sin_port = htons(port);
   67: 
   68: 	if ((sd = session_open(-1, 0, DataSequence)) == 0) {
   69: 		perror("session_open");
   70: 		return -1;
   71: 	}
   72: 	sock = session_sock(sd);
   73: 
   74: 	slen = sizeof(on);
   75: #ifdef	SO_REUSEPORT
   76: 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, slen) < 0) {
   77: 		perror("setsockopt SO_REUSEPORT");
   78: 		return -1;
   79: 	}
   80: #elif	SO_REUSEADDR
   81: 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, slen) < 0) {
   82: 		perror("setsockopt SO_REUSEADDR");
   83: 		return -1;
   84: 	}
   85: #endif
   86: 	slen = sizeof(sin);
   87: 	if (bind(sock, (struct sockaddr *)&sin, slen) < 0) {
   88: 		perror("bind");
   89: 		return -1;
   90: 	}
   91: 
   92: 	session_setcallback(sd, 0, 0, read_netflow);
   93: 	session_setcookie(sd, ph_list);
   94: 	return 0;
   95: }
   96: 
   97: static PCAP_HANDLER *
   98: match_feeder(ph, sa)
   99: 	PCAP_HANDLER *ph;
  100: 	const struct sockaddr *sa;
  101: {
  102: 	const pcap_addr_t *ap;
  103: 
  104: 	if (!sa) return 0;
  105: 
  106: 	for (; ph; ph = ph->next) {
  107: 		if (ph->pcap) /* skip pcap devices */
  108: 			continue;
  109: 
  110: 		for (ap = ph->addr; ap; ap = ap->next) {
  111: 			if (!ap->addr || ap->addr->sa_family != sa->sa_family)
  112: 				continue;
  113: 
  114: 			if (ap->addr->sa_family == AF_INET) {
  115: 				if (!memcmp(&((struct sockaddr_in *)ap->addr)->sin_addr,
  116: 					    &((struct sockaddr_in *)sa)->sin_addr,
  117: 					    sizeof(struct in_addr)))
  118: 					return ph;
  119: 			}
  120: #ifdef	INET6
  121: 			else if (ap->addr->sa_family == AF_INET6) {
  122: 				if (!memcmp(&((struct sockaddr_in6 *)ap->addr)->sin6_addr,
  123: 					    &((struct sockaddr_in6 *)sa)->sin6_addr,
  124: 					    sizeof(struct in6_addr)))
  125: 					return ph;
  126: 			}
  127: #endif
  128: 		}
  129: 	}
  130: 	return 0;
  131: }
  132: 
  133: static char *
  134: get_name(sa, dst, size)
  135: 	const struct sockaddr *sa;
  136: 	char *dst;
  137: 	int size;
  138: {
  139: 	struct hostent *hp = 0;
  140: 
  141: 	if (!sa) return 0;
  142: 
  143: 	if (sa->sa_family == AF_INET) {
  144: 		hp = gethostbyaddr((char *)&((struct sockaddr_in *)sa)->sin_addr,
  145: 				   sizeof(struct in_addr), AF_INET);
  146: 	}
  147: #ifdef	INET6
  148: 	else if (sa->sa_family == AF_INET6) {
  149: 		hp = gethostbyaddr((char *)&((struct sockaddr_in6 *)sa)->sin6_addr,
  150: 				   sizeof(struct in6_addr), AF_INET6);
  151: 	}
  152: #endif
  153: 	if (hp) {
  154: 		int i;
  155: 		for (i = 0; i < size-1; i++) {
  156: 			if (hp->h_name[i] == '\0' || hp->h_name[i] == '.')
  157: 				break;
  158: 			dst[i] = hp->h_name[i];
  159: 		}
  160: 		dst[i] = '\0';
  161: 		return dst;
  162: 	}
  163: 	return 0;
  164: }
  165: 
  166: static void
  167: read_netflow(sd, data, len)
  168: 	SESSION *sd;
  169: 	const unsigned char *data;
  170: 	int len;
  171: {
  172: 	const struct sockaddr *from;
  173: 	PCAP_HANDLER *ph, **ph_list = (PCAP_HANDLER **)session_cookie(sd);
  174: 
  175: 	/* sanity check */
  176: 	if (!ph_list || !data || len < sizeof(CNF_HDR_V1))
  177: 		return;
  178: 
  179: 	if ((from = session_from(sd)) == 0)
  180: 		return; /* should not happen */
  181: 
  182: 	if ((ph = match_feeder(*ph_list, from)) == 0) { /* insert new one */
  183: 		int cnt = 0;
  184: 		PCAP_HANDLER *ph_prev = 0;
  185: 		char buf[256];
  186: 		pcap_addr_t *ap;
  187: 
  188: 		for (ph = *ph_list; ph; ph = ph->next) {
  189: 			if (!ph->pcap) cnt++;
  190: 			ph_prev = ph;
  191: 		}
  192: 
  193: 		if ((ph = (PCAP_HANDLER *)malloc(sizeof(PCAP_HANDLER))) == 0) {
  194: 			perror("malloc");
  195: 			return;
  196: 		}
  197: 		memset(ph, 0, sizeof(PCAP_HANDLER));
  198: 
  199: 		ph->masklen = aggregate;
  200: 		if (!get_name(from, buf, sizeof(buf)))
  201: 			sprintf(buf, "netflow%d", cnt);
  202: 		ph->name = strdup(buf);
  203: 
  204: 		sprintf(buf, "Netflow V%d", ntohs(((CNF_HDR_V1 *)data)->version));
  205: 		ph->descr = strdup(buf);
  206: 
  207: 		if ((ap = (pcap_addr_t *)malloc(sizeof(struct pcap_addr))) != 0) {
  208: 			memset(ap, 0, sizeof(struct pcap_addr));
  209: 			if ((ap->addr = (struct sockaddr *)malloc(sizeof(struct sockaddr))) == 0) {
  210: 				perror("malloc");
  211: 				return;
  212: 			}
  213: 			memcpy(ap->addr, from, sizeof(struct sockaddr));
  214: 		}
  215: 		ph->addr = ap;
  216: 
  217: 		if ((ph->ns_mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t))) == 0) {
  218: 			perror("malloc");
  219: 			return;
  220: 		}
  221: 		pthread_mutex_init(ph->ns_mutex, 0);
  222: 
  223: 		ph->prev = ph_prev;
  224: 		if (ph_prev)
  225: 			ph_prev->next = ph;
  226: 		else    *ph_list = ph;
  227: 	}
  228: 
  229: 	parse_netflow(ph, data, len);
  230: }
  231: 
  232: static void
  233: parse_netflow(ph, data, len)
  234: 	PCAP_HANDLER *ph;
  235: 	const unsigned char *data;
  236: 	int len;
  237: {
  238: 	struct timeval now;
  239: 	int version, counter, msec, hdrlen, dump_it;
  240: 	CNF_HDR_V1 *v1h;
  241: 	CNF_HDR_V5 *v5h;
  242: 	CNF_HDR_V7 *v7h;
  243: 	CNF_DATA_V1 *v1d = 0;
  244: 	CNF_DATA_V5 *v5d = 0;
  245: 	CNF_DATA_V7 *v7d = 0;
  246: 	NETSTAT ns;
  247: 
  248: 	v1h = (CNF_HDR_V1 *)data;
  249: 	if (!v1h || len < sizeof(CNF_HDR_V1))
  250: 		return;
  251: 
  252: 	version = ntohs(v1h->version);
  253: 	counter = ntohs(v1h->counter);
  254: 	if (version == 1) {
  255: 		v1d = (CNF_DATA_V1 *)(data + sizeof(CNF_HDR_V1));
  256: 		len -= sizeof(sizeof(CNF_HDR_V1));
  257: 		len /= sizeof(CNF_DATA_V1);
  258: 	} else if (version == 5) {
  259: 		v5h = (CNF_HDR_V5 *)data;
  260: 		v5d = (CNF_DATA_V5 *)(data + sizeof(CNF_HDR_V5));
  261: 		len -= sizeof(sizeof(CNF_HDR_V5));
  262: 		len /= sizeof(CNF_DATA_V5);
  263: 	} else if (version == 7) {
  264: 		v7h = (CNF_HDR_V7 *)data;
  265: 		v7d = (CNF_DATA_V7 *)(data + sizeof(CNF_HDR_V7));
  266: 		len -= sizeof(sizeof(CNF_HDR_V7));
  267: 		len /= sizeof(CNF_DATA_V7);
  268: 	} else	return;
  269: 
  270: 	gettimeofday(&now, 0);
  271: 
  272: 	while (counter-- > 0 && len-- > 0) {
  273: 		struct ip_address *src = &ns.ip_src_addr;
  274: 		struct ip_address *dst = &ns.ip_dst_addr;
  275: 
  276: 		memset(&ns, 0, sizeof(NETSTAT));
  277: 		ns.ip_ver = 4; /* XXX what about IPv6? */
  278: 		ns.mtime = now;
  279: 		msec = 0;
  280: 		dump_it = 0;
  281: 
  282: 		if (version == 1 && v1d) {
  283: 			ns.ip_proto = v1d->proto;
  284: 
  285: 			src->ip_addr.s_addr = v1d->src_addr;
  286: 			src->ip_port = v1d->src_port;
  287: 
  288: 			dst->ip_addr.s_addr = v1d->dst_addr;
  289: 			dst->ip_port = v1d->dst_port;
  290: 
  291: 			ns.pkt_cnt = ntohl(v1d->dpkts);
  292: 			ns.pkt_len = ntohl(v1d->doctets);
  293: 
  294: 			msec = ntohl(v1d->lasttime) - ntohl(v1d->firsttime);
  295: 
  296: 		} else if (version == 5 && v5d) {
  297: 			ns.ip_proto = v5d->proto;
  298: 
  299: 			src->ip_addr.s_addr = v5d->src_addr;
  300: 			src->ip_port = v5d->src_port;
  301: 
  302: 			dst->ip_addr.s_addr = v5d->dst_addr;
  303: 			dst->ip_port = v5d->dst_port;
  304: 
  305: 			ns.pkt_cnt = ntohl(v5d->dpkts);
  306: 			ns.pkt_len = ntohl(v5d->doctets);
  307: 
  308: 			msec = ntohl(v5d->lasttime) - ntohl(v5d->firsttime);
  309: 
  310: 		} else if (version == 7 && v7d) {
  311: 			ns.ip_proto = v7d->proto;
  312: 
  313: 			src->ip_addr.s_addr = v7d->src_addr;
  314: 			src->ip_port = v7d->src_port;
  315: 
  316: 			dst->ip_addr.s_addr = v7d->dst_addr;
  317: 			dst->ip_port = v7d->dst_port;
  318: 
  319: 			ns.pkt_cnt = ntohl(v7d->dpkts);
  320: 			ns.pkt_len = ntohl(v7d->doctets);
  321: 
  322: 			msec = ntohl(v7d->lasttime) - ntohl(v7d->firsttime);
  323: 		}
  324: 
  325: 		/* suggest data length (dirty fake) */
  326: 		hdrlen = sizeof(struct ip);
  327: 		switch (ns.ip_proto) {
  328: 		case IPPROTO_TCP:
  329: 			hdrlen += sizeof(struct tcphdr);
  330: 			break;
  331: 		case IPPROTO_UDP:
  332: 			hdrlen += sizeof(struct udphdr);
  333: 			break;
  334: 		case IPPROTO_ICMP:
  335: 			hdrlen += sizeof(struct icmp);
  336: 			break;
  337: 		}
  338: 		hdrlen *= ns.pkt_cnt;
  339: 		if (ns.pkt_len >= hdrlen)
  340: 			ns.data_len = ns.pkt_len - hdrlen;
  341: 
  342: 		if (msec > 0) {
  343: 			ns.pkt_cnt_rate = ns.pkt_cnt * 1000 / msec;
  344: 			ns.pkt_len_rate = ns.pkt_len * 1000 / msec;
  345: 			ns.data_len_rate = ns.data_len * 1000 / msec;
  346: 		}
  347: 
  348: 		pcap_save(ph, &ns);
  349: 
  350: 		if (cisco_netflow_dump && ph->name &&
  351: 		    !strcmp(cisco_netflow_dump, ph->name) &&
  352: 		    netstat_match(&ns, dump_match)) {
  353: 			dump_it++;
  354: 		}
  355: 		if (version == 1 && v1d) {
  356: 			if (dump_it) dump_netflow_v1(v1d);
  357: 			v1d++;
  358: 		} else if (version == 5 && v5d) {
  359: 			if (dump_it) dump_netflow_v5(v5d);
  360: 			v5d++;
  361: 		} else if (version == 7 && v7d) {
  362: 			if (dump_it) dump_netflow_v7(v7d);
  363: 			v7d++;
  364: 		}
  365: 	}
  366: }
  367: 
  368: static void
  369: fprint_tcpflags(fp, flags)
  370: 	FILE *fp;
  371: 	int flags;
  372: {
  373: 	fprintf(fp, "TCPflags: %02x", flags);
  374: 
  375: 	if (flags & 0x01) fprintf(fp, " FIN");
  376: 	if (flags & 0x02) fprintf(fp, " SYN");
  377: 	if (flags & 0x04) fprintf(fp, " RST");
  378: 	if (flags & 0x08) fprintf(fp, " PUSH");
  379: 	if (flags & 0x10) fprintf(fp, " ACK");
  380: 	if (flags & 0x20) fprintf(fp, " URG");
  381: 
  382: 	fprintf(fp, "\n");
  383: }
  384: 
  385: static void
  386: fprint_tos(fp, tos)
  387: 	FILE *fp;
  388: 	int tos;
  389: {
  390: 	fprintf(fp, "TOS:      %02x", tos);
  391: 
  392: 	switch (tos & 0xe0) { /* precedence bits */
  393: 	case 0xe0: fprintf(fp, " NETCONTROL"); break;
  394: 	case 0xc0: fprintf(fp, " INTERNETCONTROL"); break;
  395: 	case 0xa0: fprintf(fp, " CRITIC_ECP"); break;
  396: 	case 0x80: fprintf(fp, " FLASHOVERRIDE"); break;
  397: 	case 0x60: fprintf(fp, " FLASH"); break;
  398: 	case 0x40: fprintf(fp, " IMMEDIATE"); break;
  399: 	case 0x20: fprintf(fp, " PRIORITY"); break;
  400: 	}
  401: 	tos &= 0x1e; /* type of service bits */
  402: 	if (tos & 0x10) fprintf(fp, " LOWDELAY");
  403: 	if (tos & 0x08) fprintf(fp, " THROUGHPUT");
  404: 	if (tos & 0x04) fprintf(fp, " RELIABILITY");
  405: 	if (tos & 0x02) fprintf(fp, " LOWCOST");
  406: 
  407: 	fprintf(fp, "\n");
  408: }
  409: 
  410: static void
  411: dump_netflow_v1(dp)
  412: 	const CNF_DATA_V1 *dp;
  413: {
  414: 	FILE *fp;
  415: 
  416: 	if (!dump_file || (fp = fopen(dump_file, "a")) == 0)
  417: 		return;
  418: 
  419: 	fprintf(fp, "\nNetflow:  V1\n");
  420: 	fprintf(fp, "SrcAddr:  %s\n", intoa(dp->src_addr));
  421: 	fprintf(fp, "DstAddr:  %s\n", intoa(dp->dst_addr));
  422: 	fprintf(fp, "NextHop:  %s\n", intoa(dp->nexthop));
  423: 	fprintf(fp, "InputIf:  %d\n", (int)ntohs(dp->ifin));
  424: 	fprintf(fp, "OutputIf: %d\n", (int)ntohs(dp->ifout));
  425: 	fprintf(fp, "Packets:  %u\n", (u_int32_t)ntohl(dp->dpkts));
  426: 	fprintf(fp, "Octets:   %u\n", (u_int32_t)ntohl(dp->doctets));
  427: 	fprintf(fp, "First:    %u\n", (u_int32_t)ntohl(dp->firsttime));
  428: 	fprintf(fp, "Last:     %u\n", (u_int32_t)ntohl(dp->lasttime));
  429: 	if (dp->proto == IPPROTO_TCP) {
  430: 		fprintf(fp, "SrcPort:  %s\n",  tcpport_string(ntohs(dp->src_port)));
  431: 		fprintf(fp, "DstPort:  %s\n",  tcpport_string(ntohs(dp->dst_port)));
  432: 	} else if (dp->proto == IPPROTO_UDP) {
  433: 		fprintf(fp, "SrcPort:  %s\n",  udpport_string(ntohs(dp->src_port)));
  434: 		fprintf(fp, "DstPort:  %s\n",  udpport_string(ntohs(dp->dst_port)));
  435: 	} else {
  436: 		fprintf(fp, "SrcPort:  %d\n",  (int)ntohs(dp->src_port));
  437: 		fprintf(fp, "DstPort:  %d\n",  (int)ntohs(dp->dst_port));
  438: 	}
  439: 	fprintf(fp, "Protocol: %s\n", ipproto_string(dp->proto));
  440: 	fprint_tos(fp, dp->tos);
  441: 	fprint_tcpflags(fp, dp->flags);
  442: 
  443: 	(void)fclose(fp);
  444: }
  445: 
  446: static void
  447: dump_netflow_v5(dp)
  448: 	const CNF_DATA_V5 *dp;
  449: {
  450: 	FILE *fp;
  451: 
  452: 	if (!dump_file || (fp = fopen(dump_file, "a")) == 0)
  453: 		return;
  454: 
  455: 	fprintf(fp, "\nNetflow:  V5\n");
  456: 	fprintf(fp, "SrcAddr:  %s\n", intoa(dp->src_addr));
  457: 	fprintf(fp, "DstAddr:  %s\n", intoa(dp->dst_addr));
  458: 	fprintf(fp, "NextHop:  %s\n", intoa(dp->nexthop));
  459: 	fprintf(fp, "InputIf:  %d\n", (int)ntohs(dp->ifin));
  460: 	fprintf(fp, "OutputIf: %d\n", (int)ntohs(dp->ifout));
  461: 	fprintf(fp, "Packets:  %u\n", (u_int32_t)ntohl(dp->dpkts));
  462: 	fprintf(fp, "Octets:   %u\n", (u_int32_t)ntohl(dp->doctets));
  463: 	fprintf(fp, "First:    %u\n", (u_int32_t)ntohl(dp->firsttime));
  464: 	fprintf(fp, "Last:     %u\n", (u_int32_t)ntohl(dp->lasttime));
  465: 	if (dp->proto == IPPROTO_TCP) {
  466: 		fprintf(fp, "SrcPort:  %s\n",  tcpport_string(ntohs(dp->src_port)));
  467: 		fprintf(fp, "DstPort:  %s\n",  tcpport_string(ntohs(dp->dst_port)));
  468: 	} else if (dp->proto == IPPROTO_UDP) {
  469: 		fprintf(fp, "SrcPort:  %s\n",  udpport_string(ntohs(dp->src_port)));
  470: 		fprintf(fp, "DstPort:  %s\n",  udpport_string(ntohs(dp->dst_port)));
  471: 	} else {
  472: 		fprintf(fp, "SrcPort:  %d\n",  (int)ntohs(dp->src_port));
  473: 		fprintf(fp, "DstPort:  %d\n",  (int)ntohs(dp->dst_port));
  474: 	}
  475: 	fprint_tcpflags(fp, dp->flags);
  476: 	fprintf(fp, "Protocol: %s\n", ipproto_string(dp->proto));
  477: 	fprint_tos(fp, dp->tos);
  478: 
  479: 	fprintf(fp, "SrcASN:   %d\n", (int)ntohs(dp->src_as));
  480: 	fprintf(fp, "DstASN:   %d\n", (int)ntohs(dp->dst_as));
  481: 	fprintf(fp, "SrcMask:  %d\n", (int)dp->src_mask);
  482: 	fprintf(fp, "DstMask:  %d\n", (int)dp->dst_mask);
  483: 
  484: 	(void)fclose(fp);
  485: }
  486: 
  487: static void
  488: dump_netflow_v7(dp)
  489: 	const CNF_DATA_V7 *dp;
  490: {
  491: 	FILE *fp;
  492: 
  493: 	if (!dump_file || (fp = fopen(dump_file, "a")) == 0)
  494: 		return;
  495: 
  496: 	fprintf(fp, "\nNetflow:  V7\n");
  497: 	fprintf(fp, "SrcAddr:  %s\n", intoa(dp->src_addr));
  498: 	fprintf(fp, "DstAddr:  %s\n", intoa(dp->dst_addr));
  499: 	fprintf(fp, "NextHop:  %s\n", intoa(dp->nexthop));
  500: 	fprintf(fp, "InputIf:  %d\n", (int)ntohs(dp->ifin));
  501: 	fprintf(fp, "OutputIf: %d\n", (int)ntohs(dp->ifout));
  502: 	fprintf(fp, "Packets:  %u\n", (u_int32_t)ntohl(dp->dpkts));
  503: 	fprintf(fp, "Octets:   %u\n", (u_int32_t)ntohl(dp->doctets));
  504: 	fprintf(fp, "First:    %u\n", (u_int32_t)ntohl(dp->firsttime));
  505: 	fprintf(fp, "Last:     %u\n", (u_int32_t)ntohl(dp->lasttime));
  506: 	if (dp->proto == IPPROTO_TCP) {
  507: 		fprintf(fp, "SrcPort:  %s\n",  tcpport_string(ntohs(dp->src_port)));
  508: 		fprintf(fp, "DstPort:  %s\n",  tcpport_string(ntohs(dp->dst_port)));
  509: 	} else if (dp->proto == IPPROTO_UDP) {
  510: 		fprintf(fp, "SrcPort:  %s\n",  udpport_string(ntohs(dp->src_port)));
  511: 		fprintf(fp, "DstPort:  %s\n",  udpport_string(ntohs(dp->dst_port)));
  512: 	} else {
  513: 		fprintf(fp, "SrcPort:  %d\n",  (int)ntohs(dp->src_port));
  514: 		fprintf(fp, "DstPort:  %d\n",  (int)ntohs(dp->dst_port));
  515: 	}
  516: 	fprint_tcpflags(fp, dp->flags);
  517: 	fprintf(fp, "Protocol: %s\n", ipproto_string(dp->proto));
  518: 	fprint_tos(fp, dp->tos);
  519: 
  520: 	fprintf(fp, "SrcASN:   %d\n", (int)ntohl(dp->src_as));
  521: 	fprintf(fp, "DstASN:   %d\n", (int)ntohl(dp->dst_as));
  522: 	fprintf(fp, "SrcMask:  %d\n", (int)dp->src_mask);
  523: 	fprintf(fp, "DstMask:  %d\n", (int)dp->dst_mask);
  524: 
  525: 	fprintf(fp, "RouterSc: %s\n", intoa(dp->router_sc));
  526: 
  527: 	(void)fclose(fp);
  528: }
  529: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>