1 /* 2 * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996 3 * The Regents of the University of California. 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 distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 #ifndef lint 23 static const char rcsid[] = 24 "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.40 1999/11/22 04:24:28 fenner Exp $ (LBL)"; 25 #endif 26 27 #ifdef HAVE_CONFIG_H 28 #include "config.h" 29 #endif 30 31 #include <sys/param.h> 32 #include <sys/time.h> 33 #include <sys/socket.h> 34 35 #include <netinet/in.h> 36 #include <netinet/in_systm.h> 37 #include <netinet/ip.h> 38 #include <netinet/ip_var.h> 39 #include <netinet/udp.h> 40 #include <netinet/udp_var.h> 41 42 #include <stdio.h> 43 44 #include "interface.h" 45 #include "addrtoname.h" 46 #include "extract.h" /* must come after interface.h */ 47 48 struct rip { 49 u_char rip_cmd; /* request/response */ 50 u_char rip_vers; /* protocol version # */ 51 u_short rip_zero2; /* unused */ 52 }; 53 #define RIPCMD_REQUEST 1 /* want info */ 54 #define RIPCMD_RESPONSE 2 /* responding to request */ 55 #define RIPCMD_TRACEON 3 /* turn tracing on */ 56 #define RIPCMD_TRACEOFF 4 /* turn it off */ 57 #define RIPCMD_POLL 5 /* want info from everybody */ 58 #define RIPCMD_POLLENTRY 6 /* poll for entry */ 59 60 struct rip_netinfo { 61 u_short rip_family; 62 u_short rip_tag; 63 u_int32_t rip_dest; 64 u_int32_t rip_dest_mask; 65 u_int32_t rip_router; 66 u_int32_t rip_metric; /* cost of route */ 67 }; 68 69 static void 70 rip_entry_print(register int vers, register const struct rip_netinfo *ni) 71 { 72 register u_char *cp, *ep; 73 74 if (EXTRACT_16BITS(&ni->rip_family) != AF_INET) { 75 76 printf(" [family %d:", EXTRACT_16BITS(&ni->rip_family)); 77 cp = (u_char *)&ni->rip_tag; 78 ep = (u_char *)&ni->rip_metric + sizeof(ni->rip_metric); 79 for (; cp < ep; cp += 2) 80 printf(" %04x", EXTRACT_16BITS(cp)); 81 printf("]"); 82 } else if (vers < 2) { 83 /* RFC 1058 */ 84 printf(" %s", ipaddr_string(&ni->rip_dest)); 85 } else { 86 /* RFC 1723 */ 87 printf(" {%s", ipaddr_string(&ni->rip_dest)); 88 if (ni->rip_dest_mask) 89 printf("/%s", ipaddr_string(&ni->rip_dest_mask)); 90 if (ni->rip_router) 91 printf("->%s", ipaddr_string(&ni->rip_router)); 92 if (ni->rip_tag) 93 printf(" tag %04x", EXTRACT_16BITS(&ni->rip_tag)); 94 printf("}"); 95 } 96 printf("(%d)", EXTRACT_32BITS(&ni->rip_metric)); 97 } 98 99 void 100 rip_print(const u_char *dat, u_int length) 101 { 102 register const struct rip *rp; 103 register const struct rip_netinfo *ni; 104 register int i, j, trunc; 105 106 i = min(length, snapend - dat) - sizeof(*rp); 107 if (i < 0) { 108 printf(" [|rip]"); 109 return; 110 } 111 112 rp = (struct rip *)dat; 113 switch (rp->rip_cmd) { 114 115 case RIPCMD_REQUEST: 116 printf(" rip-req %d", length); 117 break; 118 119 case RIPCMD_RESPONSE: 120 j = length / sizeof(*ni); 121 if (j * sizeof(*ni) != length - 4) 122 printf(" rip-resp %d[%d]:", j, length); 123 else 124 printf(" rip-resp %d:", j); 125 trunc = (i / sizeof(*ni)) != j; 126 ni = (struct rip_netinfo *)(rp + 1); 127 for (; (i -= sizeof(*ni)) >= 0; ++ni) 128 rip_entry_print(rp->rip_vers, ni); 129 if (trunc) 130 printf("[|rip]"); 131 break; 132 133 case RIPCMD_TRACEON: 134 printf(" rip-traceon %d: \"", length); 135 (void)fn_print((const u_char *)(rp + 1), snapend); 136 fputs("\"\n", stdout); 137 break; 138 139 case RIPCMD_TRACEOFF: 140 printf(" rip-traceoff %d", length); 141 break; 142 143 case RIPCMD_POLL: 144 printf(" rip-poll %d", length); 145 break; 146 147 case RIPCMD_POLLENTRY: 148 printf(" rip-pollentry %d", length); 149 break; 150 151 default: 152 printf(" rip-#%d %d", rp->rip_cmd, length); 153 break; 154 } 155 switch (rp->rip_vers) { 156 157 case 1: 158 case 2: 159 break; 160 161 default: 162 printf(" [vers %d]", rp->rip_vers); 163 break; 164 } 165 } 166