|
|
1.1 root 1: #include <stdio.h>
2: #include <sys/param.h>
3: #include <sys/stream.h>
4: #include <sys/inet/in.h>
5: #define KERNEL 1 /* get kernel definitions */
6: #include <sys/inet/tcp.h>
7: #include <sys/inet/socket.h>
8: #include <sys/inet/udp.h>
9: #include <sys/inet/ip_var.h>
10: #include <sys/inet/tcp_timer.h>
11: #define TCPSTATES 1
12: #include <sys/inet/tcp_fsm.h>
13: #include <sys/inet/tcp_var.h>
14: #include <sys/inet/tcpdebug.h>
15:
16: static int strip = 0; /* true if we're stripping the high bit from kernel addrs */
17:
18: /* predeclared */
19: doseek();
20: void doseekoff();
21: void doread();
22:
23: main(argc, argv)
24: char *argv[];
25: {
26: char *xinu, *kmem;
27:
28: xinu = "/unix";
29: kmem = "/dev/kmem";
30:
31: if(argc > 3)
32: kmem = argv[3];
33: if(argc > 2)
34: xinu = argv[2];
35: kern_init(xinu, kmem);
36:
37: if(argc < 2) {
38: tcps(0);
39: udps();
40: }
41: else if(strcmp(argv[1], "-i") == 0)
42: interfaces();
43: else if(strcmp(argv[1], "-s") == 0)
44: statistics();
45: else if(strcmp(argv[1], "-r") == 0)
46: routes();
47: else if(strcmp(argv[1], "-a") == 0)
48: arps();
49: else if(strcmp(argv[1], "-c") == 0) {
50: tcps(0);
51: udps();
52: }
53: else if(strcmp(argv[1], "-C") == 0)
54: tcps(1);
55: else if(strcmp(argv[1], "-t") == 0)
56: debugtcp();
57: else
58: fprintf(stderr, "Usage: %s -icCrat [unix [vmcore]]\n", argv[0]);
59: }
60:
61: #include "nlist.h"
62: struct nlist nl[] = {
63: {"_ipif", 0},
64: #define NL_INET 0
65: {"_ipstat", 0},
66: #define NL_IPSTAT 1
67: {"_tcpstat", 0},
68: #define NL_TCPSTAT 2
69: {"_Ntcp", 0},
70: #define NL_NTCP 3
71: {"_tcpsocks", 0},
72: #define NL_TCP 4
73: {"_ip_routes", 0},
74: #define NL_ROUTE 5
75: {"_ip_arps", 0},
76: #define NL_ARP 6
77: {"_Ninet", 0},
78: #define NL_NINET 7
79: {"_Nip_route", 0},
80: #define NL_NROUTE 8
81: {"_Nip_arp", 0},
82: #define NL_NARP 9
83: {"_ip_default_route", 0},
84: #define NL_DR 10
85: {"_bugarr", 0},
86: #define NL_TCPDEB 11
87: {"_Nbugarr", 0},
88: #define NL_NBUGARR 12
89: {"_Nudp", 0},
90: #define NL_NUDP 13
91: {"_udpconn", 0},
92: #define NL_UDP 14
93: {0, 0}
94: };
95: int kern_fd;
96:
97: kern_init(xinu, kmem)
98: char *xinu, *kmem;
99: {
100: int i;
101: nlist(xinu, nl);
102: if((long)nl[0].n_value == 0){
103: fprintf(stderr, "nlist %s failed\n", xinu);
104: exit(1);
105: }
106: if(strcmp(kmem, "/dev/kmem") != 0){
107: for(i = 0; nl[i].n_name; i++){
108: nl[i].n_value &= 0xffffff;
109: }
110: strip = 1;
111: }
112: kern_fd = open(kmem, 0);
113: if(kern_fd < 0){
114: perror(kmem);
115: exit(1);
116: }
117: }
118:
119: interfaces()
120: {
121: extern char *xflags();
122: struct ipif ipif[128];
123: int i, ninet;
124:
125: if (doseek(NL_NINET) < 0) {
126: printf("Internet not compiled into this kernel\n");
127: return;
128: }
129: doread((char *)&ninet, sizeof ninet);
130: if (ninet > (sizeof(ipif)/sizeof(struct ipif)))
131: ninet = sizeof(ipif)/sizeof(struct ipif);
132: printf("%-4s %-12s %-12s %5s %6s %6s %6s %6s\n",
133: "Mtu", "Network", "Address", "Flags",
134: "Ipkts", "Ierrs", "Opkts", "Oerrs");
135: doseek(NL_INET);
136: doread((char *)ipif, ninet*sizeof(struct ipif));
137: for(i = 0; i < ninet; i++){
138: if((ipif[i].flags&IFF_UP) == 0)
139: continue;
140: printf("%-4d %-12.12s ", ipif[i].mtu, in_host(ipif[i].that));
141: printf("%-12.12s %5s %6d %6d %6d %6d\n",
142: in_host(ipif[i].thishost),
143: xflags(ipif[i].flags, "UHA?", " "),
144: ipif[i].ipackets, ipif[i].ierrors,
145: ipif[i].opackets, ipif[i].oerrors);
146: }
147: }
148:
149: statistics()
150: {
151: struct ipstat stats;
152: struct tcpstat tcpstat;
153:
154: if (doseek(NL_IPSTAT) < 0) {
155: printf("Internet not compiled into this kernel\n");
156: return;
157: }
158: doread((char *)&stats, sizeof(stats));
159: printf("IP:\n");
160: printf("%6d bad sums\n", stats.ips_badsum);
161: printf("%6d short packets\n", stats.ips_tooshort);
162: printf("%6d short data\n", stats.ips_toosmall);
163: printf("%6d bad header lengths\n", stats.ips_badhlen);
164: printf("%6d real bad header lengths\n", stats.ips_badlen);
165: printf("%6d queue overflows\n", stats.ips_qfull);
166: printf("%6d output routing errors\n", stats.ips_route);
167: printf("%6d fragmented packets\n", stats.ips_fragout);
168: if (doseek(NL_TCPSTAT) < 0) {
169: printf("Tcp not compiled into this kernel\n");
170: return;
171: }
172: doread((char *)&tcpstat, sizeof(tcpstat));
173: printf("TCP:\n");
174: printf("%6d bad sums\n", tcpstat.tcps_badsum);
175: printf("%6d bad offsets\n", tcpstat.tcps_badoff);
176: printf("%6d header drops\n", tcpstat.tcps_hdrops);
177: printf("%6d bad segments\n", tcpstat.tcps_badsegs);
178: printf("%6d retransmit timeouts\n", tcpstat.tcps_timeouts[0]);
179: printf("%6d persist timeouts\n", tcpstat.tcps_timeouts[1]);
180: printf("%6d keep-alive timeouts\n", tcpstat.tcps_timeouts[2]);
181: printf("%6d quiet time timeouts\n", tcpstat.tcps_timeouts[3]);
182: printf("%6d duplicate packets received\n", tcpstat.tcps_duplicates);
183: printf("%6d possibly late packets received\n", tcpstat.tcps_delayed);
184: }
185:
186: tcps(flag)
187: {
188: int i, ntcp;
189: struct socket so;
190: struct tcpcb tcpcb;
191: extern char *xflags();
192: char b1[100], b2[100];
193: struct in_service *sp;
194: #define SS_INTERESTING (SS_RCVATMARK|SS_OPEN|SS_ACTIVE|SS_WAITING|SS_PLEASEOPEN)
195:
196: if (doseek(NL_NTCP) < 0) {
197: printf("Tcp not compiled into this kernel\n");
198: return;
199: }
200: doread((char *)&ntcp, sizeof ntcp);
201: printf("Proto Dev Wque Rque State %18s %18s %14s\n",
202: "Remote Addr", "Local Addr", "Cstate");
203: for(i = 0; i < ntcp; i++){
204: doseekoff(NL_TCP, sizeof(so)*i);
205: doread((char *)&so, sizeof(so));
206: if((so.so_state&SS_INTERESTING) == 0)
207: continue;
208: if(so.so_tcpcb){
209: if(strip)
210: so.so_tcpcb =
211: (struct tcpcb *)((int)(so.so_tcpcb)&0xffffff);
212: lseek(kern_fd, so.so_tcpcb, 0);
213: doread((char *)&tcpcb, sizeof(tcpcb));
214: } else {
215: tcpcb.t_state = 0;
216: }
217: sp = in_service(0, "tcp", so.so_fport);
218: sprintf(b1, "%.11s.%.6s", in_host(so.so_faddr), sp->name);
219: sp = in_service(0, "tcp", so.so_lport);
220: sprintf(b2, "%.11s.%.6s", in_host(so.so_laddr), sp->name);
221: if(!flag || tcpcb.t_state != TCPS_LISTEN)
222: printf(" tcp %02d %4d %4d %5s %18.18s %18.18s %14s\n",
223: so.so_dev,
224: so.so_wcount, so.so_rcount,
225: xflags(so.so_state, "OPRWA?", " "),
226: b1, b2,
227: tcpstates[tcpcb.t_state]);
228: #ifdef ALL
229: if(!flag || tcpcb.t_state != TCPS_LISTEN)
230: printf("template %x\n", tcpcb.t_template);
231: #endif
232: if(flag && tcpcb.t_state != TCPS_LISTEN){
233: printf(" Timers:\n");
234: printf("\tretransmit %d\n\tpersist %d\n\tkeepalive %d\n\t2msl %d\n",
235: tcpcb.t_timer[0], tcpcb.t_timer[1],
236: tcpcb.t_timer[2], tcpcb.t_timer[3]);
237: printf(" Send sequence variables:");
238: printf("\n\tunacked %d\n\tnext %d\n\turgent ptr %d",
239: tcpcb.snd_una, tcpcb.snd_nxt, tcpcb.snd_up);
240: printf("\n\tinitial number %d\n\twindow %d\n\thighest sent %d\n",
241: tcpcb.iss, tcpcb.snd_wnd, tcpcb.snd_max);
242: printf(" Receive sequence variables:");
243: printf("\n\tnext %d\n\turgent ptr %d",
244: tcpcb.rcv_nxt, tcpcb.rcv_up);
245: printf("\n\tinitial number %d\n\twindow %d\n\tadvertised %d\n",
246: tcpcb.irs, tcpcb.rcv_wnd, tcpcb.rcv_adv);
247: printf(" Transmit timing:");
248: printf("\n\tinactive %d\n\tround trip %d\n\tseq # timed %d\n\tsmoothed round trip %f\n",
249: tcpcb.t_idle, tcpcb.t_rtt, tcpcb.t_rtseq,
250: tcpcb.t_srtt);
251: printf(" Status:");
252: printf("\n\tmax segment size %d", tcpcb.t_maxseg);
253: printf("\n\tforcing out byte %d", tcpcb.t_force);
254: printf("\n\tflags 0x%x\n", tcpcb.t_flags);
255: printf("\n");
256: }
257: }
258: }
259:
260: udps()
261: {
262: int i, nudp;
263: struct udp udp[132];
264: extern char *xflags();
265: char b1[100], b2[100];
266: struct in_service *sp;
267:
268: if (doseek(NL_NUDP) < 0) {
269: printf("Udp not compiled into this kernel\n");
270: return;
271: }
272: doread((char *)&nudp, sizeof nudp);
273: printf("\nProto Dev State %18s %18s\n",
274: "Remote Addr", "Local Addr");
275: doseek(NL_UDP);
276: doread((char *)udp, nudp*sizeof(struct udp));
277: for (i = 0; i < nudp; i++) {
278: if(udp[i].rq == 0)
279: continue;
280: sp = in_service(0, "udp", udp[i].sport);
281: sprintf(b1, "%.11s.%.6s", in_host(udp[i].src), sp->name);
282: sp = in_service(0, "udp", udp[i].dport);
283: sprintf(b2, "%.11s.%.6s", in_host(udp[i].dst), sp->name);
284: printf(" udp %02d %5s %18.18s %18.18s\n",
285: i, xflags(udp[i].flags, "ILC?", " "),
286: b2, b1);
287: }
288: }
289:
290: char *
291: xflags(fl, fs, buf)
292: char *fs, *buf;
293: {
294: int i, len;
295: char *os;
296:
297: os = buf;
298: len = strlen(fs);
299: for(i = 0; i < len; i++){
300: if(fl & (1<<i))
301: *buf++ = fs[i];
302: }
303: *buf++ = '\0';
304: return(os);
305: }
306:
307: routes()
308: {
309: struct ip_route r[256];
310: int i;
311: int nroute;
312:
313: doseek(NL_DR);
314: doread((char *)r, sizeof(struct ip_route));
315: if (r[0].gate != 0)
316: printf("Default route is %-14.14s\n\n", in_host(r[0].gate));
317: doseek(NL_NROUTE);
318: doread((char *)&nroute, sizeof nroute);
319: if (nroute > (sizeof(r)/sizeof(struct ip_route)))
320: nroute = sizeof(r)/sizeof(struct ip_route);
321: doseek(NL_ROUTE);
322: doread((char *)r, nroute*sizeof(struct ip_route));
323: printf("%-14s %-14s\n", "Destination", "Gateway");
324: for(i = 0; i < nroute; i++){
325: if(r[i].dst){
326: printf("%-14.14s ", in_host(r[i].dst));
327: printf("%-14.14s\n", in_host(r[i].gate));
328: }
329: }
330: }
331:
332: arps()
333: {
334: struct ip_arp a[256];
335: int i, j, narp;
336:
337: if (doseek(NL_NARP) < 0) {
338: printf("Arp not compiled into this kernel\n");
339: return;
340: }
341: doread((char *)&narp, sizeof narp);
342: if (narp > (sizeof(a)/sizeof(struct ip_arp)))
343: narp = sizeof(a)/sizeof(struct ip_arp);
344: doseek(NL_ARP);
345: doread((char *)a, narp*sizeof(struct ip_arp));
346: printf("%-10.10s Ether-Address\n", "Host");
347: for(i = 0; i < narp; i++){
348: if(a[i].inaddr){
349: printf("%-10.10s ", in_host(a[i].inaddr));
350: for(j = 0; j < 6; j++){
351: printf("%02x ", a[i].enaddr[j]);
352: }
353: printf("\n");
354: }
355: }
356: }
357:
358: debugtcp()
359: {
360: struct tcpdebug loc_bugarr[SIZDEBUG];
361: int last, inc, newlast, todo;
362: time_t savtim, oldtim;
363: char *io;
364:
365: printf("qInd In/Out Seq No Ack No sPort dPort Window Flags\n\n");
366: last = -1;
367: newlast = 0;
368: oldtim = 0;
369:
370: /*
371: Forever, do the following: read the tcp debug array (bugarr), find
372: the youngest entry, check to make sure this last entry is not in the
373: same position in the debug queue as the last time the check was made
374: (if it is the same position, check to see if the time stamps are
375: different because exactly SIZDEBUG entries may have been made), and
376: print out all the entries from the oldest to this youngest. Note that
377: before printing the entries from the header, they have to be converted
378: from network order to host order.
379: */
380:
381: while (1) {
382: if (doseek(NL_TCPDEB) < 0) {
383: printf("Tcp debugging not compiled into this kernel\n");
384: return;
385: }
386: doread((char *)loc_bugarr, sizeof(loc_bugarr));
387: savtim = 0;
388: inc = 0;
389: while (inc < SIZDEBUG) {
390: if (loc_bugarr[inc].stamp > savtim) {
391: savtim = loc_bugarr[inc].stamp;
392: newlast = inc;
393: }
394: inc++;
395: }
396: if (last == -1) last = newlast; /* first time thru this process */
397: if ((last != newlast || oldtim != savtim) && (savtim > 0)) {
398: if ((todo = newlast - last) < 0)
399: todo = SIZDEBUG - (last - newlast);
400: else if (todo == 0)
401: todo = SIZDEBUG;
402: inc = (last + 1) % SIZDEBUG;
403: while (todo) {
404: if (loc_bugarr[inc].inout == 0)
405: io = "in";
406: else
407: io = "out";
408: printf("%4d %3s %10d %10d %5d %5d %5d %x\n",
409: inc, io,
410: ntohl(loc_bugarr[inc].savhdr.th_seq),
411: ntohl(loc_bugarr[inc].savhdr.th_ack),
412: ntohs(loc_bugarr[inc].savhdr.th_sport),
413: ntohs(loc_bugarr[inc].savhdr.th_dport),
414: ntohs(loc_bugarr[inc].savhdr.th_win),
415: ntohs(loc_bugarr[inc].savhdr.th_flags));
416: inc = (inc + 1) % SIZDEBUG;
417: todo--;
418: } /* end while there are more packets to print out */
419: printf("\n");
420: fflush(stdout);
421: } /* end if packets came in since the last check */
422: last = newlast;
423: oldtim = savtim;
424: sleep (1);
425: } /* end while forever */
426: } /* end procedure debugtcp */
427:
428: doseek(nlitem)
429: unsigned int nlitem;
430: {
431: if (nl[nlitem].n_value == 0)
432: return -1;
433: if(lseek(kern_fd, (long)nl[nlitem].n_value, 0) == -1){
434: perror("seek");
435: exit(1);
436: }
437: return 0;
438: }
439:
440: void
441: doseekoff(nlitem, offset)
442: unsigned int nlitem;
443: unsigned int offset;
444: {
445: if(lseek(kern_fd, (long)(nl[nlitem].n_value+offset), 0) == -1){
446: perror("seek");
447: exit(1);
448: }
449: }
450:
451: void
452: doread(addr, size)
453: char *addr;
454: unsigned int size;
455: {
456: if(read(kern_fd, addr, size) < 0){
457: perror("read");
458: exit(1);
459: }
460: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.