trace.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:7k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Packet tracing - top level and generic routines, including hex/ascii
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #include <time.h>
  7. #include "global.h"
  8. #include <stdarg.h>
  9. #include "mbuf.h"
  10. #include "iface.h"
  11. #include "pktdrvr.h"
  12. #include "commands.h"
  13. #include "trace.h"
  14. #include "session.h"
  15. static void ascii_dump(FILE *fp,struct mbuf **bpp);
  16. static void ctohex(char *buf,uint16 c);
  17. static void fmtline(FILE *fp,uint16 addr,uint8 *buf,uint16 len);
  18. void hex_dump(FILE *fp,struct mbuf **bpp);
  19. static void showtrace(struct iface *ifp);
  20. /* Redefined here so that programs calling dump in the library won't pull
  21.  * in the rest of the package
  22.  */
  23. static char nospace[] = "No space!!n";
  24. struct tracecmd Tracecmd[] = {
  25. "input", IF_TRACE_IN, IF_TRACE_IN,
  26. "-input", 0, IF_TRACE_IN,
  27. "output", IF_TRACE_OUT, IF_TRACE_OUT,
  28. "-output", 0, IF_TRACE_OUT,
  29. "broadcast", 0, IF_TRACE_NOBC,
  30. "-broadcast", IF_TRACE_NOBC, IF_TRACE_NOBC,
  31. "raw", IF_TRACE_RAW, IF_TRACE_RAW,
  32. "-raw", 0, IF_TRACE_RAW,
  33. "ascii", IF_TRACE_ASCII, IF_TRACE_ASCII|IF_TRACE_HEX,
  34. "-ascii", 0, IF_TRACE_ASCII|IF_TRACE_HEX,
  35. "hex", IF_TRACE_HEX, IF_TRACE_ASCII|IF_TRACE_HEX,
  36. "-hex", IF_TRACE_ASCII, IF_TRACE_ASCII|IF_TRACE_HEX,
  37. "off", 0, 0xffff,
  38. NULL, 0, 0
  39. };
  40. void
  41. dump(
  42. struct iface *ifp,
  43. int direction,
  44. struct mbuf *bp
  45. ){
  46. struct mbuf *tbp;
  47. uint16 size;
  48. time_t timer;
  49. char *cp;
  50. struct iftype *ift;
  51. FILE *fp;
  52. if(ifp == NULL || (ifp->trace & direction) == 0
  53.  || (fp = ifp->trfp) == NULL)
  54. return; /* Nothing to trace */
  55. ift = ifp->iftype;
  56. switch(direction){
  57. case IF_TRACE_IN:
  58. if((ifp->trace & IF_TRACE_NOBC)
  59.  && ift != NULL
  60.  && (ift->addrtest != NULL)
  61.  && (*ift->addrtest)(ifp,bp) == 0)
  62. return; /* broadcasts are suppressed */
  63. time(&timer);
  64. cp = ctime(&timer);
  65. cp[24] = '';
  66. fprintf(fp,"n%s - %s recv:n",cp,ifp->name);
  67. break;
  68. case IF_TRACE_OUT:
  69. time(&timer);
  70. cp = ctime(&timer);
  71. cp[24] = '';
  72. fprintf(fp,"n%s - %s sent:n",cp,ifp->name);
  73. break;
  74. }
  75. if(bp == NULL || (size = len_p(bp)) == 0){
  76. fprintf(fp,"empty packet!!n");
  77. return;
  78. }
  79. dup_p(&tbp,bp,0,size);
  80. if(tbp == NULL){
  81. fprintf(fp,nospace);
  82. return;
  83. }
  84. if(ift != NULL && ift->trace != NULL)
  85. (*ift->trace)(fp,&tbp,1);
  86. if(ifp->trace & IF_TRACE_ASCII){
  87. /* Dump only data portion of packet in ascii */
  88. ascii_dump(fp,&tbp);
  89. } else if(ifp->trace & IF_TRACE_HEX){
  90. /* Dump entire packet in hex/ascii */
  91. free_p(&tbp);
  92. dup_p(&tbp,bp,0,len_p(bp));
  93. if(tbp != NULL)
  94. hex_dump(fp,&tbp);
  95. else
  96. fprintf(fp,nospace);
  97. }
  98. free_p(&tbp);
  99. }
  100. /* Dump packet bytes, no interpretation */
  101. void
  102. raw_dump(ifp,direction,bp)
  103. struct iface *ifp;
  104. int direction;
  105. struct mbuf *bp;
  106. {
  107. struct mbuf *tbp;
  108. FILE *fp;
  109. if((fp = ifp->trfp) == NULL)
  110. return;
  111. fprintf(fp,"n******* raw packet dump (%s)n",
  112.  ((direction & IF_TRACE_OUT) ? "send" : "recv"));
  113. dup_p(&tbp,bp,0,len_p(bp));
  114. if(tbp != NULL)
  115. hex_dump(fp,&tbp);
  116. else
  117. fprintf(fp,nospace);
  118. fprintf(fp,"*******n");
  119. free_p(&tbp);
  120. }
  121. /* Dump an mbuf in hex */
  122. void
  123. hex_dump(fp,bpp)
  124. FILE *fp;
  125. register struct mbuf **bpp;
  126. {
  127. uint16 n;
  128. uint16 address;
  129. uint8 buf[16];
  130. if(bpp == NULL || *bpp == NULL || fp == NULL)
  131. return;
  132. address = 0;
  133. while((n = pullup(bpp,buf,sizeof(buf))) != 0){
  134. fmtline(fp,address,buf,n);
  135. address += n;
  136. }
  137. }
  138. /* Dump an mbuf in ascii */
  139. static void
  140. ascii_dump(fp,bpp)
  141. FILE *fp;
  142. register struct mbuf **bpp;
  143. {
  144. int c;
  145. register uint16 tot;
  146. if(bpp == NULL || *bpp == NULL || fp == NULL)
  147. return;
  148. tot = 0;
  149. while((c = PULLCHAR(bpp)) != -1){
  150. if((tot % 64) == 0)
  151. fprintf(fp,"%04x  ",tot);
  152. putc(isprint(c) ? c : '.',fp);
  153. if((++tot % 64) == 0)
  154. fprintf(fp,"n");
  155. }
  156. if((tot % 64) != 0)
  157. fprintf(fp,"n");
  158. }
  159. /* Print a buffer up to 16 bytes long in formatted hex with ascii
  160.  * translation, e.g.,
  161.  * 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f  0123456789:;<=>?
  162.  */
  163. static void
  164. fmtline(fp,addr,buf,len)
  165. FILE *fp;
  166. uint16 addr;
  167. uint8 *buf;
  168. uint16 len;
  169. {
  170. char line[80];
  171. char *aptr,*cptr;
  172. uint8 c;
  173. memset(line,' ',sizeof(line));
  174. ctohex(line,(uint16)hibyte(addr));
  175. ctohex(line+2,(uint16)lobyte(addr));
  176. aptr = &line[6];
  177. cptr = &line[55];
  178. while(len-- != 0){
  179. c = *buf++;
  180. ctohex(aptr,(uint16)c);
  181. aptr += 3;
  182. *cptr++ = isprint(c) ? c : '.';
  183. }
  184. *cptr++ = 'n';
  185. fwrite(line,1,(unsigned)(cptr-line),fp);
  186. }
  187. /* Convert byte to two ascii-hex characters */
  188. static void
  189. ctohex(buf,c)
  190. register char *buf;
  191. register uint16 c;
  192. {
  193. static char hex[] = "0123456789abcdef";
  194. *buf++ = hex[hinibble(c)];
  195. *buf = hex[lonibble(c)];
  196. }
  197. /* Modify or displace interface trace flags */
  198. int
  199. dotrace(argc,argv,p)
  200. int argc;
  201. char *argv[];
  202. void *p;
  203. {
  204. struct iface *ifp;
  205. struct tracecmd *tp;
  206. struct session *sp;
  207. if(argc < 2){
  208. for(ifp = Ifaces; ifp != NULL; ifp = ifp->next)
  209. showtrace(ifp);
  210. return 0;
  211. }
  212. if((ifp = if_lookup(argv[1])) == NULL){
  213. printf("Interface %s unknownn",argv[1]);
  214. return 1;
  215. }
  216. if(argc == 2){
  217. showtrace(ifp);
  218. return 0;
  219. }
  220. /* MODIFY THIS TO HANDLE MULTIPLE OPTIONS */
  221. if(argc >= 3){
  222. for(tp = Tracecmd;tp->name != NULL;tp++)
  223. if(strncmp(tp->name,argv[2],strlen(argv[2])) == 0)
  224. break;
  225. if(tp->name != NULL)
  226. ifp->trace = (ifp->trace & ~tp->mask) | tp->val;
  227. else
  228. ifp->trace = htoi(argv[2]);
  229. }
  230. if(ifp->trfp != NULL){
  231. /* Close existing trace file */
  232. fclose(ifp->trfp);
  233. ifp->trfp = NULL;
  234. }
  235. if(argc >= 4){
  236. if((ifp->trfp = fopen(argv[3],APPEND_TEXT)) == NULL){
  237. printf("Can't write to %sn",argv[3]);
  238. }
  239. } else if(ifp->trace != 0){
  240. /* Create trace session */
  241. sp = newsession(Cmdline,ITRACE,1);
  242. sp->cb.p = NULL;
  243. sp->proc = sp->proc1 = sp->proc2 = NULL;
  244. ifp->trfp = sp->output;
  245. showtrace(ifp);
  246. getchar(); /* Wait for the user to hit something */
  247. ifp->trace = 0;
  248. ifp->trfp = NULL;
  249. freesession(sp);
  250. }
  251. return 0;
  252. }
  253. /* Display the trace flags for a particular interface */
  254. static void
  255. showtrace(ifp)
  256. register struct iface *ifp;
  257. {
  258. char *cp;
  259. if(ifp == NULL)
  260. return;
  261. printf("%s:",ifp->name);
  262. if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT | IF_TRACE_RAW)){
  263. if(ifp->trace & IF_TRACE_IN)
  264. printf(" input");
  265. if(ifp->trace & IF_TRACE_OUT)
  266. printf(" output");
  267. if(ifp->trace & IF_TRACE_NOBC)
  268. printf(" - no broadcasts");
  269. if(ifp->trace & IF_TRACE_HEX)
  270. printf(" (Hex/ASCII dump)");
  271. else if(ifp->trace & IF_TRACE_ASCII)
  272. printf(" (ASCII dump)");
  273. else
  274. printf(" (headers only)");
  275. if(ifp->trace & IF_TRACE_RAW)
  276. printf(" Raw output");
  277. if(ifp->trfp != NULL && (cp = fpname(ifp->trfp)) != NULL)
  278. printf(" trace file: %s",cp);
  279. printf("n");
  280. } else
  281. printf(" tracing offn");
  282. }
  283. /* shut down all trace files */
  284. void
  285. shuttrace()
  286. {
  287. struct iface *ifp;
  288. for(ifp = Ifaces; ifp != NULL; ifp = ifp->next){
  289. fclose(ifp->trfp);
  290. ifp->trfp = NULL;
  291. }
  292. }
  293. /* Log messages of the form
  294.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  295.  */
  296. void
  297. trace_log(struct iface *ifp,char *fmt, ...)
  298. {
  299. va_list ap;
  300. char *cp;
  301. long t;
  302. FILE *fp;
  303. if((fp = ifp->trfp) == NULL)
  304. return;
  305. time(&t);
  306. cp = ctime(&t);
  307. rip(cp);
  308. fprintf(fp,"%s - ",cp);
  309. va_start(ap,fmt);
  310. vfprintf(fp,fmt,ap);
  311. va_end(ap);
  312. fprintf(fp,"n");
  313. }
  314. int
  315. tprintf(struct iface *ifp,char *fmt, ...)
  316. {
  317. va_list ap;
  318. int ret = 0;
  319. if(ifp->trfp == NULL)
  320. return -1; 
  321. va_start(ap,fmt);
  322. ret = vfprintf(ifp->trfp,fmt,ap);
  323. va_end(ap);
  324. return ret;
  325. }