1 /* $OpenBSD: print-rip.c,v 1.11 2007/10/07 16:41:05 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #ifndef lint 25 static const char rcsid[] = 26 "@(#) $Id: print-rip.c,v 1.11 2007/10/07 16:41:05 deraadt Exp $ (LBL)"; 27 #endif 28 29 #include <sys/param.h> 30 #include <sys/time.h> 31 #include <sys/socket.h> 32 33 #include <netinet/in.h> 34 #include <netinet/in_systm.h> 35 #include <netinet/ip.h> 36 #include <netinet/ip_var.h> 37 #include <netinet/udp.h> 38 #include <netinet/udp_var.h> 39 40 #include <stdio.h> 41 #include <string.h> 42 #include <ctype.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 #define RIP_AUTHLEN 16 61 62 struct rip_netinfo { 63 u_short rip_family; 64 u_short rip_tag; 65 u_int32_t rip_dest; 66 u_int32_t rip_dest_mask; 67 u_int32_t rip_router; 68 u_int32_t rip_metric; /* cost of route */ 69 }; 70 71 static void 72 rip_printblk(const u_char *cp, const u_char *ep) 73 { 74 for (; cp < ep; cp += 2) 75 printf(" %04x", EXTRACT_16BITS(cp)); 76 return; 77 } 78 79 static void 80 rip_entry_print_v1(register int vers, register const struct rip_netinfo *ni) 81 { 82 register u_short family; 83 84 /* RFC 1058 */ 85 family = EXTRACT_16BITS(&ni->rip_family); 86 if (family != AF_INET) { 87 printf(" [family %d:", family); 88 rip_printblk((u_char *)&ni->rip_tag, 89 (u_char *)&ni->rip_metric + 90 sizeof(ni->rip_metric)); 91 printf("]"); 92 return; 93 } 94 if (ni->rip_tag || ni->rip_dest_mask || ni->rip_router) { 95 /* MBZ fields not zero */ 96 printf(" ["); 97 rip_printblk((u_char *)&ni->rip_family, 98 (u_char *)&ni->rip_metric + 99 sizeof(ni->rip_metric)); 100 printf("]"); 101 return; 102 } 103 printf(" {%s}(%d)", ipaddr_string(&ni->rip_dest), 104 EXTRACT_32BITS(&ni->rip_metric)); 105 } 106 107 static void 108 rip_entry_print_v2(register int vers, register const struct rip_netinfo *ni) 109 { 110 register u_char *p; 111 register u_short family; 112 char buf[RIP_AUTHLEN]; 113 114 /* RFC 1723 */ 115 family = EXTRACT_16BITS(&ni->rip_family); 116 if (family == 0xFFFF) { 117 if (EXTRACT_16BITS(&ni->rip_tag) == 2) { 118 memcpy(buf, &ni->rip_dest, sizeof(buf)); 119 buf[sizeof(buf)-1] = '\0'; 120 for (p = buf; *p; p++) { 121 if (!isprint(*p)) 122 break; 123 } 124 if (!*p) { 125 printf(" [password %s]", buf); 126 } else { 127 printf(" [password: "); 128 rip_printblk((u_char *)&ni->rip_dest, 129 (u_char *)&ni->rip_metric + 130 sizeof(ni->rip_metric)); 131 printf("]"); 132 } 133 } else { 134 printf(" [auth %d:", 135 EXTRACT_16BITS(&ni->rip_tag)); 136 rip_printblk((u_char *)&ni->rip_dest, 137 (u_char *)&ni->rip_metric + 138 sizeof(ni->rip_metric)); 139 printf("]"); 140 } 141 } else if (family != AF_INET) { 142 printf(" [family %d:", family); 143 rip_printblk((u_char *)&ni->rip_tag, 144 (u_char *)&ni->rip_metric + 145 sizeof(ni->rip_metric)); 146 printf("]"); 147 return; 148 } else { /* AF_INET */ 149 printf(" {%s", ipaddr_string(&ni->rip_dest)); 150 if (ni->rip_dest_mask) 151 printf("/%s", ipaddr_string(&ni->rip_dest_mask)); 152 if (ni->rip_router) 153 printf("->%s", ipaddr_string(&ni->rip_router)); 154 if (ni->rip_tag) 155 printf(" tag %04x", EXTRACT_16BITS(&ni->rip_tag)); 156 printf("}(%d)", EXTRACT_32BITS(&ni->rip_metric)); 157 } 158 } 159 160 void 161 rip_print(const u_char *dat, u_int length) 162 { 163 register const struct rip *rp; 164 register const struct rip_netinfo *ni; 165 register int i, j, trunc; 166 167 i = min(length, snapend - dat) - sizeof(*rp); 168 if (i < 0) { 169 printf(" [|rip]"); 170 return; 171 } 172 173 rp = (struct rip *)dat; 174 switch (rp->rip_vers) { 175 case 0: 176 /* RFC 1058 */ 177 printf(" RIPv0: "); 178 rip_printblk((u_char *)(rp + 1), snapend); 179 break; 180 default: 181 switch (rp->rip_cmd) { 182 case RIPCMD_REQUEST: 183 printf(" RIPv%d-req %d", rp->rip_vers, length); 184 break; 185 case RIPCMD_RESPONSE: 186 j = length / sizeof(*ni); 187 if (j * sizeof(*ni) != length - 4) 188 printf(" RIPv%d-resp [items %d] [%d]:", 189 rp->rip_vers, j, length); 190 else 191 printf(" RIPv%d-resp [items %d]:", 192 rp->rip_vers, j); 193 trunc = (i / sizeof(*ni)) != j; 194 ni = (struct rip_netinfo *)(rp + 1); 195 for (; (i -= sizeof(*ni)) >= 0; ++ni) { 196 if (rp->rip_vers == 1) 197 rip_entry_print_v1(rp->rip_vers, ni); 198 else 199 rip_entry_print_v2(rp->rip_vers, ni); 200 } 201 if (trunc) 202 printf("[|rip]"); 203 break; 204 case RIPCMD_TRACEON: 205 printf(" RIPv%d-traceon %d: \"", rp->rip_vers, length); 206 (void)fn_print((const u_char *)(rp + 1), snapend); 207 fputs("\"\n", stdout); 208 break; 209 case RIPCMD_TRACEOFF: 210 printf(" RIPv%d-traceoff %d", rp->rip_vers, length); 211 break; 212 case RIPCMD_POLL: 213 printf(" RIPv%d-poll %d", rp->rip_vers, length); 214 break; 215 case RIPCMD_POLLENTRY: 216 printf(" RIPv%d-pollentry %d", rp->rip_vers, length); 217 break; 218 default: 219 printf(" RIPv%d-#%d %d", rp->rip_vers, rp->rip_cmd, 220 length); 221 break; 222 } 223 } 224 } 225