]> The Tcpdump Group git mirrors - tcpdump/blob - print-igrp.c
Use EXTRACT_nBITS even when just testing against zero.
[tcpdump] / print-igrp.c
1 /*
2 * Copyright (c) 1996, 1997
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 * Initial contribution from Francis Dupont (francis.dupont@inria.fr)
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <tcpdump-stdinc.h>
29
30 #include <stdio.h>
31
32 #include "interface.h"
33 #include "addrtoname.h"
34 #include "ip.h"
35 #include "extract.h" /* must come after interface.h */
36
37 /* Cisco IGRP definitions */
38
39 /* IGRP Header */
40
41 struct igrphdr {
42 u_int8_t ig_vop; /* protocol version number / opcode */
43 #define IGRP_V(x) (((x) & 0xf0) >> 4)
44 #define IGRP_OP(x) ((x) & 0x0f)
45 u_int8_t ig_ed; /* edition number */
46 u_int16_t ig_as; /* autonomous system number */
47 u_int16_t ig_ni; /* number of subnet in local net */
48 u_int16_t ig_ns; /* number of networks in AS */
49 u_int16_t ig_nx; /* number of networks ouside AS */
50 u_int16_t ig_sum; /* checksum of IGRP header & data */
51 };
52
53 #define IGRP_UPDATE 1
54 #define IGRP_REQUEST 2
55
56 /* IGRP routing entry */
57
58 struct igrprte {
59 u_int8_t igr_net[3]; /* 3 significant octets of IP address */
60 u_int8_t igr_dly[3]; /* delay in tens of microseconds */
61 u_int8_t igr_bw[3]; /* bandwidth in units of 1 kb/s */
62 u_int8_t igr_mtu[2]; /* MTU in octets */
63 u_int8_t igr_rel; /* percent packets successfully tx/rx */
64 u_int8_t igr_ld; /* percent of channel occupied */
65 u_int8_t igr_hct; /* hop count */
66 };
67
68 #define IGRP_RTE_SIZE 14 /* don't believe sizeof ! */
69
70 static void
71 igrp_entry_print(register struct igrprte *igr, register int is_interior,
72 register int is_exterior)
73 {
74 register u_int delay, bandwidth;
75 u_int metric, mtu;
76
77 if (is_interior)
78 printf(" *.%d.%d.%d", igr->igr_net[0],
79 igr->igr_net[1], igr->igr_net[2]);
80 else if (is_exterior)
81 printf(" X%d.%d.%d.0", igr->igr_net[0],
82 igr->igr_net[1], igr->igr_net[2]);
83 else
84 printf(" %d.%d.%d.0", igr->igr_net[0],
85 igr->igr_net[1], igr->igr_net[2]);
86
87 delay = EXTRACT_24BITS(igr->igr_dly);
88 bandwidth = EXTRACT_24BITS(igr->igr_bw);
89 metric = bandwidth + delay;
90 if (metric > 0xffffff)
91 metric = 0xffffff;
92 mtu = EXTRACT_16BITS(igr->igr_mtu);
93
94 printf(" d=%d b=%d r=%d l=%d M=%d mtu=%d in %d hops",
95 10 * delay, bandwidth == 0 ? 0 : 10000000 / bandwidth,
96 igr->igr_rel, igr->igr_ld, metric,
97 mtu, igr->igr_hct);
98 }
99
100 static const struct tok op2str[] = {
101 { IGRP_UPDATE, "update" },
102 { IGRP_REQUEST, "request" },
103 { 0, NULL }
104 };
105
106 void
107 igrp_print(register const u_char *bp, u_int length, const u_char *bp2 _U_)
108 {
109 register struct igrphdr *hdr;
110 register u_char *cp;
111 u_int nint, nsys, next;
112
113 hdr = (struct igrphdr *)bp;
114 cp = (u_char *)(hdr + 1);
115 (void)printf("igrp:");
116
117 /* Header */
118 TCHECK(*hdr);
119 nint = EXTRACT_16BITS(&hdr->ig_ni);
120 nsys = EXTRACT_16BITS(&hdr->ig_ns);
121 next = EXTRACT_16BITS(&hdr->ig_nx);
122
123 (void)printf(" %s V%d edit=%d AS=%d (%d/%d/%d)",
124 tok2str(op2str, "op-#%d", IGRP_OP(hdr->ig_vop)),
125 IGRP_V(hdr->ig_vop),
126 hdr->ig_ed,
127 EXTRACT_16BITS(&hdr->ig_as),
128 nint,
129 nsys,
130 next);
131
132 length -= sizeof(*hdr);
133 while (length >= IGRP_RTE_SIZE) {
134 if (nint > 0) {
135 TCHECK2(*cp, IGRP_RTE_SIZE);
136 igrp_entry_print((struct igrprte *)cp, 1, 0);
137 --nint;
138 } else if (nsys > 0) {
139 TCHECK2(*cp, IGRP_RTE_SIZE);
140 igrp_entry_print((struct igrprte *)cp, 0, 0);
141 --nsys;
142 } else if (next > 0) {
143 TCHECK2(*cp, IGRP_RTE_SIZE);
144 igrp_entry_print((struct igrprte *)cp, 0, 1);
145 --next;
146 } else {
147 (void)printf(" [extra bytes %d]", length);
148 break;
149 }
150 cp += IGRP_RTE_SIZE;
151 length -= IGRP_RTE_SIZE;
152 }
153 if (nint == 0 && nsys == 0 && next == 0)
154 return;
155 trunc:
156 fputs(" [|igrp]", stdout);
157 }