measure.c 3.6 KB

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