bing-1.1.3/0042755000076500007770000000000007137411511012244 5ustar mbabcockcodingbing-1.1.3/bing.c0100644000076500007770000012133206345720630013331 0ustar mbabcockcoding/* * Unofficial release 1.1.3 * B I N G * * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, * measure point-to-point bandwidth. * * Hack by Pierre Beyssac (pb@fasterix.freenix.fr), based on FreeBSD ping. * Comments and bug reports welcome ! * * Original ping author - * Mike Muuss * U. S. Army Ballistic Research Laboratory * December, 1983 * * * Copyright (c) 1995,1997 Pierre Beyssac. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Pierre Beyssac, * Mike Muss, the University of California, Berkeley and its contributors. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY PIERRE BEYSSAC AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ /* The original UCB copyright notice follows */ /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Mike Muuss. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #ifndef lint char copyright[] = "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ All rights reserved.\n"; #endif /* not lint */ #ifndef lint static char rcsid[] = "$Id: bing.c,v 1.17 1997/01/23 21:00:03 pb Exp $"; #endif /* not lint */ /* Usual includes/declarations */ #include #include #include #include #include /* More specific includes/declarations */ #include #include #include #include #ifdef WIN32 /* This variable is expected by getopt.c */ char* __progname; #else /* #include */ #include #include /* #include */ #include #include #include #endif /* WIN32 */ /* Network includes/definitions */ #ifdef WIN32 #define MAXHOSTNAMELEN 64 #include "win32/win32.h" #include #include "win32/types.h" #else #include #include #include #include #include #endif /* WIN32 */ /* These come either from the compatibility library or from the * standard libraries. */ #include #include #include #include "mod_icmp.h" /* System dependent apsects */ #ifdef NO_RANDOM #define random rand #define srandom srand #endif #ifdef NO_STRERROR int sys_nerr; char *sys_errlist[]; char *sys_unk = "Unknown error"; #define strerror(e) (((e)>=sys_nerr||(e)<0)?sys_unk:sys_errlist[(e)]) #endif #ifdef NO_SNPRINTF #define snprintf sprintf #define snfargs(str,size,format) str,format #else #ifdef WIN32 #define snprintf _snprintf #endif #define snfargs(str,size,format) str,size,format #endif #define ICMP_TO_DATA(icp) ((u_char *)((icp)->icmp_data)) /* * The default small packet size should be big enough that no padding * needs to be done at the physical level (ethernet typically requires this). * * The initial value was chosen to be 8 bytes, just enough to * contain a struct timeval, but it proved too small. The current value is * chosen to be around 40 bytes. If you add the IP and ICMP headers, that * should be more than the minimal ethernet packet size. * * 44 is nice because that's 64 bytes less than the other value, which * has not been changed. * * The default big packet size is not too big so as not to waste resources * unless the user explicitly chooses to. */ #define DEFDATALEN_SMALL 44 /* default small data len */ #define DEFDATALEN_BIG 108 /* default big data len */ #define MAXIPLEN 60 #define MAXICMPLEN 76 #define MAXPACKET (65536 - 60 - 8)/* max packet size */ #define MAXWAIT 10 /* max seconds to wait for response */ #define NROUTES 9 /* number of record route slots */ #define A(bit,tbl) (tbl)[(unsigned)(bit)>>3] /* identify byte in array */ #define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ #define SET(bit,tbl) (A(bit,(tbl)) |= B(bit)) #define CLR(bit,tbl) (A(bit,(tbl)) &= (~B(bit))) #define TST(bit,tbl) (A(bit,(tbl)) & B(bit)) /* various options */ int options; #define F_NODELTA 0x001 #define F_INTERVAL 0x002 #define F_NUMERIC 0x004 #define F_PINGFILLED 0x008 #define F_VVERBOSE 0x010 #define F_RROUTE 0x020 #define F_SO_DEBUG 0x040 #define F_SO_DONTROUTE 0x080 #define F_VERBOSE 0x100 #define F_RANDOMFILL 0x200 #define F_PEDANTIC 0x400 #define F_WARN 0x800 /* multicast options */ int moptions; #define MULTICAST_NOLOOP 0x001 #define MULTICAST_TTL 0x002 #define MULTICAST_IF 0x004 /* * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum * number of received sequence numbers we can keep track of. Change 128 * to 8192 for complete accuracy... */ #define MAX_DUP_CHK (8 * 128) unsigned short mx_dup_ck = MAX_DUP_CHK; typedef char duptable[MAX_DUP_CHK / 8]; unsigned short icmpseq = 0; /* Sequence number of last packet we sent */ int datalen_small = DEFDATALEN_SMALL; int datalen_big = DEFDATALEN_BIG; int datalen_step; int bits; /* From packet len, compute the index for the entry */ #define datalen_to_index(len) ((len) == datalen_big \ ? nts-1 \ : ((len)-datalen_small)/datalen_step) #define datalen_check(len) ((len) >= datalen_small \ && (len) <= datalen_big \ && (((len) == datalen_big \ || ((len)-datalen_small) % datalen_step == 0))) icmp_handle my_icmp; /* ICMP module handle */ u_char outpack[MAXPACKET]; /* counters */ long npackets = 1; /* max sampling loops */ long nsamples; /* max samples to take in a loop */ int maxwait = 4; /* max wait for reply packet (seconds) */ FILE *samplefile = NULL; /* timing */ struct dst { /* RTT statistics in ms */ double tmin; /* minimum */ double tmax; /* maximum */ double tsum; /* sum */ double tsum2; /* sum of squares */ long nsamples; /* number of samples */ }; #define dst_newsample(dst,s) { \ if ((s) < (dst)->tmin) (dst)->tmin = (s); \ if ((s) > (dst)->tmax) (dst)->tmax = (s); \ (dst)->tsum += (s); \ (dst)->tsum2 += (s)*(s); \ (dst)->nsamples++; \ } #define dst_init(dst) { \ (dst)->tmin = (double)LONG_MAX; \ (dst)->tmax = 0.0; \ (dst)->tsum = 0.0; \ (dst)->tsum2 = 0.0; \ (dst)->nsamples = 0; \ } #define dst_min(dst) ((dst)->tmin) #define dst_max(dst) ((dst)->tmax) #define dst_avg(dst) ((dst)->nsamples ? (dst)->tsum/(dst)->nsamples : 0.0) struct timestats { /* Time stats */ struct dst rttstats; /* round trip time stats */ /* including # of packets we got back */ #define nreceived rttstats.nsamples long nrepeats; /* number of duplicates */ long ntransmitted; /* number of packets sent */ }; #define ts_init(ts) \ dst_init(&(ts)->rttstats); \ (ts)->nrepeats = (ts)->ntransmitted = 0; struct hoststats { /* Host info */ char hnamebuf[MAXHOSTNAMELEN]; char *hostname; struct sockaddr_in whereto; struct sockaddr_in *to; struct timestats *ts; }; duptable rcvd_tbl; /* bit array for duplicate replies detection */ struct hoststats *phs; int nhosts; struct timestats *pts; int nts = 2; /* volatile */ char exit_flag = 0; /* Compute variance */ double dst_var(dst) struct dst *dst; { if (dst->nsamples > 1) return (dst->tsum2 - (dst->tsum * dst->tsum / dst->nsamples)) / (dst->nsamples-1); else return 0.0; } /* Compute standard deviation */ double dst_stddev(dst) struct dst *dst; { double v = dst_var(dst); if (dst->nsamples > 1 && v > 0) return (double) sqrt(v); else return 0.0; } void set_ip(hs, target) struct hoststats *hs; char *target; { struct hostent *hp; hs->to = &hs->whereto; memset((char *)hs->to, 0, sizeof(struct sockaddr_in)); hs->to->sin_family = AF_INET; hs->to->sin_addr.s_addr = inet_addr(target); if (hs->to->sin_addr.s_addr != (u_int)-1) hs->hostname = target; else { hp = gethostbyname(target); if (!hp) { (void)fprintf(stderr, "bing: unknown host %s\n", target); exit(1); } hs->to->sin_family = hp->h_addrtype; memcpy((caddr_t)&hs->to->sin_addr, hp->h_addr, hp->h_length); strncpy(hs->hnamebuf, hp->h_name, sizeof(hs->hnamebuf) - 1); hs->hnamebuf[sizeof(hs->hnamebuf)-1] = '\0'; hs->hostname = hs->hnamebuf; } } void randomfill(bp, len, seed) char *bp; int len; long seed; { /* Initialise the packet payload with random data. * Note that on some platforms (e.g. Win32) RAND_MAX is less * than INT_MAX. Thus we only use the lower byte of the returned * int which in turn relies on the assumption that RAND_MAX+1 * is a power of 2. Fortunately this seems to always be the * case. */ srandom((unsigned)seed); while (len > 0) { *bp++ = (char)(random() & 0xff); len--; } } static long lastrand; static char nrand; void randominit(seed) long seed; { srandom((unsigned)seed); nrand = 0; } u_char randomnext() { u_char r; if (nrand-- == 0) { lastrand = random(); nrand = 3; } r = lastrand >> 24; lastrand <<= 8; return r; } /* * pinger -- * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet * will be added on by the kernel. The ID field is our UNIX process ID, * and the sequence number is an ascending integer. */ void pinger(hs, datalen) struct hoststats *hs; int datalen; { struct timestats *ts; register struct icmp *icp; register int cc; int i; ts = hs->ts + datalen_to_index(datalen); icp = (struct icmp *)outpack; icp->icmp_type = ICMP_ECHO; icp->icmp_code = 0; icp->icmp_seq = ++icmpseq; /* icmp_id and icmp_cksum will be filled-in by icmp_send() */ ts->ntransmitted++; CLR(icp->icmp_seq % mx_dup_ck, rcvd_tbl); if (options & F_RANDOMFILL) randomfill((long *)(outpack + 8), datalen, icp->icmp_seq); cc = datalen + 8; /* skips ICMP portion */ i = icmp_send(my_icmp, (char *)outpack, cc, (struct sockaddr *)hs->to, sizeof(struct sockaddr)); if (i < 0 || i != cc) { if (i < 0) perror("icmp_send"); (void)printf("bing: wrote %s %d chars, ret=%d\n", hs->hostname, cc, i); } } /* * pr_iph -- * Print an IP header with options. */ void pr_iph(ip) struct ip *ip; { int hlen; u_char *cp; hlen = ip->ip_hl << 2; cp = (u_char *)ip + 20; /* point to options */ (void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst Data\n"); (void)printf(" %1x %1x %02x %04x %04x", ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id); (void)printf(" %1x %04x", ((ip->ip_off) & 0xe000) >> 13, (ip->ip_off) & 0x1fff); (void)printf(" %02x %02x %04x", ip->ip_ttl, ip->ip_p, ip->ip_sum); #ifndef linux (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr)); (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr)); #else (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src)); (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst)); #endif /* dump any option bytes */ while (hlen-- > 20) { (void)printf("%02x", *cp++); } (void)putchar('\n'); } /* * pr_retip -- * Dump some info on a returned (via ICMP) IP packet. */ void pr_retip(ip) struct ip *ip; { int hlen; u_char *cp; pr_iph(ip); hlen = ip->ip_hl << 2; cp = (u_char *)ip + hlen; if (ip->ip_p == 6) (void)printf("TCP: from port %u, to port %u (decimal)\n", (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3))); else if (ip->ip_p == 17) (void)printf("UDP: from port %u, to port %u (decimal)\n", (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3))); } #ifdef notdef static char *ttab[] = { "Echo Reply", /* ip + seq + udata */ "Dest Unreachable", /* net, host, proto, port, frag, sr + IP */ "Source Quench", /* IP */ "Redirect", /* redirect type, gateway, + IP */ "Echo", "Time Exceeded", /* transit, frag reassem + IP */ "Parameter Problem", /* pointer + IP */ "Timestamp", /* id + seq + three timestamps */ "Timestamp Reply", /* " */ "Info Request", /* id + sq */ "Info Reply" /* " */ }; #endif /* * pr_icmph -- * Print a descriptive string about an ICMP header. */ void pr_icmph(icp) struct icmp *icp; { switch(icp->icmp_type) { case ICMP_ECHOREPLY: (void)printf("Echo Reply\n"); /* XXX ID + Seq + Data */ break; case ICMP_UNREACH: switch(icp->icmp_code) { case ICMP_UNREACH_NET: (void)printf("Destination Net Unreachable\n"); break; case ICMP_UNREACH_HOST: (void)printf("Destination Host Unreachable\n"); break; case ICMP_UNREACH_PROTOCOL: (void)printf("Destination Protocol Unreachable\n"); break; case ICMP_UNREACH_PORT: (void)printf("Destination Port Unreachable\n"); break; case ICMP_UNREACH_NEEDFRAG: (void)printf("frag needed and DF set\n"); break; case ICMP_UNREACH_SRCFAIL: (void)printf("Source Route Failed\n"); break; default: (void)printf("Dest Unreachable, Bad Code: %d\n", icp->icmp_code); break; } /* Print returned IP header information */ pr_retip((struct ip *)ICMP_TO_DATA(icp)); break; case ICMP_SOURCEQUENCH: (void)printf("Source Quench\n"); pr_retip((struct ip *)ICMP_TO_DATA(icp)); break; case ICMP_REDIRECT: switch(icp->icmp_code) { case ICMP_REDIRECT_NET: (void)printf("Redirect Network"); break; case ICMP_REDIRECT_HOST: (void)printf("Redirect Host"); break; case ICMP_REDIRECT_TOSNET: (void)printf("Redirect Type of Service and Network"); break; case ICMP_REDIRECT_TOSHOST: (void)printf("Redirect Type of Service and Host"); break; default: (void)printf("Redirect, Bad Code: %d", icp->icmp_code); break; } (void)printf("(New addr: 0x%08lx)\n", (unsigned long)icp->icmp_gwaddr.s_addr); pr_retip((struct ip *)ICMP_TO_DATA(icp)); break; case ICMP_ECHO: (void)printf("Echo Request\n"); /* XXX ID + Seq + Data */ break; case ICMP_TIMXCEED: switch(icp->icmp_code) { case ICMP_TIMXCEED_INTRANS: (void)printf("Time to live exceeded\n"); break; case ICMP_TIMXCEED_REASS: (void)printf("Frag reassembly time exceeded\n"); break; default: (void)printf("Time exceeded, Bad Code: %d\n", icp->icmp_code); break; } pr_retip((struct ip *)ICMP_TO_DATA(icp)); break; case ICMP_PARAMPROB: (void)printf("Parameter problem: pointer = 0x%02x\n", icp->icmp_hun.ih_pptr); pr_retip((struct ip *)ICMP_TO_DATA(icp)); break; case ICMP_TSTAMP: (void)printf("Timestamp\n"); /* XXX ID + Seq + 3 timestamps */ break; case ICMP_TSTAMPREPLY: (void)printf("Timestamp Reply\n"); /* XXX ID + Seq + 3 timestamps */ break; case ICMP_IREQ: (void)printf("Information Request\n"); /* XXX ID + Seq */ break; case ICMP_IREQREPLY: (void)printf("Information Reply\n"); /* XXX ID + Seq */ break; #ifdef ICMP_MASKREQ case ICMP_MASKREQ: (void)printf("Address Mask Request\n"); break; #endif #ifdef ICMP_MASKREPLY case ICMP_MASKREPLY: (void)printf("Address Mask Reply\n"); break; #endif default: (void)printf("Bad ICMP type: %d\n", icp->icmp_type); } } /* * pr_addr -- * Return an ascii host address as a dotted quad and optionally with * a hostname. */ char * pr_addr(l) u_long l; { struct hostent *hp; static char buf[80]; if ((options & F_NUMERIC) || !(hp = gethostbyaddr((char *)&l, 4, AF_INET))) (void)snprintf(snfargs(buf, sizeof(buf), "%s"), inet_ntoa(*(struct in_addr *)&l)); else (void)snprintf(snfargs(buf, sizeof(buf), "%s (%s)"), hp->h_name, inet_ntoa(*(struct in_addr *)&l)); return(buf); } /* * pr_pack -- * Print out the packet, if it came from us. This logic is necessary * because ALL readers of the ICMP socket get a copy of ALL ICMP packets * which arrive ('tis only fair). This permits multiple copies of this * program to be run without having intermingled output (or statistics!). */ int pr_pack(buf, cc, from, elapsed) char *buf; int cc; struct sockaddr_in *from; double elapsed; { struct timestats *ts; struct hoststats *hs; register struct icmp *icp; register u_long l; register int hn, i, j; register u_char *cp,*dp; u_char d; static int old_rrlen; static char old_rr[MAX_IPOPTLEN]; struct ip *ip; int hlen, dupflag; int bcc = cc; /* ip header */ ip = (struct ip *)buf; hlen = ip->ip_hl << 2; /* icmp header */ bcc -= hlen; icp = (struct icmp *)(buf + hlen); /* Look for the source host in our list */ hs = NULL; for (hn = 0; hn < nhosts; hn++) { if (from->sin_addr.s_addr == phs[hn].to->sin_addr.s_addr) { hs = phs+hn; break; } } if (hs == NULL) { /* * Never heard about this host... * Can either be an unexpected reply to one of our packets, * or a reply to somebody else (another ping/bing running on * the same host as we do, for example). * The best is to ignore it. */ return -1; } if (!datalen_check(cc - 28)) { if (!(options & F_VERBOSE)) return -1; (void)fprintf(stderr, "bing: unexpected packet size (%d bytes) from %s\n", cc, inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr)); pr_icmph(icp); } else { ts = &hs->ts[datalen_to_index(cc - 28)]; } /* Check the IP header */ if (bcc < ICMP_MINLEN) { if (!(options & F_VERBOSE)) return -1; (void)fprintf(stderr, "bing: packet too short (%d bytes) from %s\n", cc, inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr)); } /* Now the ICMP part */ if (icp->icmp_type == ICMP_ECHOREPLY) { if (icp->icmp_id != icmp_get_id(my_icmp)) return -1; /* 'Twas not our ECHO */ if (icp->icmp_seq == icmpseq) { /* * This is the last packet we sent, * 'elapsed' is the rtt. */ dst_newsample(&ts->rttstats, elapsed); if (samplefile) { fprintf(samplefile, "%d\t%d\t%.3f\n", hn, cc, elapsed); } } if (TST(icp->icmp_seq % mx_dup_ck, rcvd_tbl)) { ++(ts->nrepeats); dupflag = 1; } else { SET(icp->icmp_seq % mx_dup_ck, rcvd_tbl); dupflag = 0; } if (!(options & F_VVERBOSE)) return 0; (void)printf("%d bytes from %s: icmp_seq=%u", cc, inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr), icp->icmp_seq); (void)printf(" ttl=%d", ip->ip_ttl); (void)printf(" time=%.3f ms", elapsed); if (dupflag) (void)printf(" (DUP!)"); /* check the data */ cp = ICMP_TO_DATA(icp); if (options & F_RANDOMFILL) { randominit(icp->icmp_seq); } else { dp = &outpack[8]; } for (i = 8; i < cc; ++i, ++cp, ++dp) { if (options & F_RANDOMFILL) { d = randomnext(); } else { d = *dp; } if (*cp != d) { (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, d, *cp); cp = ICMP_TO_DATA(icp); for (i = 8; i < cc; ++i, ++cp) { if ((i % 32) == 8) (void)printf("\n\t"); (void)printf("%x ", *cp); } break; } } } else { /* We've got something other than an ECHOREPLY */ if (!(options & F_VERBOSE)) return -1; (void)printf("%d bytes from %s: ", cc, pr_addr(from->sin_addr.s_addr)); pr_icmph(icp); } /* Display any IP options */ cp = (u_char *)buf + sizeof(struct ip); for (; hlen > (int)sizeof(struct ip); --hlen, ++cp) switch (*cp) { case IPOPT_EOL: hlen = 0; break; case IPOPT_LSRR: (void)printf("\nLSRR: "); hlen -= 2; j = *++cp; ++cp; if (j > IPOPT_MINOFF) for (;;) { l = *++cp; l = (l<<8) + *++cp; l = (l<<8) + *++cp; l = (l<<8) + *++cp; if (l == 0) (void)printf("\t0.0.0.0"); else (void)printf("\t%s", pr_addr(ntohl(l))); hlen -= 4; j -= 4; if (j <= IPOPT_MINOFF) break; (void)putchar('\n'); } break; case IPOPT_RR: j = *++cp; /* get length */ i = *++cp; /* and pointer */ hlen -= 2; if (i > j) i = j; i -= IPOPT_MINOFF; if (i <= 0) continue; if (i == old_rrlen && cp == (u_char *)buf + sizeof(struct ip) + 2 && !memcmp((char *)cp, old_rr, i)) { (void)printf("\t(same route)"); i = ((i + 3) / 4) * 4; hlen -= i; cp += i; break; } old_rrlen = i; memcpy(old_rr, (char *)cp, i); (void)printf("\nRR: "); for (;;) { l = *++cp; l = (l<<8) + *++cp; l = (l<<8) + *++cp; l = (l<<8) + *++cp; if (l == 0) (void)printf("\t0.0.0.0"); else (void)printf("\t%s", pr_addr(ntohl(l))); hlen -= 4; i -= 4; if (i <= 0) break; (void)putchar('\n'); } break; case IPOPT_NOP: (void)printf("\nNOP"); break; default: (void)printf("\nunknown option %x", *cp); break; } (void)putchar('\n'); (void)fflush(stdout); return 0; } void ping_and_wait(hs, datalen, buf, buflen) struct hoststats *hs; int datalen; char *buf; int buflen; { struct sockaddr_in from; int fromlen; int cc; struct timestats *ts; double elapsed; ts = hs->ts + datalen_to_index(datalen); fromlen = sizeof(from); pinger(hs, datalen); for (;;) { /* Now read the reply packet */ cc = icmp_recv(my_icmp, buf, buflen, (struct sockaddr *)&from, &fromlen, &elapsed); if (cc > 0) { /* Print and exit if OK */ if (pr_pack((char *)buf, cc, &from, elapsed) == 0) { break; } } else if (cc == 0) { /* Time out */ break; } else if (exit_flag) { ts->ntransmitted--; break; } } } void warn_rtt(h1, h2, min1s, min1b, min2s, min2b) char *h1, *h2; double min1s, min1b, min2s, min2b; { double deltab, deltas; char *pmsg = (options & F_PEDANTIC) ? " (ignored)" : ""; /* Small packet rtts should be < big packet rtts */ if (min1b < min1s) fprintf(stderr, "warning: rtt big %s %.3fms < rtt small %s %.3fms%s\n", h1, min1b, h1, min1s, pmsg); if (min2b < min2s) fprintf(stderr, "warning: rtt big %s %.3fms < rtt small %s %.3fms%s\n", h2, min2b, h2, min2s, pmsg); /* rtts to host1 should be < rtts to host2 */ if (min1s > min2s) fprintf(stderr, "warning: rtt small %s %.3fms > rtt small %s %.3fms%s\n", h1, min1s, h2, min2s, pmsg); if (min1b > min2b) fprintf(stderr, "warning: rtt big %s %.3fms > rtt big %s %.3fms%s\n", h1, min1b, h2, min2b, pmsg); /* Delta on small packets should be < delta on big packets */ deltab = min2b - min1b; deltas = min2s - min1s; if (deltab < deltas) fprintf(stderr, "warning: %s to %s delta big rtts %.3fms < delta small rtts %.3fms%s\n", h1, h2, deltab, deltas, pmsg); } /* Sanity checks and corrections for rtts */ void adapt_rtt(min1s, min1b, min2s, min2b) double *min1s, *min1b, *min2s, *min2b; { double deltab, deltas; /* Don't correct anything if pedantic mode */ if (options & F_PEDANTIC) return; /* Small packet rtts should be < big packet rtts */ if (*min1b < *min1s) *min1s = *min1b; if (*min2b < *min2s) *min2s = *min2b; /* rtts to host1 should be < rtts to host2 */ if (*min1s > *min2s) *min2s = *min1s; if (*min1b > *min2b) *min2b = *min1b; /* Delta on small packets should be < delta on big packets */ deltab = *min2b - *min1b; deltas = *min2s - *min1s; if (deltab < deltas) { *min2s = *min2b; *min1s = *min1b; } } void finishpa(ntransmitted, received, nrepeats, vmin, vavg, vmax, vsd) long ntransmitted, received, nrepeats; double vmin, vavg, vmax, vsd; { /* XXX: float a; */ (void)printf("%6ld%6ld", ntransmitted, received - nrepeats); if (nrepeats) (void)printf("%6ld", nrepeats); else (void)printf(" "); if (ntransmitted) if (received - nrepeats > ntransmitted) (void)printf(" ****\t"); else (void)printf("%5d%%\t", (int) (((ntransmitted - received + nrepeats) * 100) / ntransmitted)); else (void)printf(" \t"); if (received - nrepeats) (void)printf(" %9.3f %9.3f %9.3f %9.3f\n", vmin, vavg, vmax, vsd); else (void)putchar('\n'); } #define finishp(ts) finishpa((ts)->ntransmitted, \ (ts)->nreceived, \ (ts)->nrepeats, \ dst_min(&(ts)->rttstats), \ dst_avg(&(ts)->rttstats), \ dst_max(&(ts)->rttstats), \ dst_stddev(&(ts)->rttstats)) /* * finish -- * Print out ping statistics for one host */ void finish(hs) struct hoststats *hs; { int j; (void)putchar('\n'); (void)printf("--- %s statistics ---\n", hs->hostname); (void)printf( "bytes out in dup loss\trtt (ms): min avg max std dev\n"); for (j = 0; j < nts; j++) { (void)printf("%5d", j+1 == nts ? datalen_big : datalen_small + j*datalen_step); finishp(&hs->ts[j]); } } void finishit() { double secs; double maxthru; double mindel; double rtt1s, rtt1b, rtt2s, rtt2b; struct hoststats *hs1, *hs2; int i; for (i = 0; i < nhosts; i++) { hs2 = phs+i; finish(hs2); } printf("\n--- estimated link characteristics ---\n"); printf("host\t\t\t bandwidth ms\n"); for (i = 1; i < nhosts; i++) { hs1 = phs+i-1; hs2 = phs+i; if (hs1->ts[nts-1].nreceived == 0 || hs1->ts[0].nreceived == 0 || hs2->ts[nts-1].nreceived == 0 || hs2->ts[0].nreceived == 0) { (void)printf("%s: not enough received packets\n", hs2->hostname); continue; } rtt1s = dst_min(&hs1->ts[0].rttstats); rtt1b = dst_min(&hs1->ts[nts-1].rttstats); rtt2s = dst_min(&hs2->ts[0].rttstats); rtt2b = dst_min(&hs2->ts[nts-1].rttstats); warn_rtt(hs1->hostname, hs2->hostname, rtt1s, rtt1b, rtt2s, rtt2b); adapt_rtt(&rtt1s, &rtt1b, &rtt2s, &rtt2b); secs = (rtt2b - rtt1b) - (rtt2s - rtt1s); if (secs == 0) { (void)printf( "%s: minimum delay difference is zero, can't estimate link throughput.\n", hs2->hostname); continue; } maxthru = bits / secs * 1e3; mindel = (dst_min(&hs2->ts[0].rttstats) - dst_min(&hs1->ts[0].rttstats)) - (datalen_small * (8*2)) / maxthru; if (maxthru<1e3) printf("%-32s %6.3fbps %9.3f\n", hs2->hostname, maxthru, mindel); else if (maxthru>1e6) printf("%-32s %6.3fMbps %9.3f\n", hs2->hostname, maxthru/1e6, mindel); else printf("%-32s %6.3fKbps %9.3f\n", hs2->hostname, maxthru/1e3, mindel); } return; } /* Flag for exit as soon as possible */ void finishit_exit() { exit_flag = 1; } /* Fill the packet with the provided pattern */ void fill(bp, patp) char *bp, *patp; { register int ii, jj, kk; int pat[16]; char *cp; for (cp = patp; *cp; cp++) if (!isxdigit(*cp)) { (void)fprintf(stderr, "bing: patterns must be specified as hex digits.\n"); exit(1); } ii = sscanf(patp, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6], &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12], &pat[13], &pat[14], &pat[15]); if (ii > 0) for (kk = 0; kk <= MAXPACKET - (8 + ii); kk += ii) for (jj = 0; jj < ii; ++jj) bp[jj + kk] = pat[jj]; if (options & F_VVERBOSE) { (void)printf("PATTERN: 0x"); for (jj = 0; jj < ii; ++jj) (void)printf("%02x", bp[jj] & 0xFF); (void)printf("\n"); } } void usage() { (void)fprintf(stderr, "usage: bing [-dDnrRPvVwz] [-c count] [-e samples] [-i wait]\n\t[-p pattern] [-s small packetsize] [-S big packetsize]\n\t[-u size increment] [-t ttl] [-I interface address]\n\t[-f sample file] host1 host2...\n"); exit(1); } #ifdef WIN32 BOOL PASCAL ConsoleCtrlHandler(DWORD dwCtrlType) { if (dwCtrlType==CTRL_C_EVENT) { finishit_exit(); return TRUE; } else return FALSE; } #endif int main(argc, argv) int argc; char **argv; { extern int optind; extern char *optarg; struct in_addr ifaddr; int ntrans, nloops; int i, j; int ch, hold, recv_packlen; u_char *datap, *recv_packet; u_char ttl, loop; #ifdef IP_OPTIONS char rspace[3 + 4 * NROUTES + 1]; /* record route space */ #endif #ifdef WIN32 { WSADATA wsaData; WORD wsaVersionRequested; int err; /* Initialise the winsock */ wsaVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wsaVersionRequested, &wsaData ); if (err!=0) { fprintf(stderr,"bing: Could not initialise the winsock\n"); exit(1); } /* Install the ^C handler */ SetConsoleCtrlHandler(ConsoleCtrlHandler,TRUE); __progname=argv[0]; } #endif /* * Open our raw socket at once, then setuid() back to * the real uid as soon as possible (we have to, in * case the -f option is used, and it's better anyway for * obvious security reasons). */ my_icmp = icmp_open(); if (my_icmp == NULL) { fprintf(stderr, "cannot open ICMP module\n"); exit(1); } #ifndef WIN32 setgid(getgid()); setuid(getuid()); #endif datap = &outpack[8]; while ((ch = getopt(argc, argv, "c:dDe:f:I:i:LnPp:RrS:s:t:u:vVwz")) != EOF) switch(ch) { case 'f': samplefile = fopen(optarg, "a"); if (samplefile == NULL) { (void)fprintf(stderr, "bing: unable to open %s: ", optarg); perror(""); exit(1); } break; case 'c': npackets = atoi(optarg); if (npackets <= 0) { (void)fprintf(stderr, "bing: bad number of packets to transmit.\n"); exit(1); } break; case 'D': options |= F_NODELTA; break; case 'P': options |= F_PEDANTIC; break; case 'w': options |= F_WARN; break; case 'd': options |= F_SO_DEBUG; break; case 'e': nsamples = atoi(optarg); if (nsamples <= 0) { (void)fprintf(stderr, "bing: bad number of samples.\n"); exit(1); } break; case 'i': /* wait between sending packets */ maxwait = atoi(optarg); if (maxwait <= 0) { (void)fprintf(stderr, "bing: bad maximum wait.\n"); exit(1); } options |= F_INTERVAL; break; case 'u': /* packet size increment */ datalen_step = atoi(optarg); if (datalen_step <= 0) { (void)fprintf(stderr, "bing: bad packet size increment.\n"); exit(1); } break; case 'n': options |= F_NUMERIC; break; case 'p': /* fill buffer with user pattern */ options |= F_PINGFILLED; fill((char *)datap, optarg); break; case 'V': options |= F_VVERBOSE; break; case 'R': options |= F_RROUTE; break; case 'r': options |= F_SO_DONTROUTE; break; case 'S': /* size of big packet to send */ datalen_big = atoi(optarg); if (datalen_big > MAXPACKET) { (void)fprintf(stderr, "bing: big packet size too large.\n"); exit(1); } if (datalen_big <= 0) { (void)fprintf(stderr, "bing: illegal big packet size.\n"); exit(1); } break; case 's': /* size of small packet to send */ datalen_small = atoi(optarg); if (datalen_small > MAXPACKET) { (void)fprintf(stderr, "bing: small packet size too large.\n"); exit(1); } if (datalen_small <= 0) { (void)fprintf(stderr, "bing: illegal small packet size.\n"); exit(1); } break; case 'v': options |= F_VERBOSE; break; case 'z': options |= F_RANDOMFILL; break; case 'L': moptions |= MULTICAST_NOLOOP; loop = 0; break; case 't': moptions |= MULTICAST_TTL; i = atoi(optarg); if (i < 0 || i > 255) { printf("ttl %u out of range\n", i); exit(1); } ttl = i; break; case 'I': moptions |= MULTICAST_IF; { int i1, i2, i3, i4; char dummy; if (sscanf(optarg, "%u.%u.%u.%u%c", &i1, &i2, &i3, &i4, &dummy) != 4) { printf("bad interface address '%s'\n", optarg); exit(1); } ifaddr.s_addr = (i1<<24)|(i2<<16)|(i3<<8)|i4; ifaddr.s_addr = htonl(ifaddr.s_addr); } break; default: usage(); } if (datalen_small >= datalen_big) { (void)fprintf(stderr, "bing: small packet size >= big packet size\n"); exit(1); } if (datalen_small < 0) { (void)fprintf(stderr, "bing: invalid packet size\n"); exit(1); } bits = (datalen_big - datalen_small) * (8*2); if (datalen_step == 0 || datalen_small + datalen_step > datalen_big) datalen_step = datalen_big - datalen_small; nts = (datalen_big + datalen_step - 1 - datalen_small)/datalen_step + 1; argc -= optind; argv += optind; if (argc < 2) usage(); icmp_set_timeout(my_icmp, maxwait*1000000); phs = (struct hoststats *)malloc(sizeof(struct hoststats) * argc); nhosts = argc; pts = (struct timestats *) malloc(sizeof(struct timestats) * nts * nhosts); if (!phs || !pts) { (void)fprintf(stderr, "bing: out of memory.\n"); exit(1); } for (i = 0; i < nhosts; i++) { set_ip(phs + i, argv[i]); phs[i].ts = pts + i*nts; } recv_packlen = datalen_big + MAXIPLEN + MAXICMPLEN; if (!(recv_packet = (u_char *)malloc((u_int)recv_packlen))) { (void)fprintf(stderr, "bing: out of memory.\n"); exit(1); } if (!(options & F_PINGFILLED)) for (i = 0; i < datalen_big; ++i) *datap++ = i; hold = 1; if (options & F_SO_DEBUG) icmp_set_option(my_icmp, SOL_SOCKET, SO_DEBUG, (char *)&hold, sizeof(hold)); if (options & F_SO_DONTROUTE) (void)icmp_set_option(my_icmp, SOL_SOCKET, SO_DONTROUTE, (char *)&hold, sizeof(hold)); /* record route option */ if (options & F_RROUTE) { #ifdef IP_OPTIONS rspace[IPOPT_OPTVAL] = IPOPT_RR; rspace[IPOPT_OLEN] = sizeof(rspace)-1; rspace[IPOPT_OFFSET] = IPOPT_MINOFF; if (icmp_set_option(my_icmp, IPPROTO_IP, IP_OPTIONS, rspace, sizeof(rspace)) < 0) { perror("bing: record route"); exit(1); } #else (void)fprintf(stderr, "bing: record route not available in this implementation.\n"); exit(1); #endif /* IP_OPTIONS */ } /* * When pinging the broadcast address, you can get a lot of answers. * Doing something so evil is useful if you are trying to stress the * ethernet, or just want to fill the arp cache to get some stuff for * /etc/ethers. */ hold = 48 * 1024; (void)icmp_set_option(my_icmp, SOL_SOCKET, SO_RCVBUF, (char *)&hold, sizeof(hold)); #ifdef IP_MULTICAST_NOLOOP if (moptions & MULTICAST_NOLOOP) { if (icmp_set_option(my_icmp, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop, 1) == -1) { perror ("can't disable multicast loopback"); exit(92); } } #endif #ifdef IP_MULTICAST_TTL if (moptions & MULTICAST_TTL) { if (icmp_set_option(my_icmp, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, 1) == -1) { perror ("can't set multicast time-to-live"); exit(93); } } #endif #ifdef IP_MULTICAST_IF if (moptions & MULTICAST_IF) { if (icmp_set_option(my_icmp, IPPROTO_IP, IP_MULTICAST_IF, (char *)&ifaddr, sizeof(ifaddr)) == -1) { perror ("can't set multicast source interface"); exit(94); } } #endif if (samplefile) { char myname[MAXHOSTNAMELEN]; time_t t; gethostname(myname, sizeof myname); t = time(NULL); fprintf(samplefile, "# From %s, %s", myname, ctime(&t)); for (i = 0; i < nhosts; i++) { if (phs[i].to->sin_family == AF_INET) { fprintf(samplefile, "# %d\t%s (%s)\n", i, phs[i].hostname, inet_ntoa(*(struct in_addr *)&phs[i].to->sin_addr.s_addr)); } else { fprintf(samplefile, "# %d\t%s\n", i, phs[i].hostname); } } } if (nhosts == 2 && phs[0].to->sin_family == AF_INET && phs[1].to->sin_family == AF_INET) { (void)printf("BING\t%s (%s) and ", phs->hostname, inet_ntoa(*(struct in_addr *)&phs->to->sin_addr.s_addr)); (void)printf("%s (%s)\n\t%d and %d data bytes (%d bits)\n", (phs+1)->hostname, inet_ntoa(*(struct in_addr *)&(phs+1)->to->sin_addr.s_addr), datalen_small, datalen_big, bits); } else if (nhosts == 2) { (void)printf("BING %s and %s:\n\t%d and %d data bytes (%d bits)\n", phs->hostname, (phs+1)->hostname, datalen_small, datalen_big, bits); } else { (void)printf("BING\t%d and %d data bytes (%d bits)\n", datalen_small, datalen_big, bits); for (i = 0; i < nhosts; i++) { if (phs[i].to->sin_family == AF_INET) { (void)printf("%d:\t%s (%s)\n", i, phs[i].hostname, inet_ntoa(*(struct in_addr *)&phs[i].to->sin_addr.s_addr)); } else { (void)printf("%d:\t%s\n", i, phs[i].hostname); } } } #ifndef WIN32 { /* Set the interrupt handler for exit */ struct sigaction sa; sa.sa_handler = finishit_exit; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask,SIGINT); sigaction(SIGINT, &sa, NULL); } #endif for (nloops = 0; !nloops || nloops < npackets; nloops++) { double oldsecs = -1; if (nloops) fprintf(stderr,"resetting after %ld samples.\n", nsamples); for (i = 0; i < nhosts; i++) for (j = 0; j < nts; j++) { ts_init(&phs[i].ts[j]); } for (ntrans = 0; !nsamples || ntrans < nsamples ; ntrans++) { double secs; double min1b, min1s, min2b, min2s; if (exit_flag) break; for (i = 0; i < nhosts; i++) { struct hoststats *hs1, *hs2; struct timestats *ts1s, *ts1b, *ts2s, *ts2b; if (exit_flag) break; hs2 = phs + i; for (j = datalen_small; j < datalen_big && !exit_flag; j += datalen_step) { ping_and_wait(hs2, j, (char *)recv_packet, recv_packlen); } if (exit_flag) break; ping_and_wait(hs2, datalen_big, (char *)recv_packet, recv_packlen); if (i == 0) /* Don't display stats on the first host */ continue; hs1 = phs + i-1; ts1b = &hs1->ts[nts-1]; ts1s = &hs1->ts[0]; ts2b = &hs2->ts[nts-1]; ts2s = &hs2->ts[0]; if (ts1b->nreceived && ts1s->nreceived == 0 && ts2b->nreceived == 0 && ts2s->nreceived == 0) continue; min1s = dst_min(&(ts1s->rttstats)); min1b = dst_min(&(ts1b->rttstats)); min2s = dst_min(&(ts2s->rttstats)); min2b = dst_min(&(ts2b->rttstats)); adapt_rtt(&min1s, &min1b, &min2s, &min2b); secs = (min2b - min1b) - (min2s - min1s); if ((options & F_NODELTA) || (oldsecs != secs)) { oldsecs = secs; if (options & F_WARN) warn_rtt(hs1->hostname, hs2->hostname, dst_min(&(ts1s->rttstats)), dst_min(&(ts1b->rttstats)), dst_min(&(ts2s->rttstats)), dst_min(&(ts2b->rttstats))); if (secs>0) { if (bits * 1e3 / secs<1e3) printf("%s: %6.3fbps %.3fms %.6fus/bit\n", hs2->hostname, bits * 1e3 / secs, secs, secs * 1e3 / bits); else if ((bits / secs) * 1e3>1e6) printf("%s: %6.3fMbps %.3fms %.6fus/bit\n", hs2->hostname, (bits * 1e3 / secs) / 1e6, secs, secs * 1e3 / bits); else printf("%s: %6.3fKbps %.3fms %.6fus/bit\n", hs2->hostname, (bits * 1e3 / secs) / 1e3, secs, secs * 1e3 / bits); } else { printf("%s: minimum delay difference is zero, can't estimate link throughput\n", hs2->hostname); } fflush(stdout); } } } finishit(); if (exit_flag) break; } if (samplefile) { fclose(samplefile); } icmp_close(my_icmp); return 0; } bing-1.1.3/ChangeLog0100644000076500007770000000632306345721213014020 0ustar mbabcockcodingFri Jun 05 07:30:49 MET DST 1997 *** Release 1.1.3 *** Fri Jun 05 07:30:49 MET DST 1997 - Modified the Win32 code to improve the RTT measurment. It now uses the QueryPerformanceCounter API to get an 8 microsecond precision. - Improved the portability of the bing 1.1 serie. It has been compiled and tested on: AIX 2 HP-UX 10 Linux 2.0.27 Solaris 2.5 SunOS 4.1.3 Windows 95 Windows NT 3.51 and 4.0 on i386 - Fixed a bug in finishit, secs should be a double not a long. - Fixed a bug related to srand()/rand(). On some platforms (alpha, win32) RAND_MAX is not INT_MAX in which case the content of the buffer was not random. - Modified the output to make it more readable. bing now display Mbps or Kbps as sensible. - Converted the bing man page format from mandoc to man. This should be more portable. - Changed the order in which adapt_rtt checks the RTT for coherency. It seems safer to check the coherency for each host separately first and only then to check the coherency between hosts. Fri Apr 23 01:30:49 MET DST 1997 *** Release 1.1.2 *** Fri Apr 23 01:30:49 MET DST 1997 - Putting some Win32 code back in. - Update of the bing man page. - Update of the Readme file. - Enhanced the makefile. Fri Mar 9 01:43:35 MET DST 1997 *** Release 1.1.1 *** Fri Mar 9 01:43:35 MET DST 1997 - bing code after Pierre's cleanup - Pierre added two new options: '-u' and 'f' - bing now supports more than two hosts on the command line. This allows you to exploit the results of a traceroute. - Supports multiple destination hosts. Fri Feb 7 04:23:12 MET DST 1997 *** Release 1.1.0 *** Fri Feb 7 04:23:12 MET DST 1997 - ported to Win32. This involves a new icmp module which hides the interface differences. - The win32 specific parts have been put into the win32 directory and the unix specific parts are in the ux directory. - the Win32 section contains a preformatted version of the manual "bing.8". - README changed. Fri Jul 21 09:47:39 MET DST 1995 *** Release 1.0.4 *** Fri Jul 21 00:42:17 MET DST 1995 - small change in output format. - changed default small packet size. It seems the previous size of 8 bytes was too small and was padded to something bigger on many links. - README changed. Thu Jul 20 01:36:35 MET DST 1995 *** Release 1.0.3 *** Thu Jul 20 00:55:09 MET DST 1995 - new sanity check on rtt deltas. Submitted by - warnings now displayed only at the end, unless -w is used. - enhanced final stats display (should fit in a 25x80 screen in most cases). - README improved. - some cleanups in timeval code. - more Solaris 2 cleanups. Tue Jul 18 22:16:21 MET DST 1995 - portability fixes (Solaris, AIX, Linux, BSDI) - some code cleanup (gcc -Wall) Tue Jul 18 01:06:21 MET DST 1995 *** Release 1.0.2 *** Tue Jul 18 00:25:56 MET DST 1995 - patches for Linux included. Submitted by - sysdep.h created for system-dependent defines. Mon Jul 17 23:44:32 MET DST 1995 - README improved Mon Jul 17 22:38:07 MET DST 1995 - ChangeLog (this file) created - Option -q reversed as -V - Usage corrected. Fix submitted by Sun Jul 16 23:06:07 MET DST 1995 *** Initial release 1.0.1 *** bing-1.1.3/Makefile0100644000076500007770000000432007135603057013704 0ustar mbabcockcoding# # $Id: Makefile, unofficial v1.1.3 # ########## # # Customise the following variables to match your configuration standards # ########## BINDIR=/usr/bin MANDIR=/usr/man ########## # # Uncomment the lines below as appropriate for your platform. # ########## # Uncomment if you need the 4.4 BSD compatibility includes. # -> required on Linux (and Win32) COMPAT_INCS = -Iinclude # Maybe specify some specific compatibility options # -> on AIX activate the BSD mode #COMPAT_DEFS= -D_BSD # On some systems you may need to link with specific libraries # -> on SunOS 5 (Solaris) link with #COMPAT_LIBS=-lnsl -lsocket -L/usr/ucblib -lucb # Define if you lack srandom()/random() # -> required on Solaris (and Win32) #NO_RANDOM = -DNO_RANDOM=1 # Define to use srandom/random rather than srand/rand # -> required on SunOS 4.1.3, SunOS 5, AIX 2 (BOSX 2 really), OSF1 V2.0 NO_SNPRINTF = -DNO_SNPRINTF=1 # Define if you lack strerror() #NO_STRERROR = -DNO_STRERROR=1 # You may optionally provide some optimisation flags. Optimising bing for # speed should slightly improve the results. # -> if you want to debug bing define #COPTIM = -g # -> on Linux, SunOS 4 and OSF1 V2.0 you may specify COPTIM = -O2 # -> on Solaris you may use #COPTIM = -O # on some hosts like AIX, HP-UX the optimisation options are already set ########## # # Define where tools are stored # ########## INSTALL=install -c GROFF=groff NROFF=nroff RM=/bin/rm ########## # # Compilation rules # ########## BINCS = \ -I. \ $(COMPAT_INCS) BDEFS = \ $(COMPAT_DEFS) \ $(NO_RANDOM) \ $(NO_SNPRINTF) \ $(NO_STRERROR) \ $(CDEBUG) BLIBS = \ $(COMPAT_LIBS) OBJS= bing.o icmp_ux.o all: bing bing.0 bing.ps dist: clean bing.0 bing.ps bing.o: bing.c mod_icmp.h $(CC) $(CFLAGS) $(BINCS) $(BDEFS) -o $@ -c bing.c icmp_ux.o: unix/icmp_ux.c mod_icmp.h $(CC) $(CFLAGS) $(BINCS) $(BDEFS) -o $@ -c unix/icmp_ux.c bing: $(OBJS) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(BLIBS) -lm bing.ps: unix/bing.8 $(GROFF) -man unix/bing.8 > bing.ps bing.0: unix/bing.8 $(NROFF) -man unix/bing.8 > bing.0 clean: $(RM) -f bing bing.ps bing.0 $(OBJS) install: bing unix/bing.8 $(INSTALL) -m 644 -o man -g man unix/bing.8 $(MANDIR)/man8 $(INSTALL) -m 4555 -o root -g staff bing $(BINDIR) bing-1.1.3/mod_icmp.h0100644000076500007770000000360406345720643014213 0ustar mbabcockcoding/* * This file provides a system independant interface to send and * receive ICMP messages. */ #ifndef _mod_icmp_h_ #define _mod_icmp_h_ #if defined(__STDC__) || defined(__cplusplus) #define PROTO(a,b) a b #else #define PROTO(a,b) a() #endif #ifdef __cplusplus #define API "C" #else #define API #endif typedef void* icmp_handle; /* initialize the ICMP module, return a pointer to it. */ extern icmp_handle PROTO( icmp_open, ( void )); /* set a socket option. Returns >= 0 if successful, -1 otherwise */ extern int PROTO( icmp_set_option, ( icmp_handle handle, /* module handle */ int level, int optname, /* option to be set */ void *optval, /* option value */ int optlen /* length of option value */ )); /* set the timeout for receives */ extern void PROTO( icmp_set_timeout, ( icmp_handle handle, unsigned long timeout /* timeout in microseconds */ )); /* get the ID used in packets */ extern unsigned short PROTO( icmp_get_id, ( icmp_handle handle )); /* send an ICMP message. Returns >= 0 if successful, -1 otherwise */ extern int PROTO( icmp_send, ( icmp_handle handle, /* module handle */ void *msg, /* ICMP message contents */ int msg_size, /* size */ struct sockaddr *to_addr, /* who to send to */ int to_addr_size /* sockaddr size */ )); /* * Wait for an ICMP message. * Returns: * >0: successful, return value is the packet size * 0: timeout * -1: interrupted, should be called again */ extern int PROTO( icmp_recv, ( icmp_handle handle, /* module handle */ char *buffer, /* buffer pointer */ int buffer_size, /* buffer size */ struct sockaddr *from_addr, int *from_addr_size, double *elapsed /* elapsed microseconds since last icmp_send */ )); /* close the ICMP module. Returns >= 0 if successful, -1 otherwise */ extern int PROTO( icmp_close, ( icmp_handle handle )); #endif /* End of File */ bing-1.1.3/win32/0042755000076500007770000000000006345722253013216 5ustar mbabcockcodingbing-1.1.3/win32/icmp_win32.c0100644000076500007770000002057006345722253015333 0ustar mbabcockcoding/* * This module provides an interface to send and receive ICMP messages * which is closer to the way Unix programs are written than the standard * WIN32 icmp dll's interface. */ #include "win32/win32.h" #include #include "win32/types.h" #include "netinet/ip.h" #include "netinet/ip_var.h" #include "netinet/ip_icmp.h" #include #include #include "mod_icmp.h" #include #include typedef struct { HANDLE hICMP; /* The ICMP dll handle */ /* "Socket" options */ int rcvbufsize; /* Size of the receive buffer */ struct ip_option_information ip_options;/* The IP options */ unsigned long timeout; /* Time to wait for a reply */ /* A few things to remember about the request */ u_short msg_id; u_short msg_seq; /* Some fields to process the answers */ struct icmp_echo_reply* rcvbuf; /* The buffer in which */ /* IcmpSendEcho will store the answers */ int nb_replies; /* -1 => message not sent yet. */ /* >=0 => number of reply messages */ struct icmp_echo_reply* current; /* Pointer to next reply */ LARGE_INTEGER rtt_in_ticks; /* This is our own measurment of the RTT */ LARGE_INTEGER ticks_freq; } icmp_state_i; #define handle2state(h) ((icmp_state_i*)h) icmp_handle icmp_open() { icmp_state_i* handle; /* Perform some initialisation to ease error recovery */ handle=NULL; /* Give a higher priority so that bing has better * chances not to be delayed when measuring the RTT. */ SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); /* Allocate the handle */ handle=malloc(sizeof(icmp_state_i)); /* Fill defaults */ handle->hICMP=IcmpCreateFile(); handle->rcvbufsize=4096; handle->rcvbuf=NULL; handle->nb_replies=-1; QueryPerformanceFrequency(&handle->ticks_freq); /* Set options defaults */ handle->ip_options.Ttl=255; handle->ip_options.Tos=0; handle->ip_options.Flags=0; handle->ip_options.OptionsSize=0; handle->ip_options.OptionsData=NULL; return (icmp_handle)handle; error: if (handle!=NULL) free(handle); return NULL; } int icmp_set_option(icmp_handle handle, int level, int optname, char* optval, int optlen) { int ret; ret=0; switch (level) { case IPPROTO_IP: /* The IP options are handled by building the * corresponding IP structure by hand. */ /* No IP option is supported yet */ errno=ENOSYS; ret=-1; break; case SOL_SOCKET: switch (optname) { case SO_RCVBUF: handle2state(handle)->rcvbufsize=*((int*)optval); break; default: errno=ENOSYS; ret=-1; break; } break; default: errno=ENOSYS; ret=-1; } return ret; } void icmp_set_timeout(icmp_handle handle,unsigned long timeout) { handle2state(handle)->timeout=timeout/1000; } unsigned short icmp_get_id(icmp_handle handle) { return handle2state(handle)->msg_id; } int icmp_send(icmp_handle handle, char* msg, int msg_size, struct sockaddr* to_addr, int to_addr_size) { DWORD reply_size; LARGE_INTEGER start,stop; static int nb_toohigh=0,nb=0; static int icmp_min=1000000,query_min=1000000; /* Record some information for the recv */ handle2state(handle)->msg_id=((struct icmp*)msg)->icmp_id; handle2state(handle)->msg_seq=((struct icmp*)msg)->icmp_seq; /* allocate the buffer for the replies */ handle2state(handle)->rcvbuf=realloc(handle2state(handle)->rcvbuf, handle2state(handle)->rcvbufsize); QueryPerformanceCounter(&start); handle2state(handle)->nb_replies=IcmpSendEcho( handle2state(handle)->hICMP, *((IPAddr*)&(((struct sockaddr_in*)to_addr)->sin_addr)), msg+ICMP_MINLEN, (WORD)(msg_size-ICMP_MINLEN), &handle2state(handle)->ip_options, handle2state(handle)->rcvbuf, handle2state(handle)->rcvbufsize, handle2state(handle)->timeout ); QueryPerformanceCounter(&stop); if ((handle2state(handle)->ticks_freq.QuadPart!=0) && (handle2state(handle)->nb_replies==1)) { /* If we have a high performance counter, use it to measure * the RTT. The high performance counter will either give us * a much more precise measure of the RTT than the ICMP * library or it will give us a gross exageration of the RTT * if the execution of our process has been delayed by the * scheduler. Statistically this should give much better * results than the ICMP library (which tends to sometimes * under-estimate the RTT by up to nearly 2 ms which is * BAD in our case. */ handle2state(handle)->rtt_in_ticks.QuadPart= stop.QuadPart-start.QuadPart; } else handle2state(handle)->rtt_in_ticks.QuadPart=0; if (handle2state(handle)->nb_replies==0) { if (GetLastError()==IP_REQ_TIMED_OUT) return 0; printf("icmp_send: error %d\n",GetLastError()); errno=GetLastError(); return -1; } handle2state(handle)->current=handle2state(handle)->rcvbuf; return msg_size; } int icmp_recv(icmp_handle handle, char* buffer, int buffer_size, struct sockaddr* from_addr, int* from_addr_size, double* elapsed) { if (handle2state(handle)->nb_replies>0) { struct ip* ip_msg; struct icmp* icmp_msg; /* Misc return values */ ((struct sockaddr_in*)from_addr)->sin_family=AF_INET; ((struct sockaddr_in*)from_addr)->sin_port=0; memcpy(&(((struct sockaddr_in*)from_addr)->sin_addr), &handle2state(handle)->current->Address,4); if (handle2state(handle)->rtt_in_ticks.QuadPart==0) *elapsed=(double)(handle2state(handle)->current->RoundTripTime); else *elapsed=((double)(handle2state(handle)->rtt_in_ticks.QuadPart*1000))/ handle2state(handle)->ticks_freq.QuadPart; /* Reconstruct the ip header */ ip_msg=(struct ip*)buffer; ip_msg->ip_v=4; ip_msg->ip_hl=(sizeof(struct ip) +handle2state(handle)->current->Options.OptionsSize) >> 2; ip_msg->ip_tos=handle2state(handle)->current->Options.Tos; ip_msg->ip_len=((ip_msg->ip_hl) << 2) +ICMP_MINLEN +handle2state(handle)->current->DataSize; ip_msg->ip_id=0; ip_msg->ip_off=0; ip_msg->ip_ttl=handle2state(handle)->current->Options.Ttl; ip_msg->ip_p=0; ip_msg->ip_sum=0; memcpy(&(ip_msg->ip_src),&handle2state(handle)->current->Address,4); memset(&ip_msg->ip_dst,0,4); if (handle2state(handle)->current->Options.OptionsSize>0) memcpy(buffer+sizeof(struct ip), handle2state(handle)->current->Options.OptionsData, handle2state(handle)->current->Options.OptionsSize); /* Reconstruct the icmp header */ icmp_msg=(struct icmp*)(buffer+((ip_msg->ip_hl) << 2)); switch (handle2state(handle)->current->Status) { /* Echo Reply (what we expect) */ case IP_SUCCESS: icmp_msg->icmp_type=0; icmp_msg->icmp_code=0; icmp_msg->icmp_id=handle2state(handle)->msg_id; icmp_msg->icmp_seq=handle2state(handle)->msg_seq; break; /* Destination Unreachable */ case IP_DEST_NET_UNREACHABLE: icmp_msg->icmp_type=3; icmp_msg->icmp_code=0; break; case IP_DEST_HOST_UNREACHABLE: icmp_msg->icmp_type=3; icmp_msg->icmp_code=1; break; case IP_DEST_PROT_UNREACHABLE: icmp_msg->icmp_type=3; icmp_msg->icmp_code=2; break; case IP_DEST_PORT_UNREACHABLE: icmp_msg->icmp_type=3; icmp_msg->icmp_code=3; break; /* Time Exceeded */ case IP_TTL_EXPIRED_TRANSIT: icmp_msg->icmp_type=11; icmp_msg->icmp_code=0; break; case IP_TTL_EXPIRED_REASSEM: icmp_msg->icmp_type=11; icmp_msg->icmp_code=1; break; /* Parameter Problem */ case IP_PARAM_PROBLEM: icmp_msg->icmp_type=12; icmp_msg->icmp_code=0; /* how can I get a value for the pointer field ? */ break; /* Source Quench */ case IP_SOURCE_QUENCH: icmp_msg->icmp_type=4; icmp_msg->icmp_code=0; break; default: handle2state(handle)->nb_replies--; handle2state(handle)->current++; return -handle2state(handle)->current->Status; } /* Who cares about the checksum ? */ icmp_msg->icmp_cksum=0; /* Copy data */ memcpy(buffer+((ip_msg->ip_hl) << 2)+ICMP_MINLEN, handle2state(handle)->current->Data, handle2state(handle)->current->DataSize); handle2state(handle)->nb_replies--; handle2state(handle)->current++; return ip_msg->ip_len; } else return 0; } int icmp_close(icmp_handle handle) { int ret; ret=IcmpCloseHandle((HANDLE)(((icmp_state_i*)handle)->hICMP)); free(handle); return (ret?0:-1); } bing-1.1.3/win32/bing.txt0100644000076500007770000001470106345720563014676 0ustar mbabcockcoding BING(8) UNIX System Manager's Manual BING(8) NAME bing - compute point to point throughput using two sizes of ICMP ECHO_REQUEST packets to pairs of remote hosts. SYNOPSIS bing [dDnrRPvVwz] [-c count] [-e samples] [-f samplefile] [-i wait] [-p pattern] [-s small packetsize] [-S big pack- etsize] host1 host2 [...] DESCRIPTION Bing determines bandwidth on a point-to-point link by sending ICMP ECHO_REQUEST packets and measuring their roundtrip times for different packet sizes on each end of the link. host1 is supposed to be the nearest end of the link, while host2 is the other end. The options are as follows: -c count Stop after count resets of the stats. Useful only in conjunction with the -e option. Defaults to 1. -d Set the SO_DEBUG option on the socket being used. -D Display the measured throughput at every received packet. By default, it is displayed only when the computed value changes, which itself changes only when the minimum roundtrip time for one of the packet sizes changes. -e samples Reset stats after sending samples ECHO_REQUEST pack- ets. -f samplefile Saves the bandwidth measurements to the file sample- file. -i wait Wait wait seconds for each ECHO_REPLY packet. The default is to wait for four seconds. -n Numeric output only. No attempt will be made to lookup symbolic names for host addresses. -P Be pedantic regarding round-trip times. Normally, bing assumes that the roundtrip time for a small packet should always be smaller than the roundtrip time for a big packet to the same host, that for a given size the roundtrip time for host1 April 3, 1995 1 BING(8) UNIX System Manager's Manual BING(8) should always be smaller than the roundtrip time for host2, and that the increase in the roundtrip time between host1 and host2 should always be bigger for big packets than for small packets. bing takes advantage of this to better determine the minimum roundtrip times. Option -P disables this behaviour, in the unlikely event it could be of any use someday. Even IP/X25 links are not weird enough to require this, though. -p pattern You may specify up to 16 ``pad'' bytes to fill out the packet you send. This is useful for diagnosing data-dependent problems in a network. For example, ``-p ff'' will cause the sent packet to be filled with all ones. -R Record route. Includes the RECORD_ROUTE option in the ECHO_REQUEST packet and displays the route buffer on returned packets. Note that the IP header is only large enough for nine such routes. Many hosts ignore or discard this option. -r Bypass the normal routing tables and send directly to a host on an attached network. If the host is not on a directly-attached network, an error is returned. This option can be used to ping a local host through an interface that has no route through it (e.g., after the interface was dropped by routed(8)). -s small packetsize Specifies the number of data bytes to be sent in the small packets. The default and minimum value is 44. -S big packetsize Specifies the number of data bytes to be sent in the big packets. The default is 108. The size should be chosen so that big packet roundtrip times are long enough to be accurately measured (depending on clock resolution and number of hops). -u size increment Specifies that bing should start sending packets of the size of small packetsize and then increase the size by size increment until it reaches big packet- size. -v Verbose output. ICMP packets other than ECHO_RESPONSE that are received are listed. -V Very verbose output. The roundtrip time of each received echo is displayed. April 3, 1995 2 BING(8) UNIX System Manager's Manual BING(8) -w Display possible warnings about roundtrip times all the time. By default, warnings are printed only at the end. -z Fill packets with uncompressible (pseudo-random) data. Round-trip times and packet loss statistics are computed. If duplicate packets are received, they are not included in the packet loss calculation, although the round trip time of these packets is used in calculating the mini- mum/average/maximum round-trip time numbers. When the specified number of loops have been made or if the program is terminated with a SIGINT, a brief summary is displayed. This program is intended for use in network testing, mea- surement and management. Because of the load it can impose on the network, it is unwise to use bing during normal operations or from automated scripts. BUGS Many Hosts and Gateways ignore the RECORD_ROUTE option. The maximum IP header length is too small for options like RECORD_ROUTE to be completely useful. There's not much that that can be done about this, however. Some of the final stats (average throughputs) almost never give a even marginally correct result. SEE ALSO netstat(1), ifconfig(8), ping(8), routed(8), traceroute(8) AUTHOR Pierre Beyssac Port to Windows: Francois Gouget April 3, 1995 3 bing-1.1.3/win32/getopt.c0100644000076500007770000000763406345722243014670 0ustar mbabcockcoding/* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)getopt.c 8.2 (Berkeley) 4/2/94"; #endif /* LIBC_SCCS and not lint */ #include #include #include int opterr = 1, /* if error message should be printed */ optind = 1, /* index into parent argv vector */ optopt, /* character checked for validity */ optreset; /* reset getopt */ char *optarg; /* argument associated with option */ #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" /* * getopt -- * Parse argc/argv argument vector. */ int getopt(nargc, nargv, ostr) int nargc; char * const *nargv; const char *ostr; { extern char *__progname; static char *place = EMSG; /* option letter processing */ char *oli; /* option letter list index */ if (optreset || !*place) { /* update scanning pointer */ optreset = 0; if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; return (EOF); } if (place[1] && *++place == '-') { /* found "--" */ ++optind; place = EMSG; return (EOF); } } /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr, optopt))) { /* * if the user didn't specify '-' as an option, * assume it means EOF. */ if (optopt == (int)'-') return (EOF); if (!*place) ++optind; if (opterr && *ostr != ':') (void)fprintf(stderr, "%s: illegal option -- %c\n", __progname, optopt); return (BADCH); } if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; } else { /* need an argument */ if (*place) /* no white space */ optarg = place; else if (nargc <= ++optind) { /* no arg */ place = EMSG; if (*ostr == ':') return (BADARG); if (opterr) (void)fprintf(stderr, "%s: option requires an argument -- %c\n", __progname, optopt); return (BADCH); } else /* white space */ optarg = nargv[optind]; place = EMSG; ++optind; } return (optopt); /* dump back option letter */ } bing-1.1.3/win32/win32.h0100644000076500007770000000026006345722245014323 0ustar mbabcockcoding#ifndef bing_win32_h_ #define bing_win32_h_ #define WIN32_LEAN_AND_MEAN #define NOSERVICE #define NOMCX #define NOIME #include #endif /* End of File */ bing-1.1.3/win32/types.h0100644000076500007770000000065306345722250014527 0ustar mbabcockcoding#ifndef bing_types_h_ #define bing_types_h_ #include /* * Missing in Microsoft's types.h */ typedef unsigned short u_short; typedef unsigned long u_long; typedef char* caddr_t; typedef u_short n_short; /* short as received from the net */ typedef u_long n_long; /* long as received from the net */ typedef u_long n_time; /* ms since 00:00 GMT, byte rev */ #endif /* End of File */ bing-1.1.3/unix/0042755000076500007770000000000006345720660013237 5ustar mbabcockcodingbing-1.1.3/unix/icmp_ux.c0100644000076500007770000001264606345720660015053 0ustar mbabcockcoding/* $Id$ */ /* Usual includes/declarations */ #include #include #include #include /* More specific includes/declarations */ #include /* Network includes/definitions */ #include #include #include #include #ifdef linux /* Needed for IP structures */ #include #endif /* These come either from the compatibility library or from the * standard libraries. */ #include #include #include "mod_icmp.h" typedef struct { int s; /* Raw socket fd */ short id; /* 16 bit id to be put in the echo request */ struct timeval last_send; /* date of last send */ struct timeval timeout; /* timeout for replies */ fd_set fds; /* Precomputed fd_set for select() */ } mod_icmp_i; #define to_mod_icmp(h) ((mod_icmp_i*)(h)) /* * tvsub -- * Subtract 2 timeval structs: out = out - in. * Out is assumed to be >= in. */ void tvsub(out, in) register struct timeval *out, *in; { if ((out->tv_usec -= in->tv_usec) < 0) { --out->tv_sec; out->tv_usec += 1000000; } out->tv_sec -= in->tv_sec; } /* * in_cksum -- * Checksum routine for Internet Protocol family headers (C Version) */ static int in_cksum(addr, len) u_short *addr; int len; { register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); } icmp_handle icmp_open() { struct protoent *proto; int s; mod_icmp_i *new; if (!(proto = getprotobyname("icmp"))) { fprintf(stderr, "unknown protocol icmp.\n"); return NULL; } /* * Open a raw socket */ if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) { perror("socket"); return NULL; } /* * Everything ok, alloc our private state */ new = (mod_icmp_i *)malloc(sizeof(mod_icmp_i)); if (new == NULL) { close(s); fprintf(stderr, "out of memory!\n"); return NULL; } new->s = s; new->id = getpid() & 0xFFFF; FD_ZERO(&new->fds); FD_SET(new->s, &new->fds); return (icmp_handle)new; } int icmp_set_option(handle,level,optname,optval,optlen) icmp_handle handle; int level; int optname; void *optval; int optlen; { return setsockopt(to_mod_icmp(handle)->s, level, optname, optval, optlen); } void icmp_set_timeout(handle,timeout) icmp_handle handle; unsigned long timeout; { mod_icmp_i *h = to_mod_icmp(handle); h->timeout.tv_sec = timeout / 1000000; h->timeout.tv_usec = timeout % 1000000; } unsigned short icmp_get_id(handle) icmp_handle handle; { mod_icmp_i *h = to_mod_icmp(handle); return h->id; } int icmp_send(handle,msg,msg_size,to_addr,to_addr_size) icmp_handle handle; void *msg; int msg_size; struct sockaddr *to_addr; int to_addr_size; { mod_icmp_i *h = to_mod_icmp(handle); struct icmp *icmp_header; /* Fill-in the last bits in the icmp message */ icmp_header = (struct icmp *)msg; icmp_header->icmp_id = h->id; /* Compute the checksum */ icmp_header->icmp_cksum = 0; icmp_header->icmp_cksum = in_cksum((u_short *)msg, msg_size); /* Get the send date as late as possible */ gettimeofday(&h->last_send, (struct timezone *)NULL); /* Send packet and return to caller */ return sendto(h->s, (char *)msg, msg_size, 0, (struct sockaddr *)to_addr, to_addr_size); } int icmp_recv(handle,buf,buflen,from_addr,from_addr_size,elapsed) icmp_handle handle; char *buf; int buflen; struct sockaddr *from_addr; int *from_addr_size; double *elapsed; { mod_icmp_i *h = to_mod_icmp(handle); int cc; int rsel; struct timeval tv, selw; /* * Note that we can spare rebuilding the FD mask each time, * since it will only be altered if select() times out, in which * case we exit anyway... */ FD_SET(h->s, &h->fds); /* Set timeout */ selw = h->timeout; /* Wait */ rsel = select(h->s+1, &h->fds, (fd_set *)0, (fd_set *)0, &selw); /* Get date as soon as possible */ gettimeofday(&tv, (struct timezone *)NULL); /* Compute the elapsed time since last icmp_send */ tvsub(&tv, &h->last_send); *elapsed = ((double)tv.tv_sec * 1e3) + ((double)tv.tv_usec / 1e3); if (rsel > 0) { /* Got a reply packet, read it and return it */ cc = recvfrom(h->s, buf, buflen, 0, from_addr, from_addr_size); return cc; } else if (rsel == 0) { /* Time out */ return 0; } else if (errno == EINTR) { return -1; } else { perror("select"); exit(1); } } int icmp_close(handle) icmp_handle handle; { mod_icmp_i *h = to_mod_icmp(handle); close(h->s); free(h); return 0; } bing-1.1.3/unix/bing.80100644000076500007770000001717106345720331014244 0ustar mbabcockcoding.\" -*- nroff -*- .rn '' }` '\" Copyright (c) 1985, 1991 The Regents of the University of California. '\" All rights reserved. '\" '\" Redistribution and use in source and binary forms, with or without '\" modification, are permitted provided that the following conditions '\" are met: '\" 1. Redistributions of source code must retain the above copyright '\" notice, this list of conditions and the following disclaimer. '\" 2. Redistributions in binary form must reproduce the above copyright '\" notice, this list of conditions and the following disclaimer in the '\" documentation and/or other materials provided with the distribution. '\" 3. All advertising materials mentioning features or use of this software '\" must display the following acknowledgement: '\" This product includes software developed by the University of '\" California, Berkeley and its contributors. '\" 4. Neither the name of the University nor the names of its contributors '\" may be used to endorse or promote products derived from this software '\" without specific prior written permission. '\" '\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND '\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE '\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE '\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE '\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL '\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS '\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) '\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT '\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY '\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF '\" SUCH DAMAGE. '\" '\" bing.8, unofficial release v1.1.3 '\" .de Sh .br .ne 5 .PP \fB\\$1\fR .PP .. .de Sp .if t .sp .5v .if n .sp .. '\" '\" Set up \*(-- to give an unbreakable dash; '\" string Tr holds user defined translation string. '\" Bell System Logo is used as a dummy character. '\" .ie n \{\ .tr \(*W-\*(Tr .ds -- \(*W- .if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch .if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch .ds L" "" .ds R" "" .ds L' ' .ds R' ' 'br \} .el \{\ .ds -- \(em\| .tr \*(Tr .ds L" `` .ds R" '' .ds L' ` .ds R' ' 'br\} .TH BING 8 "April 3, 1995" "" "UNIX System Manager's Manual" .SH NAME .B bing - compute point to point throughput using two sizes of ICMP ECHO_REQUEST packets to pairs of remote hosts. .SH SYNOPSIS .B bing [\fBdDnrRPvVwz\fP] [\fB-c\fP \fIcount\fR] [\fB-e\fP \fIsamples\fR] [\fB-f\fP \fIsamplefile\fR] [\fB-i\fP \fIwait\fR] [\fB-p\fP \fIpattern\fR] [\fB-s\fP \fIsmall packetsize\fR] [\fB-S\fP \fIbig packetsize\fR] \fIhost1 host2\fR [\fI...\fR] .SH DESCRIPTION .B Bing determines bandwidth on a point-to-point link by sending ICMP ECHO_REQUEST packets and measuring their roundtrip times for different packet sizes on each end of the link. .PP \fIhost1\fR is supposed to be the nearest end of the link, while \fIhost2\fR is the other end. .PP The options are as follows: .TP 5 \fB-c\fP \fIcount\fR Stop after \fIcount\fR resets of the stats. Useful only in conjunction with the \fB-e\fP option. Defaults to 1. .TP 5 \fB-d\fP Set the SO_DEBUG option on the socket being used. .TP 5 \fB-D\fP Display the measured throughput at every received packet. By default, it is displayed only when the computed value changes, which itself changes only when the minimum roundtrip time for one of the packet sizes changes. .TP 5 \fB-e\fP \fIsamples\fR Reset stats after sending \fIsamples\fR ECHO_REQUEST packets. .TP 5 \fB-f\fP \fIsamplefile\fR Saves the bandwidth measurements to the file \fIsamplefile\fR. .TP 5 \fB-i\fP \fIwait\fR Wait \fIwait\fR seconds \fIfor each\fR ECHO_REPLY packet. The default is to wait for four seconds. .TP 5 \fB-n\fP Numeric output only. No attempt will be made to lookup symbolic names for host addresses. .TP 5 \fB-P\fP Be pedantic regarding round-trip times. Normally, \fBbing\fP assumes that the roundtrip time for a small packet should always be smaller than the roundtrip time for a big packet to the same host, that for a given size the roundtrip time for \fBhost1\fP should always be smaller than the roundtrip time for \fBhost2\fP, and that the increase in the roundtrip time between \fBhost1\fP and \fBhost2\fP should always be bigger for big packets than for small packets. \fBBing\fP takes advantage of this to better determine the minimum roundtrip times. Option \fB-P\fP disables this behaviour, in the unlikely event it could be of any use someday. Even IP/X25 links are not weird enough to require this, though. .TP 5 \fB-p\fP \fIpattern\fR You may specify up to 16 ``pad'' bytes to fill out the packet you send. This is useful for diagnosing data-dependent problems in a network. For example, ``-p ff'' will cause the sent packet to be filled with all ones. .TP 5 \fB-R\fP Record route. Includes the RECORD_ROUTE option in the ECHO_REQUEST packet and displays the route buffer on returned packets. Note that the IP header is only large enough for nine such routes. Many hosts ignore or discard this option. .TP 5 \fB-r\fP Bypass the normal routing tables and send directly to a host on an attached network. If the host is not on a directly-attached network, an error is returned. This option can be used to ping a local host through an interface that has no route through it (e.g., after the interface was dropped by routed(8)). .TP 5 \fB-s\fP \fIsmall packetsize\fR Specifies the number of data bytes to be sent in the small packets. The default and minimum value is 44. .TP 5 \fB-S\fP \fIbig packetsize\fR Specifies the number of data bytes to be sent in the big packets. The default is 108. The size should be chosen so that big packet roundtrip times are long enough to be accurately measured (depending on clock resolution and number of hops). .TP 5 \fB-u\fP \fIsize increment\fR Specifies that \fBbing\fR should start sending packets of the size of \fIsmall packetsize\fR and then increase the size by \fIsize increment\fR until it reaches \fIbig packetsize\fR. .TP 5 \fB-v\fP Verbose output. ICMP packets other than ECHO_RESPONSE that are received are listed. .TP 5 \fB-V\fP Very verbose output. The roundtrip time of each received echo is displayed. .TP 5 \fB-w\fP Display possible warnings about roundtrip times all the time. By default, warnings are printed only at the end. .TP 5 \fB-z\fP Fill packets with uncompressible (pseudo-random) data. .PP Round-trip times and packet loss statistics are computed. If duplicate packets are received, they are not included in the packet loss calculation, although the round trip time of these packets is used in calculating the minimum/average/maximum round-trip time numbers. When the specified number of loops have been made or if the program is terminated with a SIGINT, a brief summary is displayed. This program is intended for use in network testing, measurement and management. Because of the load it can impose on the network, it is unwise to use \fBbing\fP during normal operations or from automated scripts. .SH BUGS Many Hosts and Gateways ignore the RECORD_ROUTE option. The maximum IP header length is too small for options like RECORD_ROUTE to be completely useful. There's not much that that can be done about this, however. Some of the final stats (average throughputs) almost never give a even marginally correct result. .SH SEE ALSO netstat(1), ifconfig(8), ping(8), routed(8), traceroute(8) .SH AUTHOR Pierre Beyssac Port to Windows: Francois Gouget .rn }` '' bing-1.1.3/Readme.txt0100644000076500007770000002701106345721224014203 0ustar mbabcockcoding ** Unofficial Release ** Bing 1.1.3 Table of Contents ----------------- 1. What is bing ? 2. Infos on bing 3. Installing bing 1. Installing bing on Unix systems 2. Installing bing on Windows systems 4. How to use bing 5. Measurement problems 6. Packet loss evaluation 7. Ethernet devices measurement 8. Possible NTP influence 9. Possible enhancements 1. What is bing ? ----------------- Bing is a point-to-point bandwidth measurement tool (hence the 'b'), based on ping. Bing determines the real (raw, as opposed to available or average) throughput on a link by measuring ICMP echo requests roundtrip times for different packet sizes for each end of the link. Suppose we are on host A and want to know the throughput between L1 and L2, two extremities of a point-to-point link. A ----( the Internet )--- L1 --- L2 If we know the rtt (roundtrip time) between A and L1, and the rtt between A and L2, we can deduce the rtt between L1 and L2. If we do that for two different packet sizes, we can compute the raw capacity (bps) of the link. Note that bing can also be used to have an idea of ethernet cards performance. Many thanks to the following people for their help, hints, support, and real beers : Marc Baudoin Fran‡ois Berjon Julien Boissinot St‰phane Bortzmeyer Jacques Caron Laurent Chemla Ren‰ Cougnenc Nat Makarevitch Jean-Philippe Nicaise Christian Perrier Bertrand Petit Philippe Regnauld Ollivier Robert Herv‰ Schauer Christophe Wolfhugel Send virtual beers, bug reports, enhancements and flames to : Pierre Beyssac 2. Infos on bing ---------------- You can subscribe to the "bing-users" mailing list by sending a mail containing : subscribe bing-users to . The posting address is 3. Installing bing ------------------ The provided source has been compiled and run on : Linux 2.0.28 SunOS 4.1.3 SunOS 5 (Solaris 2.5) AIX 2 (BOSX 2 actually) OSF1 V2.0 (DEC Alpha) Windows 95 Windows NT 3.51 and 4.0 on i386 It is expected to compile and run with minor changes in the Makefile on many more platforms. 3.1. Installing bing on Unix systems ------------------------------------ You should first edit the Makefile to adjust it to your system. There are few options and if your host is in the list above the lines to uncomment are already listed. If this is not the case you will have to make a few tries but it should not be very difficult. Send me the options that you had to change together with your "uname -s -r" so that I can add it to the list. Then (on all systems) : $ make $ su root # make install bing, like ping, needs to be installed setuid root to be able to make its own ICMP packets. 3.2. Installing bing on Windows systems --------------------------------------- To compile bing you must also get the icmp package. This is a package which provides the required include files and libraries to send and receive ICMP messages. You may also have to modify the file makefile.nt so that ICMP_DIR points to the place where you have put the ICMP package. Then the command below should be enough: nmake -f makefile.nt There are options you may add to this command line to customise the result. All options are disabled by default: - DLL=1 Links bing with the Dll C library rather. This makes bing much smaller but may require that you ship the Dll with it. - DEBUG=1 Builds a debug version. - BROWSER=1 Generates Visual C++'s "browser" database. and commands - all or Builds bing. - clean Removes the generated files. - help Describes the makefile options. 4. How to use bing ------------------ 1) using 'traceroute', find the IP adresses of the endpoints of the link you want to measure. 2) try : bing -v point1 point2 where 'point1' is the nearest endpoint. Option '-v' is useful to be warned of any routing problems. 3) wait a little for the measure to stabilize. 4) if after a while, the measurement looks weird (typically, negative or amazing throughputs) have a look at the indicated roundtrip times. If they are too small (below a few milliseconds), try to rerun bing with a bigger packet size : bing -S 1000 -v point1 point2 CAUTION : do not increase packet size too much, because this could trigger IP fragmentation/reassembly on the link to measure *or* on intermediate links, which messes up the measures completely. If you stay below 1400 bytes, you should be safe (except on SLIP links where you should not go over 1000). This depends on the MTU (maximum transmit unit) of the link. 5) if, after increasing packet size, you still can't get stable results, try to use the -z option. This option fills packets will random data, defeating compressed links. 6) if you still can't get anything reasonnable, the link you're trying to measure is probably a high-throughput link too far away (network- and throughput-wise) from you, or some weird animal (IP over X25, Frame Relay, ATM, satellite...). You can try to run bing from a better connected machine (with respect to the target link). If you can't, you can always try to think of a way (I'm sure there are) of improving bing to make it work anyway :-). Probably the best solution is to find something else to do (I leave it to your choice entirely, suggestions are : go for a walk, eat, drink, be elected). 5. Measurement problems ----------------------- There are many cases in which the measurements may not be accurate (read: "plain wrong") : - links attained through a link of much lower throughput (typically, don't expect to measure a 34Mbps backbone link through your V32bis dialup account). You can expect to measure links about 15 to 30 times faster than the slower link in your path to them, i.e. up to 512kbps through a V32bis modem, up to 2Mbps through a 64kbps link, and so on. - saturated links. bing works by measuring the minimal rtts. The more saturated links there are in the measure path, the more time it takes to get a packet through all of them with minimal delay. - IP/X25 connections. Due to encapsulation in small packets, it is very difficult to know the "raw" bit capacity because the overhead by IP packet is not fixed and varies with the packet size. However, a clever bing could be able to find out about the encapsulating size by slowly increasing the strobe packet size and detecting steps in the rtt increase. Maybe one day ;-) - more generally, what you might call "hidden multi-hop" links can give strange results. This includes IP over X25, Frame Relay, as well as probably any IP encapsulation over a switched packet network. - padding. On many links, the smallest packet size is bigger than the smallest possible IP packet size and padding occurs. For example it happens on ethernet. It tends to give optimistic results. - non symmetrical routing : -----------------<--- | | | ( somewhere ) | ^ | | A ---( the Internet )--> L1 ---> L2 If the routings are set in such a way that the ICMP echo replies from L2 don't cross the L1-L2 link, bing can't reliably compute the link capacity. It generally happens, at least in France, on links crossing ASs (autonomous systems) between different providers. Sadly, these links happen to be the most interesting to measure, to be able to check providers claims regarding their connection with the rest of the world... I don't think there's an easy way around (this is the same problem as traceroute not being able to report network return paths). I have been objected that high-bandwidth links with dedicated routers might be impossible to measure, due to the way these devices work. Fast routers are designed in such a way that, when receiving a packet, they decode the header as soon as possible, even before the packet is completely received. They can thus decide on an outgoing route for the packet and might even (I'm not sure about that) begin resending it before receiving it completely. This should not directly interfere with ICMP ECHO_REQUEST packets because these packets must be locally processed and this is generally done entirely by software at a lower priority when the packet has been completely received. Moreover, since bing only considers minimal round-trip times in its throughput calculations, you only have to expect that some ICMP ECHO_REQUESTs will be processed by the router as soon as they are received, which should happen often enough if the router is not saturated. 6. Packet loss evaluation ------------------------- Knowing the packet losses on A-L1 and on A-L2, it should be possible to compute the loss between L1 and L2 : A --- L1 --- L2 a b A-L1 packet loss = a A-L2 packet loss = ab L1-L2 packet loss = ab / a Bing attempts to calculate it, but the results are generally not significant. 7. Ethernet devices measurement ------------------------------- This might sound surprising, since ethernet throughput is known to be 10Mbps ! By running bing between two machines on an ethernet, you can evaluate the CPU overhead induced by memory copies and polled I/O. For example, between two Sparc 2 running SunOS 4.1.3, I generally get around 9Mbps. Between two PCs running FreeBSD with NE2000 clones, expect around 4 or 5Mbps (or a little more depending on processor speed). Between two PCs with 3C509 cards, I get about 7Mbps. 8. Possible NTP influence ------------------------- Though I never got any evidence of it, it is possible that running bing on a NTP-synchronized machine introduces a bias in the measurements, when the NTP daemon makes a small correction while bing is waiting for an echo reply packet (almost all the time). I suppose this should mainly have an effect when measuring fast and far away links, which are difficult or impossible to measure anyway. 9. Possible enhancements ------------------------ * It should be possible to measure mono-directional throughput by varying the packet size only for one of the packets, the sent packet or the received packet. For example, sending variable-sized ICMP ECHO_REPLY packets with a small TTL should elicit fixed-size "ttl exceeded" replies. * Another interesting extension would be a mechanism trying to determine the optimal big packet size in such a way that the measurement is accurate enough yet fast. * Bing derives from ping and it shows. Its structure could probably be enhanced, modularised and simplified. Also many options that were significant for ping are not significant for bing and could be removed. * Most of the IP options are not supported by the icmp part of the Win32 version. While they may not really be needed it they could be by building the IP options by hand. * The Win32 error reporting needs to be fixed. It reflects more what could have happened on Unix that what actually happened and the error codes are usually incorrect. * The makefile is probably too Visual C++ centric. I'd be interested in a makefile for Borland or Watcom or other. * An option to disable the "smart" display of the measured bandwidth could ease the parsing of the results by a script. bing-1.1.3/Readme.1st0100644000076500007770000000746106345721220014076 0ustar mbabcockcoding Bing 1.1.3 Table of Contents ----------------- 1. About this release ? 2. Where to get it ? 3. Why would you want to use this release of bing ? 4. What's new ? 5. Who should you report bugs to ? 1. About this release ? ----------------------- This is an unofficial bing release. I ported bing to the Win32 platform and made changes so that the same code could be compiled on Unix and on Win32. I reported the changes to Pierre and he found them acceptable. He made some more changes that were integrated back into this version. But right now he does not have the time to make an official bing release. This is why decided to get this version out (with his agreement). So here unofficial means that the source code versioning is not done by Pierre and that it is probably better if you bother me rather than Pierre if you have problems (see point 4). Also I have modified the Readme.txt file and the documentation, so assume Pierre is responsible for the good things and I'm responsible for the bad ones ! As for versioning we agreed to use a scheme similar to that of the Linux kernel: x.y.z x is the major version number, actually 1 z is the fix/patch/iteration level y is the minor version. If even then the release is "stable", if odd it is unstable. So the last stable release is 1.0.4 and the current one is 1.1.2. 1.1.2 also means that with this release can be heavily patched/ modified/enhanced. So if you want to hack the source don't hesitate. When the time comes there will be a new version: 1.2.0 or 2.0.0 depending on the amount of changes. 2. Where to get it ? -------------------- Currently it's only available on my Web site: http://www.mygale.org/~fgouget/apps/index_uk.shtml If you have problems getting it, send me an email at: fgouget@club-internet.fr 3. Why would you want to use this release of bing ? -------------------------------------------------- - Because you're using Windows and this is the only release of bing for Win32 platforms to my knowledge. - Because you want to make sure that this release of bing still compiles on your platform. This has to be checked because of the "cleanup" that have been made to the code. It no longer uses the "sysdep.h" file for instance. - Because you want to modify bing. In that case it's better to modify this code because it will avoid having two diverging versions. Too late ??!! Ooops. - Because you want to check that this release of bing did not introduce bugs (especially security bugs) in the Unix version. This is very kind of you and I'll appreciate bug reports very much. 4. What's new ? --------------- Release 1.1.3: - The RTT measurement on Win32 is now on a par with that of Unix, i.e. the precision is in the order of 10 microseconds. - bing has been made more portable. You should have fewer problems compiling bing 1.1.3 on your platform. - bing now displays Mbps or Kbps as most sensible. Release 1.1.2: - All the icmp specific code has been put in the "mod_icmp" module. The bing core accesses this code via the interface defined in "mod_icmp.h". - The files layout has been modified to accomodate the Unix/Win32 duality. This layout is not yet really satisfactory. - The code has been "cleaned". The process if far from being finished yet (imho). - Pierre added two options '-u' and 'f' - bing now supports multiple hosts on the command line, not only two. - Also read the ChangeLog. For more details, see the ChangeLog file. 5. Who should you report bugs to ? ---------------------------------- The best place to start with is still the bing user list. Otherwise it is better if you bug me rather than Pierre since after all I took the responsibility for getting this release out. So to contact me, send mail to: fgouget@club-internet.fr bing-1.1.3/include/0042755000076500007770000000000006342663440013676 5ustar mbabcockcodingbing-1.1.3/include/netinet/0042755000076500007770000000000006345720703015343 5ustar mbabcockcodingbing-1.1.3/include/netinet/ip.h0100644000076500007770000001474706345720673016142 0ustar mbabcockcoding/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ip.h 8.1 (Berkeley) 6/10/93 * ip.h,v 1.5 1995/05/30 08:09:33 rgrimes Exp */ #ifndef _NETINET_IP_H_ #define _NETINET_IP_H_ /* * Define the bytesex if it has not already been done. */ #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #endif #ifndef BIG_ENDIAN #define BIG_ENDIAN 4321 #endif #ifndef PDP_ENDIAN #define PDP_ENDIAN 3412 #endif #ifndef BYTE_ORDER #if defined(i386) || defined(__i386__) || defined(__alpha__) \ || (defined(__mips__) && (defined(MIPSEL) || defined (__MIPSEL__))) #define BYTE_ORDER LITTLE_ENDIAN #elif defined(__mc68000__) || defined (__sparc__) || defined (__PPC__) \ || (defined(__mips__) && (defined(MIPSEB) || defined (__MIPSEB__))) # define BYTE_ORDER BIG_ENDIAN #else # error Unknown architecture. You must manually define the endianness. #endif #endif /* * Definitions for internet protocol version 4. * Per RFC 791, September 1981. */ #define IPVERSION 4 /* * Structure of an internet header, naked of options. * * We declare ip_len and ip_off to be short, rather than u_short * pragmatically since otherwise unsigned comparisons can result * against negative integers quite easily, and fail in subtle ways. */ struct ip { #if BYTE_ORDER == LITTLE_ENDIAN u_char ip_hl:4, /* header length */ ip_v:4; /* version */ #endif #ifndef WIN32 #if BYTE_ORDER == BIG_ENDIAN u_char ip_v:4, /* version */ ip_hl:4; /* header length */ #endif #endif u_char ip_tos; /* type of service */ short ip_len; /* total length */ u_short ip_id; /* identification */ short ip_off; /* fragment offset field */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ }; #define IP_MAXPACKET 65535 /* maximum packet size */ /* * Definitions for IP type of service (ip_tos) */ #define IPTOS_LOWDELAY 0x10 #define IPTOS_THROUGHPUT 0x08 #define IPTOS_RELIABILITY 0x04 #define IPTOS_MINCOST 0x02 /* * Definitions for IP precedence (also in ip_tos) (hopefully unused) */ #define IPTOS_PREC_NETCONTROL 0xe0 #define IPTOS_PREC_INTERNETCONTROL 0xc0 #define IPTOS_PREC_CRITIC_ECP 0xa0 #define IPTOS_PREC_FLASHOVERRIDE 0x80 #define IPTOS_PREC_FLASH 0x60 #define IPTOS_PREC_IMMEDIATE 0x40 #define IPTOS_PREC_PRIORITY 0x20 #define IPTOS_PREC_ROUTINE 0x00 /* * Definitions for options. */ #define IPOPT_COPIED(o) ((o)&0x80) #define IPOPT_CLASS(o) ((o)&0x60) #define IPOPT_NUMBER(o) ((o)&0x1f) #define IPOPT_CONTROL 0x00 #define IPOPT_RESERVED1 0x20 #define IPOPT_DEBMEAS 0x40 #define IPOPT_RESERVED2 0x60 #define IPOPT_EOL 0 /* end of option list */ #define IPOPT_NOP 1 /* no operation */ #define IPOPT_RR 7 /* record packet route */ #define IPOPT_TS 68 /* timestamp */ #define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ #define IPOPT_LSRR 131 /* loose source route */ #define IPOPT_SATID 136 /* satnet id */ #define IPOPT_SSRR 137 /* strict source route */ /* * Offsets to fields in options other than EOL and NOP. */ #define IPOPT_OPTVAL 0 /* option ID */ #define IPOPT_OLEN 1 /* option length */ #define IPOPT_OFFSET 2 /* offset within option */ #define IPOPT_MINOFF 4 /* min value of above */ /* * Time stamp option structure. */ struct ip_timestamp { u_char ipt_code; /* IPOPT_TS */ u_char ipt_len; /* size of structure (variable) */ u_char ipt_ptr; /* index of current entry */ #if BYTE_ORDER == LITTLE_ENDIAN u_char ipt_flg:4, /* flags, see below */ ipt_oflw:4; /* overflow counter */ #endif #ifndef WIN32 #if BYTE_ORDER == BIG_ENDIAN u_char ipt_oflw:4, /* overflow counter */ ipt_flg:4; /* flags, see below */ #endif #endif union ipt_timestamp { n_long ipt_time[1]; struct ipt_ta { struct in_addr ipt_addr; n_long ipt_time; } ipt_ta[1]; } ipt_timestamp; }; /* flag bits for ipt_flg */ #define IPOPT_TS_TSONLY 0 /* timestamps only */ #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ #define IPOPT_TS_PRESPEC 3 /* specified modules only */ /* bits for security (not byte swapped) */ #define IPOPT_SECUR_UNCLASS 0x0000 #define IPOPT_SECUR_CONFID 0xf135 #define IPOPT_SECUR_EFTO 0x789a #define IPOPT_SECUR_MMMM 0xbc4d #define IPOPT_SECUR_RESTR 0xaf13 #define IPOPT_SECUR_SECRET 0xd788 #define IPOPT_SECUR_TOPSECRET 0x6bc5 /* * Internet implementation parameters. */ #define MAXTTL 255 /* maximum time to live (seconds) */ #define IPDEFTTL 64 /* default ttl, from RFC 1340 */ #define IPFRAGTTL 60 /* time to live for frags, slowhz */ #define IPTTLDEC 1 /* subtracted when forwarding */ #define IP_MSS 576 /* default maximum segment size */ #endif bing-1.1.3/include/netinet/ip_icmp.h0100644000076500007770000001471006345720677017144 0ustar mbabcockcoding/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp */ #ifndef _NETINET_IP_ICMP_H_ #define _NETINET_IP_ICMP_H_ /* * Interface Control Message Protocol Definitions. * Per RFC 792, September 1981. */ /* * Structure of an icmp header. */ struct icmp { u_char icmp_type; /* type of message, see below */ u_char icmp_code; /* type sub code */ u_short icmp_cksum; /* ones complement cksum of struct */ union { u_char ih_pptr; /* ICMP_PARAMPROB */ struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ struct ih_idseq { n_short icd_id; n_short icd_seq; } ih_idseq; int ih_void; /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ struct ih_pmtu { n_short ipm_void; n_short ipm_nextmtu; } ih_pmtu; } icmp_hun; #define icmp_pptr icmp_hun.ih_pptr #define icmp_gwaddr icmp_hun.ih_gwaddr #define icmp_id icmp_hun.ih_idseq.icd_id #define icmp_seq icmp_hun.ih_idseq.icd_seq #define icmp_void icmp_hun.ih_void #define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void #define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu union { struct id_ts { n_time its_otime; n_time its_rtime; n_time its_ttime; } id_ts; struct id_ip { struct ip idi_ip; /* options and then 64 bits of data */ } id_ip; u_long id_mask; char id_data[1]; } icmp_dun; #define icmp_otime icmp_dun.id_ts.its_otime #define icmp_rtime icmp_dun.id_ts.its_rtime #define icmp_ttime icmp_dun.id_ts.its_ttime #define icmp_ip icmp_dun.id_ip.idi_ip #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data }; /* * Lower bounds on packet lengths for various types. * For the error advice packets must first insure that the * packet is large enought to contain the returned ip header. * Only then can we do the check to see if 64 bits of packet * data have been returned, since we need to check the returned * ip header length. */ #define ICMP_MINLEN 8 /* abs minimum */ #define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ #define ICMP_MASKLEN 12 /* address mask */ #define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ #define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) /* N.B.: must separately check that ip_hl >= 5 */ /* * Definition of type and code field values. */ #define ICMP_ECHOREPLY 0 /* echo reply */ #define ICMP_UNREACH 3 /* dest unreachable, codes: */ #define ICMP_UNREACH_NET 0 /* bad net */ #define ICMP_UNREACH_HOST 1 /* bad host */ #define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ #define ICMP_UNREACH_PORT 3 /* bad port */ #define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ #define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ #define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ #define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ #define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ #define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ #define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ #define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ #define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ #define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ #define ICMP_REDIRECT 5 /* shorter route, codes: */ #define ICMP_REDIRECT_NET 0 /* for network */ #define ICMP_REDIRECT_HOST 1 /* for host */ #define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ #define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ #define ICMP_ECHO 8 /* echo service */ #define ICMP_ROUTERADVERT 9 /* router advertisement */ #define ICMP_ROUTERSOLICIT 10 /* router solicitation */ #define ICMP_TIMXCEED 11 /* time exceeded, code: */ #define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ #define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ #define ICMP_PARAMPROB 12 /* ip header bad */ #define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ #define ICMP_TSTAMP 13 /* timestamp request */ #define ICMP_TSTAMPREPLY 14 /* timestamp reply */ #define ICMP_IREQ 15 /* information request */ #define ICMP_IREQREPLY 16 /* information reply */ #define ICMP_MASKREQ 17 /* address mask request */ #define ICMP_MASKREPLY 18 /* address mask reply */ #define ICMP_MAXTYPE 18 #define ICMP_INFOTYPE(type) \ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) #ifdef KERNEL void icmp_error __P((struct mbuf *, int, int, n_long, struct ifnet *)); void icmp_input __P((struct mbuf *, int)); void icmp_reflect __P((struct mbuf *)); void icmp_send __P((struct mbuf *, struct mbuf *)); int icmp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t)); #endif #endif bing-1.1.3/include/netinet/ip_var.h0100644000076500007770000001760706345720703017002 0ustar mbabcockcoding/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ip_var.h 8.1 (Berkeley) 6/10/93 * ip_var.h,v 1.10 1995/05/30 08:09:50 rgrimes Exp */ #ifndef _NETINET_IP_VAR_H_ #define _NETINET_IP_VAR_H_ /* * Overlay for ip header used by other protocols (tcp, udp). */ struct ipovly { caddr_t ih_next, ih_prev; /* for protocol sequence q's */ u_char ih_x1; /* (unused) */ u_char ih_pr; /* protocol */ short ih_len; /* protocol length */ struct in_addr ih_src; /* source internet address */ struct in_addr ih_dst; /* destination internet address */ }; /* * Ip reassembly queue structure. Each fragment * being reassembled is attached to one of these structures. * They are timed out after ipq_ttl drops to 0, and may also * be reclaimed if memory becomes tight. */ struct ipq { struct ipq *next,*prev; /* to other reass headers */ u_char ipq_ttl; /* time for reass q to live */ u_char ipq_p; /* protocol of this fragment */ u_short ipq_id; /* sequence id for reassembly */ struct ipasfrag *ipq_next,*ipq_prev; /* to ip headers of fragments */ struct in_addr ipq_src,ipq_dst; }; /* * Ip header, when holding a fragment. * * Note: ipf_next must be at same offset as ipq_next above */ struct ipasfrag { #if BYTE_ORDER == LITTLE_ENDIAN u_char ip_hl:4, ip_v:4; #endif #if BYTE_ORDER == BIG_ENDIAN u_char ip_v:4, ip_hl:4; #endif u_char ipf_mff; /* XXX overlays ip_tos: use low bit * to avoid destroying tos; * copied from (ip_off&IP_MF) */ short ip_len; u_short ip_id; short ip_off; u_char ip_ttl; u_char ip_p; u_short ip_sum; struct ipasfrag *ipf_next; /* next fragment */ struct ipasfrag *ipf_prev; /* previous fragment */ }; /* * Structure stored in mbuf in inpcb.ip_options * and passed to ip_output when ip options are in use. * The actual length of the options (including ipopt_dst) * is in m_len. */ #define MAX_IPOPTLEN 40 struct ipoption { struct in_addr ipopt_dst; /* first-hop dst if source routed */ char ipopt_list[MAX_IPOPTLEN]; /* options proper */ }; /* * Structure attached to inpcb.ip_moptions and * passed to ip_output when IP multicast options are in use. */ struct ip_moptions { struct ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */ u_long imo_multicast_vif; /* vif num outgoing multicasts */ u_char imo_multicast_ttl; /* TTL for outgoing multicasts */ u_char imo_multicast_loop; /* 1 => hear sends if a member */ u_short imo_num_memberships; /* no. memberships this socket */ struct in_multi *imo_membership[IP_MAX_MEMBERSHIPS]; }; struct ipstat { u_long ips_total; /* total packets received */ u_long ips_badsum; /* checksum bad */ u_long ips_tooshort; /* packet too short */ u_long ips_toosmall; /* not enough data */ u_long ips_badhlen; /* ip header length < data size */ u_long ips_badlen; /* ip length < ip header length */ u_long ips_fragments; /* fragments received */ u_long ips_fragdropped; /* frags dropped (dups, out of space) */ u_long ips_fragtimeout; /* fragments timed out */ u_long ips_forward; /* packets forwarded */ u_long ips_cantforward; /* packets rcvd for unreachable dest */ u_long ips_redirectsent; /* packets forwarded on same net */ u_long ips_noproto; /* unknown or unsupported protocol */ u_long ips_delivered; /* datagrams delivered to upper level*/ u_long ips_localout; /* total ip packets generated here */ u_long ips_odropped; /* lost packets due to nobufs, etc. */ u_long ips_reassembled; /* total packets reassembled ok */ u_long ips_fragmented; /* datagrams sucessfully fragmented */ u_long ips_ofragments; /* output fragments created */ u_long ips_cantfrag; /* don't fragment flag was set, etc. */ u_long ips_badoptions; /* error in option processing */ u_long ips_noroute; /* packets discarded due to no route */ u_long ips_badvers; /* ip version != 4 */ u_long ips_rawout; /* total raw ip packets generated */ }; #ifdef KERNEL /* flags passed to ip_output as last parameter */ #define IP_FORWARDING 0x1 /* most of ip header exists */ #define IP_RAWOUTPUT 0x2 /* raw ip header exists */ #define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */ #define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */ extern struct ipstat ipstat; extern struct ipq ipq; /* ip reass. queue */ extern u_short ip_id; /* ip packet ctr, for ids */ extern int ip_defttl; /* default IP ttl */ extern u_char ip_protox[]; extern struct socket *ip_rsvpd; /* reservation protocol daemon */ extern struct socket *ip_mrouter; /* multicast routing daemon */ extern int (*legal_vif_num) __P((int)); int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **)); void ip_deq __P((struct ipasfrag *)); int ip_dooptions __P((struct mbuf *)); void ip_drain __P((void)); void ip_enq __P((struct ipasfrag *, struct ipasfrag *)); void ip_forward __P((struct mbuf *, int)); void ip_freef __P((struct ipq *)); void ip_freemoptions __P((struct ip_moptions *)); int ip_getmoptions __P((int, struct ip_moptions *, struct mbuf **)); void ip_init __P((void)); extern int (*ip_mforward) __P((struct ip *, struct ifnet *, struct mbuf *, struct ip_moptions *)); int ip_optcopy __P((struct ip *, struct ip *)); int ip_output __P((struct mbuf *, struct mbuf *, struct route *, int, struct ip_moptions *)); int ip_pcbopts __P((struct mbuf **, struct mbuf *)); struct ip * ip_reass __P((struct ipasfrag *, struct ipq *)); struct in_ifaddr * ip_rtaddr __P((struct in_addr)); int ip_setmoptions __P((int, struct ip_moptions **, struct mbuf *)); void ip_slowtimo __P((void)); struct mbuf * ip_srcroute __P((void)); void ip_stripoptions __P((struct mbuf *, struct mbuf *)); int ip_sysctl __P((int *, u_int, void *, size_t *, void *, size_t)); void ipintr __P((void)); int rip_ctloutput __P((int, struct socket *, int, int, struct mbuf **)); void rip_init __P((void)); void rip_input __P((struct mbuf *)); int rip_output __P((struct mbuf *, struct socket *, u_long)); int rip_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *)); int ip_rsvp_init __P((struct socket *)); int ip_rsvp_done __P((void)); void rip_ip_input __P((struct mbuf *mm, register struct socket *ip_mrouter, struct sockaddr *src)); #endif #endif bing-1.1.3/makefile.nt0100644000076500007770000000601506345411405014363 0ustar mbabcockcoding##### # Paths ##### # This path should point to where the icmp files are. !ifndef ICMP_DIR ICMP_DIR=../icmp_dev-0.1.1 !endif ICMP_INCLUDE=$(ICMP_DIR) ICMP_LIB=$(ICMP_DIR)/i386 # This is where you want the compiler to put the binaries # (including bing.exe). BIN=bin ##### # Macro definitions ##### # General options APPVER = 4.0 TARGETOS = BOTH TARGETLANG = LANG_FRENCH CPU=i386 !ifndef DEBUG NODEBUG=1 !endif !include # compilation !ifdef BROWSER cbrowser=-FR$(*D)/ !endif !ifdef DEBUG cdebug=-Od -Zi -Fd$(*D)/ !endif !ifdef DLL bing_cvars=$(cvarsdll) !else bing_cvars=$(cvars) !endif bing_cvars=-nologo $(bing_cvars) $(cdebug) $(cbrowser) -D$(CPU) -DNO_RANDOM -I$(ICMP_INCLUDE) -I. -Iinclude -c -Fo$(*D)/ # linking !ifdef DEBUG !ifdef DLL ldebug=-debug msvcrtd.lib !else ldebug=-debug libcd.lib !endif !endif bing_lflags=-nologo -nodefaultlib $(ldebug) -out:$@ !ifdef DLL bing_libs=$(conlibsdll) !else bing_libs=$(conlibs) !endif bing_libs=$(bing_libs) wsock32.lib $(ICMP_LIB)/icmp.lib ###### # What to do ###### L_OBJS= \ $(BIN)/bing.obj \ $(BIN)/icmp_win32.obj \ $(BIN)/getopt.obj \ L_EXE= \ $(BIN)/bing.exe \ L_BSC= \ !ifdef BROWSER $(BIN)/bing.bsc \ !endif all: bin_dir $(L_EXE) $(L_BSC) clean: if exist $(BIN)\*.obj del $(BIN)\*.obj if exist $(BIN)\*.exe del $(BIN)\*.exe if exist $(BIN)\*.ilk del $(BIN)\*.ilk if exist $(BIN)\*.pdb del $(BIN)\*.pdb if exist $(BIN)\*.sbr del $(BIN)\*.sbr if exist $(BIN)\*.bsc del $(BIN)\*.bsc if exist $(BIN)\nul rmdir $(BIN) bin_dir: -if not exist $(BIN)\nul mkdir $(BIN) help: @echo "Usage: nmake -f makefile.nt [DLL=1] [DEBUG=1] [BROWSER=1] [all | clean | help] @echo " @echo " DLL=1 @echo " Causes bing to be dynamically linked with the C library. @echo " DEBUG=1 @echo " Set DEBUG to 1 to generate debugging information for bing @echo " BROWSER=1 @echo " Use this option to generate information for the Microsoft browser @echo " @echo " all @echo " This causes bing to be built as specified by the options @echo " above. This is the default action. Note that if you @echo " change the options you should probably do a 'make clean' @echo " before you re-generate bing. @echo " clean @echo " This action deletes all the generated files *including* 'bing.exe'. @echo " help @echo " This action displays this help information. ###### # Commands ###### # compilation $(L_OBJS): $(CC) $(bing_cvars) -o $*.obj $** # link $(L_EXE): $(link) $(bing_lflags) $(bing_libs) $** # browser !ifdef BROWSER $(L_BSC): bscmake -nologo -o $@ $** !endif ##### # Dependencies ##### $(BIN)/bing.obj: bing.c $(BIN)/icmp_win32.obj: win32/icmp_win32.c $(BIN)/getopt.obj: win32/getopt.c $(BIN)/bing.exe: \ $(BIN)/bing.obj \ $(BIN)/icmp_win32.obj \ $(BIN)/getopt.obj \ !ifdef BROWSER $(BIN)/bing.bsc: \ $(BIN)/bing.sbr \ $(BIN)/icmp_win32.sbr \ $(BIN)/getopt.sbr \ !endif