1 |
|
|
/* $OpenBSD: print-bootp.c,v 1.22 2015/12/22 21:01:07 mmcc Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 |
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 |
|
|
* Format and print bootp packets. |
24 |
|
|
*/ |
25 |
|
|
#include <sys/time.h> |
26 |
|
|
#include <sys/socket.h> |
27 |
|
|
|
28 |
|
|
struct mbuf; |
29 |
|
|
struct rtentry; |
30 |
|
|
#include <net/if.h> |
31 |
|
|
|
32 |
|
|
#include <netinet/in.h> |
33 |
|
|
#include <netinet/if_ether.h> |
34 |
|
|
|
35 |
|
|
#include <ctype.h> |
36 |
|
|
#include <stdio.h> |
37 |
|
|
#include <string.h> |
38 |
|
|
|
39 |
|
|
#include "interface.h" |
40 |
|
|
#include "addrtoname.h" |
41 |
|
|
#include "bootp.h" |
42 |
|
|
|
43 |
|
|
static void rfc1048_print(const u_char *, u_int); |
44 |
|
|
static void cmu_print(const u_char *, u_int); |
45 |
|
|
|
46 |
|
|
static char tstr[] = " [|bootp]"; |
47 |
|
|
|
48 |
|
|
/* |
49 |
|
|
* Print bootp requests |
50 |
|
|
*/ |
51 |
|
|
void |
52 |
|
|
bootp_print(const u_char *cp, u_int length, |
53 |
|
|
u_short sport, u_short dport) |
54 |
|
|
{ |
55 |
|
|
const struct bootp *bp; |
56 |
|
|
static u_char vm_cmu[4] = VM_CMU; |
57 |
|
|
static u_char vm_rfc1048[4] = VM_RFC1048; |
58 |
|
|
|
59 |
|
|
bp = (struct bootp *)cp; |
60 |
|
|
TCHECK(bp->bp_op); |
61 |
|
|
switch (bp->bp_op) { |
62 |
|
|
|
63 |
|
|
case BOOTREQUEST: |
64 |
|
|
/* Usually, a request goes from a client to a server */ |
65 |
|
|
if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS) |
66 |
|
|
printf(" (request)"); |
67 |
|
|
break; |
68 |
|
|
|
69 |
|
|
case BOOTREPLY: |
70 |
|
|
/* Usually, a reply goes from a server to a client */ |
71 |
|
|
if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC) |
72 |
|
|
printf(" (reply)"); |
73 |
|
|
break; |
74 |
|
|
|
75 |
|
|
default: |
76 |
|
|
printf(" bootp-#%d", bp->bp_op); |
77 |
|
|
} |
78 |
|
|
|
79 |
|
|
TCHECK(bp->bp_flags); |
80 |
|
|
|
81 |
|
|
/* The usual hardware address type is 1 (10Mb Ethernet) */ |
82 |
|
|
if (bp->bp_htype != 1) |
83 |
|
|
printf(" htype-#%d", bp->bp_htype); |
84 |
|
|
|
85 |
|
|
/* The usual length for 10Mb Ethernet address is 6 bytes */ |
86 |
|
|
if (bp->bp_htype != 1 || bp->bp_hlen != 6) |
87 |
|
|
printf(" hlen:%d", bp->bp_hlen); |
88 |
|
|
|
89 |
|
|
/* Only print interesting fields */ |
90 |
|
|
if (bp->bp_hops) |
91 |
|
|
printf(" hops:%d", bp->bp_hops); |
92 |
|
|
if (bp->bp_xid) |
93 |
|
|
printf(" xid:0x%x", (u_int32_t)ntohl(bp->bp_xid)); |
94 |
|
|
if (bp->bp_secs) |
95 |
|
|
printf(" secs:%d", ntohs(bp->bp_secs)); |
96 |
|
|
if (bp->bp_flags) |
97 |
|
|
printf(" flags:0x%x", ntohs(bp->bp_flags)); |
98 |
|
|
|
99 |
|
|
/* Client's ip address */ |
100 |
|
|
TCHECK(bp->bp_ciaddr); |
101 |
|
|
if (bp->bp_ciaddr.s_addr) |
102 |
|
|
printf(" C:%s", ipaddr_string(&bp->bp_ciaddr)); |
103 |
|
|
|
104 |
|
|
/* 'your' ip address (bootp client) */ |
105 |
|
|
TCHECK(bp->bp_yiaddr); |
106 |
|
|
if (bp->bp_yiaddr.s_addr) |
107 |
|
|
printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr)); |
108 |
|
|
|
109 |
|
|
/* Server's ip address */ |
110 |
|
|
TCHECK(bp->bp_siaddr); |
111 |
|
|
if (bp->bp_siaddr.s_addr) |
112 |
|
|
printf(" S:%s", ipaddr_string(&bp->bp_siaddr)); |
113 |
|
|
|
114 |
|
|
/* Gateway's ip address */ |
115 |
|
|
TCHECK(bp->bp_giaddr); |
116 |
|
|
if (bp->bp_giaddr.s_addr) |
117 |
|
|
printf(" G:%s", ipaddr_string(&bp->bp_giaddr)); |
118 |
|
|
|
119 |
|
|
/* Client's Ethernet address */ |
120 |
|
|
if (bp->bp_htype == 1 && bp->bp_hlen == 6) { |
121 |
|
|
const struct ether_header *eh; |
122 |
|
|
const char *e; |
123 |
|
|
|
124 |
|
|
TCHECK2(bp->bp_chaddr[0], 6); |
125 |
|
|
eh = (struct ether_header *)packetp; |
126 |
|
|
if (bp->bp_op == BOOTREQUEST) |
127 |
|
|
e = (const char *)ESRC(eh); |
128 |
|
|
else if (bp->bp_op == BOOTREPLY) |
129 |
|
|
e = (const char *)EDST(eh); |
130 |
|
|
else |
131 |
|
|
e = NULL; |
132 |
|
|
if (e == 0 || memcmp((char *)bp->bp_chaddr, e, 6) != 0) |
133 |
|
|
printf(" ether %s", etheraddr_string(bp->bp_chaddr)); |
134 |
|
|
} |
135 |
|
|
|
136 |
|
|
TCHECK2(bp->bp_sname[0], 1); /* check first char only */ |
137 |
|
|
if (*bp->bp_sname) { |
138 |
|
|
printf(" sname \""); |
139 |
|
|
if (fn_print(bp->bp_sname, snapend)) { |
140 |
|
|
putchar('"'); |
141 |
|
|
fputs(tstr + 1, stdout); |
142 |
|
|
return; |
143 |
|
|
} |
144 |
|
|
putchar('"'); |
145 |
|
|
} |
146 |
|
|
TCHECK2(bp->bp_file[0], 1); /* check first char only */ |
147 |
|
|
if (*bp->bp_file) { |
148 |
|
|
printf(" file \""); |
149 |
|
|
if (fn_print(bp->bp_file, snapend)) { |
150 |
|
|
putchar('"'); |
151 |
|
|
fputs(tstr + 1, stdout); |
152 |
|
|
return; |
153 |
|
|
} |
154 |
|
|
putchar('"'); |
155 |
|
|
} |
156 |
|
|
|
157 |
|
|
/* Decode the vendor buffer */ |
158 |
|
|
TCHECK2(bp->bp_vend[0], sizeof(u_int32_t)); |
159 |
|
|
length -= sizeof(*bp) - sizeof(bp->bp_vend); |
160 |
|
|
if (memcmp((char *)bp->bp_vend, (char *)vm_rfc1048, |
161 |
|
|
sizeof(u_int32_t)) == 0) |
162 |
|
|
rfc1048_print(bp->bp_vend, length); |
163 |
|
|
else if (memcmp((char *)bp->bp_vend, (char *)vm_cmu, |
164 |
|
|
sizeof(u_int32_t)) == 0) |
165 |
|
|
cmu_print(bp->bp_vend, length); |
166 |
|
|
else { |
167 |
|
|
u_int32_t ul; |
168 |
|
|
|
169 |
|
|
memcpy((char *)&ul, (char *)bp->bp_vend, sizeof(ul)); |
170 |
|
|
if (ul != 0) |
171 |
|
|
printf("vend-#0x%x", ul); |
172 |
|
|
} |
173 |
|
|
|
174 |
|
|
return; |
175 |
|
|
trunc: |
176 |
|
|
fputs(tstr, stdout); |
177 |
|
|
} |
178 |
|
|
|
179 |
|
|
/* The first character specifies the format to print */ |
180 |
|
|
static struct tok tag2str[] = { |
181 |
|
|
/* RFC1048 tags */ |
182 |
|
|
{ TAG_PAD, " PAD" }, |
183 |
|
|
{ TAG_SUBNET_MASK, "iSM" }, /* subnet mask (RFC950) */ |
184 |
|
|
{ TAG_TIME_OFFSET, "lTZ" }, /* seconds from UTC */ |
185 |
|
|
{ TAG_GATEWAY, "iDG" }, /* default gateway */ |
186 |
|
|
{ TAG_TIME_SERVER, "iTS" }, /* time servers (RFC868) */ |
187 |
|
|
{ TAG_NAME_SERVER, "iIEN" }, /* IEN name servers (IEN116) */ |
188 |
|
|
{ TAG_DOMAIN_SERVER, "iNS" }, /* domain name (RFC1035) */ |
189 |
|
|
{ TAG_LOG_SERVER, "iLOG" }, /* MIT log servers */ |
190 |
|
|
{ TAG_COOKIE_SERVER, "iCS" }, /* cookie servers (RFC865) */ |
191 |
|
|
{ TAG_LPR_SERVER, "iLPR" }, /* lpr server (RFC1179) */ |
192 |
|
|
{ TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */ |
193 |
|
|
{ TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */ |
194 |
|
|
{ TAG_HOSTNAME, "aHN" }, /* ascii hostname */ |
195 |
|
|
{ TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */ |
196 |
|
|
{ TAG_END, " END" }, |
197 |
|
|
/* RFC1497 tags */ |
198 |
|
|
{ TAG_DUMPPATH, "aDP" }, |
199 |
|
|
{ TAG_DOMAINNAME, "aDN" }, |
200 |
|
|
{ TAG_SWAP_SERVER, "iSS" }, |
201 |
|
|
{ TAG_ROOTPATH, "aRP" }, |
202 |
|
|
{ TAG_EXTPATH, "aEP" }, |
203 |
|
|
/* RFC2132 tags */ |
204 |
|
|
{ TAG_IP_FORWARD, "BIPF" }, |
205 |
|
|
{ TAG_NL_SRCRT, "BSRT" }, |
206 |
|
|
{ TAG_PFILTERS, "pPF" }, |
207 |
|
|
{ TAG_REASS_SIZE, "sRSZ" }, |
208 |
|
|
{ TAG_DEF_TTL, "bTTL" }, |
209 |
|
|
{ TAG_MTU_TIMEOUT, "lMA" }, |
210 |
|
|
{ TAG_MTU_TABLE, "sMT" }, |
211 |
|
|
{ TAG_INT_MTU, "sMTU" }, |
212 |
|
|
{ TAG_LOCAL_SUBNETS, "BLSN" }, |
213 |
|
|
{ TAG_BROAD_ADDR, "iBR" }, |
214 |
|
|
{ TAG_DO_MASK_DISC, "BMD" }, |
215 |
|
|
{ TAG_SUPPLY_MASK, "BMS" }, |
216 |
|
|
{ TAG_DO_RDISC, "BRD" }, |
217 |
|
|
{ TAG_RTR_SOL_ADDR, "iRSA" }, |
218 |
|
|
{ TAG_STATIC_ROUTE, "pSR" }, |
219 |
|
|
{ TAG_USE_TRAILERS, "BUT" }, |
220 |
|
|
{ TAG_ARP_TIMEOUT, "lAT" }, |
221 |
|
|
{ TAG_ETH_ENCAP, "BIE" }, |
222 |
|
|
{ TAG_TCP_TTL, "bTT" }, |
223 |
|
|
{ TAG_TCP_KEEPALIVE, "lKI" }, |
224 |
|
|
{ TAG_KEEPALIVE_GO, "BKG" }, |
225 |
|
|
{ TAG_NIS_DOMAIN, "aYD" }, |
226 |
|
|
{ TAG_NIS_SERVERS, "iYS" }, |
227 |
|
|
{ TAG_NTP_SERVERS, "iNTP" }, |
228 |
|
|
{ TAG_VENDOR_OPTS, "bVO" }, |
229 |
|
|
{ TAG_NETBIOS_NS, "iWNS" }, |
230 |
|
|
{ TAG_NETBIOS_DDS, "iWDD" }, |
231 |
|
|
{ TAG_NETBIOS_NODE, "bWNT" }, |
232 |
|
|
{ TAG_NETBIOS_SCOPE, "aWSC" }, |
233 |
|
|
{ TAG_XWIN_FS, "iXFS" }, |
234 |
|
|
{ TAG_XWIN_DM, "iXDM" }, |
235 |
|
|
{ TAG_NIS_P_DOMAIN, "sN+D" }, |
236 |
|
|
{ TAG_NIS_P_SERVERS, "iN+S" }, |
237 |
|
|
{ TAG_MOBILE_HOME, "iMH" }, |
238 |
|
|
{ TAG_SMPT_SERVER, "iSMTP" }, |
239 |
|
|
{ TAG_POP3_SERVER, "iPOP3" }, |
240 |
|
|
{ TAG_NNTP_SERVER, "iNNTP" }, |
241 |
|
|
{ TAG_WWW_SERVER, "iWWW" }, |
242 |
|
|
{ TAG_FINGER_SERVER, "iFG" }, |
243 |
|
|
{ TAG_IRC_SERVER, "iIRC" }, |
244 |
|
|
{ TAG_STREETTALK_SRVR, "iSTS" }, |
245 |
|
|
{ TAG_STREETTALK_STDA, "iSTDA" }, |
246 |
|
|
{ TAG_REQUESTED_IP, "iRQ" }, |
247 |
|
|
{ TAG_IP_LEASE, "lLT" }, |
248 |
|
|
{ TAG_OPT_OVERLOAD, "bOO" }, |
249 |
|
|
{ TAG_TFTP_SERVER, "aTFTP" }, |
250 |
|
|
{ TAG_BOOTFILENAME, "aBF" }, |
251 |
|
|
{ TAG_DHCP_MESSAGE, " DHCP" }, |
252 |
|
|
{ TAG_SERVER_ID, "iSID" }, |
253 |
|
|
{ TAG_PARM_REQUEST, "bPR" }, |
254 |
|
|
{ TAG_MESSAGE, "aMSG" }, |
255 |
|
|
{ TAG_MAX_MSG_SIZE, "sMSZ" }, |
256 |
|
|
{ TAG_RENEWAL_TIME, "lRN" }, |
257 |
|
|
{ TAG_REBIND_TIME, "lRB" }, |
258 |
|
|
{ TAG_VENDOR_CLASS, "bVC" }, |
259 |
|
|
{ TAG_CLIENT_ID, "bCID" }, |
260 |
|
|
{ 0, NULL } |
261 |
|
|
}; |
262 |
|
|
|
263 |
|
|
static void |
264 |
|
|
rfc1048_print(const u_char *bp, u_int length) |
265 |
|
|
{ |
266 |
|
|
u_char tag; |
267 |
|
|
u_int len, size; |
268 |
|
|
const char *cp; |
269 |
|
|
u_char c; |
270 |
|
|
int first; |
271 |
|
|
u_int32_t ul; |
272 |
|
|
u_short us; |
273 |
|
|
|
274 |
|
|
printf(" vend-rfc1048"); |
275 |
|
|
|
276 |
|
|
/* Step over magic cookie */ |
277 |
|
|
bp += sizeof(int32_t); |
278 |
|
|
|
279 |
|
|
/* Loop while we there is a tag left in the buffer */ |
280 |
|
|
while (bp + 1 < snapend) { |
281 |
|
|
tag = *bp++; |
282 |
|
|
if (tag == TAG_PAD) |
283 |
|
|
continue; |
284 |
|
|
if (tag == TAG_END) |
285 |
|
|
return; |
286 |
|
|
cp = tok2str(tag2str, "?T%d", tag); |
287 |
|
|
c = *cp++; |
288 |
|
|
printf(" %s:", cp); |
289 |
|
|
|
290 |
|
|
/* Get the length; check for truncation */ |
291 |
|
|
if (bp + 1 >= snapend) { |
292 |
|
|
fputs(tstr, stdout); |
293 |
|
|
return; |
294 |
|
|
} |
295 |
|
|
len = *bp++; |
296 |
|
|
if (bp + len >= snapend) { |
297 |
|
|
fputs(tstr, stdout); |
298 |
|
|
return; |
299 |
|
|
} |
300 |
|
|
|
301 |
|
|
if (tag == TAG_DHCP_MESSAGE && len == 1) { |
302 |
|
|
c = *bp++; |
303 |
|
|
switch (c) { |
304 |
|
|
case DHCPDISCOVER: printf("DISCOVER"); break; |
305 |
|
|
case DHCPOFFER: printf("OFFER"); break; |
306 |
|
|
case DHCPREQUEST: printf("REQUEST"); break; |
307 |
|
|
case DHCPDECLINE: printf("DECLINE"); break; |
308 |
|
|
case DHCPACK: printf("ACK"); break; |
309 |
|
|
case DHCPNAK: printf("NACK"); break; |
310 |
|
|
case DHCPRELEASE: printf("RELEASE"); break; |
311 |
|
|
case DHCPINFORM: printf("INFORM"); break; |
312 |
|
|
default: printf("%u", c); break; |
313 |
|
|
} |
314 |
|
|
continue; |
315 |
|
|
} |
316 |
|
|
|
317 |
|
|
if (tag == TAG_PARM_REQUEST) { |
318 |
|
|
first = 1; |
319 |
|
|
while (len-- > 0) { |
320 |
|
|
c = *bp++; |
321 |
|
|
cp = tok2str(tag2str, "?%d", c); |
322 |
|
|
if (!first) |
323 |
|
|
putchar('+'); |
324 |
|
|
printf("%s", cp + 1); |
325 |
|
|
first = 0; |
326 |
|
|
} |
327 |
|
|
continue; |
328 |
|
|
} |
329 |
|
|
|
330 |
|
|
/* Print data */ |
331 |
|
|
size = len; |
332 |
|
|
if (c == '?') { |
333 |
|
|
/* Base default formats for unknown tags on data size */ |
334 |
|
|
if (size & 1) |
335 |
|
|
c = 'b'; |
336 |
|
|
else if (size & 2) |
337 |
|
|
c = 's'; |
338 |
|
|
else |
339 |
|
|
c = 'l'; |
340 |
|
|
} |
341 |
|
|
first = 1; |
342 |
|
|
switch (c) { |
343 |
|
|
|
344 |
|
|
case 'a': |
345 |
|
|
/* ascii strings */ |
346 |
|
|
putchar('"'); |
347 |
|
|
(void)fn_printn(bp, size, NULL); |
348 |
|
|
putchar('"'); |
349 |
|
|
bp += size; |
350 |
|
|
size = 0; |
351 |
|
|
break; |
352 |
|
|
|
353 |
|
|
case 'i': |
354 |
|
|
case 'l': |
355 |
|
|
/* ip addresses/32-bit words */ |
356 |
|
|
while (size >= sizeof(ul)) { |
357 |
|
|
if (!first) |
358 |
|
|
putchar(','); |
359 |
|
|
memcpy((char *)&ul, (char *)bp, sizeof(ul)); |
360 |
|
|
if (c == 'i') |
361 |
|
|
printf("%s", ipaddr_string(&ul)); |
362 |
|
|
else |
363 |
|
|
printf("%u", ntohl(ul)); |
364 |
|
|
bp += sizeof(ul); |
365 |
|
|
size -= sizeof(ul); |
366 |
|
|
first = 0; |
367 |
|
|
} |
368 |
|
|
break; |
369 |
|
|
|
370 |
|
|
case 'p': |
371 |
|
|
/* IP address pairs */ |
372 |
|
|
while (size >= 2*sizeof(ul)) { |
373 |
|
|
if (!first) |
374 |
|
|
putchar(','); |
375 |
|
|
memcpy((char *)&ul, (char *)bp, sizeof(ul)); |
376 |
|
|
printf("(%s:", ipaddr_string(&ul)); |
377 |
|
|
bp += sizeof(ul); |
378 |
|
|
memcpy((char *)&ul, (char *)bp, sizeof(ul)); |
379 |
|
|
printf("%s)", ipaddr_string(&ul)); |
380 |
|
|
bp += sizeof(ul); |
381 |
|
|
size -= 2*sizeof(ul); |
382 |
|
|
first = 0; |
383 |
|
|
} |
384 |
|
|
break; |
385 |
|
|
|
386 |
|
|
case 's': |
387 |
|
|
/* shorts */ |
388 |
|
|
while (size >= sizeof(us)) { |
389 |
|
|
if (!first) |
390 |
|
|
putchar(','); |
391 |
|
|
memcpy((char *)&us, (char *)bp, sizeof(us)); |
392 |
|
|
printf("%u", ntohs(us)); |
393 |
|
|
bp += sizeof(us); |
394 |
|
|
size -= sizeof(us); |
395 |
|
|
first = 0; |
396 |
|
|
} |
397 |
|
|
break; |
398 |
|
|
|
399 |
|
|
case 'B': |
400 |
|
|
/* boolean */ |
401 |
|
|
while (size > 0) { |
402 |
|
|
if (!first) |
403 |
|
|
putchar(','); |
404 |
|
|
switch (*bp) { |
405 |
|
|
case 0: |
406 |
|
|
putchar('N'); |
407 |
|
|
break; |
408 |
|
|
case 1: |
409 |
|
|
putchar('Y'); |
410 |
|
|
break; |
411 |
|
|
default: |
412 |
|
|
printf("%d?", *bp); |
413 |
|
|
break; |
414 |
|
|
} |
415 |
|
|
++bp; |
416 |
|
|
--size; |
417 |
|
|
first = 0; |
418 |
|
|
} |
419 |
|
|
break; |
420 |
|
|
|
421 |
|
|
case 'b': |
422 |
|
|
default: |
423 |
|
|
/* Bytes */ |
424 |
|
|
while (size > 0) { |
425 |
|
|
if (!first) |
426 |
|
|
putchar('.'); |
427 |
|
|
printf("%d", *bp); |
428 |
|
|
++bp; |
429 |
|
|
--size; |
430 |
|
|
first = 0; |
431 |
|
|
} |
432 |
|
|
break; |
433 |
|
|
} |
434 |
|
|
/* Data left over? */ |
435 |
|
|
if (size) |
436 |
|
|
printf("[len %d]", len); |
437 |
|
|
} |
438 |
|
|
} |
439 |
|
|
|
440 |
|
|
static void |
441 |
|
|
cmu_print(const u_char *bp, u_int length) |
442 |
|
|
{ |
443 |
|
|
const struct cmu_vend *cmu; |
444 |
|
|
static const char fmt[] = " %s:%s"; |
445 |
|
|
|
446 |
|
|
#define PRINTCMUADDR(m, s) { TCHECK(cmu->m); \ |
447 |
|
|
if (cmu->m.s_addr != 0) \ |
448 |
|
|
printf(fmt, s, ipaddr_string(&cmu->m.s_addr)); } |
449 |
|
|
|
450 |
|
|
printf(" vend-cmu"); |
451 |
|
|
cmu = (struct cmu_vend *)bp; |
452 |
|
|
|
453 |
|
|
/* Only print if there are unknown bits */ |
454 |
|
|
TCHECK(cmu->v_flags); |
455 |
|
|
if ((cmu->v_flags & ~(VF_SMASK)) != 0) |
456 |
|
|
printf(" F:0x%x", cmu->v_flags); |
457 |
|
|
PRINTCMUADDR(v_dgate, "DG"); |
458 |
|
|
PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*"); |
459 |
|
|
PRINTCMUADDR(v_dns1, "NS1"); |
460 |
|
|
PRINTCMUADDR(v_dns2, "NS2"); |
461 |
|
|
PRINTCMUADDR(v_ins1, "IEN1"); |
462 |
|
|
PRINTCMUADDR(v_ins2, "IEN2"); |
463 |
|
|
PRINTCMUADDR(v_ts1, "TS1"); |
464 |
|
|
PRINTCMUADDR(v_ts2, "TS2"); |
465 |
|
|
return; |
466 |
|
|
|
467 |
|
|
trunc: |
468 |
|
|
fputs(tstr, stdout); |
469 |
|
|
#undef PRINTCMUADDR |
470 |
|
|
} |