📄 print-pim.c
字号:
/* * Copyright (c) 1995, 1996 * The Regents of the University of California. All rights reserved. * * 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 in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lintstatic const char rcsid[] = "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.23 2000/10/03 02:55:00 itojun Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifndef WIN32
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <winsock2.h>
#include "bittypes.h"
#endif /* WIN32 */
/* * XXX: We consider a case where IPv6 is not ready yet for portability, * but PIM dependent defintions should be independent of IPv6... */struct pim { u_int8_t pim_typever; /* upper 4bit: PIM version number; 2 for PIMv2 */ /* lower 4bit: the PIM message type, currently they are: * Hello, Register, Register-Stop, Join/Prune, * Bootstrap, Assert, Graft (PIM-DM only), * Graft-Ack (PIM-DM only), C-RP-Adv */#define PIM_VER(x) (((x) & 0xf0) >> 4)#define PIM_TYPE(x) ((x) & 0x0f) u_char pim_rsv; /* Reserved */ u_short pim_cksum; /* IP style check sum */};#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include "interface.h"#include "addrtoname.h"#include "extract.h"#include "ip.h"static void pimv2_print(register const u_char *bp, register u_int len);static voidpimv1_join_prune_print(register const u_char *bp, register u_int len){ int maddrlen, addrlen, ngroups, njoin, nprune; int njp; /* If it's a single group and a single source, use 1-line output. */ if (TTEST2(bp[0], 30) && bp[11] == 1 && ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { int hold; (void)printf(" RPF %s ", ipaddr_string(bp)); hold = EXTRACT_16BITS(&bp[6]); if (hold != 180) { (void)printf("Hold "); relts_print(hold); } (void)printf("%s (%s/%d, %s", njoin ? "Join" : "Prune", ipaddr_string(&bp[26]), bp[25] & 0x3f, ipaddr_string(&bp[12])); if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) (void)printf("/%s", ipaddr_string(&bp[16])); (void)printf(") %s%s %s", (bp[24] & 0x01) ? "Sparse" : "Dense", (bp[25] & 0x80) ? " WC" : "", (bp[25] & 0x40) ? "RP" : "SPT"); return; } TCHECK2(bp[0], 4); (void)printf("\n Upstream Nbr: %s", ipaddr_string(bp)); TCHECK2(bp[6], 2); (void)printf("\n Hold time: "); relts_print(EXTRACT_16BITS(&bp[6])); bp += 8; len -= 8; TCHECK2(bp[0], 4); maddrlen = bp[1]; addrlen = bp[2]; ngroups = bp[3]; bp += 4; len -= 4; while (ngroups--) { TCHECK2(bp[0], 4); (void)printf("\n\tGroup: %s", ipaddr_string(bp)); if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) (void)printf("/%s", ipaddr_string(&bp[4])); TCHECK2(bp[8], 4); njoin = EXTRACT_16BITS(&bp[8]); nprune = EXTRACT_16BITS(&bp[10]); (void)printf(" joined: %d pruned: %d", njoin, nprune); bp += 12; len -= 12; for (njp = 0; njp < (njoin + nprune); njp++) { char *type; if (njp < njoin) { type = "Join "; } else { type = "Prune"; } TCHECK2(bp[0], 6); (void)printf("\n\t%s %s%s%s%s/%d", type, (bp[0] & 0x01) ? "Sparse " : "Dense ", (bp[1] & 0x80) ? "WC " : "", (bp[1] & 0x40) ? "RP " : "SPT ", ipaddr_string(&bp[2]), bp[1] & 0x3f); bp += 6; len -= 6; } } return;trunc: (void)printf("[|pim]"); return;}voidpimv1_print(register const u_char *bp, register u_int len){ register const u_char *ep; register u_char type; ep = (const u_char *)snapend; if (bp >= ep) return; type = bp[1]; switch (type) { case 0: (void)printf(" Query"); if (TTEST(bp[8])) { switch (bp[8] >> 4) { case 0: (void)printf(" Dense-mode"); break; case 1: (void)printf(" Sparse-mode"); break; case 2: (void)printf(" Sparse-Dense-mode"); break; default: (void)printf(" mode-%d", bp[8] >> 4); break; } } if (vflag) { TCHECK2(bp[10],2); (void)printf(" (Hold-time "); relts_print(EXTRACT_16BITS(&bp[10])); (void)printf(")"); } break; case 1: (void)printf(" Register"); TCHECK2(bp[8], 20); /* ip header */ (void)printf(" for %s > %s", ipaddr_string(&bp[20]), ipaddr_string(&bp[24])); break; case 2: (void)printf(" Register-Stop"); TCHECK2(bp[12], 4); (void)printf(" for %s > %s", ipaddr_string(&bp[8]), ipaddr_string(&bp[12])); break; case 3: (void)printf(" Join/Prune"); if (vflag) { pimv1_join_prune_print(&bp[8], len - 8); } break; case 4: (void)printf(" RP-reachable"); if (vflag) { TCHECK2(bp[22], 2); (void)printf(" group %s", ipaddr_string(&bp[8])); if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) (void)printf("/%s", ipaddr_string(&bp[12])); (void)printf(" RP %s hold ", ipaddr_string(&bp[16])); relts_print(EXTRACT_16BITS(&bp[22])); } break; case 5: (void)printf(" Assert"); TCHECK2(bp[16], 4); (void)printf(" for %s > %s", ipaddr_string(&bp[16]), ipaddr_string(&bp[8])); if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) (void)printf("/%s", ipaddr_string(&bp[12])); TCHECK2(bp[24], 4); (void)printf(" %s pref %d metric %d", (bp[20] & 0x80) ? "RP-tree" : "SPT", EXTRACT_32BITS(&bp[20]) & 0x7fffffff, EXTRACT_32BITS(&bp[24])); break; case 6: (void)printf(" Graft"); if (vflag) { pimv1_join_prune_print(&bp[8], len - 8); } break; case 7: (void)printf(" Graft-ACK"); if (vflag) { pimv1_join_prune_print(&bp[8], len - 8); } break; case 8: (void)printf(" Mode"); break; default: (void)printf(" [type %d]", type); break; } if ((bp[4] >> 4) != 1) (void)printf(" [v%d]", bp[4] >> 4); return;trunc: (void)printf("[|pim]"); return;}/* * auto-RP is a cisco protocol, documented at * ftp://ftpeng.cisco.com/ipmulticast/pim-autorp-spec01.txt */voidcisco_autorp_print(register const u_char *bp, register u_int len){ int type; int numrps; int hold; TCHECK(bp[0]); (void)printf(" auto-rp "); type = bp[0]; switch (type) { case 0x11: (void)printf("candidate-advert"); break; case 0x12: (void)printf("mapping"); break; default: (void)printf("type-0x%02x", type); break; } TCHECK(bp[1]); numrps = bp[1]; TCHECK2(bp[2], 2); (void)printf(" Hold "); hold = EXTRACT_16BITS(&bp[2]); if (hold) relts_print(EXTRACT_16BITS(&bp[2])); else printf("FOREVER"); /* Next 4 bytes are reserved. */ bp += 8; len -= 8; /*XXX skip unless -v? */ /* * Rest of packet: * numrps entries of the form: * 32 bits: RP * 6 bits: reserved * 2 bits: PIM version supported, bit 0 is "supports v1", 1 is "v2". * 8 bits: # of entries for this RP * each entry: 7 bits: reserved, 1 bit: negative, * 8 bits: mask 32 bits: source * lather, rinse, repeat. */ while (numrps--) { int nentries; char s; TCHECK2(bp[0], 4); (void)printf(" RP %s", ipaddr_string(bp)); TCHECK(bp[4]); switch (bp[4] & 0x3) { case 0: printf(" PIMv?"); break; case 1: printf(" PIMv1"); break; case 2: printf(" PIMv2"); break; case 3: printf(" PIMv1+2"); break; } TCHECK(bp[5]); nentries = bp[5]; bp += 6; len -= 6; s = ' '; for (; nentries; nentries--) { TCHECK2(bp[0], 6); (void)printf("%c%s%s/%d", s, bp[0] & 1 ? "!" : "", ipaddr_string(&bp[2]), bp[1]); s = ','; bp += 6; len -= 6; } } return;trunc: (void)printf("[|autorp]"); return;}voidpim_print(register const u_char *bp, register u_int len){ register const u_char *ep; register struct pim *pim = (struct pim *)bp; ep = (const u_char *)snapend; if (bp >= ep) return;#ifdef notyet /* currently we see only version and type */ TCHECK(pim->pim_rsv);#endif switch (PIM_VER(pim->pim_typever)) { case 2: /* avoid hardcoding? */ (void)printf("pim v2"); pimv2_print(bp, len); break; default: (void)printf("pim v%d", PIM_VER(pim->pim_typever)); break; } return;}/* * PIMv2 uses encoded address representations. * * The last PIM-SM I-D before RFC2117 was published specified the * following representation for unicast addresses. However, RFC2117 * specified no encoding for unicast addresses with the unicast * address length specified in the header. Therefore, we have to * guess which encoding is being used (Cisco's PIMv2 implementation * uses the non-RFC encoding). RFC2117 turns a previously "Reserved" * field into a 'unicast-address-length-in-bytes' field. We guess * that it's the draft encoding if this reserved field is zero. * * RFC2362 goes back to the encoded format, and calls the addr length * field "reserved" again. * * The first byte is the address family, from: * * 0 Reserved * 1 IP (IP version 4) * 2 IP6 (IP version 6) * 3 NSAP * 4 HDLC (8-bit multidrop) * 5 BBN 1822 * 6 802 (includes all 802 media plus Ethernet "canonical format") * 7 E.163 * 8 E.164 (SMDS, Frame Relay, ATM) * 9 F.69 (Telex) * 10 X.121 (X.25, Frame Relay) * 11 IPX * 12 Appletalk * 13 Decnet IV * 14 Banyan Vines * 15 E.164 with NSAP format subaddress * * In addition, the second byte is an "Encoding". 0 is the default * encoding for the address family, and no other encodings are currently * specified. * */static int pimv2_addr_len;enum pimv2_addrtype { pimv2_unicast, pimv2_group, pimv2_source};#if 0static char *addrtypestr[] = { "unicast", "group", "source"};#endif/* 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Addr Family | Encoding Type | Unicast Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++ * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Addr Family | Encoding Type | Reserved | Mask Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Group multicast Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Source Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */static intpimv2_addr_print(const u_char *bp, enum pimv2_addrtype at, int silent){ int af; char *afstr; int len, hdrlen; TCHECK(bp[0]); if (pimv2_addr_len == 0) { TCHECK(bp[1]); switch (bp[0]) { case 1: af = AF_INET; afstr = "IPv4"; len = 4; break;#ifdef INET6 case 2: af = AF_INET6; afstr = "IPv6"; len = 16; break;#endif default: return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -