source: rtems-libbsd/freebsd/contrib/tcpdump/print-dhcp6.c @ 8440506

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 8440506 was 8440506, checked in by Chris Johns <chrisj@…>, on 06/15/15 at 07:42:23

Add tcpdump and libpcap.

  • Update the file builder generator to handle generator specific cflags and includes. The tcpdump and libpcap have localised headers and need specific headers paths to see them. There are also module specific flags and these need to be passed to the lex and yacc generators.
  • Add the tcpdump support.
  • Property mode set to 100644
File size: 20.0 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright (C) 1998 and 1999 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31/*
32 * RFC3315: DHCPv6
33 * supported DHCPv6 options:
34 *  RFC3319: Session Initiation Protocol (SIP) Servers options,
35 *  RFC3633: IPv6 Prefix options,
36 *  RFC3646: DNS Configuration options,
37 *  RFC3898: Network Information Service (NIS) Configuration options,
38 *  RFC4075: Simple Network Time Protocol (SNTP) Configuration option,
39 *  RFC4242: Information Refresh Time option,
40 *  RFC4280: Broadcast and Multicast Control Servers options,
41 *  RFC6334: Dual-Stack Lite option,
42 */
43
44#ifndef lint
45static const char rcsid[] _U_ =
46    "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.37 2008-02-06 10:26:09 guy Exp $";
47#endif
48
49#ifdef HAVE_CONFIG_H
50#include "config.h"
51#endif
52
53#include <tcpdump-stdinc.h>
54
55#include <stdio.h>
56#include <string.h>
57
58#include "interface.h"
59#include "addrtoname.h"
60#include "extract.h"
61
62/* lease duration */
63#define DHCP6_DURATITION_INFINITE 0xffffffff
64
65/* Error Values */
66#define DH6ERR_FAILURE          16
67#define DH6ERR_AUTHFAIL         17
68#define DH6ERR_POORLYFORMED     18
69#define DH6ERR_UNAVAIL          19
70#define DH6ERR_OPTUNAVAIL       20
71
72/* Message type */
73#define DH6_SOLICIT     1
74#define DH6_ADVERTISE   2
75#define DH6_REQUEST     3
76#define DH6_CONFIRM     4
77#define DH6_RENEW       5
78#define DH6_REBIND      6
79#define DH6_REPLY       7
80#define DH6_RELEASE     8
81#define DH6_DECLINE     9
82#define DH6_RECONFIGURE 10
83#define DH6_INFORM_REQ  11
84#define DH6_RELAY_FORW  12
85#define DH6_RELAY_REPLY 13
86#define DH6_LEASEQUERY  14
87#define DH6_LQ_REPLY    15
88
89/* DHCP6 base packet format */
90struct dhcp6 {
91        union {
92                u_int8_t m;
93                u_int32_t x;
94        } dh6_msgtypexid;
95        /* options follow */
96};
97#define dh6_msgtype     dh6_msgtypexid.m
98#define dh6_xid         dh6_msgtypexid.x
99#define DH6_XIDMASK     0x00ffffff
100
101/* DHCPv6 relay messages */
102struct dhcp6_relay {
103        u_int8_t dh6relay_msgtype;
104        u_int8_t dh6relay_hcnt;
105        u_int8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */
106        u_int8_t dh6relay_peeraddr[16];
107        /* options follow */
108};
109
110/* options */
111#define DH6OPT_CLIENTID 1
112#define DH6OPT_SERVERID 2
113#define DH6OPT_IA_NA 3
114#define DH6OPT_IA_TA 4
115#define DH6OPT_IA_ADDR 5
116#define DH6OPT_ORO 6
117#define DH6OPT_PREFERENCE 7
118#  define DH6OPT_PREF_MAX 255
119#define DH6OPT_ELAPSED_TIME 8
120#define DH6OPT_RELAY_MSG 9
121/*#define DH6OPT_SERVER_MSG 10 deprecated */
122#define DH6OPT_AUTH 11
123#  define DH6OPT_AUTHPROTO_DELAYED 2
124#  define DH6OPT_AUTHPROTO_RECONFIG 3
125#  define DH6OPT_AUTHALG_HMACMD5 1
126#  define DH6OPT_AUTHRDM_MONOCOUNTER 0
127#  define DH6OPT_AUTHRECONFIG_KEY 1
128#  define DH6OPT_AUTHRECONFIG_HMACMD5 2
129#define DH6OPT_UNICAST 12
130#define DH6OPT_STATUS_CODE 13
131#  define DH6OPT_STCODE_SUCCESS 0
132#  define DH6OPT_STCODE_UNSPECFAIL 1
133#  define DH6OPT_STCODE_NOADDRAVAIL 2
134#  define DH6OPT_STCODE_NOBINDING 3
135#  define DH6OPT_STCODE_NOTONLINK 4
136#  define DH6OPT_STCODE_USEMULTICAST 5
137#  define DH6OPT_STCODE_NOPREFIXAVAIL 6
138#  define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7
139#  define DH6OPT_STCODE_MALFORMEDQUERY 8
140#  define DH6OPT_STCODE_NOTCONFIGURED 9
141#  define DH6OPT_STCODE_NOTALLOWED 10
142#define DH6OPT_RAPID_COMMIT 14
143#define DH6OPT_USER_CLASS 15
144#define DH6OPT_VENDOR_CLASS 16
145#define DH6OPT_VENDOR_OPTS 17
146#define DH6OPT_INTERFACE_ID 18
147#define DH6OPT_RECONF_MSG 19
148#define DH6OPT_RECONF_ACCEPT 20
149#define DH6OPT_SIP_SERVER_D 21
150#define DH6OPT_SIP_SERVER_A 22
151#define DH6OPT_DNS 23
152#define DH6OPT_DNSNAME 24
153#define DH6OPT_IA_PD 25
154#define DH6OPT_IA_PD_PREFIX 26
155#define DH6OPT_NIS_SERVERS 27
156#define DH6OPT_NISP_SERVERS 28
157#define DH6OPT_NIS_NAME 29
158#define DH6OPT_NISP_NAME 30
159#define DH6OPT_NTP_SERVERS 31
160#define DH6OPT_LIFETIME 32
161#define DH6OPT_BCMCS_SERVER_D 33
162#define DH6OPT_BCMCS_SERVER_A 34
163#define DH6OPT_GEOCONF_CIVIC 36
164#define DH6OPT_REMOTE_ID 37
165#define DH6OPT_SUBSCRIBER_ID 38
166#define DH6OPT_CLIENT_FQDN 39
167#define DH6OPT_PANA_AGENT 40
168#define DH6OPT_NEW_POSIX_TIMEZONE 41
169#define DH6OPT_NEW_TZDB_TIMEZONE 42
170#define DH6OPT_ERO 43
171#define DH6OPT_LQ_QUERY 44
172#define DH6OPT_CLIENT_DATA 45
173#define DH6OPT_CLT_TIME 46
174#define DH6OPT_LQ_RELAY_DATA 47
175#define DH6OPT_LQ_CLIENT_LINK 48
176#define DH6OPT_AFTR_NAME 64
177
178struct dhcp6opt {
179        u_int16_t dh6opt_type;
180        u_int16_t dh6opt_len;
181        /* type-dependent data follows */
182};
183
184static const char *
185dhcp6opt_name(int type)
186{
187        static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */
188
189        if (type > 65535)
190                return "INVALID-option";
191
192        switch(type) {
193        case DH6OPT_CLIENTID:
194                return "client-ID";
195        case DH6OPT_SERVERID:
196                return "server-ID";
197        case DH6OPT_IA_NA:
198                return "IA_NA";
199        case DH6OPT_IA_TA:
200                return "IA_TA";
201        case DH6OPT_IA_ADDR:
202                return "IA_ADDR";
203        case DH6OPT_ORO:
204                return "option-request";
205        case DH6OPT_PREFERENCE:
206                return "preference";
207        case DH6OPT_ELAPSED_TIME:
208                return "elapsed-time";
209        case DH6OPT_RELAY_MSG:
210                return "relay-message";
211        case DH6OPT_AUTH:
212                return "authentication";
213        case DH6OPT_UNICAST:
214                return "server-unicast";
215        case DH6OPT_STATUS_CODE:
216                return "status-code";
217        case DH6OPT_RAPID_COMMIT:
218                return "rapid-commit";
219        case DH6OPT_USER_CLASS:
220                return "user-class";
221        case DH6OPT_VENDOR_CLASS:
222                return "vendor-class";
223        case DH6OPT_VENDOR_OPTS:
224                return "vendor-specific-info";
225        case DH6OPT_INTERFACE_ID:
226                return "interface-ID";
227        case DH6OPT_RECONF_MSG:
228                return "reconfigure-message";
229        case DH6OPT_RECONF_ACCEPT:
230                return "reconfigure-accept";
231        case DH6OPT_SIP_SERVER_D:
232                return "SIP-servers-domain";
233        case DH6OPT_SIP_SERVER_A:
234                return "SIP-servers-address";
235        case DH6OPT_DNS:
236                return "DNS-server";
237        case DH6OPT_DNSNAME:
238                return "DNS-search-list";
239        case DH6OPT_IA_PD:
240                return "IA_PD";
241        case DH6OPT_IA_PD_PREFIX:
242                return "IA_PD-prefix";
243        case DH6OPT_NTP_SERVERS:
244                return "NTP-server";
245        case DH6OPT_LIFETIME:
246                return "lifetime";
247        case DH6OPT_NIS_SERVERS:
248                return "NIS-server";
249        case DH6OPT_NISP_SERVERS:
250                return "NIS+-server";
251        case DH6OPT_NIS_NAME:
252                return "NIS-domain-name";
253        case DH6OPT_NISP_NAME:
254                return "NIS+-domain-name";
255        case DH6OPT_BCMCS_SERVER_D:
256                return "BCMCS-domain-name";
257        case DH6OPT_BCMCS_SERVER_A:
258                return "BCMCS-server";
259        case DH6OPT_GEOCONF_CIVIC:
260                return "Geoconf-Civic";
261        case DH6OPT_REMOTE_ID:
262                return "Remote-ID";
263        case DH6OPT_SUBSCRIBER_ID:
264                return "Subscriber-ID";
265        case DH6OPT_CLIENT_FQDN:
266                return "Client-FQDN";
267        case DH6OPT_PANA_AGENT:
268                return "PANA-agent";
269        case DH6OPT_NEW_POSIX_TIMEZONE:
270                return "POSIX-timezone";
271        case DH6OPT_NEW_TZDB_TIMEZONE:
272                return "POSIX-tz-database";
273        case DH6OPT_ERO:
274                return "Echo-request-option";
275        case DH6OPT_LQ_QUERY:
276                return "Lease-query";
277        case DH6OPT_CLIENT_DATA:
278                return "LQ-client-data";
279        case DH6OPT_CLT_TIME:
280                return "Clt-time";
281        case DH6OPT_LQ_RELAY_DATA:
282                return "LQ-relay-data";
283        case DH6OPT_LQ_CLIENT_LINK:
284                return "LQ-client-link";
285        case DH6OPT_AFTR_NAME:
286                return "AFTR-Name";
287        default:
288                snprintf(genstr, sizeof(genstr), "opt_%d", type);
289                return(genstr);
290        }
291}
292
293static const char *
294dhcp6stcode(int code)
295{
296        static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */
297
298        if (code > 255)
299                return "INVALID code";
300
301        switch(code) {
302        case DH6OPT_STCODE_SUCCESS:
303                return "success";
304        case DH6OPT_STCODE_UNSPECFAIL:
305                return "unspec failure";
306        case DH6OPT_STCODE_NOADDRAVAIL:
307                return "no addresses";
308        case DH6OPT_STCODE_NOBINDING:
309                return "no binding";
310        case DH6OPT_STCODE_NOTONLINK:
311                return "not on-link";
312        case DH6OPT_STCODE_USEMULTICAST:
313                return "use multicast";
314        case DH6OPT_STCODE_NOPREFIXAVAIL:
315                return "no prefixes";
316        case DH6OPT_STCODE_UNKNOWNQUERYTYPE:
317                return "unknown query type";
318        case DH6OPT_STCODE_MALFORMEDQUERY:
319                return "malformed query";
320        case DH6OPT_STCODE_NOTCONFIGURED:
321                return "not configured";
322        case DH6OPT_STCODE_NOTALLOWED:
323                return "not allowed";
324        default:
325                snprintf(genstr, sizeof(genstr), "code%d", code);
326                return(genstr);
327        }
328}
329
330static void
331dhcp6opt_print(const u_char *cp, const u_char *ep)
332{
333        struct dhcp6opt *dh6o;
334        u_char *tp;
335        size_t i;
336        u_int16_t opttype;
337        size_t optlen;
338        u_int8_t auth_proto;
339        u_int authinfolen, authrealmlen;
340
341        if (cp == ep)
342                return;
343        while (cp < ep) {
344                if (ep < cp + sizeof(*dh6o))
345                        goto trunc;
346                dh6o = (struct dhcp6opt *)cp;
347                TCHECK(*dh6o);
348                optlen = EXTRACT_16BITS(&dh6o->dh6opt_len);
349                if (ep < cp + sizeof(*dh6o) + optlen)
350                        goto trunc;
351                opttype = EXTRACT_16BITS(&dh6o->dh6opt_type);
352                printf(" (%s", dhcp6opt_name(opttype));
353                switch (opttype) {
354                case DH6OPT_CLIENTID:
355                case DH6OPT_SERVERID:
356                        if (optlen < 2) {
357                                /*(*/
358                                printf(" ?)");
359                                break;
360                        }
361                        tp = (u_char *)(dh6o + 1);
362                        switch (EXTRACT_16BITS(tp)) {
363                        case 1:
364                                if (optlen >= 2 + 6) {
365                                        printf(" hwaddr/time type %u time %u ",
366                                            EXTRACT_16BITS(&tp[2]),
367                                            EXTRACT_32BITS(&tp[4]));
368                                        for (i = 8; i < optlen; i++)
369                                                printf("%02x", tp[i]);
370                                        /*(*/
371                                        printf(")");
372                                } else {
373                                        /*(*/
374                                        printf(" ?)");
375                                }
376                                break;
377                        case 2:
378                                if (optlen >= 2 + 8) {
379                                        printf(" vid ");
380                                        for (i = 2; i < 2 + 8; i++)
381                                                printf("%02x", tp[i]);
382                                        /*(*/
383                                        printf(")");
384                                } else {
385                                        /*(*/
386                                        printf(" ?)");
387                                }
388                                break;
389                        case 3:
390                                if (optlen >= 2 + 2) {
391                                        printf(" hwaddr type %u ",
392                                            EXTRACT_16BITS(&tp[2]));
393                                        for (i = 4; i < optlen; i++)
394                                                printf("%02x", tp[i]);
395                                        /*(*/
396                                        printf(")");
397                                } else {
398                                        /*(*/
399                                        printf(" ?)");
400                                }
401                                break;
402                        default:
403                                printf(" type %d)", EXTRACT_16BITS(tp));
404                                break;
405                        }
406                        break;
407                case DH6OPT_IA_ADDR:
408                        if (optlen < 24) {
409                                /*(*/
410                                printf(" ?)");
411                                break;
412                        }
413                        tp = (u_char *)(dh6o + 1);
414                        printf(" %s", ip6addr_string(&tp[0]));
415                        printf(" pltime:%u vltime:%u",
416                            EXTRACT_32BITS(&tp[16]),
417                            EXTRACT_32BITS(&tp[20]));
418                        if (optlen > 24) {
419                                /* there are sub-options */
420                                dhcp6opt_print(tp + 24, tp + optlen);
421                        }
422                        printf(")");
423                        break;
424                case DH6OPT_ORO:
425                case DH6OPT_ERO:
426                        if (optlen % 2) {
427                                printf(" ?)");
428                                break;
429                        }
430                        tp = (u_char *)(dh6o + 1);
431                        for (i = 0; i < optlen; i += 2) {
432                                printf(" %s",
433                                    dhcp6opt_name(EXTRACT_16BITS(&tp[i])));
434                        }
435                        printf(")");
436                        break;
437                case DH6OPT_PREFERENCE:
438                        if (optlen != 1) {
439                                printf(" ?)");
440                                break;
441                        }
442                        tp = (u_char *)(dh6o + 1);
443                        printf(" %d)", *tp);
444                        break;
445                case DH6OPT_ELAPSED_TIME:
446                        if (optlen != 2) {
447                                printf(" ?)");
448                                break;
449                        }
450                        tp = (u_char *)(dh6o + 1);
451                        printf(" %d)", EXTRACT_16BITS(tp));
452                        break;
453                case DH6OPT_RELAY_MSG:
454                        printf(" (");
455                        tp = (u_char *)(dh6o + 1);
456                        dhcp6_print(tp, optlen);
457                        printf(")");
458                        break;
459                case DH6OPT_AUTH:
460                        if (optlen < 11) {
461                                printf(" ?)");
462                                break;
463                        }
464                        tp = (u_char *)(dh6o + 1);
465                        auth_proto = *tp;
466                        switch (auth_proto) {
467                        case DH6OPT_AUTHPROTO_DELAYED:
468                                printf(" proto: delayed");
469                                break;
470                        case DH6OPT_AUTHPROTO_RECONFIG:
471                                printf(" proto: reconfigure");
472                                break;
473                        default:
474                                printf(" proto: %d", auth_proto);
475                                break;
476                        }
477                        tp++;
478                        switch (*tp) {
479                        case DH6OPT_AUTHALG_HMACMD5:
480                                /* XXX: may depend on the protocol */
481                                printf(", alg: HMAC-MD5");
482                                break;
483                        default:
484                                printf(", alg: %d", *tp);
485                                break;
486                        }
487                        tp++;
488                        switch (*tp) {
489                        case DH6OPT_AUTHRDM_MONOCOUNTER:
490                                printf(", RDM: mono");
491                                break;
492                        default:
493                                printf(", RDM: %d", *tp);
494                                break;
495                        }
496                        tp++;
497                        printf(", RD:");
498                        for (i = 0; i < 4; i++, tp += 2)
499                                printf(" %04x", EXTRACT_16BITS(tp));
500
501                        /* protocol dependent part */
502                        authinfolen = optlen - 11;
503                        switch (auth_proto) {
504                        case DH6OPT_AUTHPROTO_DELAYED:
505                                if (authinfolen == 0)
506                                        break;
507                                if (authinfolen < 20) {
508                                        printf(" ??");
509                                        break;
510                                }
511                                authrealmlen = authinfolen - 20;
512                                if (authrealmlen > 0) {
513                                        printf(", realm: ");
514                                }
515                                for (i = 0; i < authrealmlen; i++, tp++)
516                                        printf("%02x", *tp);
517                                printf(", key ID: %08x", EXTRACT_32BITS(tp));
518                                tp += 4;
519                                printf(", HMAC-MD5:");
520                                for (i = 0; i < 4; i++, tp+= 4)
521                                        printf(" %08x", EXTRACT_32BITS(tp));
522                                break;
523                        case DH6OPT_AUTHPROTO_RECONFIG:
524                                if (authinfolen != 17) {
525                                        printf(" ??");
526                                        break;
527                                }
528                                switch (*tp++) {
529                                case DH6OPT_AUTHRECONFIG_KEY:
530                                        printf(" reconfig-key");
531                                        break;
532                                case DH6OPT_AUTHRECONFIG_HMACMD5:
533                                        printf(" type: HMAC-MD5");
534                                        break;
535                                default:
536                                        printf(" type: ??");
537                                        break;
538                                }
539                                printf(" value:");
540                                for (i = 0; i < 4; i++, tp+= 4)
541                                        printf(" %08x", EXTRACT_32BITS(tp));
542                                break;
543                        default:
544                                printf(" ??");
545                                break;
546                        }
547
548                        printf(")");
549                        break;
550                case DH6OPT_RAPID_COMMIT: /* nothing todo */
551                        printf(")");
552                        break;
553                case DH6OPT_INTERFACE_ID:
554                case DH6OPT_SUBSCRIBER_ID:
555                        /*
556                         * Since we cannot predict the encoding, print hex dump
557                         * at most 10 characters.
558                         */
559                        tp = (u_char *)(dh6o + 1);
560                        printf(" ");
561                        for (i = 0; i < optlen && i < 10; i++)
562                                printf("%02x", tp[i]);
563                        printf("...)");
564                        break;
565                case DH6OPT_RECONF_MSG:
566                        tp = (u_char *)(dh6o + 1);
567                        switch (*tp) {
568                        case DH6_RENEW:
569                                printf(" for renew)");
570                                break;
571                        case DH6_INFORM_REQ:
572                                printf(" for inf-req)");
573                                break;
574                        default:
575                                printf(" for ?\?\?(%02x))", *tp);
576                                break;
577                        }
578                        break;
579                case DH6OPT_RECONF_ACCEPT: /* nothing todo */
580                        printf(")");
581                        break;
582                case DH6OPT_SIP_SERVER_A:
583                case DH6OPT_DNS:
584                case DH6OPT_NTP_SERVERS:
585                case DH6OPT_NIS_SERVERS:
586                case DH6OPT_NISP_SERVERS:
587                case DH6OPT_BCMCS_SERVER_A:
588                case DH6OPT_PANA_AGENT:
589                case DH6OPT_LQ_CLIENT_LINK:
590                        if (optlen % 16) {
591                                printf(" ?)");
592                                break;
593                        }
594                        tp = (u_char *)(dh6o + 1);
595                        for (i = 0; i < optlen; i += 16)
596                                printf(" %s", ip6addr_string(&tp[i]));
597                        printf(")");
598                        break;
599                case DH6OPT_STATUS_CODE:
600                        if (optlen < 2) {
601                                printf(" ?)");
602                                break;
603                        }
604                        tp = (u_char *)(dh6o + 1);
605                        printf(" %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0])));
606                        break;
607                case DH6OPT_IA_NA:
608                case DH6OPT_IA_PD:
609                        if (optlen < 12) {
610                                printf(" ?)");
611                                break;
612                        }
613                        tp = (u_char *)(dh6o + 1);
614                        printf(" IAID:%u T1:%u T2:%u",
615                            EXTRACT_32BITS(&tp[0]),
616                            EXTRACT_32BITS(&tp[4]),
617                            EXTRACT_32BITS(&tp[8]));
618                        if (optlen > 12) {
619                                /* there are sub-options */
620                                dhcp6opt_print(tp + 12, tp + optlen);
621                        }
622                        printf(")");
623                        break;
624                case DH6OPT_IA_TA:
625                        if (optlen < 4) {
626                                printf(" ?)");
627                                break;
628                        }
629                        tp = (u_char *)(dh6o + 1);
630                        printf(" IAID:%u", EXTRACT_32BITS(tp));
631                        if (optlen > 4) {
632                                /* there are sub-options */
633                                dhcp6opt_print(tp + 4, tp + optlen);
634                        }
635                        printf(")");
636                        break;
637                case DH6OPT_IA_PD_PREFIX:
638                        if (optlen < 25) {
639                                printf(" ?)");
640                                break;
641                        }
642                        tp = (u_char *)(dh6o + 1);
643                        printf(" %s/%d", ip6addr_string(&tp[9]), tp[8]);
644                        printf(" pltime:%u vltime:%u",
645                            EXTRACT_32BITS(&tp[0]),
646                            EXTRACT_32BITS(&tp[4]));
647                        if (optlen > 25) {
648                                /* there are sub-options */
649                                dhcp6opt_print(tp + 25, tp + optlen);
650                        }
651                        printf(")");
652                        break;
653                case DH6OPT_LIFETIME:
654                case DH6OPT_CLT_TIME:
655                        if (optlen != 4) {
656                                printf(" ?)");
657                                break;
658                        }
659                        tp = (u_char *)(dh6o + 1);
660                        printf(" %d)", EXTRACT_32BITS(tp));
661                        break;
662                case DH6OPT_REMOTE_ID:
663                        if (optlen < 4) {
664                                printf(" ?)");
665                                break;
666                        }
667                        tp = (u_char *)(dh6o + 1);
668                        printf(" %d ", EXTRACT_32BITS(tp));
669                        /*
670                         * Print hex dump first 10 characters.
671                         */
672                        for (i = 4; i < optlen && i < 14; i++)
673                                printf("%02x", tp[i]);
674                        printf("...)");
675                        break;
676                case DH6OPT_LQ_QUERY:
677                        if (optlen < 17) {
678                                printf(" ?)");
679                                break;
680                        }
681                        tp = (u_char *)(dh6o + 1);
682                        switch (*tp) {
683                        case 1:
684                                printf(" by-address");
685                                break;
686                        case 2:
687                                printf(" by-clientID");
688                                break;
689                        default:
690                                printf(" type_%d", (int)*tp);
691                                break;
692                        }
693                        printf(" %s", ip6addr_string(&tp[1]));
694                        if (optlen > 17) {
695                                /* there are query-options */
696                                dhcp6opt_print(tp + 17, tp + optlen);
697                        }
698                        printf(")");
699                        break;
700                case DH6OPT_CLIENT_DATA:
701                        tp = (u_char *)(dh6o + 1);
702                        if (optlen > 0) {
703                                /* there are encapsulated options */
704                                dhcp6opt_print(tp, tp + optlen);
705                        }
706                        printf(")");
707                        break;
708                case DH6OPT_LQ_RELAY_DATA:
709                        if (optlen < 16) {
710                                printf(" ?)");
711                                break;
712                        }
713                        tp = (u_char *)(dh6o + 1);
714                        printf(" %s ", ip6addr_string(&tp[0]));
715                        /*
716                         * Print hex dump first 10 characters.
717                         */
718                        for (i = 16; i < optlen && i < 26; i++)
719                                printf("%02x", tp[i]);
720                        printf("...)");
721                        break;
722                case DH6OPT_AFTR_NAME:
723                        if (optlen < 3) {
724                                printf(" ?)");
725                                break;
726                        }
727                        tp = (u_char *)(dh6o + 1);
728                        int remain_len = optlen;
729                        printf(" ");
730                        /* Encoding is described in section 3.1 of RFC 1035 */
731                        int label_len; /* Label length */
732                        while (remain_len && *tp) {
733                                label_len =  *tp++;
734                                if (label_len < remain_len - 1) {
735                                        printf("%.*s", label_len, tp);
736                                        tp += label_len;
737                                        remain_len -= (label_len + 1);
738                                        if(*tp) printf(".");
739                                } else {
740                                        printf(" ?");
741                                        break;
742                                }
743                        }
744                        printf(")");
745                        break;
746                default:
747                        printf(")");
748                        break;
749                }
750
751                cp += sizeof(*dh6o) + optlen;
752        }
753        return;
754
755trunc:
756        printf("[|dhcp6ext]");
757}
758
759/*
760 * Print dhcp6 packets
761 */
762void
763dhcp6_print(const u_char *cp, u_int length)
764{
765        struct dhcp6 *dh6;
766        struct dhcp6_relay *dh6relay;
767        const u_char *ep;
768        u_char *extp;
769        const char *name;
770
771        printf("dhcp6");
772
773        ep = (u_char *)snapend;
774        if (cp + length < ep)
775                ep = cp + length;
776
777        dh6 = (struct dhcp6 *)cp;
778        dh6relay = (struct dhcp6_relay *)cp;
779        TCHECK(dh6->dh6_xid);
780        switch (dh6->dh6_msgtype) {
781        case DH6_SOLICIT:
782                name = "solicit";
783                break;
784        case DH6_ADVERTISE:
785                name = "advertise";
786                break;
787        case DH6_REQUEST:
788                name = "request";
789                break;
790        case DH6_CONFIRM:
791                name = "confirm";
792                break;
793        case DH6_RENEW:
794                name = "renew";
795                break;
796        case DH6_REBIND:
797                name = "rebind";
798                break;
799        case DH6_REPLY:
800                name = "reply";
801                break;
802        case DH6_RELEASE:
803                name = "release";
804                break;
805        case DH6_DECLINE:
806                name = "decline";
807                break;
808        case DH6_RECONFIGURE:
809                name = "reconfigure";
810                break;
811        case DH6_INFORM_REQ:
812                name= "inf-req";
813                break;
814        case DH6_RELAY_FORW:
815                name= "relay-fwd";
816                break;
817        case DH6_RELAY_REPLY:
818                name= "relay-reply";
819                break;
820        case DH6_LEASEQUERY:
821                name= "leasequery";
822                break;
823        case DH6_LQ_REPLY:
824                name= "leasequery-reply";
825                break;
826        default:
827                name = NULL;
828                break;
829        }
830
831        if (!vflag) {
832                if (name)
833                        printf(" %s", name);
834                else if (dh6->dh6_msgtype != DH6_RELAY_FORW &&
835                    dh6->dh6_msgtype != DH6_RELAY_REPLY) {
836                        printf(" msgtype-%u", dh6->dh6_msgtype);
837                }
838                return;
839        }
840
841        /* XXX relay agent messages have to be handled differently */
842
843        if (name)
844                printf(" %s (", name);  /*)*/
845        else
846                printf(" msgtype-%u (", dh6->dh6_msgtype);      /*)*/
847        if (dh6->dh6_msgtype != DH6_RELAY_FORW &&
848            dh6->dh6_msgtype != DH6_RELAY_REPLY) {
849                printf("xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK);
850                extp = (u_char *)(dh6 + 1);
851                dhcp6opt_print(extp, ep);
852        } else {                /* relay messages */
853                struct in6_addr addr6;
854
855                TCHECK(dh6relay->dh6relay_peeraddr);
856
857                memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6));
858                printf("linkaddr=%s", ip6addr_string(&addr6));
859
860                memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6));
861                printf(" peeraddr=%s", ip6addr_string(&addr6));
862
863                dhcp6opt_print((u_char *)(dh6relay + 1), ep);
864        }
865        /*(*/
866        printf(")");
867        return;
868
869trunc:
870        printf("[|dhcp6]");
871}
Note: See TracBrowser for help on using the repository browser.