/*
+ * Copyright (c) 1998-2005 The TCPDUMP project
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code
* distributions retain the above copyright notice and this paragraph
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.30 2004-07-21 21:50:46 guy Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.42 2006-06-23 02:03:09 hannes Exp $";
#endif
#ifdef HAVE_CONFIG_H
#define RSVP_OBJ_SESSION 1 /* rfc2205 */
#define RSVP_OBJ_RSVP_HOP 3 /* rfc2205, rfc3473 */
-#define RSVP_OBJ_INTEGRITY 4
+#define RSVP_OBJ_INTEGRITY 4 /* rfc2747 */
#define RSVP_OBJ_TIME_VALUES 5 /* rfc2205 */
#define RSVP_OBJ_ERROR_SPEC 6
#define RSVP_OBJ_SCOPE 7
#define RSVP_OBJ_UPSTREAM_LABEL 35 /* rfc3473 */
#define RSVP_OBJ_LABEL_SET 36 /* rfc3473 */
#define RSVP_OBJ_PROTECTION 37 /* rfc3473 */
-#define RSVP_OBJ_DETOUR 63 /* draft-ietf-mpls-rsvp-lsp-fastreroute-01 */
+#define RSVP_OBJ_DETOUR 63 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */
+#define RSVP_OBJ_CLASSTYPE 66 /* rfc4124 */
+#define RSVP_OBJ_CLASSTYPE_OLD 125 /* draft-ietf-tewg-diff-te-proto-07 */
#define RSVP_OBJ_SUGGESTED_LABEL 129 /* rfc3473 */
#define RSVP_OBJ_ACCEPT_LABEL_SET 130 /* rfc3473 */
#define RSVP_OBJ_RESTART_CAPABILITY 131 /* rfc3473 */
#define RSVP_OBJ_NOTIFY_REQ 195 /* rfc3473 */
#define RSVP_OBJ_ADMIN_STATUS 196 /* rfc3473 */
#define RSVP_OBJ_PROPERTIES 204 /* juniper proprietary */
-#define RSVP_OBJ_FASTREROUTE 205 /* draft-ietf-mpls-rsvp-lsp-fastreroute-01 */
+#define RSVP_OBJ_FASTREROUTE 205 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */
#define RSVP_OBJ_SESSION_ATTRIBUTE 207 /* rfc3209 */
#define RSVP_OBJ_CALL_ID 230 /* rfc3474 */
#define RSVP_OBJ_CALL_OPS 236 /* rfc3474 */
{ RSVP_OBJ_LABEL_SET, "Label Set" },
{ RSVP_OBJ_ACCEPT_LABEL_SET, "Acceptable Label Set" },
{ RSVP_OBJ_DETOUR, "Detour" },
+ { RSVP_OBJ_CLASSTYPE, "Class Type" },
+ { RSVP_OBJ_CLASSTYPE_OLD, "Class Type (old)" },
{ RSVP_OBJ_SUGGESTED_LABEL, "Suggested Label" },
{ RSVP_OBJ_PROPERTIES, "Properties" },
{ RSVP_OBJ_FASTREROUTE, "Fast Re-Route" },
{ 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" },
{ 256*RSVP_OBJ_RESTART_CAPABILITY+RSVP_CTYPE_1, "IPv4" },
{ 256*RSVP_OBJ_SESSION_ATTRIBUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
- { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
+ { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, /* old style*/
+ { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_1, "1" }, /* new style */
{ 256*RSVP_OBJ_DETOUR+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
{ 256*RSVP_OBJ_PROPERTIES+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_CLASSTYPE+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_CLASSTYPE_OLD+RSVP_CTYPE_1, "1" },
+ { 0, NULL}
+};
+
+struct rsvp_obj_integrity_t {
+ u_int8_t flags;
+ u_int8_t res;
+ u_int8_t key_id[6];
+ u_int8_t sequence[8];
+ u_int8_t digest[16];
+};
+
+static const struct tok rsvp_obj_integrity_flag_values[] = {
+ { 0x80, "Handshake" },
{ 0, NULL}
};
+struct rsvp_obj_frr_t {
+ u_int8_t setup_prio;
+ u_int8_t hold_prio;
+ u_int8_t hop_limit;
+ u_int8_t flags;
+ u_int8_t bandwidth[4];
+ u_int8_t include_any[4];
+ u_int8_t exclude_any[4];
+ u_int8_t include_all[4];
+};
+
+
#define RSVP_OBJ_XRO_MASK_SUBOBJ(x) ((x)&0x7f)
#define RSVP_OBJ_XRO_MASK_LOOSE(x) ((x)&0x80)
{ 0, NULL}
};
-/* draft-ietf-mpls-rsvp-lsp-fastreroute-02.txt */
+/* draft-ietf-mpls-rsvp-lsp-fastreroute-07.txt */
static const struct tok rsvp_obj_rro_flag_values[] = {
{ 0x01, "Local protection available" },
{ 0x02, "Local protection in use" },
#define RSVP_OBJ_ERROR_SPEC_CODE_ROUTING 24
#define RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY 25
+#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE 28
+#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD 125
static struct tok rsvp_obj_error_code_values[] = {
{ RSVP_OBJ_ERROR_SPEC_CODE_ROUTING, "Routing Problem" },
{ RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY, "Notify Error" },
+ { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE, "Diffserv TE Error" },
+ { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD, "Diffserv TE Error (Old)" },
{ 0, NULL}
};
{ 0, NULL}
};
-#define FALSE 0
-#define TRUE 1
-
+static struct tok rsvp_obj_error_code_diffserv_te_values[] = {
+ { 1, "Unexpected CT object" },
+ { 2, "Unsupported CT" },
+ { 3, "Invalid CT value" },
+ { 4, "CT/setup priority do not form a configured TE-Class" },
+ { 5, "CT/holding priority do not form a configured TE-Class" },
+ { 6, "CT/setup priority and CT/holding priority do not form a configured TE-Class" },
+ { 7, "Inconsistency between signaled PSC and signaled CT" },
+ { 8, "Inconsistency between signaled PHBs and signaled CT" },
+ { 0, NULL}
+};
static int rsvp_intserv_print(const u_char *, u_short);
const struct rsvp_object_header *rsvp_obj_header;
const u_char *obj_tptr;
+ union {
+ const struct rsvp_obj_integrity_t *rsvp_obj_integrity;
+ const struct rsvp_obj_frr_t *rsvp_obj_frr;
+ } obj_ptr;
+
u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen;
int hexdump,processed,padbytes,error_code,error_value,i;
union {
} bw;
u_int8_t namelen;
- while(tlen>0) {
+ while(tlen>=sizeof(struct rsvp_object_header)) {
/* did we capture enough for fully decoding the object header ? */
if (!TTEST2(*tptr, sizeof(struct rsvp_object_header)))
goto trunc;
rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length);
rsvp_obj_ctype=rsvp_obj_header->ctype;
- if(rsvp_obj_len % 4 || rsvp_obj_len < sizeof(struct rsvp_object_header)) {
- printf("ERROR: object header too short %u < %lu", rsvp_obj_len,
+ if(rsvp_obj_len % 4) {
+ printf("%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len);
+ return -1;
+ }
+ if(rsvp_obj_len < sizeof(struct rsvp_object_header)) {
+ printf("%sERROR: object header too short %u < %lu", ident, rsvp_obj_len,
(unsigned long)sizeof(const struct rsvp_object_header));
return -1;
}
rsvp_obj_ctype,
rsvp_obj_len);
+ if(tlen < rsvp_obj_len) {
+ printf("%sERROR: object goes past end of objects TLV", ident);
+ return -1;
+ }
+
obj_tptr=tptr+sizeof(struct rsvp_object_header);
obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header);
printf("%s IPv4 DestAddress: %s, Protocol ID: 0x%02x",
ident,
ipaddr_string(obj_tptr),
- *(obj_tptr+4));
+ *(obj_tptr+sizeof(struct in_addr)));
printf("%s Flags: [0x%02x], DestPort %u",
ident,
*(obj_tptr+5),
printf("%s IPv6 DestAddress: %s, Protocol ID: 0x%02x",
ident,
ip6addr_string(obj_tptr),
- *(obj_tptr+16));
+ *(obj_tptr+sizeof(struct in6_addr)));
printf("%s Flags: [0x%02x], DestPort %u",
ident,
- *(obj_tptr+17),
- EXTRACT_16BITS(obj_tptr+18));
+ *(obj_tptr+sizeof(struct in6_addr)+1),
+ EXTRACT_16BITS(obj_tptr+sizeof(struct in6_addr)+2));
obj_tlen-=20;
obj_tptr+=20;
break;
case RSVP_OBJ_CONFIRM:
switch(rsvp_obj_ctype) {
case RSVP_CTYPE_IPV4:
- if (obj_tlen < 4)
+ if (obj_tlen < sizeof(struct in_addr))
return -1;
printf("%s IPv4 Receiver Address: %s",
ident,
ipaddr_string(obj_tptr));
- obj_tlen-=4;
- obj_tptr+=4;
+ obj_tlen-=sizeof(struct in_addr);
+ obj_tptr+=sizeof(struct in_addr);
break;
#ifdef INET6
case RSVP_CTYPE_IPV6:
- if (obj_tlen < 16)
+ if (obj_tlen < sizeof(struct in6_addr))
return -1;
printf("%s IPv6 Receiver Address: %s",
ident,
ip6addr_string(obj_tptr));
- obj_tlen-=16;
- obj_tptr+=16;
+ obj_tlen-=sizeof(struct in6_addr);
+ obj_tptr+=sizeof(struct in6_addr);
break;
#endif
default:
case RSVP_OBJ_NOTIFY_REQ:
switch(rsvp_obj_ctype) {
case RSVP_CTYPE_IPV4:
- if (obj_tlen < 4)
+ if (obj_tlen < sizeof(struct in_addr))
return -1;
printf("%s IPv4 Notify Node Address: %s",
ident,
ipaddr_string(obj_tptr));
- obj_tlen-=4;
- obj_tptr+=4;
+ obj_tlen-=sizeof(struct in_addr);
+ obj_tptr+=sizeof(struct in_addr);
break;
#ifdef INET6
case RSVP_CTYPE_IPV6:
- if (obj_tlen < 16)
+ if (obj_tlen < sizeof(struct in6_addr))
return-1;
printf("%s IPv6 Notify Node Address: %s",
ident,
ip6addr_string(obj_tptr));
- obj_tlen-=16;
- obj_tptr+=16;
+ obj_tlen-=sizeof(struct in6_addr);
+ obj_tptr+=sizeof(struct in6_addr);
break;
#endif
default:
switch(rsvp_obj_ctype) {
case RSVP_CTYPE_IPV4:
while(obj_tlen >= 4 ) {
- printf("%s Subobject Type: %s",
+ printf("%s Subobject Type: %s, length %u",
ident,
tok2str(rsvp_obj_xro_values,
"Unknown %u",
- RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)));
+ RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)),
+ *(obj_tptr+1));
+
+ if (*(obj_tptr+1) == 0) { /* prevent infinite loops */
+ printf("%s ERROR: zero length ERO subtype",ident);
+ break;
+ }
+
switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) {
case RSVP_OBJ_XRO_IPV4:
printf(", %s, %s/%u, Flags: [%s]",
return-1;
printf("%s Restart Time: %ums, Recovery Time: %ums",
ident,
- EXTRACT_16BITS(obj_tptr),
- EXTRACT_16BITS(obj_tptr+4));
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr+4));
obj_tlen-=8;
obj_tptr+=8;
break;
EXTRACT_32BITS(obj_tptr+4));
obj_tlen-=8;
obj_tptr+=8;
- hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
+ if (obj_tlen)
+ hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
break;
#ifdef INET6
case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */
break;
case RSVP_OBJ_FASTREROUTE:
+ /* the differences between c-type 1 and 7 are minor */
+ obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
+ bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
+
switch(rsvp_obj_ctype) {
- case RSVP_CTYPE_TUNNEL_IPV4:
+ case RSVP_CTYPE_1: /* new style */
+ if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
+ return-1;
+ printf("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
+ ident,
+ (int)obj_ptr.rsvp_obj_frr->setup_prio,
+ (int)obj_ptr.rsvp_obj_frr->hold_prio,
+ (int)obj_ptr.rsvp_obj_frr->hop_limit,
+ bw.f*8/1000000);
+ printf("%s Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x",
+ ident,
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all));
+ obj_tlen-=sizeof(struct rsvp_obj_frr_t);
+ obj_tptr+=sizeof(struct rsvp_obj_frr_t);
+ break;
+
+ case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
if (obj_tlen < 16)
return-1;
- bw.i = EXTRACT_32BITS(obj_tptr+4);
printf("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
ident,
- (int)*obj_tptr,
- (int)*(obj_tptr+1),
- (int)*(obj_tptr+2),
+ (int)obj_ptr.rsvp_obj_frr->setup_prio,
+ (int)obj_ptr.rsvp_obj_frr->hold_prio,
+ (int)obj_ptr.rsvp_obj_frr->hop_limit,
bw.f*8/1000000);
printf("%s Include Colors: 0x%08x, Exclude Colors: 0x%08x",
ident,
- EXTRACT_32BITS(obj_tptr+8),
- EXTRACT_32BITS(obj_tptr+12));
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any));
obj_tlen-=16;
obj_tptr+=16;
break;
+
default:
hexdump=TRUE;
}
}
break;
+ case RSVP_OBJ_CLASSTYPE:
+ case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ printf("%s CT: %u",
+ ident,
+ EXTRACT_32BITS(obj_tptr)&0x7);
+ obj_tlen-=4;
+ obj_tptr+=4;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
case RSVP_OBJ_ERROR_SPEC:
switch(rsvp_obj_ctype) {
case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */
tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value),
error_value);
break;
+ case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */
+ case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD:
+ printf(", Error Value: %s (%u)",
+ tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value),
+ error_value);
+ break;
default:
printf(", Unknown Error Value (%u)", error_value);
break;
*(obj_tptr+1));
if (obj_tlen < *(obj_tptr+1))
return-1;
+ if (*(obj_tptr+1) < 2)
+ return -1;
print_unknown_data(obj_tptr+2,"\n\t\t",*(obj_tptr+1)-2);
obj_tlen-=*(obj_tptr+1);
obj_tptr+=*(obj_tptr+1);
}
break;
+ case RSVP_OBJ_INTEGRITY:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ if (obj_tlen < sizeof(struct rsvp_obj_integrity_t))
+ return-1;
+ obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr;
+ printf("%s Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]",
+ ident,
+ EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4),
+ bittok2str(rsvp_obj_integrity_flag_values,
+ "none",
+ obj_ptr.rsvp_obj_integrity->flags));
+ printf("%s MD5-sum 0x%08x%08x%08x%08x (unverified)",
+ ident,
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+12));
+ obj_tlen+=sizeof(struct rsvp_obj_integrity_t);
+ obj_tptr+=sizeof(struct rsvp_obj_integrity_t);
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
/*
* FIXME those are the defined objects that lack a decoder
* you are welcome to contribute code ;-)
*/
- case RSVP_OBJ_INTEGRITY:
case RSVP_OBJ_SCOPE:
case RSVP_OBJ_POLICY_DATA:
case RSVP_OBJ_LABEL_SET:
return;
}
+ if (tlen < subtlen) {
+ printf("ERROR: common header too large %u > %u", subtlen,
+ tlen);
+ return;
+ }
+
subtptr+=sizeof(const struct rsvp_common_header);
subtlen-=sizeof(const struct rsvp_common_header);