]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/measure.c
socksd: setnetmtpt
[plan9front.git] / sys / src / cmd / ip / measure.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ip.h>
5
6 /*
7  *  ether packet
8  */
9 typedef struct Etherpkt Etherpkt;
10 struct Etherpkt {
11         uchar d[6];
12         uchar s[6];
13         uchar type[2];
14         char data[1500];
15 };
16 #define ETHERMINTU      60      /* minimum transmit size */
17 #define ETHERMAXTU      1514    /* maximum transmit size */
18 #define ETHERHDRSIZE    14      /* size of an ethernet header */
19
20 /*
21  *  ip packets
22  */
23 typedef struct Ippkt    Ippkt;
24 struct Ippkt
25 {
26         uchar   vihl;           /* Version and header length */
27         uchar   tos;            /* Type of service */
28         uchar   length[2];      /* packet length */
29         uchar   id[2];          /* Identification */
30         uchar   frag[2];        /* Fragment information */
31         uchar   ttl;            /* Time to live */
32         uchar   proto;          /* Protocol */
33         uchar   cksum[2];       /* Header checksum */
34         uchar   src[4];         /* Ip source */
35         uchar   dst[4];         /* Ip destination */
36         char    data[1];
37 };
38
39 #define IP_HDRSIZE      20
40 #define IP_UDPPROTO     17
41 #define IP_MBONEPROTO   4
42 #define IP_TCPPROTO     6
43 #define IP_ILPROTO      40
44 #define IP_ICMPPROTO    1
45 #define IP_DF           0x4000
46 #define IP_MF           0x2000
47
48 #define NetS(x) (((x)[0]<<8) | (x)[1])
49 #define NetL(x) (((x)[0]<<24) | ((x)[1]<<16) | ((x)[2]<<8) | (x)[3])
50
51 /*
52  *  run flags
53  */
54 int     debug;
55 int     mbone;
56
57 ulong protoin[256];
58 ulong protoout[256];
59 ulong protopin[256];
60 ulong protopout[256];
61
62 void
63 error(char *s)
64 {
65         char buf[ERRMAX];
66
67         errstr(buf, sizeof buf);
68         fprint(2, "snoopy: %s %s\n", buf, s);
69         exits("death");
70 }
71
72 void
73 warning(char *s)
74 {
75         char buf[ERRMAX];
76
77         errstr(buf, sizeof buf);
78         fprint(2, "snoopy: %s %s\n", buf, s);
79 }
80
81 void
82 printproto(int p)
83 {
84         print("\t%d(%ld %ld %ld %ld)", p, protoin[p], protopin[p], protoout[p], protopout[p]);
85 }
86
87 void
88 main(int argc, char *argv[])
89 {
90         Etherpkt e;
91         Ippkt *ip;
92         long n;
93         int fd, cfd;
94         int ts, len, t;
95         long start;
96         int delta;
97         uchar target[6];
98         char buf[256];
99         ulong samples;
100
101         samples = -1;
102         ARGBEGIN{
103         case 'd':
104                 debug++;
105                 break;
106         case 's':
107                 samples = atoi(ARGF());
108                 break;
109         }ARGEND;
110
111         if(argc < 2){
112                 fprint(2, "usage: %s device ip-addr [minutes-per-sample]\n", argv0);
113                 exits("usage");
114         }
115         if(argc > 2)
116                 delta = atoi(argv[2])*60*1000;
117         else
118                 delta = 5*60*1000;
119         parseether(target, argv[1]);
120
121         fmtinstall('E', eipfmt);
122         fmtinstall('I', eipfmt);
123
124         snprint(buf, sizeof(buf), "%s!-2", argv[0]);
125         fd = dial(buf, 0, 0, &cfd);
126         if(fd < 0)
127                 error("opening ether data");
128         if(write(cfd, "promiscuous", sizeof("promiscuous")-1) <= 0)
129                 error("connecting");
130
131         start = 0;
132         fd = -1;
133
134         for(;;){
135                 if(fd < 0){
136                         fd = dial(buf, 0, 0, &cfd);
137                         if(fd < 0)
138                                 error("opening ether data");
139                         if(write(cfd, "promiscuous", sizeof("promiscuous")-1) <= 0)
140                                 error("connecting");
141                         close(cfd);
142                 }
143                 n = read(fd, &e, sizeof(e));
144                 if(n <= 0)
145                         break;
146                 ts = NetL(&e.d[60]);
147                 n = NetS(&e.d[58]) - ETHERHDRSIZE;
148                 if(n < 0)
149                         continue;
150                 if(start == 0)
151                         start = ts;
152                 t = NetS(e.type);
153                 if(t == 0x0800 || (t&0xFF00) == 0x1000){
154                         ip = (Ippkt*)e.data;
155                         len = NetS(ip->length);
156                         if(len > n)
157                                 len = n;
158                         if(debug)
159                                 fprint(2, "%I -> %I %d\n", ip->src, ip->dst, len);
160                         if(memcmp(e.s, target, 6) == 0){
161                                 protopin[0]++;
162                                 protoin[0] += len;
163                                 if(ip->proto){
164                                         protopin[ip->proto]++;
165                                         protoin[ip->proto] += len;
166                                 }
167                         }
168                         if(memcmp(e.d, target, 6) == 0){
169                                 protopout[0]++;
170                                 protoout[0] += len;
171                                 if(ip->proto){
172                                         protopout[ip->proto]++;
173                                         protoout[ip->proto] += len;
174                                 }
175                         }
176                 }
177                 if(ts - start >= delta){
178                         print("%8.8ld %ld", time(0), ts - start);
179                         printproto(0);
180                         printproto(IP_MBONEPROTO);
181                         printproto(IP_UDPPROTO);
182                         printproto(IP_TCPPROTO);
183                         print("\n");
184                         start = 0;
185                         memset(protoin, 0, sizeof(protoin));
186                         memset(protoout, 0, sizeof(protoout));
187                         memset(protopin, 0, sizeof(protopin));
188                         memset(protopout, 0, sizeof(protopout));
189                         close(fd);
190                         fd = -1;
191                         if(--samples == 0)
192                                 break;
193                 }
194         }
195         exits(0);
196 }