print-rip.c revision 98524
117680Spst/* 217680Spst * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2017680Spst */ 2117680Spst 2217680Spst#ifndef lint 2326180Sfennerstatic const char rcsid[] = 2498524Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.49 2001/05/10 05:30:22 fenner Exp $ (LBL)"; 2517680Spst#endif 2617680Spst 2756893Sfenner#ifdef HAVE_CONFIG_H 2856893Sfenner#include "config.h" 2956893Sfenner#endif 3056893Sfenner 3117680Spst#include <sys/param.h> 3217680Spst#include <sys/time.h> 3317680Spst#include <sys/socket.h> 3417680Spst 3517680Spst#include <netinet/in.h> 3617680Spst 3717680Spst#include <stdio.h> 3875115Sfenner#include <ctype.h> 3975115Sfenner#include <string.h> 4017680Spst 4117680Spst#include "interface.h" 4217680Spst#include "addrtoname.h" 4317680Spst#include "extract.h" /* must come after interface.h */ 4417680Spst 4517680Spststruct rip { 4617680Spst u_char rip_cmd; /* request/response */ 4717680Spst u_char rip_vers; /* protocol version # */ 4817680Spst u_short rip_zero2; /* unused */ 4917680Spst}; 5017680Spst#define RIPCMD_REQUEST 1 /* want info */ 5117680Spst#define RIPCMD_RESPONSE 2 /* responding to request */ 5217680Spst#define RIPCMD_TRACEON 3 /* turn tracing on */ 5317680Spst#define RIPCMD_TRACEOFF 4 /* turn it off */ 5417680Spst#define RIPCMD_POLL 5 /* want info from everybody */ 5517680Spst#define RIPCMD_POLLENTRY 6 /* poll for entry */ 5617680Spst 5775115Sfenner#define RIP_AUTHLEN 16 5875115Sfenner 5917680Spststruct rip_netinfo { 6017680Spst u_short rip_family; 6117680Spst u_short rip_tag; 6217680Spst u_int32_t rip_dest; 6317680Spst u_int32_t rip_dest_mask; 6417680Spst u_int32_t rip_router; 6517680Spst u_int32_t rip_metric; /* cost of route */ 6617680Spst}; 6717680Spst 6817680Spststatic void 6975115Sfennerrip_printblk(const u_char *cp, const u_char *ep) 7017680Spst{ 7175115Sfenner for (; cp < ep; cp += 2) 7275115Sfenner printf(" %04x", EXTRACT_16BITS(cp)); 7375115Sfenner return; 7475115Sfenner} 7517680Spst 7675115Sfennerstatic void 7775115Sfennerrip_entry_print_v1(register int vers, register const struct rip_netinfo *ni) 7875115Sfenner{ 7975115Sfenner register u_short family; 8017680Spst 8175115Sfenner /* RFC 1058 */ 8275115Sfenner family = EXTRACT_16BITS(&ni->rip_family); 8375115Sfenner if (family != AF_INET) { 8475115Sfenner printf(" [family %d:", family); 8575115Sfenner rip_printblk((u_char *)&ni->rip_tag, 8675115Sfenner (u_char *)&ni->rip_metric + 8775115Sfenner sizeof(ni->rip_metric)); 8817680Spst printf("]"); 8975115Sfenner return; 9075115Sfenner } 9175115Sfenner if (ni->rip_tag || ni->rip_dest_mask || ni->rip_router) { 9275115Sfenner /* MBZ fields not zero */ 9375115Sfenner printf(" ["); 9475115Sfenner rip_printblk((u_char *)&ni->rip_family, 9575115Sfenner (u_char *)&ni->rip_metric + 9675115Sfenner sizeof(ni->rip_metric)); 9775115Sfenner printf("]"); 9875115Sfenner return; 9975115Sfenner } 10075115Sfenner printf(" {%s}(%d)", ipaddr_string(&ni->rip_dest), 10175115Sfenner EXTRACT_32BITS(&ni->rip_metric)); 10275115Sfenner} 10375115Sfenner 10475115Sfennerstatic void 10575115Sfennerrip_entry_print_v2(register int vers, register const struct rip_netinfo *ni) 10675115Sfenner{ 10775115Sfenner register u_char *p; 10875115Sfenner register u_short family; 10975115Sfenner u_char buf[RIP_AUTHLEN]; 11075115Sfenner 11175115Sfenner /* RFC 1723 */ 11275115Sfenner family = EXTRACT_16BITS(&ni->rip_family); 11375115Sfenner if (family == 0xFFFF) { 11475115Sfenner if (EXTRACT_16BITS(&ni->rip_tag) == 2) { 11575115Sfenner memcpy(buf, &ni->rip_dest, sizeof(buf)); 11675115Sfenner buf[sizeof(buf)-1] = '\0'; 11775115Sfenner for (p = buf; *p; p++) { 11875115Sfenner if (!isprint(*p)) 11975115Sfenner break; 12075115Sfenner } 12175115Sfenner if (!*p) { 12275115Sfenner printf(" [password %s]", buf); 12375115Sfenner } else { 12475115Sfenner printf(" [password: "); 12575115Sfenner rip_printblk((u_char *)&ni->rip_dest, 12675115Sfenner (u_char *)&ni->rip_metric + 12775115Sfenner sizeof(ni->rip_metric)); 12875115Sfenner printf("]"); 12975115Sfenner } 13075115Sfenner } else { 13175115Sfenner printf(" [auth %d:", 13275115Sfenner EXTRACT_16BITS(&ni->rip_tag)); 13375115Sfenner rip_printblk((u_char *)&ni->rip_dest, 13475115Sfenner (u_char *)&ni->rip_metric + 13575115Sfenner sizeof(ni->rip_metric)); 13675115Sfenner printf("]"); 13775115Sfenner } 13875115Sfenner } else if (family != AF_INET) { 13975115Sfenner printf(" [family %d:", family); 14075115Sfenner rip_printblk((u_char *)&ni->rip_tag, 14175115Sfenner (u_char *)&ni->rip_metric + 14275115Sfenner sizeof(ni->rip_metric)); 14375115Sfenner printf("]"); 14475115Sfenner return; 14575115Sfenner } else { /* AF_INET */ 14617680Spst printf(" {%s", ipaddr_string(&ni->rip_dest)); 14717680Spst if (ni->rip_dest_mask) 14817680Spst printf("/%s", ipaddr_string(&ni->rip_dest_mask)); 14917680Spst if (ni->rip_router) 15017680Spst printf("->%s", ipaddr_string(&ni->rip_router)); 15117680Spst if (ni->rip_tag) 15217680Spst printf(" tag %04x", EXTRACT_16BITS(&ni->rip_tag)); 15375115Sfenner printf("}(%d)", EXTRACT_32BITS(&ni->rip_metric)); 15417680Spst } 15517680Spst} 15617680Spst 15717680Spstvoid 15817680Spstrip_print(const u_char *dat, u_int length) 15917680Spst{ 16017680Spst register const struct rip *rp; 16117680Spst register const struct rip_netinfo *ni; 16217680Spst register int i, j, trunc; 16317680Spst 16426180Sfenner i = min(length, snapend - dat) - sizeof(*rp); 16556893Sfenner if (i < 0) { 16656893Sfenner printf(" [|rip]"); 16717680Spst return; 16856893Sfenner } 16917680Spst 17017680Spst rp = (struct rip *)dat; 17175115Sfenner switch (rp->rip_vers) { 17275115Sfenner case 0: 17375115Sfenner /* 17475115Sfenner * RFC 1058. 17575115Sfenner * 17675115Sfenner * XXX - RFC 1058 says 17775115Sfenner * 17875115Sfenner * 0 Datagrams whose version number is zero are to be ignored. 17975115Sfenner * These are from a previous version of the protocol, whose 18075115Sfenner * packet format was machine-specific. 18175115Sfenner * 18275115Sfenner * so perhaps we should just dump the first few words of 18375115Sfenner * the packet, in hex. 18498524Sfenner */ 18575115Sfenner printf(" RIPv0: "); 18617680Spst ni = (struct rip_netinfo *)(rp + 1); 18775115Sfenner rip_printblk((u_char *)&ni->rip_family, 18875115Sfenner (u_char *)&ni->rip_metric + 18975115Sfenner sizeof(ni->rip_metric)); 19017680Spst break; 19117680Spst default: 19275115Sfenner switch (rp->rip_cmd) { 19375115Sfenner case RIPCMD_REQUEST: 19475115Sfenner printf(" RIPv%d-req %d", rp->rip_vers, length); 19575115Sfenner break; 19675115Sfenner case RIPCMD_RESPONSE: 19775115Sfenner j = length / sizeof(*ni); 19875115Sfenner if (j * sizeof(*ni) != length - 4) 19975115Sfenner printf(" RIPv%d-resp [items %d] [%d]:", 20075115Sfenner rp->rip_vers, j, length); 20175115Sfenner else 20275115Sfenner printf(" RIPv%d-resp [items %d]:", 20375115Sfenner rp->rip_vers, j); 20475115Sfenner trunc = (i / sizeof(*ni)) != j; 20575115Sfenner ni = (struct rip_netinfo *)(rp + 1); 20675115Sfenner for (; (i -= sizeof(*ni)) >= 0; ++ni) { 20775115Sfenner if (rp->rip_vers == 1) 20875115Sfenner rip_entry_print_v1(rp->rip_vers, ni); 20975115Sfenner else 21075115Sfenner rip_entry_print_v2(rp->rip_vers, ni); 21175115Sfenner } 21275115Sfenner if (trunc) 21375115Sfenner printf("[|rip]"); 21475115Sfenner break; 21575115Sfenner case RIPCMD_TRACEON: 21675115Sfenner printf(" RIPv%d-traceon %d: \"", rp->rip_vers, length); 21775115Sfenner (void)fn_print((const u_char *)(rp + 1), snapend); 21898524Sfenner fputs("\"", stdout); 21975115Sfenner break; 22075115Sfenner case RIPCMD_TRACEOFF: 22175115Sfenner printf(" RIPv%d-traceoff %d", rp->rip_vers, length); 22275115Sfenner break; 22375115Sfenner case RIPCMD_POLL: 22475115Sfenner printf(" RIPv%d-poll %d", rp->rip_vers, length); 22575115Sfenner break; 22675115Sfenner case RIPCMD_POLLENTRY: 22775115Sfenner printf(" RIPv%d-pollentry %d", rp->rip_vers, length); 22875115Sfenner break; 22975115Sfenner default: 23075115Sfenner printf(" RIPv%d-#%d %d", rp->rip_vers, rp->rip_cmd, 23175115Sfenner length); 23275115Sfenner break; 23375115Sfenner } 23498524Sfenner } 23517680Spst} 236