|
|
1.1 root 1: #include <values.h>
2: #include <stdio.h>
3: #include <sys/param.h>
4: #include <sys/stream.h>
5: #include <sys/inet/in.h>
6: #define KERNEL 1 /* get kernel definitions */
7: #include <sys/inet/tcp.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/tcpip.h>
15: #include <sys/inet/tcpdebug.h>
16: #include <sys/ethernet.h>
17: #include <sys/inet/udp_var.h>
18:
19: static int strip = 0; /* true if we're stripping the high bit from kernel addrs */
20: static int numeric = 0;
21:
22: /* predeclared */
23: doseek();
24: void doseekoff();
25: void doread();
26: char *inettoascii();
27:
28: main(argc, argv)
29: char *argv[];
30: {
31: char *xinu, *kmem;
32: int c;
33: int action;
34: char *operand;
35: extern char *optarg;
36: extern int optind;
37:
38: xinu = "/unix";
39: kmem = "/dev/kmem";
40:
41: action = 'c';
42: while((c = getopt(argc, argv, "CRacinrst:")) != -1) {
43: switch(c){
44: case 'C':
45: case 'R':
46: case 'a':
47: case 'c':
48: case 'i':
49: case 'r':
50: case 's':
51: action = c;
52: break;
53: case 'n':
54: numeric = 1;
55: break;
56: case 't':
57: action = c;
58: operand = optarg;
59: break;
60: default:
61: fprintf(stderr, "Usage: %s -CRacinrst [unix [vmcore]]\n", argv[0]);
62: break;
63: }
64: }
65: if (argc > optind+1)
66: xinu = argv[optind++];
67: if (argc > optind)
68: kmem = argv[optind];
69: kern_init(xinu, kmem);
70:
71: switch(action) {
72: case '\0':
73: case 'c':
74: tcps(0);
75: udps();
76: break;
77: case 'n':
78: numeric = 1;
79: break;
80: case 'i':
81: interfaces();
82: break;
83: case 's':
84: statistics();
85: break;
86: case 'r':
87: routes(0);
88: break;
89: case 'R':
90: routes(1);
91: break;
92: case 'a':
93: arps();
94: break;
95: case 'C':
96: tcps(1);
97: break;
98: case 't':
99: if (*operand == '\0' || strcmp(operand, "tcp")==0)
100: debugtcp();
101: else if (strcmp(operand, "il")==0)
102: debugil();
103: else if (strcmp(operand, "qe")==0)
104: debugqe();
105: break;
106: default:
107: fprintf(stderr, "Usage: %s -icCrat [unix [vmcore]]\n", argv[0]);
108: break;
109: }
110: }
111:
112: /*
113: * truncate name to rightmost n chars
114: */
115: trunc(name, n)
116: char *name;
117: int n;
118: {
119: register int i=strlen(name);
120:
121: return ((i<=n) ? name : name+(i-n));
122: }
123:
124:
125: #include "nlist.h"
126: struct nlist nl[] = {
127: {"_ipif", 0},
128: #define NL_INET 0
129: {"_ipstat", 0},
130: #define NL_IPSTAT 1
131: {"_tcpstat", 0},
132: #define NL_TCPSTAT 2
133: {"_tcpcnt", 0},
134: #define NL_NTCP 3
135: {"_tcpcb", 0},
136: #define NL_TCP 4
137: {"_ip_routes", 0},
138: #define NL_ROUTE 5
139: {"_ip_arps", 0},
140: #define NL_ARP 6
141: {"_ipcnt", 0},
142: #define NL_NINET 7
143: {"_Nip_route", 0},
144: #define NL_NROUTE 8
145: {"_arpcnt", 0},
146: #define NL_NARP 9
147: {"_ip_default_route", 0},
148: #define NL_DR 10
149: {"_bugarr", 0},
150: #define NL_TCPDEB 11
151: {"_Nbugarr", 0},
152: #define NL_NBUGARR 12
153: {"_udpcnt", 0},
154: #define NL_NUDP 13
155: {"_udpconn", 0},
156: #define NL_UDP 14
157: {"_ild", 0},
158: #define NL_ILDEB 15
159: {"_qed", 0},
160: #define NL_QEDEB 16
161: {"_udpstat", 0},
162: #define NL_UDPSTAT 17
163: {0, 0}
164: };
165: int kern_fd;
166:
167: kern_init(xinu, kmem)
168: char *xinu, *kmem;
169: {
170: int i;
171: nlist(xinu, nl);
172: if((long)nl[0].n_value == 0){
173: fprintf(stderr, "nlist %s failed\n", xinu);
174: exit(1);
175: }
176: if(strcmp(kmem, "/dev/kmem") != 0){
177: for(i = 0; nl[i].n_name; i++){
178: nl[i].n_value &= 0xffffff;
179: }
180: strip = 1;
181: }
182: kern_fd = open(kmem, 0);
183: if(kern_fd < 0){
184: perror(kmem);
185: exit(1);
186: }
187: }
188:
189: interfaces()
190: {
191: extern char *xflags();
192: struct ipif ipif[128];
193: int i, ninet;
194:
195: if (doseek(NL_NINET) < 0) {
196: printf("Internet not compiled into this kernel\n");
197: return;
198: }
199: doread((char *)&ninet, sizeof ninet);
200: if (ninet > (sizeof(ipif)/sizeof(struct ipif)))
201: ninet = sizeof(ipif)/sizeof(struct ipif);
202: printf("%-4s %-24s %-15s %5s %6s %6s %6s %6s\n",
203: "Mtu", "Network&Mask", "Address", "Flags",
204: "Ipkts", "Ierrs", "Opkts", "Oerrs");
205: doseek(NL_INET);
206: doread((char *)ipif, ninet*sizeof(struct ipif));
207: for(i = 0; i < ninet; i++){
208: if((ipif[i].flags&IFF_UP) == 0)
209: continue;
210: printf("%-4d %-15.15s&%x ", ipif[i].mtu, inettoascii(ipif[i].that), ipif[i].mask);
211: printf("%-15.15s %5s %6d %6d %6d %6d\n",
212: inettoascii(ipif[i].thishost),
213: xflags(ipif[i].flags, "UHA?", " "),
214: ipif[i].ipackets, ipif[i].ierrors,
215: ipif[i].opackets, ipif[i].oerrors);
216: }
217: }
218:
219:
220: statistics()
221: {
222: struct ipstat stats;
223: struct tcpstat tcpstat;
224:
225: if (doseek(NL_IPSTAT) < 0) {
226: printf("Internet not compiled into this kernel\n");
227: return;
228: }
229: doread((char *)&stats, sizeof(stats));
230: printf("IP:\n");
231: printf("%6d bad sums\n", stats.ips_badsum);
232: printf("%6d short packets\n", stats.ips_tooshort);
233: printf("%6d short data\n", stats.ips_toosmall);
234: printf("%6d bad header lengths\n", stats.ips_badhlen);
235: printf("%6d real bad header lengths\n", stats.ips_badlen);
236: printf("%6d queue overflows\n", stats.ips_qfull);
237: printf("%6d output routing errors\n", stats.ips_route);
238: printf("%6d fragmented packets\n", stats.ips_fragout);
239: if (doseek(NL_TCPSTAT) < 0) {
240: printf("Tcp not compiled into this kernel\n");
241: return;
242: }
243: doread((char *)&tcpstat, sizeof(tcpstat));
244: printf("TCP:\n");
245: printf("%6d bad sums\n", tcpstat.tcps_badsum);
246: printf("%6d bad offsets\n", tcpstat.tcps_badoff);
247: printf("%6d header drops\n", tcpstat.tcps_hdrops);
248: printf("%6d bad segments\n", tcpstat.tcps_badsegs);
249: printf("%6d retransmit timeouts\n", tcpstat.tcps_timeouts[0]);
250: printf("%6d persist timeouts\n", tcpstat.tcps_timeouts[1]);
251: printf("%6d keep-alive timeouts\n", tcpstat.tcps_timeouts[2]);
252: printf("%6d quiet time timeouts\n", tcpstat.tcps_timeouts[3]);
253: printf("%6d duplicate packets received\n", tcpstat.tcps_duplicates);
254: printf("%6d possibly late packets received\n", tcpstat.tcps_delayed);
255: if (doseek(NL_UDPSTAT) < 0) {
256: printf("Udp not compiled into this kernel\n");
257: return;
258: }
259: doread((char *)&udpstat, sizeof(udpstat));
260: printf("UDP:\n");
261: printf("%6d bad sums\n", udpstat.udps_badsum);
262: printf("%6d bad length\n", udpstat.udps_badlen);
263: printf("%6d bad port\n", udpstat.udps_badport);
264: printf("%6d q overflows\n", udpstat.udps_inqfull);
265: printf("%6d input packets\n", udpstat.udps_ipackets);
266: }
267:
268: tcps(flag)
269: {
270: int i, ntcp;
271: struct tcpcb tcpcb;
272: extern char *xflags();
273: char b1[100], b2[100];
274: struct in_service *sp;
275:
276: if (doseek(NL_NTCP) < 0) {
277: printf("Tcp not compiled into this kernel\n");
278: return;
279: }
280: doread((char *)&ntcp, sizeof ntcp);
281: printf("Dev Wque Rque State %-22s %-22s %11s\n",
282: "Remote Addr", "Local Addr", "Cstate");
283: for(i = 0; i < ntcp; i++){
284: doseekoff(NL_TCP, sizeof(tcpcb)*i);
285: doread((char *)&tcpcb, sizeof(tcpcb));
286: if(tcpcb.t_state == TCPS_CLOSED)
287: continue;
288: sp = in_service(0, "tcp", tcpcb.so_fport);
289: sprintf(b1, "%.17s-%s", inettoascii(tcpcb.so_faddr), sp->name);
290: sp = in_service(0, "tcp", tcpcb.so_lport);
291: sprintf(b2, "%.17s-%s", inettoascii(tcpcb.so_laddr), sp->name);
292: if(!flag || tcpcb.t_state != TCPS_LISTEN)
293: printf("tcp%02d %4d %4d %5s %-22.22s %-22.22s %11s\n",
294: tcpcb.so_dev,
295: tcpcb.so_wcount, tcpcb.so_rcount,
296: xflags(tcpcb.so_state, "OPRWAHU?", " "),
297: b1, b2,
298: tcpstates[tcpcb.t_state]);
299: #ifdef ALL
300: if(!flag || tcpcb.t_state != TCPS_LISTEN)
301: printf("template %x\n", tcpcb.t_template);
302: #endif
303: if(flag && tcpcb.t_state != TCPS_LISTEN){
304: printf(" Timers:\n");
305: printf("\tretransmit %d\n\tpersist %d\n\tkeepalive %d\n\t2msl %d\n",
306: tcpcb.t_timer[0], tcpcb.t_timer[1],
307: tcpcb.t_timer[2], tcpcb.t_timer[3]);
308: printf(" Send sequence variables:");
309: printf("\n\tunacked %d\n\tnext %d\n\turgent ptr %d",
310: tcpcb.snd_una, tcpcb.snd_nxt, tcpcb.snd_up);
311: printf("\n\tinitial number %d\n\twindow %d\n\thighest sent %d\n",
312: tcpcb.iss, tcpcb.snd_wnd, tcpcb.snd_max);
313: printf(" Receive sequence variables:");
314: printf("\n\tnext %d\n\turgent ptr %d",
315: tcpcb.rcv_nxt, tcpcb.rcv_up);
316: printf("\n\tinitial number %d\n\twindow %d\n\tadvertised %d\n",
317: tcpcb.irs, tcpcb.rcv_wnd, tcpcb.rcv_adv);
318: printf(" Transmit timing:");
319: printf("\n\tinactive %d\n\tround trip %d\n\tseq # timed %d\n\tsmoothed round trip %f\n",
320: tcpcb.t_idle, tcpcb.t_rtt, tcpcb.t_rtseq,
321: tcpcb.t_srtt);
322: printf(" Status:");
323: printf("\n\tmax segment size %d", tcpcb.t_maxseg);
324: printf("\n\tforcing out byte %d", tcpcb.t_force);
325: printf("\n\tflags 0x%x\n", tcpcb.t_flags);
326: printf("\n");
327: }
328: }
329: }
330:
331: udps()
332: {
333: int i, nudp;
334: struct udp udp[132];
335: extern char *xflags();
336: char b1[100], b2[100];
337: struct in_service *sp;
338:
339: if (doseek(NL_NUDP) < 0) {
340: printf("Udp not compiled into this kernel\n");
341: return;
342: }
343: doread((char *)&nudp, sizeof nudp);
344: printf("\nDev State %-30s %-30s\n",
345: "Remote Addr", "Local Addr");
346: doseek(NL_UDP);
347: doread((char *)udp, nudp*sizeof(struct udp));
348: for (i = 0; i < nudp; i++) {
349: if(udp[i].rq == 0)
350: continue;
351: sp = in_service(0, "udp", udp[i].sport);
352: sprintf(b1, "%s-%.6s", inettoascii(udp[i].src), sp->name);
353: sp = in_service(0, "udp", udp[i].dport);
354: sprintf(b2, "%s-%.6s", inettoascii(udp[i].dst), sp->name);
355: printf("udp%02d %5s %-30.30s %-30.30s\n",
356: i, xflags(udp[i].flags, "ILC?", " "),
357: b2, b1);
358: }
359: }
360:
361: char *
362: xflags(fl, fs, buf)
363: char *fs, *buf;
364: {
365: int i, len;
366: char *os;
367:
368: os = buf;
369: len = strlen(fs);
370: for(i = 0; i < len; i++){
371: if(fl & (1<<i))
372: *buf++ = fs[i];
373: }
374: *buf++ = '\0';
375: return(os);
376: }
377:
378: routes(all)
379: int all;
380: {
381: struct ip_route r[256];
382: int i;
383: int nroute;
384:
385: doseek(NL_DR);
386: doread((char *)r, sizeof(struct ip_route));
387: if (r[0].gate != 0)
388: printf("Default route is %s\n\n", inettoascii(r[0].gate));
389: doseek(NL_NROUTE);
390: doread((char *)&nroute, sizeof nroute);
391: if (nroute > (sizeof(r)/sizeof(struct ip_route)))
392: nroute = sizeof(r)/sizeof(struct ip_route);
393: doseek(NL_ROUTE);
394: doread((char *)r, nroute*sizeof(struct ip_route));
395: printf("%-14s %-14s\n", "Destination", "Gateway");
396: for(i = 0; i < nroute; i++){
397: if(all || r[i].dst!=r[i].gate){
398: printf("%-14s ", inettoascii(r[i].dst));
399: printf("%-14s\n", inettoascii(r[i].gate));
400: }
401: }
402: }
403:
404: arps()
405: {
406: struct ip_arp a[256];
407: int i, j, narp;
408:
409: if (doseek(NL_NARP) < 0) {
410: printf("Arp not compiled into this kernel\n");
411: return;
412: }
413: doread((char *)&narp, sizeof narp);
414: if (narp > (sizeof(a)/sizeof(struct ip_arp)))
415: narp = sizeof(a)/sizeof(struct ip_arp);
416: doseek(NL_ARP);
417: doread((char *)a, narp*sizeof(struct ip_arp));
418: printf("%-11s Ether-Address\n", "Host");
419: for(i = 0; i < narp; i++){
420: if(a[i].inaddr){
421: printf("%-11s ", inettoascii(a[i].inaddr));
422: for(j = 0; j < 6; j++){
423: printf("%02x ", a[i].enaddr[j]);
424: }
425: printf("\n");
426: }
427: }
428: }
429:
430: #define NEXT(i) ((i+1)%SIZDEBUG)
431: #define PREV(i) ((i+SIZDEBUG-1)%SIZDEBUG)
432: #define HEADER\
433: "\ntime src dst seq bytes ack wind cksm urg flags\n"
434: #define FORMAT "%4d %c %8x.%-4d %8x.%-4d %8x %3x %8x %4x %04x %8x %s\n"
435:
436: debugtcp()
437: {
438: struct tcpdebug d[SIZDEBUG];
439: int i, lowi;
440: unsigned long low, high;
441: unsigned long lastlow = 0, lasthigh = 0;
442: time_t t, lastt = 0;
443: time_t base = 0;
444: int line = 0;
445: char *xflags();
446: char xbuf[9];
447:
448: for(;;) {
449: /* get array */
450: if (doseek(NL_TCPDEB) < 0) {
451: printf("Tcp debugging not compiled into this kernel\n");
452: return;
453: }
454: doread((char *)d, sizeof(d));
455:
456: /* find lowest sequence entry */
457: lowi = 0;
458: low = d[0].seq;
459: for (i = 1; i < SIZDEBUG; i++) {
460: if (d[i].seq < low) {
461: lowi = i;
462: low = d[i].seq;
463: }
464: }
465: if(low > lasthigh+1)
466: printf("** missing messages **\n");
467:
468: if (base == 0)
469: base = d[lowi].stamp;
470:
471: /* print all new entries */
472: i = lowi;
473: high = low;
474: for(;;) {
475: if(d[i].seq < lastlow || d[i].seq > lasthigh){
476: if ((line++ % 22) == 0)
477: printf(HEADER);
478: printf(FORMAT, d[i].stamp-base,
479: d[i].inout ? 'o' : 'i',
480: ntohl(d[i].hdr.ti_src),
481: ntohs(d[i].hdr.ti_sport),
482: ntohl(d[i].hdr.ti_dst),
483: ntohs(d[i].hdr.ti_dport),
484: ntohl(d[i].hdr.ti_seq),
485: ntohs(d[i].hdr.ti_len) - sizeof(struct tcphdr),
486: ntohl(d[i].hdr.ti_ack),
487: ntohs(d[i].hdr.ti_win),
488: ntohs(d[i].hdr.ti_sum),
489: ntohs(d[i].hdr.ti_urp),
490: xflags(d[i].hdr.ti_flags&0xff, "FSRPAU??",
491: xbuf)
492: );
493: }
494: if(d[i].seq > high)
495: high = d[i].seq;
496: i = NEXT(i);
497: if(i==lowi)
498: break;
499: }
500: lasthigh = high;
501: lastlow = low;
502: fflush(stdout);
503: sleep(1);
504: }
505: }
506:
507: #define QENRCV 30
508: #define QEDEBSIZE 64
509: #define QENEXT(i) ((i+1)%QEDEBSIZE)
510: #define QEPREV(i) ((i+QEDEBSIZE-1)%QEDEBSIZE)
511: #define QEHEADER\
512: "\n time src dst type sizes\n"
513: #define QEFORMAT "%7d %c %02x%02x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x %4x %x\n"
514:
515: #define ILDEBSIZE 64
516: #define ILNEXT(i) ((i+1)%ILDEBSIZE)
517: #define ILPREV(i) ((i+ILDEBSIZE-1)%ILDEBSIZE)
518: #define ILHEADER\
519: "\n time src dst type\n"
520: #define ILFORMAT "%7d %c %02x%02x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x %4x\n"
521:
522: debugil()
523: {
524: struct {
525: time_t time;
526: unsigned short code;
527: struct etherpup pup;
528: short len;
529: } d[ILDEBSIZE];
530: int i, lasti= 0;
531: time_t t, lastt = 0;
532: time_t base = 0;
533: int line = 0;
534: char *xflags();
535: char xbuf[9];
536:
537: for(;;) {
538: /* get array */
539: if (doseek(NL_ILDEB) < 0) {
540: printf("Interlan debugging not compiled into this kernel\n");
541: return;
542: }
543: doread((char *)d, sizeof(d));
544:
545: /* see if we've overflowed the buffer (or first time around) */
546: if (d[lasti].time != lastt) {
547: if (lastt != 0)
548: printf("** missing messages **\n");
549: /* find last(highest) timestamped entry */
550: for (i = ILNEXT(lasti); i != lasti; i = ILNEXT(i)) {
551: if (d[i].time < lastt) {
552: if (base == 0 || d[i].time < base)
553: base = d[i].time;
554: lasti = ILPREV(i);
555: lastt = 0; /* for start of next loop */
556: break;
557: }
558: lastt = d[i].time;
559: }
560: }
561:
562: /* print all new entries */
563: for (i = ILNEXT(lasti); i != lasti; i = ILNEXT(i)) {
564: if (d[i].time < lastt)
565: break;
566: if (d[i].time == 0)
567: continue;
568: if ((line++ % 22) == 0)
569: printf(ILHEADER);
570: if(d[i].code) {
571: printf(ILFORMAT, d[i].time-base, 'o',
572: 0, 0,
573: 0, 0,
574: 0, 0,
575: d[i].pup.dhost[0], d[i].pup.dhost[1],
576: d[i].pup.dhost[2], d[i].pup.dhost[3],
577: d[i].pup.dhost[4], d[i].pup.dhost[5],
578: (d[i].pup.shost[1]<<8) | d[i].pup.shost[0]
579: );
580: } else {
581: printf(ILFORMAT, d[i].time-base, 'i',
582: d[i].pup.shost[0], d[i].pup.shost[1],
583: d[i].pup.shost[2], d[i].pup.shost[3],
584: d[i].pup.shost[4], d[i].pup.shost[5],
585: d[i].pup.dhost[0], d[i].pup.dhost[1],
586: d[i].pup.dhost[2], d[i].pup.dhost[3],
587: d[i].pup.dhost[4], d[i].pup.dhost[5],
588: d[i].pup.type
589: );
590: }
591: lastt = d[i].time;
592: lasti = i;
593: }
594: fflush(stdout);
595: sleep(1);
596: }
597: }
598:
599: debugqe()
600: {
601: struct {
602: time_t time;
603: unsigned short code;
604: struct etherpup pup;
605: short len;
606: } d[QEDEBSIZE];
607: int i, j, lasti= 0;
608: time_t t, lastt = 0;
609: time_t base = 0;
610: int line = 0;
611: char *xflags();
612: char xbuf[9];
613:
614: for(;;) {
615: /* get array */
616: if (doseek(NL_QEDEB) < 0) {
617: printf("deqna/delqa debugging not compiled into this kernel\n");
618: return;
619: }
620: doread((char *)d, sizeof(d));
621:
622: /* see if we've overflowed the buffer (or first time around) */
623: if (d[lasti].time != lastt) {
624: if (lastt != 0)
625: printf("** missing messages **\n");
626: /* find last(highest) timestamped entry */
627: for (i = QENEXT(lasti); i != lasti; i = QENEXT(i)) {
628: if (base == 0 || d[i].time < base)
629: base = d[i].time;
630: if (d[i].time < lastt) {
631: lasti = QEPREV(i);
632: lastt = 0; /* for start of next loop */
633: break;
634: }
635: lastt = d[i].time;
636: }
637: }
638:
639: /* print all new entries */
640: for (i = QENEXT(lasti); i != lasti; i = QENEXT(i)) {
641: if (d[i].time < lastt)
642: break;
643: if (d[i].time == 0)
644: continue;
645: if ((line++ % 22) == 0)
646: printf(QEHEADER);
647: printf(QEFORMAT, d[i].time-base, d[i].code?'o':'i',
648: d[i].pup.shost[0], d[i].pup.shost[1],
649: d[i].pup.shost[2], d[i].pup.shost[3],
650: d[i].pup.shost[4], d[i].pup.shost[5],
651: d[i].pup.dhost[0], d[i].pup.dhost[1],
652: d[i].pup.dhost[2], d[i].pup.dhost[3],
653: d[i].pup.dhost[4], d[i].pup.dhost[5],
654: d[i].pup.type, d[i].len
655: );
656: lastt = d[i].time;
657: lasti = i;
658: }
659: fflush(stdout);
660: sleep(1);
661: }
662: }
663:
664: doseek(nlitem)
665: unsigned int nlitem;
666: {
667: if (nl[nlitem].n_value == 0)
668: return -1;
669: if(lseek(kern_fd, (long)nl[nlitem].n_value, 0) == -1){
670: perror("seek");
671: exit(1);
672: }
673: return 0;
674: }
675:
676: void
677: doseekoff(nlitem, offset)
678: unsigned int nlitem;
679: unsigned int offset;
680: {
681: if(lseek(kern_fd, (long)(nl[nlitem].n_value+offset), 0) == -1){
682: perror("seek");
683: exit(1);
684: }
685: }
686:
687: void
688: doread(addr, size)
689: char *addr;
690: unsigned int size;
691: {
692: if(read(kern_fd, addr, size) < 0){
693: perror("read");
694: exit(1);
695: }
696: }
697:
698: char *
699: inettoascii(inaddr)
700: long inaddr;
701: {
702: return numeric ? in_ntoa(inaddr) : in_host(inaddr);
703: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.