diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ip/measure.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ip/measure.c')
-rwxr-xr-x | sys/src/cmd/ip/measure.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/sys/src/cmd/ip/measure.c b/sys/src/cmd/ip/measure.c new file mode 100755 index 000000000..2df5660f1 --- /dev/null +++ b/sys/src/cmd/ip/measure.c @@ -0,0 +1,196 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ip.h> + +/* + * ether packet + */ +typedef struct Etherpkt Etherpkt; +struct Etherpkt { + uchar d[6]; + uchar s[6]; + uchar type[2]; + char data[1500]; +}; +#define ETHERMINTU 60 /* minimum transmit size */ +#define ETHERMAXTU 1514 /* maximum transmit size */ +#define ETHERHDRSIZE 14 /* size of an ethernet header */ + +/* + * ip packets + */ +typedef struct Ippkt Ippkt; +struct Ippkt +{ + uchar vihl; /* Version and header length */ + uchar tos; /* Type of service */ + uchar length[2]; /* packet length */ + uchar id[2]; /* Identification */ + uchar frag[2]; /* Fragment information */ + uchar ttl; /* Time to live */ + uchar proto; /* Protocol */ + uchar cksum[2]; /* Header checksum */ + uchar src[4]; /* Ip source */ + uchar dst[4]; /* Ip destination */ + char data[1]; +}; + +#define IP_HDRSIZE 20 +#define IP_UDPPROTO 17 +#define IP_MBONEPROTO 4 +#define IP_TCPPROTO 6 +#define IP_ILPROTO 40 +#define IP_ICMPPROTO 1 +#define IP_DF 0x4000 +#define IP_MF 0x2000 + +#define NetS(x) (((x)[0]<<8) | (x)[1]) +#define NetL(x) (((x)[0]<<24) | ((x)[1]<<16) | ((x)[2]<<8) | (x)[3]) + +/* + * run flags + */ +int debug; +int mbone; + +ulong protoin[256]; +ulong protoout[256]; +ulong protopin[256]; +ulong protopout[256]; + +void +error(char *s) +{ + char buf[ERRMAX]; + + errstr(buf, sizeof buf); + fprint(2, "snoopy: %s %s\n", buf, s); + exits("death"); +} + +void +warning(char *s) +{ + char buf[ERRMAX]; + + errstr(buf, sizeof buf); + fprint(2, "snoopy: %s %s\n", buf, s); +} + +void +printproto(int p) +{ + print("\t%d(%ld %ld %ld %ld)", p, protoin[p], protopin[p], protoout[p], protopout[p]); +} + +void +main(int argc, char *argv[]) +{ + Etherpkt e; + Ippkt *ip; + long n; + int fd, cfd; + int ts, len, t; + long start; + int delta; + uchar target[6]; + char buf[256]; + ulong samples; + + samples = -1; + ARGBEGIN{ + case 'd': + debug++; + break; + case 's': + samples = atoi(ARGF()); + break; + }ARGEND; + + if(argc < 2){ + fprint(2, "usage: %s device ip-addr [minutes-per-sample]\n", argv0); + exits("usage"); + } + if(argc > 2) + delta = atoi(argv[2])*60*1000; + else + delta = 5*60*1000; + parseether(target, argv[1]); + + fmtinstall('E', eipfmt); + fmtinstall('I', eipfmt); + + snprint(buf, sizeof(buf), "%s!-2", argv[0]); + fd = dial(buf, 0, 0, &cfd); + if(fd < 0) + error("opening ether data"); + if(write(cfd, "promiscuous", sizeof("promiscuous")-1) <= 0) + error("connecting"); + + start = 0; + fd = -1; + + for(;;){ + if(fd < 0){ + fd = dial(buf, 0, 0, &cfd); + if(fd < 0) + error("opening ether data"); + if(write(cfd, "promiscuous", sizeof("promiscuous")-1) <= 0) + error("connecting"); + close(cfd); + } + n = read(fd, &e, sizeof(e)); + if(n <= 0) + break; + ts = NetL(&e.d[60]); + n = NetS(&e.d[58]) - ETHERHDRSIZE; + if(n < 0) + continue; + if(start == 0) + start = ts; + t = NetS(e.type); + if(t == 0x0800 || (t&0xFF00) == 0x1000){ + ip = (Ippkt*)e.data; + len = NetS(ip->length); + if(len > n) + len = n; + if(debug) + fprint(2, "%I -> %I %d\n", ip->src, ip->dst, len); + if(memcmp(e.s, target, 6) == 0){ + protopin[0]++; + protoin[0] += len; + if(ip->proto){ + protopin[ip->proto]++; + protoin[ip->proto] += len; + } + } + if(memcmp(e.d, target, 6) == 0){ + protopout[0]++; + protoout[0] += len; + if(ip->proto){ + protopout[ip->proto]++; + protoout[ip->proto] += len; + } + } + } + if(ts - start >= delta){ + print("%8.8ld %ld", time(0), ts - start); + printproto(0); + printproto(IP_MBONEPROTO); + printproto(IP_UDPPROTO); + printproto(IP_TCPPROTO); + print("\n"); + start = 0; + memset(protoin, 0, sizeof(protoin)); + memset(protoout, 0, sizeof(protoout)); + memset(protopin, 0, sizeof(protopin)); + memset(protopout, 0, sizeof(protopout)); + close(fd); + fd = -1; + if(--samples == 0) + break; + } + } + exits(0); +} |