Home | History | Annotate | Download | only in tcpdump
      1 /*
      2  * Copyright (c) 2001 William C. Fenner.
      3  *                All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that: (1) source code
      7  * distributions retain the above copyright notice and this paragraph
      8  * in its entirety, and (2) distributions including binary code include
      9  * the above copyright notice and this paragraph in its entirety in
     10  * the documentation or other materials provided with the distribution.
     11  * The name of William C. Fenner may not be used to endorse or
     12  * promote products derived from this software without specific prior
     13  * written permission.  THIS SOFTWARE IS PROVIDED ``AS IS'' AND
     14  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
     15  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     16  * FOR A PARTICULAR PURPOSE.
     17  */
     18 
     19 /* \summary: Multicast Source Discovery Protocol (MSDP) printer */
     20 
     21 #ifdef HAVE_CONFIG_H
     22 #include "config.h"
     23 #endif
     24 
     25 #include <netdissect-stdinc.h>
     26 
     27 #include "netdissect.h"
     28 #include "addrtoname.h"
     29 #include "extract.h"
     30 
     31 #define MSDP_TYPE_MAX	7
     32 
     33 void
     34 msdp_print(netdissect_options *ndo, const u_char *sp, u_int length)
     35 {
     36 	unsigned int type, len;
     37 
     38 	ND_TCHECK2(*sp, 3);
     39 	/* See if we think we're at the beginning of a compound packet */
     40 	type = *sp;
     41 	len = EXTRACT_16BITS(sp + 1);
     42 	if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX)
     43 		goto trunc;	/* not really truncated, but still not decodable */
     44 	ND_PRINT((ndo, " msdp:"));
     45 	while (length > 0) {
     46 		ND_TCHECK2(*sp, 3);
     47 		type = *sp;
     48 		len = EXTRACT_16BITS(sp + 1);
     49 		if (len > 1400 || ndo->ndo_vflag)
     50 			ND_PRINT((ndo, " [len %u]", len));
     51 		if (len < 3)
     52 			goto trunc;
     53 		sp += 3;
     54 		length -= 3;
     55 		switch (type) {
     56 		case 1:	/* IPv4 Source-Active */
     57 		case 3: /* IPv4 Source-Active Response */
     58 			if (type == 1)
     59 				ND_PRINT((ndo, " SA"));
     60 			else
     61 				ND_PRINT((ndo, " SA-Response"));
     62 			ND_TCHECK(*sp);
     63 			ND_PRINT((ndo, " %u entries", *sp));
     64 			if ((u_int)((*sp * 12) + 8) < len) {
     65 				ND_PRINT((ndo, " [w/data]"));
     66 				if (ndo->ndo_vflag > 1) {
     67 					ND_PRINT((ndo, " "));
     68 					ip_print(ndo, sp + *sp * 12 + 8 - 3,
     69 					         len - (*sp * 12 + 8));
     70 				}
     71 			}
     72 			break;
     73 		case 2:
     74 			ND_PRINT((ndo, " SA-Request"));
     75 			ND_TCHECK2(*sp, 5);
     76 			ND_PRINT((ndo, " for %s", ipaddr_string(ndo, sp + 1)));
     77 			break;
     78 		case 4:
     79 			ND_PRINT((ndo, " Keepalive"));
     80 			if (len != 3)
     81 				ND_PRINT((ndo, "[len=%d] ", len));
     82 			break;
     83 		case 5:
     84 			ND_PRINT((ndo, " Notification"));
     85 			break;
     86 		default:
     87 			ND_PRINT((ndo, " [type=%d len=%d]", type, len));
     88 			break;
     89 		}
     90 		sp += (len - 3);
     91 		length -= (len - 3);
     92 	}
     93 	return;
     94 trunc:
     95 	ND_PRINT((ndo, " [|msdp]"));
     96 }
     97 
     98 /*
     99  * Local Variables:
    100  * c-style: whitesmith
    101  * c-basic-offset: 8
    102  * End:
    103  */
    104