xref: /freebsd/contrib/tcpdump/print-rip.c (revision 23f282aa31e9b6fceacd449020e936e98d6f2298)
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