Project

General

Profile

Actions

Bug #633

closed

ICMP extensions for MPLS support for traceroute(8)

Added by hasso over 17 years ago. Updated over 17 years ago.

Status:
Closed
Priority:
Low
Assignee:
-
Category:
-
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:

Description

  1. HG changeset patch
  2. User Hasso Tepper <>
  3. Date 1178795442 -10800
  4. Node ID da51ceae15a698a0d629dcbc0d3e834904e85069
  5. Parent ff1a613aa7893b9abe16bdcb6844d0370b80147b
    ICMP extensions for MPLS support for traceroute(8).

If noone objects, I will commit tomorrow.

Obtained-from: NetBSD

diff r ff1a613aa789 -r da51ceae15a6 usr.sbin/traceroute/traceroute.8
--
a/usr.sbin/traceroute/traceroute.8 Wed May 09 23:30:51 2007 0300
++ b/usr.sbin/traceroute/traceroute.8 Thu May 10 14:10:42 2007 0300
@ -43,7 +43,7 @
.Sh SYNOPSIS
.Nm traceroute
.Bk words
.Op Fl cdDIlnrSv
.Op Fl cdDIlMnrSv
.Op Fl f Ar first_ttl
.Op Fl g Ar gateway_addr
.Op Fl m Ar max_ttl
@ -109,6 +109,8 @ The default is the value of the system's
The default is the value of the system's
.Cm net.inet.ip.ttl
MIB variable, which defaults to 64.
.It Fl M
+If found, show the MPLS Label and the Experimental (EXP) bit for the hop.
.It Fl n
Print hop addresses numerically rather than symbolically and numerically
(saves a nameserver address-to-name lookup for each gateway found on the
diff r ff1a613aa789 -r da51ceae15a6 usr.sbin/traceroute/traceroute.c
--
a/usr.sbin/traceroute/traceroute.c Wed May 09 23:30:51 2007 +0300
++ b/usr.sbin/traceroute/traceroute.c Thu May 10 14:10:42 2007 +0300
@ -244,6 +244,54 @ struct packetdata {
u_int32_t usec;
};

/*
* Support for ICMP extensions
+
+ * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
+ */
#define ICMP_EXT_OFFSET 8 + 128 /
ICMP type, code, checksum (unused)
* + original datagram /
#define ICMP_EXT_VERSION 2
/

+ * ICMP extensions, common header
+ /
struct icmp_ext_cmn_hdr {
#if BYTE_ORDER BIG_ENDIAN
+ unsigned char version:4;
+ unsigned char reserved1:4;
#else
unsigned char reserved1:4;
+ unsigned char version:4;
#endif
unsigned char reserved2;
+ unsigned 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
+ uint32_t label:20;
+ unsigned char exp:3;
+ unsigned char s:1;
+ unsigned char ttl:8;
#else
unsigned char ttl:8;
+ unsigned char s:1;
+ unsigned char exp:3;
+ uint32_t label:20;
#endif
};
+
struct in_addr gateway[MAX_LSRR + 1];
int lsrrlen = 0;
int32_t sec_perturb;
@ -251,6 +299,7 @ int32_t usec_perturb;

u_char packet[512], outpacket;    / last inbound (icmp) packet */

+void decode_extensions(unsigned char , int);
void dump_packet(void);
int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
void send_probe(int, u_int8_t, int, struct sockaddr_in *);
@ -283,6 +332,7 @ int waittime = 5; /
time to wait for r
int waittime = 5; /* time to wait for response (in seconds) /
int nflag; /
print addresses numerically /
int dump;
+int Mflag; /
show MPLS labels if any */

int
main(int argc, char *argv[])
@ -310,7 +360,7 @ main(int argc, char *argv[])
sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size, NULL, 0);

- while ((ch = getopt(argc, argv, "SDIdg:f:m:np:q:rs:t:w:vlP:c")) != -1)
+ while ((ch = getopt(argc, argv, "SDIdg:f:m:np:q:rs:t:w:vlP:cM")) != -1)
switch (ch) {
case 'S':
sump = 1;
@ -363,6 +413,9 @ main(int argc, char *argv[])
errx(1, "max ttl must be u to %u.", first_ttl,
MAXTTL);
max_ttl = (u_int8_t)l;
+ break;
+ case 'M':
+ Mflag = 1;
break;
case 'n':
nflag++;
@ -681,6 +734,8 @ main(int argc, char *argv[])
timeout++;
loss++;
}
+ else if (cc &x%x
probe == nprobes - 1 && Mflag)
+ decode_extensions(packet, cc);
fflush(stdout);
}
if (sump)
@ -721,6 +776,118 @ wait_for_reply(int sock, struct sockaddr

free(fdsp);
return (cc);
}

void
+decode_extensions(unsigned char buf, int ip_len)
{
+ struct icmp_ext_cmn_hdr *cmn_hdr;
+ struct icmp_ext_obj_hdr *obj_hdr;
+ union {
+ struct mpls_header mpls;
+ uint32_t mpls_h;
+ } mpls;
+ int data_len, obj_len;
+ struct ip *ip;

ip = (struct ip *)buf;

if (ip_len <= (int)(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;
+ }

data_len = 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, data_len)) {
+ return;
+ }

buf = sizeof(*cmn_hdr);
data_len = sizeof(*cmn_hdr);

while (data_len > 0) {
+ obj_hdr = (struct icmp_ext_obj_hdr *)buf;
+ obj_len = ntohs(obj_hdr
>length);

/

+ * Sanity check the length field
+ /
+ if (obj_len > data_len) {
+ return;
+ }

data_len = 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 >= (int)sizeof(uint32_t)) {
+ mpls.mpls_h = ntohl(
(uint32_t )buf);

buf = sizeof(uint32_t);
obj_len = sizeof(uint32_t);
+ printf(" [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
@ -1022,7 +1189,7 @ usage(void)
usage(void) {
fprintf(stderr,
- "usage: %s [-cdDIlnrSv] [-f first_ttl] [-g gateway_addr] [-m max_ttl]\n"
+ "usage: %s [-cdDIlMnrSv] [-f first_ttl] [-g gateway_addr] [-m max_ttl]\n"
"\t[-p port] [-P proto] [-q nqueries] [-s src_addr] [-t tos]\n"
"\t[-w waittime] host [packetsize]\n", getprogname());
exit(1);

Files

icmp-mpls.patch (6.51 KB) icmp-mpls.patch hasso, 05/21/2007 11:43 PM
icmp-mpls.patch (6.53 KB) icmp-mpls.patch hasso, 05/22/2007 08:43 AM
Actions

Also available in: Atom PDF