Jon Allen Boone on Thu, 27 Feb 2003 11:44:05 -0500 |
James, Here's a unified diff with my changes. This is totally *unofficial*, as it doesn't meet mct's requirements for supporting both libnet 1.0 and 1.1, but it would get you started so that you can work on the autoconf stuff. --jon Begin forwarded message: From: Jon Allen Boone <ipmonger@delamancha.org> Date: Sun Jan 19, 2003 02:56:10 US/Eastern To: Michael C Toren <mct@toren.net> Cc: Jon Allen Boone <ipmonger@delamancha.org> Subject: tcptraceroute.c unified diff for use with libnet 1.1.0 --- tcptraceroute.c.orig Tue Jul 30 17:51:27 2002 +++ tcptraceroute.c Sun Jan 19 02:44:45 2003 @@ -30,13 +30,18 @@ * Updates are available from http://michael.toren.net/code/tcptraceroute/ */ -#define VERSION "tcptraceroute 1.4 (2002-07-30)" +#define VERSION "tcptraceroute 1.5 (2003-01-18)" #define BANNER "Copyright (c) 2001, 2002 Michael C. Toren <mct@toren.net>\n\ Updates are available from http://michael.toren.net/code/tcptraceroute/\n" /* * Revision history: * + * Version 1.5 (2003-01-18) + * + * Converted to use libnet-1.1.x instead of libnet-1.0.x + * by Jon Allen Boone <ipmonger@delamancha.org> + * * Version 1.4 (2002-07-30) * * Added linklayer support for Linux ISDN Sync-PPP interfaces, @@ -209,7 +214,7 @@ #define AF_LINK AF_INET /* BSD defines some AF_INET network interfaces as AF_LINK */ #endif -#if defined (__OpenBSD__) || defined(__FreeBSD__) || defined(__bsdi__) +#if defined (__OpenBSD__) || defined(__FreeBSD__) || defined(__bsdi__) || defined(__MACH__) #define HASSALEN /* Awful, awful hack to make subinterfaces work on BSD. */ #endif @@ -232,8 +237,8 @@ * there's a *2 there. The +32 is just to be safe. */ -#define SNAPLEN (LIBNET_IP_H * 2 + \ - (LIBNET_TCP_H > LIBNET_ICMP_H ? LIBNET_TCP_H : LIBNET_ICMP_H) + 32) +#define SNAPLEN (LIBNET_IPV4_H * 2 + \ + (LIBNET_TCP_H > LIBNET_ICMPV4_H ? LIBNET_TCP_H : LIBNET_ICMPV4_H) + 32) /* * To add support for additional link layers, add entries to the following @@ -314,11 +319,14 @@ pcap_t *pcap; int pcap_fd; struct timeval now; -int sockfd, datalink, offset; +int datalink, offset; int o_minttl, o_maxttl, o_timeout, o_debug, o_numeric, o_pktlen, o_nqueries, o_dontfrag, o_tos, o_forceport, o_syn, o_ack, o_ecn, o_nofilter, o_nogetinterfaces, o_noselect, o_trackport; +libnet_t *libnet_context; +char errbuf[LIBNET_ERRBUF_SIZE]; + /* interface linked list, built later by getinterfaces() */ struct interface_entry { char *name; @@ -593,7 +601,7 @@ return iptos(in); } - return libnet_host_lookup(in, o_numeric > 0 ? 0 : 1); + return libnet_addr2name4(in, o_numeric > 0 ? LIBNET_DONT_RESOLVE : LIBNET_RESOLVE); } /* @@ -820,7 +828,7 @@ if (p->addr == dst_ip) { debug("Destination matches local address of interface %s;\n\tattempting to find loopback interface, o_nofilter set\n", p->name); - with_src = libnet_name_resolve("127.0.0.1", 0); + with_src = libnet_name2addr4(libnet_context, "127.0.0.1", LIBNET_DONT_RESOLVE); o_nofilter = 1; } @@ -882,9 +890,9 @@ for(i = 0; i < ALLOCATEID_CACHE_SIZE; i++) { - for(ids[i] = libnet_get_prand(PRu16), j = i + 1; j < ALLOCATEID_CACHE_SIZE + i; j++) + for(ids[i] = libnet_get_prand(LIBNET_PRu16), j = i + 1; j < ALLOCATEID_CACHE_SIZE + i; j++) if (ids[i] == ids[j % ALLOCATEID_CACHE_SIZE]) - ids[i] = libnet_get_prand(PRu16), j = i + 1; + ids[i] = libnet_get_prand(LIBNET_PRu16), j = i + 1; } } @@ -1046,6 +1054,9 @@ "o_noselect", o_noselect); } + + + /* * Check command line arguments for sanity, and fill in the blanks. */ @@ -1057,14 +1068,14 @@ getinterfaces(); - if ((dst_ip = libnet_name_resolve(dst, 1)) == 0xFFFFFFFF) + if ((dst_ip = libnet_name2addr4(libnet_context, dst, 1)) == 0xFFFFFFFF) fatal("Bad destination address: %s\n", dst); recommended_src = findsrc(dst_ip); if (src) { - if ((src_ip = libnet_name_resolve(src, 1)) == 0xFFFFFFFF) + if ((src_ip = libnet_name2addr4(libnet_context,src, 1)) == 0xFFFFFFFF) fatal("Bad source address: %s\n", src); } else @@ -1133,19 +1144,16 @@ if (o_timeout <= 0) fatal("Timeout must be at least 1\n"); - if (o_pktlen < LIBNET_TCP_H + LIBNET_IP_H) + if (o_pktlen < LIBNET_TCP_H + LIBNET_IPV4_H) { if (o_pktlen != 0) - warn("Increasing packet length to %d bytes\n", LIBNET_TCP_H + LIBNET_IP_H); + warn("Increasing packet length to %d bytes\n", LIBNET_TCP_H + LIBNET_IPV4_H); o_pktlen = 0; } else - o_pktlen -= (LIBNET_TCP_H + LIBNET_IP_H); + o_pktlen -= (LIBNET_TCP_H + LIBNET_IPV4_H); - libnet_seed_prand(); - - if ((sockfd = libnet_open_raw_sock(IPPROTO_RAW)) < 0) - pfatal("socket allocation"); + libnet_seed_prand(libnet_context); if (strcmp(dst, iptos(dst_ip)) == 0) safe_snprintf(dst_name, TEXTSIZE, "%s", dst); @@ -1210,6 +1218,22 @@ } /* + * Initialize the libnet library context. + */ + +void init_libnet() +{ + /* Initialize the libnet library context */ + + libnet_context = libnet_init( LIBNET_RAW4, NULL, errbuf); + + /* verify that we've got a valid context */ + if (libnet_context == NULL) + fatal("libnet_init() failed: %s\n", errbuf); +} + + +/* * Sends out a TCP SYN packet with the specified TTL, and returns a * proberecord structure describing the packet sent, so we know what * to listen for later. A new IP ID is generated for each probe, and @@ -1218,20 +1242,36 @@ void probe(proberecord *record, int ttl, int q) { - static u_char *payload, *buf; + static u_char *payload; int i, size, ret; - /* Initialize the packet buffer */ - size = LIBNET_IP_H + LIBNET_TCP_H + o_pktlen; + static libnet_ptag_t ip_tag, tcp_tag, data_tag; + + + + /* pre-caclulate the size of the packet */ + size = LIBNET_IPV4_H + LIBNET_TCP_H + o_pktlen; + + /* set some values of the probe record */ + record->q = q; + record->ttl = ttl; + record->addr = INADDR_ANY; + record->src_prt = src_prt; + record->id = allocateid(); + record->delta = 0; - if (!buf) + if (o_trackport) { - debug("Initializing packet buffer of %d bytes\n", size); - buf = xrealloc(buf, size); + record->src_prt = allocateport(0); + if (record->src_prt == 0) + pfatal("Could not allocate local port: bind"); } - memset(buf, 0, size); + if (gettimeofday(&(record->timestamp), NULL) < 0) + pfatal("gettimeofday"); + /* Build the packet, and send it off into the cold, cruel world ... */ + /* Initialize the packet payload */ if (o_pktlen && !payload) { @@ -1250,58 +1290,63 @@ debug("Payload: %s\n", sprintable(payload)); } - record->q = q; - record->ttl = ttl; - record->addr = INADDR_ANY; - record->src_prt = src_prt; - record->id = allocateid(); - record->delta = 0; - - if (o_trackport) - { - record->src_prt = allocateport(0); - if (record->src_prt == 0) - pfatal("Could not allocate local port: bind"); - } - - if (gettimeofday(&(record->timestamp), NULL) < 0) - pfatal("gettimeofday"); - - /* Build the packet, and send it off into the cold, cruel world ... */ - libnet_build_ip( - LIBNET_TCP_H+o_pktlen, /* len */ - o_tos, /* tos */ - record->id, /* id */ - o_dontfrag ? IP_DF : 0, /* frag */ - ttl, /* ttl */ - IPPROTO_TCP, /* proto */ - src_ip, /* saddr */ - dst_ip, /* daddr */ - NULL, /* data */ - 0, /* datasize? */ - buf); /* buffer */ - - libnet_build_tcp( - record->src_prt, /* source port */ - dst_prt, /* dest port */ - 0, /* seq number */ - 0, /* ack number */ + data_tag = libnet_build_data(payload, o_pktlen, libnet_context, data_tag); + /* verify that we were able to add the payload */ + if (data_tag < 0) + fatal("Can't add payload: %s\n", libnet_geterror(libnet_context)); + + /* add the TCP Header */ + + tcp_tag = libnet_build_tcp( + record->src_prt, /* source port */ + dst_prt, /* dest port */ + 0, /* seq number */ + 0, /* ack number */ + (o_syn ? TH_SYN : 0) | (o_ack ? TH_ACK : 0) | - (o_ecn ? TH_CWR|TH_ECN : 0), /* control */ - - 0, /* window */ - 0, /* urgent? */ - payload, /* data */ - o_pktlen, /* datasize */ - buf + LIBNET_IP_H); /* buffer */ + (o_ecn ? TH_CWR|TH_ECN : 0), /* control */ - libnet_do_checksum(buf, IPPROTO_TCP, LIBNET_TCP_H + o_pktlen); - - if ((ret = libnet_write_ip(sockfd, buf, size)) < size) - fatal("libnet_write_ip failed? Attempted to write %d bytes, only wrote %d\n", + 0, /* window */ + 0, /* checksum TBD */ + 0, /* urgent? */ + LIBNET_TCP_H + o_pktlen, /* TCP PDU size */ + NULL, /* data */ + 0, /* datasize */ + libnet_context, /* libnet context */ + tcp_tag); /* libnet protocol tag */ + + /* verify that we were able to build the TCP header */ + if (tcp_tag < 0) + fatal("Can't build TCP header: %s\n", libnet_geterror(libnet_context)); + + /* add the IP header */ + ip_tag = libnet_build_ipv4( + size, /* total packet len */ + o_tos, /* tos */ + record->id, /* id */ + o_dontfrag ? IP_DF : 0, /* frag */ + ttl, /* ttl */ + IPPROTO_TCP, /* proto */ + 0, /* checksum TBD */ + src_ip, /* saddr */ + dst_ip, /* daddr */ + NULL, /* data */ + 0, /* datasize? */ + libnet_context, /* libnet context */ + ip_tag); /* libnet protocol tag */ + + /* verify that we were able to add the IP portion */ + if (ip_tag < 0) + fatal("Can't build IP header: %s\n", libnet_geterror(libnet_context)); + + /* attempt to write the packet */ + if ((ret = libnet_write(libnet_context)) < size) + fatal("libnet_write failed? Attempted to write %d bytes, only wrote %d\n", size, ret); + + } /* @@ -1329,7 +1374,7 @@ { u_char *packet; struct pcap_pkthdr packet_hdr; - struct libnet_ip_hdr *ip_hdr; + struct libnet_ipv4_hdr *ip_hdr; struct timeval start, now, timepassed, timeout_tv, timeleft; int firstpass, ret, len; double delta; @@ -1409,7 +1454,7 @@ debug("received %d byte IP packet from pcap_next()\n", len); - if (len < LIBNET_IP_H) + if (len < LIBNET_IPV4_H) { debug("Ignoring partial IP packet\n"); continue; @@ -1421,7 +1466,7 @@ continue; } - ALIGN_PACKET(ip_hdr, libnet_ip_hdr, 0); + ALIGN_PACKET(ip_hdr, libnet_ipv4_hdr, 0); if (ip_hdr->ip_v != 4) { @@ -1450,17 +1495,17 @@ if (ip_hdr->ip_p == IPPROTO_ICMP) { - struct libnet_icmp_hdr *icmp_hdr; - struct libnet_ip_hdr *old_ip_hdr; + struct libnet_icmpv4_hdr *icmp_hdr; + struct libnet_ipv4_hdr *old_ip_hdr; struct libnet_tcp_hdr *old_tcp_hdr; - if (len < LIBNET_IP_H + LIBNET_ICMP_H + 4) + if (len < LIBNET_IPV4_H + LIBNET_ICMPV4_H + 4) { debug("Ignoring partial icmp packet\n"); continue; } - ALIGN_PACKET(icmp_hdr, libnet_icmp_hdr, 0 + LIBNET_IP_H); + ALIGN_PACKET(icmp_hdr, libnet_icmpv4_hdr, 0 + LIBNET_IPV4_H); debug("Received icmp packet\n"); /* @@ -1469,14 +1514,14 @@ * padding. */ - if (len < LIBNET_IP_H + LIBNET_ICMP_H + 4 + LIBNET_IP_H + 8) + if (len < LIBNET_IPV4_H + LIBNET_ICMPV4_H + 4 + LIBNET_IPV4_H + 8) { debug("Ignoring icmp packet with incomplete payload\n"); continue; } - ALIGN_PACKET(old_ip_hdr, libnet_ip_hdr, - 0 + LIBNET_IP_H + LIBNET_ICMP_H + 4); + ALIGN_PACKET(old_ip_hdr, libnet_ipv4_hdr, + 0 + LIBNET_IPV4_H + LIBNET_ICMPV4_H + 4); /* * The entire TCP header isn't here, but the source port, @@ -1484,7 +1529,7 @@ */ ALIGN_PACKET(old_tcp_hdr, libnet_tcp_hdr, - 0 + LIBNET_IP_H + LIBNET_ICMP_H + 4 + LIBNET_IP_H); + 0 + LIBNET_IPV4_H + LIBNET_ICMPV4_H + 4 + LIBNET_IPV4_H); if (old_ip_hdr->ip_v != 4) { @@ -1619,13 +1664,13 @@ continue; } - if (len < LIBNET_IP_H + LIBNET_TCP_H) + if (len < LIBNET_IPV4_H + LIBNET_TCP_H) { debug("Ignoring partial tcp packet\n"); continue; } - ALIGN_PACKET(tcp_hdr, libnet_tcp_hdr, 0 + LIBNET_IP_H); + ALIGN_PACKET(tcp_hdr, libnet_tcp_hdr, 0 + LIBNET_IPV4_H); debug("Received tcp packet %s:%d -> %s:%d, flags %s%s%s%s%s%s%s%s%s\n", iptos(ip_hdr->ip_src.s_addr), ntohs(tcp_hdr->th_sport), @@ -1690,7 +1735,7 @@ fprintf(stderr, "Tracing the path to %s on TCP port %s, %d hops max", dst_name, dst_prt_name, o_maxttl); if (o_pktlen) - fprintf(stderr, ", %d byte packets", o_pktlen + LIBNET_TCP_H + LIBNET_IP_H); + fprintf(stderr, ", %d byte packets", o_pktlen + LIBNET_TCP_H + LIBNET_IPV4_H); fprintf(stderr, "\n"); for (ttl = o_minttl, done = 0; !done && ttl <= o_maxttl; ttl++) @@ -1716,6 +1761,7 @@ if (!done) fprintf(stderr, "Destination not reached\n"); + libnet_destroy(libnet_context); return done ? 0 : 1; } @@ -2001,6 +2047,8 @@ if (getuid() & geteuid()) fatal("Got root?\n"); + + init_libnet(); defaults(); initcapture(); seteuid(getuid());
|
|