/* * Copyright (c) 1999 RISS-Telecom etworking Center * * Copyright (c) 1993 The CAD lab of the * Novosibirsk Institute of Broadcasting and Telecommunication * * BPFT $Id: trafstat.c,v 1.3 1994/01/14 11:32:26 bob Exp $ * * $Log: trafstat.c,v $ * Revision 1.3 1994/01/14 11:32:26 bob * Bug fixed in display tcp/udp fragmented datagramms * * Revision 1.2 1994/01/06 15:39:31 bob * Changes for new output format * * Revision 1.1 1993/10/20 16:05:35 bob * Initial revision * * * Redistribution and use in source forms, with and without modification, * are permitted provided that this entire comment appears intact. * Redistribution in binary form may occur without any restrictions. * * THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND. */ /* trafstat.c - tcp/udp data traffic daemon statistics */ #include #include #include #include #include #include #include #include #include "addrtoname.h" #include "traffic.h" extern int nflag; extern int Nflag; extern char *device_name; extern char *host; static struct timeval start_time; static struct timeval drop_time; /* * Obtain traffic table. */ int traf_get(fd) register int fd; { register int nread, size, c = 0; register char *bufp; int count = 0; c += read(fd, (int *)&n_entry, sizeof(n_entry)); if (n_entry > MAX_TO_SAVE) { warning("confusion, is't trafstat port or error"); return 0; } size = n_entry * sizeof(struct t_entry); if ((entries = (struct t_entry *)malloc(size)) == NULL) { warning("insufficient memory"); return 0; } c += read(fd, (struct timeval *)&start_time, sizeof(start_time)); c += read(fd, (struct timeval *)&drop_time, sizeof(drop_time)); bufp = (char *)entries; do { if ((nread = read(fd, bufp, size - count)) < 0) { warning("error reading data"); return 0; } if (nread == 0) break; count += nread; bufp += nread; } while (count < size); c += count; (void)read(fd, (int *)&count, sizeof(count)); if (c != count) { warning("can't recover data"); return 0; } return c; } #define EQUAL 0 #define LESS -1 #define GREATER 1 int sortbysize(left, right) register struct t_entry *left; register struct t_entry *right; { if (left->n_psize < right->n_psize) return GREATER; if (left->n_psize > right->n_psize) return LESS; return EQUAL; } /* * Output humman readable traffic table to stdout. */ void traf_print() { register u_int i; u_int64_t abytes = 0, dbytes = 0; char buf[MAXHOSTNAMELEN + 1], *port, *user, *proto; qsort(entries, n_entry, sizeof(struct t_entry), sortbysize); if (host != NULL) strcpy(buf, host); else gethostname(buf, MAXHOSTNAMELEN); printf("\n (%s) %s at", device_name, buf); printf(" %.15s -", ctime((time_t *)&start_time) + 4); printf(" %.15s\n", ctime((time_t *)&drop_time) + 4); for (i = 0; i < n_entry; i++) { if (!entries[i].in_ip.s_addr) continue; abytes += entries[i].n_psize; dbytes += entries[i].n_bytes; } printf(" Summary: %qu data bytes, %qu all bytes, %u records\n", dbytes, abytes, n_entry); printf("\ From Port To Port Proto Data All\n"); for (i = 0; i < n_entry; i++) { if (!entries[i].in_ip.s_addr) continue; switch(entries[i].ip_protocol) { case IPPROTO_TCP: if (entries[i].p_port) port = tcpport_string(entries[i].p_port); proto = "tcp"; break; case IPPROTO_UDP: if (entries[i].p_port) port = udpport_string(entries[i].p_port); proto = "udp"; break; case IPPROTO_ICMP: proto = "icmp"; break; case IPPROTO_EGP: proto = "egp"; break; case IPPROTO_OSPF: proto = "ospf"; break; case IPPROTO_IGMP: proto = "igmp"; break; default: proto = "unkn"; } if (entries[i].p_port) user = "client"; else user = "none"; printf("%-18.18s %-6.6s ", ipaddr_string(&entries[i].in_ip), (entries[i].who_srv & 1) ? port : user); printf("%-18.18s %-6.6s ", ipaddr_string(&entries[i].out_ip), (entries[i].who_srv & 2) ? port : user); printf("%-4.4s %9ld %10ld\n", proto, entries[i].n_bytes, entries[i].n_psize); } return; } /* * Put traffic table to fd in binary form. */ void traf_put(fd) register int fd; { register int i; int c = 0; c += write(fd, (int *)&n_entry, sizeof(n_entry)); c += write(fd, (struct timeval *)&start_time, sizeof(start_time)); c += write(fd, (struct timeval *)&drop_time, sizeof(drop_time)); for (i = 0; i < n_entry; i++) { c += write(fd, (struct t_entry *)&entries[i], sizeof(struct t_entry)); } (void)write(fd, (int *)&c, sizeof(c)); return; }