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 char rcsid[] = 24 "@(#) $Header: print-rip.c,v 1.34 96/07/23 14:17:26 leres Exp $ (LBL)"; 25 #endif 26 27 #include <sys/param.h> 28 #include <sys/time.h> 29 #include <sys/socket.h> 30 31 #include <netinet/in.h> 32 #include <netinet/in_systm.h> 33 #include <netinet/ip.h> 34 #include <netinet/ip_var.h> 35 #include <netinet/udp.h> 36 #include <netinet/udp_var.h> 37 38 #include <stdio.h> 39 40 #include "interface.h" 41 #include "addrtoname.h" 42 #include "extract.h" /* must come after interface.h */ 43 44 struct rip { 45 u_char rip_cmd; /* request/response */ 46 u_char rip_vers; /* protocol version # */ 47 u_short rip_zero2; /* unused */ 48 }; 49 #define RIPCMD_REQUEST 1 /* want info */ 50 #define RIPCMD_RESPONSE 2 /* responding to request */ 51 #define RIPCMD_TRACEON 3 /* turn tracing on */ 52 #define RIPCMD_TRACEOFF 4 /* turn it off */ 53 #define RIPCMD_POLL 5 /* want info from everybody */ 54 #define RIPCMD_POLLENTRY 6 /* poll for entry */ 55 56 struct rip_netinfo { 57 u_short rip_family; 58 u_short rip_tag; 59 u_int32_t rip_dest; 60 u_int32_t rip_dest_mask; 61 u_int32_t rip_router; 62 u_int32_t rip_metric; /* cost of route */ 63 }; 64 65 static void 66 rip_entry_print(register int vers, register const struct rip_netinfo *ni) 67 { 68 register u_char *cp, *ep; 69 70 if (EXTRACT_16BITS(&ni->rip_family) != AF_INET) { 71 72 printf(" [family %d:", EXTRACT_16BITS(&ni->rip_family)); 73 cp = (u_char *)&ni->rip_tag; 74 ep = (u_char *)&ni->rip_metric + sizeof(ni->rip_metric); 75 for (; cp < ep; cp += 2) 76 printf(" %04x", EXTRACT_16BITS(cp)); 77 printf("]"); 78 } else if (vers < 2) { 79 /* RFC 1058 */ 80 printf(" %s", ipaddr_string(&ni->rip_dest)); 81 } else { 82 /* RFC 1723 */ 83 printf(" {%s", ipaddr_string(&ni->rip_dest)); 84 if (ni->rip_dest_mask) 85 printf("/%s", ipaddr_string(&ni->rip_dest_mask)); 86 if (ni->rip_router) 87 printf("->%s", ipaddr_string(&ni->rip_router)); 88 if (ni->rip_tag) 89 printf(" tag %04x", EXTRACT_16BITS(&ni->rip_tag)); 90 printf("}"); 91 } 92 printf("(%d)", EXTRACT_32BITS(&ni->rip_metric)); 93 } 94 95 void 96 rip_print(const u_char *dat, u_int length) 97 { 98 register const struct rip *rp; 99 register const struct rip_netinfo *ni; 100 register int i, j, trunc; 101 102 i = min(length, snapend - dat) - (sizeof(*rp) - sizeof(*ni)); 103 if (i < 0) 104 return; 105 106 rp = (struct rip *)dat; 107 switch (rp->rip_cmd) { 108 109 case RIPCMD_REQUEST: 110 printf(" rip-req %d", length); 111 break; 112 113 case RIPCMD_RESPONSE: 114 j = length / sizeof(*ni); 115 if (j * sizeof(*ni) != length - 4) 116 printf(" rip-resp %d[%d]:", j, length); 117 else 118 printf(" rip-resp %d:", j); 119 trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i); 120 ni = (struct rip_netinfo *)(rp + 1); 121 for (; (i -= sizeof(*ni)) >= 0; ++ni) 122 rip_entry_print(rp->rip_vers, ni); 123 if (trunc) 124 printf("[|rip]"); 125 break; 126 127 case RIPCMD_TRACEON: 128 printf(" rip-traceon %d: \"", length); 129 (void)fn_print((const u_char *)(rp + 1), snapend); 130 fputs("\"\n", stdout); 131 break; 132 133 case RIPCMD_TRACEOFF: 134 printf(" rip-traceoff %d", length); 135 break; 136 137 case RIPCMD_POLL: 138 printf(" rip-poll %d", length); 139 break; 140 141 case RIPCMD_POLLENTRY: 142 printf(" rip-pollentry %d", length); 143 break; 144 145 default: 146 printf(" rip-#%d %d", rp->rip_cmd, length); 147 break; 148 } 149 switch (rp->rip_vers) { 150 151 case 1: 152 case 2: 153 break; 154 155 default: 156 printf(" [vers %d]", rp->rip_vers); 157 break; 158 } 159 } 160