source: rtems-libbsd/freebsd/contrib/tcpdump/print-olsr.c @ 084d4db

4.11
Last change on this file since 084d4db 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: 19.2 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright (c) 1998-2007 The TCPDUMP project
5 * Copyright (c) 2009  Florian Forster
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code
9 * distributions retain the above copyright notice and this paragraph
10 * in its entirety, and (2) distributions including binary code include
11 * the above copyright notice and this paragraph in its entirety in
12 * the documentation or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
14 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
15 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
16 * FOR A PARTICULAR PURPOSE.
17 *
18 * Optimized Link State Protocl (OLSR) as per rfc3626
19 *
20 * Original code by Hannes Gredler <hannes@juniper.net>
21 * IPv6 additions by Florian Forster <octo at verplant.org>
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#include <string.h>
32
33#include "interface.h"
34#include "addrtoname.h"
35#include "extract.h"
36#include "ip.h"
37
38/*
39 * RFC 3626 common header
40 *
41 *  0                   1                   2                   3
42 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * |         Packet Length         |    Packet Sequence Number     |
45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 * |  Message Type |     Vtime     |         Message Size          |
47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * |                      Originator Address                       |
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 * |  Time To Live |   Hop Count   |    Message Sequence Number    |
51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 * |                                                               |
53 * :                            MESSAGE                            :
54 * |                                                               |
55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 * |  Message Type |     Vtime     |         Message Size          |
57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 * |                      Originator Address                       |
59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 * |  Time To Live |   Hop Count   |    Message Sequence Number    |
61 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62 * |                                                               |
63 * :                            MESSAGE                            :
64 * |                                                               |
65 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 * :                                                               :
67 */
68
69struct olsr_common {
70    u_int8_t packet_len[2];
71    u_int8_t packet_seq[2];
72};
73
74#define OLSR_HELLO_MSG         1 /* rfc3626 */
75#define OLSR_TC_MSG            2 /* rfc3626 */
76#define OLSR_MID_MSG           3 /* rfc3626 */
77#define OLSR_HNA_MSG           4 /* rfc3626 */
78#define OLSR_POWERINFO_MSG   128
79#define OLSR_NAMESERVICE_MSG 130
80#define OLSR_HELLO_LQ_MSG    201 /* LQ extensions olsr.org */
81#define OLSR_TC_LQ_MSG       202 /* LQ extensions olsr.org */
82
83static struct tok olsr_msg_values[] = {
84    { OLSR_HELLO_MSG, "Hello" },
85    { OLSR_TC_MSG, "TC" },
86    { OLSR_MID_MSG, "MID" },
87    { OLSR_HNA_MSG, "HNA" },
88    { OLSR_POWERINFO_MSG, "Powerinfo" },
89    { OLSR_NAMESERVICE_MSG, "Nameservice" },
90    { OLSR_HELLO_LQ_MSG, "Hello-LQ" },
91    { OLSR_TC_LQ_MSG, "TC-LQ" },
92    { 0, NULL}
93};
94
95struct olsr_msg4 {
96    u_int8_t msg_type;
97    u_int8_t vtime;
98    u_int8_t msg_len[2];
99    u_int8_t originator[4];
100    u_int8_t ttl;
101    u_int8_t hopcount;
102    u_int8_t msg_seq[2];
103};
104
105struct olsr_msg6 {
106    u_int8_t msg_type;
107    u_int8_t vtime;
108    u_int8_t msg_len[2];
109    u_int8_t originator[16];
110    u_int8_t ttl;
111    u_int8_t hopcount;
112    u_int8_t msg_seq[2];
113};
114
115struct olsr_hello {
116    u_int8_t res[2];
117    u_int8_t htime;
118    u_int8_t will;
119};
120
121struct olsr_hello_link {
122    u_int8_t link_code;
123    u_int8_t res;
124    u_int8_t len[2];
125};
126
127struct olsr_tc {
128    u_int8_t ans_seq[2];
129    u_int8_t res[2];
130};
131
132struct olsr_hna4 {
133    u_int8_t network[4];
134    u_int8_t mask[4];
135};
136
137struct olsr_hna6 {
138    u_int8_t network[16];
139    u_int8_t mask[16];
140};
141
142
143#define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3)
144#define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2)
145
146static struct tok olsr_link_type_values[] = {
147    { 0, "Unspecified" },
148    { 1, "Asymmetric" },
149    { 2, "Symmetric" },
150    { 3, "Lost" },
151    { 0, NULL}
152};
153
154static struct tok olsr_neighbor_type_values[] = {
155    { 0, "Not-Neighbor" },
156    { 1, "Symmetric" },
157    { 2, "Symmetric-MPR" },
158    { 0, NULL}
159};
160
161struct olsr_lq_neighbor4 {
162    u_int8_t neighbor[4];
163    u_int8_t link_quality;
164    u_int8_t neighbor_link_quality;
165    u_int8_t res[2];
166};
167
168struct olsr_lq_neighbor6 {
169    u_int8_t neighbor[16];
170    u_int8_t link_quality;
171    u_int8_t neighbor_link_quality;
172    u_int8_t res[2];
173};
174
175/*
176 * macro to convert the 8-bit mantissa/exponent to a double float
177 * taken from olsr.org.
178 */
179#define VTIME_SCALE_FACTOR    0.0625
180#define ME_TO_DOUBLE(me) \
181  (double)(VTIME_SCALE_FACTOR*(1+(double)(me>>4)/16)*(double)(1<<(me&0x0F)))
182
183/*
184 * print a neighbor list with LQ extensions.
185 */
186static void
187olsr_print_lq_neighbor4 (const u_char *msg_data, u_int hello_len)
188{
189    struct olsr_lq_neighbor4 *lq_neighbor;
190
191    while (hello_len >= sizeof(struct olsr_lq_neighbor4)) {
192
193        lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data;
194
195        printf("\n\t      neighbor %s, link-quality %.2lf%%"
196               ", neighbor-link-quality %.2lf%%",
197               ipaddr_string(lq_neighbor->neighbor),
198               ((double)lq_neighbor->link_quality/2.55),
199               ((double)lq_neighbor->neighbor_link_quality/2.55));
200
201        msg_data += sizeof(struct olsr_lq_neighbor4);
202        hello_len -= sizeof(struct olsr_lq_neighbor4);
203    }
204}
205
206#if INET6
207static void
208olsr_print_lq_neighbor6 (const u_char *msg_data, u_int hello_len)
209{
210    struct olsr_lq_neighbor6 *lq_neighbor;
211
212    while (hello_len >= sizeof(struct olsr_lq_neighbor6)) {
213
214        lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data;
215
216        printf("\n\t      neighbor %s, link-quality %.2lf%%"
217               ", neighbor-link-quality %.2lf%%",
218               ip6addr_string(lq_neighbor->neighbor),
219               ((double)lq_neighbor->link_quality/2.55),
220               ((double)lq_neighbor->neighbor_link_quality/2.55));
221
222        msg_data += sizeof(struct olsr_lq_neighbor6);
223        hello_len -= sizeof(struct olsr_lq_neighbor6);
224    }
225}
226#endif /* INET6 */
227
228/*
229 * print a neighbor list.
230 */
231static void
232olsr_print_neighbor (const u_char *msg_data, u_int hello_len)
233{
234    int neighbor;
235
236    printf("\n\t      neighbor\n\t\t");
237    neighbor = 1;
238
239    while (hello_len >= sizeof(struct in_addr)) {
240
241        /* print 4 neighbors per line */
242
243        printf("%s%s", ipaddr_string(msg_data),
244               neighbor % 4 == 0 ? "\n\t\t" : " ");
245
246        msg_data += sizeof(struct in_addr);
247        hello_len -= sizeof(struct in_addr);
248    }
249}
250
251
252void
253olsr_print (const u_char *pptr, u_int length, int is_ipv6)
254{
255    union {
256        const struct olsr_common *common;
257        const struct olsr_msg4 *msg4;
258        const struct olsr_msg6 *msg6;
259        const struct olsr_hello *hello;
260        const struct olsr_hello_link *hello_link;
261        const struct olsr_tc *tc;
262        const struct olsr_hna4 *hna;
263    } ptr;
264
265    u_int msg_type, msg_len, msg_tlen, hello_len;
266    u_int16_t name_entry_type, name_entry_len;
267    u_int name_entry_padding;
268    u_int8_t link_type, neighbor_type;
269    const u_char *tptr, *msg_data;
270
271    tptr = pptr;
272
273    if (length < sizeof(struct olsr_common)) {
274        goto trunc;
275    }
276
277    if (!TTEST2(*tptr, sizeof(struct olsr_common))) {
278        goto trunc;
279    }
280
281    ptr.common = (struct olsr_common *)tptr;
282    length = MIN(length, EXTRACT_16BITS(ptr.common->packet_len));
283
284    printf("OLSRv%i, seq 0x%04x, length %u",
285            (is_ipv6 == 0) ? 4 : 6,
286            EXTRACT_16BITS(ptr.common->packet_seq),
287            length);
288
289    tptr += sizeof(struct olsr_common);
290
291    /*
292     * In non-verbose mode, just print version.
293     */
294    if (vflag < 1) {
295        return;
296    }
297
298    while (tptr < (pptr+length)) {
299        union
300        {
301            struct olsr_msg4 *v4;
302            struct olsr_msg6 *v6;
303        } msgptr;
304        int msg_len_valid = 0;
305
306        if (!TTEST2(*tptr, sizeof(struct olsr_msg4)))
307            goto trunc;
308
309#if INET6
310        if (is_ipv6)
311        {
312            msgptr.v6 = (struct olsr_msg6 *) tptr;
313            msg_type = msgptr.v6->msg_type;
314            msg_len = EXTRACT_16BITS(msgptr.v6->msg_len);
315            if ((msg_len >= sizeof (struct olsr_msg6))
316                    && (msg_len <= length))
317                msg_len_valid = 1;
318
319            /* infinite loop check */
320            if (msg_type == 0 || msg_len == 0) {
321                return;
322            }
323
324            printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u"
325                    "\n\t  vtime %.3lfs, msg-seq 0x%04x, length %u%s",
326                    tok2str(olsr_msg_values, "Unknown", msg_type),
327                    msg_type, ip6addr_string(msgptr.v6->originator),
328                    msgptr.v6->ttl,
329                    msgptr.v6->hopcount,
330                    ME_TO_DOUBLE(msgptr.v6->vtime),
331                    EXTRACT_16BITS(msgptr.v6->msg_seq),
332                    msg_len, (msg_len_valid == 0) ? " (invalid)" : "");
333
334            msg_tlen = msg_len - sizeof(struct olsr_msg6);
335            msg_data = tptr + sizeof(struct olsr_msg6);
336        }
337        else /* (!is_ipv6) */
338#endif /* INET6 */
339        {
340            msgptr.v4 = (struct olsr_msg4 *) tptr;
341            msg_type = msgptr.v4->msg_type;
342            msg_len = EXTRACT_16BITS(msgptr.v4->msg_len);
343            if ((msg_len >= sizeof (struct olsr_msg4))
344                    && (msg_len <= length))
345                msg_len_valid = 1;
346
347            /* infinite loop check */
348            if (msg_type == 0 || msg_len == 0) {
349                return;
350            }
351
352            printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u"
353                    "\n\t  vtime %.3lfs, msg-seq 0x%04x, length %u%s",
354                    tok2str(olsr_msg_values, "Unknown", msg_type),
355                    msg_type, ipaddr_string(msgptr.v4->originator),
356                    msgptr.v4->ttl,
357                    msgptr.v4->hopcount,
358                    ME_TO_DOUBLE(msgptr.v4->vtime),
359                    EXTRACT_16BITS(msgptr.v4->msg_seq),
360                    msg_len, (msg_len_valid == 0) ? " (invalid)" : "");
361
362            msg_tlen = msg_len - sizeof(struct olsr_msg4);
363            msg_data = tptr + sizeof(struct olsr_msg4);
364        }
365
366        switch (msg_type) {
367        case OLSR_HELLO_MSG:
368        case OLSR_HELLO_LQ_MSG:
369            if (!TTEST2(*msg_data, sizeof(struct olsr_hello)))
370                goto trunc;
371
372            ptr.hello = (struct olsr_hello *)msg_data;
373            printf("\n\t  hello-time %.3lfs, MPR willingness %u",
374                   ME_TO_DOUBLE(ptr.hello->htime), ptr.hello->will);
375            msg_data += sizeof(struct olsr_hello);
376            msg_tlen -= sizeof(struct olsr_hello);
377
378            while (msg_tlen >= sizeof(struct olsr_hello_link)) {
379                int hello_len_valid = 0;
380
381                /*
382                 * link-type.
383                 */
384                if (!TTEST2(*msg_data, sizeof(struct olsr_hello_link)))
385                    goto trunc;
386
387                ptr.hello_link = (struct olsr_hello_link *)msg_data;
388
389                hello_len = EXTRACT_16BITS(ptr.hello_link->len);
390                link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code);
391                neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code);
392
393                if ((hello_len <= msg_tlen)
394                        && (hello_len >= sizeof(struct olsr_hello_link)))
395                    hello_len_valid = 1;
396
397                printf("\n\t    link-type %s, neighbor-type %s, len %u%s",
398                       tok2str(olsr_link_type_values, "Unknown", link_type),
399                       tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type),
400                       hello_len,
401                       (hello_len_valid == 0) ? " (invalid)" : "");
402
403                if (hello_len_valid == 0)
404                    break;
405
406                msg_data += sizeof(struct olsr_hello_link);
407                msg_tlen -= sizeof(struct olsr_hello_link);
408                hello_len -= sizeof(struct olsr_hello_link);
409
410                if (msg_type == OLSR_HELLO_MSG) {
411                    olsr_print_neighbor(msg_data, hello_len);
412                } else {
413#if INET6
414                    if (is_ipv6)
415                        olsr_print_lq_neighbor6(msg_data, hello_len);
416                    else
417#endif
418                        olsr_print_lq_neighbor4(msg_data, hello_len);
419                }
420
421                msg_data += hello_len;
422                msg_tlen -= hello_len;
423            }
424            break;
425
426        case OLSR_TC_MSG:
427        case OLSR_TC_LQ_MSG:
428            if (!TTEST2(*msg_data, sizeof(struct olsr_tc)))
429                goto trunc;
430
431            ptr.tc = (struct olsr_tc *)msg_data;
432            printf("\n\t    advertised neighbor seq 0x%04x",
433                   EXTRACT_16BITS(ptr.tc->ans_seq));
434            msg_data += sizeof(struct olsr_tc);
435            msg_tlen -= sizeof(struct olsr_tc);
436
437            if (msg_type == OLSR_TC_MSG) {
438                olsr_print_neighbor(msg_data, msg_tlen);
439            } else {
440#if INET6
441                if (is_ipv6)
442                    olsr_print_lq_neighbor6(msg_data, msg_tlen);
443                else
444#endif
445                    olsr_print_lq_neighbor4(msg_data, msg_tlen);
446            }
447            break;
448
449        case OLSR_MID_MSG:
450        {
451            size_t addr_size = sizeof(struct in_addr);
452
453#if INET6
454            if (is_ipv6)
455                addr_size = sizeof(struct in6_addr);
456#endif
457
458            while (msg_tlen >= addr_size) {
459                if (!TTEST2(*msg_data, addr_size))
460                    goto trunc;
461
462                printf("\n\t  interface address %s",
463#if INET6
464                        is_ipv6 ? ip6addr_string(msg_data) :
465#endif
466                        ipaddr_string(msg_data));
467                msg_data += addr_size;
468                msg_tlen -= addr_size;
469            }
470            break;
471        }
472
473        case OLSR_HNA_MSG:
474            printf("\n\t  Advertised networks (total %u)",
475                    (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)));
476#if INET6
477            if (is_ipv6)
478            {
479                int i = 0;
480                while (msg_tlen >= sizeof(struct olsr_hna6)) {
481                    struct olsr_hna6 *hna6;
482
483                    if (!TTEST2(*msg_data, sizeof(struct olsr_hna6)))
484                        goto trunc;
485
486                    hna6 = (struct olsr_hna6 *)msg_data;
487
488                    printf("\n\t    #%i: %s/%u",
489                            i, ip6addr_string(hna6->network),
490                            mask62plen (hna6->mask));
491
492                    msg_data += sizeof(struct olsr_hna6);
493                    msg_tlen -= sizeof(struct olsr_hna6);
494                }
495            }
496            else
497#endif
498            {
499                int col = 0;
500                while (msg_tlen >= sizeof(struct olsr_hna4)) {
501                    if (!TTEST2(*msg_data, sizeof(struct olsr_hna4)))
502                        goto trunc;
503
504                    ptr.hna = (struct olsr_hna4 *)msg_data;
505
506                    /* print 4 prefixes per line */
507                    if (col == 0)
508                        printf ("\n\t    ");
509                    else
510                        printf (", ");
511
512                    printf("%s/%u",
513                            ipaddr_string(ptr.hna->network),
514                            mask2plen(EXTRACT_32BITS(ptr.hna->mask)));
515
516                    msg_data += sizeof(struct olsr_hna4);
517                    msg_tlen -= sizeof(struct olsr_hna4);
518
519                    col = (col + 1) % 4;
520                }
521            }
522            break;
523
524        case OLSR_NAMESERVICE_MSG:
525        {
526            u_int name_entries = EXTRACT_16BITS(msg_data+2);
527            u_int addr_size = 4;
528            int name_entries_valid = 0;
529            u_int i;
530
531            if (is_ipv6)
532                addr_size = 16;
533
534            if ((name_entries > 0)
535                    && ((name_entries * (4 + addr_size)) <= msg_tlen))
536                name_entries_valid = 1;
537
538            if (msg_tlen < 4)
539                goto trunc;
540            if (!TTEST2(*msg_data, 4))
541                goto trunc;
542
543            printf("\n\t  Version %u, Entries %u%s",
544                   EXTRACT_16BITS(msg_data),
545                   name_entries, (name_entries_valid == 0) ? " (invalid)" : "");
546
547            if (name_entries_valid == 0)
548                break;
549
550            msg_data += 4;
551            msg_tlen -= 4;
552
553            for (i = 0; i < name_entries; i++) {
554                int name_entry_len_valid = 0;
555
556                if (msg_tlen < 4)
557                    break;
558                if (!TTEST2(*msg_data, 4))
559                    goto trunc;
560
561                name_entry_type = EXTRACT_16BITS(msg_data);
562                name_entry_len = EXTRACT_16BITS(msg_data+2);
563
564                msg_data += 4;
565                msg_tlen -= 4;
566
567                if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen))
568                    name_entry_len_valid = 1;
569
570                printf("\n\t    #%u: type %#06x, length %u%s",
571                        (unsigned int) i, name_entry_type,
572                        name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : "");
573
574                if (name_entry_len_valid == 0)
575                    break;
576
577                /* 32-bit alignment */
578                name_entry_padding = 0;
579                if (name_entry_len%4 != 0)
580                    name_entry_padding = 4-(name_entry_len%4);
581
582                if (msg_tlen < addr_size + name_entry_len + name_entry_padding)
583                    goto trunc;
584
585                if (!TTEST2(*msg_data, addr_size + name_entry_len + name_entry_padding))
586                    goto trunc;
587
588#if INET6
589                if (is_ipv6)
590                    printf(", address %s, name \"",
591                            ip6addr_string(msg_data));
592                else
593#endif
594                    printf(", address %s, name \"",
595                            ipaddr_string(msg_data));
596                fn_printn(msg_data + addr_size, name_entry_len, NULL);
597                printf("\"");
598
599                msg_data += addr_size + name_entry_len + name_entry_padding;
600                msg_tlen -= addr_size + name_entry_len + name_entry_padding;
601            } /* for (i = 0; i < name_entries; i++) */
602            break;
603        } /* case OLSR_NAMESERVICE_MSG */
604
605            /*
606             * FIXME those are the defined messages that lack a decoder
607             * you are welcome to contribute code ;-)
608             */
609        case OLSR_POWERINFO_MSG:
610        default:
611            print_unknown_data(msg_data, "\n\t    ", msg_tlen);
612            break;
613        } /* switch (msg_type) */
614        tptr += msg_len;
615    } /* while (tptr < (pptr+length)) */
616
617    return;
618
619 trunc:
620    printf("[|olsr]");
621}
622
623/*
624 * Local Variables:
625 * c-style: whitesmith
626 * c-basic-offset: 4
627 * End:
628 */
Note: See TracBrowser for help on using the repository browser.