Subject: Re: bin/22523
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Mihai CHELARU <kefren@netbsd.ro>
List: netbsd-bugs
Date: 08/18/2005 20:51:02
The following reply was made to PR bin/22523; it has been noted by GNATS.
From: Mihai CHELARU <kefren@netbsd.ro>
To: gnats-bugs@netbsd.org
Cc: ww@parc.styx.org
Subject: Re: bin/22523
Date: Thu, 18 Aug 2005 23:50:11 +0300
Hello,
I've made some changes in order to make this compile on later releases
(tested on 3.0_BETA).
Here is how the output looks like:
# obj/traceroute -I www.cisco.com
traceroute to www.cisco.com (198.133.219.25), 64 hops max, 40 byte packets
1 b2-f0-1 (193.28.151.1) 0.764 ms 0.347 ms 0.266 ms
2 80.86.113.1 (80.86.113.1) 1.601 ms 1.360 ms 1.295 ms
3 GE-0-2-0.B-BORDER.iNES.RO (80.86.97.61) 2.287 ms 1.913 ms 1.585 ms
4 62.153.203.201 (62.153.203.201) 16.999 ms 16.985 ms 17.582 ms
5 62.156.131.130 (62.156.131.130) 123.033 ms 122.373 ms 163.660 ms
6 192.205.32.57 (192.205.32.57) 187.034 ms 384.544 ms 264.202 ms
7 12.122.80.22 (12.122.80.22) 200.579 ms 200.115 ms 200.442 ms
[MPLS: Label 32433 Exp 0]
8 tbr1-cl1.cgcil.ip.att.net (12.122.10.2) 199.812 ms 198.438 ms
199.435 ms [MPLS: Label 32429 Exp 0]
9 tbr1-cl1.sffca.ip.att.net (12.122.10.6) 198.607 ms 198.557 ms
198.867 ms [MPLS: Label 32439 Exp 0]
10 gbr5-p100.sffca.ip.att.net (12.122.11.74) 196.896 ms 196.612 ms
196.569 ms [MPLS: Label 744 Exp 0]
11 gar1-p360.sj2ca.ip.att.net (12.122.2.253) 197.018 ms 198.305 ms
199.953 ms
12 12.127.200.82 (12.127.200.82) 200.831 ms 199.306 ms 197.921 ms
13 sjce-dmzbb-gw1.cisco.com (128.107.239.53) 200.438 ms 199.452 ms
200.910 ms
14 sjck-dmzdc-gw1.cisco.com (128.107.224.69) 198.720 ms 201.170 ms
199.382 ms
15 www.cisco.com (198.133.219.25) 198.701 ms 199.690 ms 198.989 ms
I prefered to print out only the label and exp in order to be consistent
with other implementations (cisco, linux).
So, here is what made it work here:
root@smtp:/usr/src/usr.sbin/traceroute# cvs diff -u -rHEAD traceroute.c
Index: traceroute.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/traceroute/traceroute.c,v
retrieving revision 1.61
diff -u -r1.61 traceroute.c
--- traceroute.c 22 Apr 2004 01:41:22 -0000 1.61
+++ traceroute.c 18 Aug 2005 19:31:02 -0000
@@ -269,6 +269,53 @@
u_char ttl; /* ttl packet left with */
struct timeval tv; /* time packet left */
};
+/*
+ * Support for ICMP extensions
+ *
+ * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
+ */
+#define ICMP_EXT_OFFSET 8 /* ICMP type, code, checksum, unused */ + \
+ 128 /* original datagram */
+#define ICMP_EXT_VERSION 2
+/*
+ * ICMP extensions, common header
+ */
+struct icmp_ext_cmn_hdr {
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char version:4;
+ u_char reserved1:4;
+#else
+ u_char reserved1:4;
+ u_char version:4;
+#endif
+ u_char reserved2;
+ u_short checksum;
+};
+
+/*
+ * ICMP extensions, object header
+ */
+struct icmp_ext_obj_hdr {
+ u_short length;
+ u_char class_num;
+#define MPLS_STACK_ENTRY_CLASS 1
+ u_char c_type;
+#define MPLS_STACK_ENTRY_C_TYPE 1
+};
+
+struct mpls_header {
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int32_t label:20;
+ u_char exp:3;
+ u_char s:1;
+ u_char ttl:8;
+#else
+ u_char ttl:8;
+ u_char s:1;
+ u_char exp:3;
+ u_int32_t label:20;
+#endif
+};
u_char packet[512]; /* last inbound (icmp) packet */
@@ -369,6 +416,7 @@
void tvsub(struct timeval *, struct timeval *);
__dead void usage(void);
int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
+void decode_extensions(u_char *buf, int ip_len);
void frag_err(void);
int find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
#ifdef IPSEC
@@ -1000,7 +1048,9 @@
break;
}
if (cc == 0)
- Printf(" *");
+ Printf(" *"); else
+ if (cc && probe == nprobes-1)
+ decode_extensions(packet, cc);
(void)fflush(stdout);
}
putchar('\n');
@@ -1052,6 +1102,119 @@
}
void
+decode_extensions(u_char *buf, int ip_len)
+{
+ struct icmp_ext_cmn_hdr *cmn_hdr;
+ struct icmp_ext_obj_hdr *obj_hdr;
+ union {
+ struct mpls_header mpls;
+ u_int32_t mpls_h;
+ } mpls;
+ int datalen, obj_len;
+ struct ip *ip;
+
+ ip = (struct ip *)buf;
+
+ if (ip_len <= sizeof(struct ip) + ICMP_EXT_OFFSET) {
+ /*
+ * No support for ICMP extensions on this host
+ */
+ return;
+ }
+
+ /*
+ * Move forward to the start of the ICMP extensions, if present
+ */
+ buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
+ cmn_hdr = (struct icmp_ext_cmn_hdr *)buf;
+
+ if (cmn_hdr->version != ICMP_EXT_VERSION) {
+ /*
+ * Unknown version
+ */
+ return;
+ }
+
+ datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
+
+ /*
+ * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
+ * done by sender.
+ *
+ * If the checksum is ok, we'll get 0, as the checksum is calculated
+ * with the checksum field being 0'd.
+ */
+ if (ntohs(cmn_hdr->checksum) &&
+ in_cksum((u_short *)cmn_hdr, datalen)) {
+
+ return;
+ }
+
+ buf += sizeof(*cmn_hdr);
+ datalen -= sizeof(*cmn_hdr);
+
+ while (datalen > 0) {
+ obj_hdr = (struct icmp_ext_obj_hdr *)buf;
+ obj_len = ntohs(obj_hdr->length);
+
+ /*
+ * Sanity check the length field
+ */
+ if (obj_len > datalen) {
+ return;
+ }
+
+ datalen -= obj_len;
+
+ /*
+ * Move past the object header
+ */
+ buf += sizeof(struct icmp_ext_obj_hdr);
+ obj_len -= sizeof(struct icmp_ext_obj_hdr);
+
+ switch (obj_hdr->class_num) {
+ case MPLS_STACK_ENTRY_CLASS:
+ switch (obj_hdr->c_type) {
+ case MPLS_STACK_ENTRY_C_TYPE:
+ while (obj_len >= sizeof(u_int32_t)) {
+ mpls.mpls_h = ntohl(*(u_int32_t *)buf);
+
+ buf += sizeof(u_int32_t);
+ obj_len -= sizeof(u_int32_t);
+
+ printf("\t[MPLS: Label %d Exp %d]",
+ mpls.mpls.label, mpls.mpls.exp);
+ }
+ if (obj_len > 0) {
+ /*
+ * Something went wrong, and we're at a unknown
offset
+ * into the packet, ditch the rest of it.
+ */
+ return;
+ }
+ break;
+ default:
+ /*
+ * Unknown object, skip past it
+ */
+ buf += ntohs(obj_hdr->length) -
+ sizeof(struct icmp_ext_obj_hdr);
+ break;
+ }
+ break;
+
+ default:
+ /*
+ * Unknown object, skip past it
+ */
+ buf += ntohs(obj_hdr->length) -
+ sizeof(struct icmp_ext_obj_hdr);
+ break;
+ }
+ }
+}
+
+void
dump_packet()
{
u_char *p;
--
Thanks,
Mihai