source: rtems-libbsd/freebsd/contrib/tcpdump/print-babel.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: 13.1 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright (c) 2007-2011 Grégoire Henry, Juliusz Chroboczek
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the project nor the names of its contributors
15 *    may be used to endorse or promote products derived from this software
16 *    without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include <tcpdump-stdinc.h>
36
37#include <stdio.h>
38#include <string.h>
39
40#include "addrtoname.h"
41#include "interface.h"
42#include "extract.h"
43
44static void babel_print_v2(const u_char *cp, u_int length);
45
46void
47babel_print(const u_char *cp, u_int length) {
48    printf("babel");
49
50    TCHECK2(*cp, 4);
51
52    if(cp[0] != 42) {
53        printf(" malformed header");
54        return;
55    } else {
56        printf(" %d", cp[1]);
57    }
58
59    switch(cp[1]) {
60    case 2:
61        babel_print_v2(cp,length);
62        break;
63    default:
64        printf(" unknown version");
65        break;
66    }
67
68    return;
69
70 trunc:
71    printf(" [|babel]");
72    return;
73}
74
75#define MESSAGE_PAD1 0
76#define MESSAGE_PADN 1
77#define MESSAGE_ACK_REQ 2
78#define MESSAGE_ACK 3
79#define MESSAGE_HELLO 4
80#define MESSAGE_IHU 5
81#define MESSAGE_ROUTER_ID 6
82#define MESSAGE_NH 7
83#define MESSAGE_UPDATE 8
84#define MESSAGE_REQUEST 9
85#define MESSAGE_MH_REQUEST 10
86#define MESSAGE_TSPC 11
87#define MESSAGE_HMAC 12
88
89static const char *
90format_id(const u_char *id)
91{
92    static char buf[25];
93    snprintf(buf, 25, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
94             id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]);
95    buf[24] = '\0';
96    return buf;
97}
98
99static const unsigned char v4prefix[16] =
100    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
101
102static const char *
103format_prefix(const u_char *prefix, unsigned char plen)
104{
105    static char buf[50];
106    if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0)
107        snprintf(buf, 50, "%s/%u", ipaddr_string(prefix + 12), plen - 96);
108    else
109#ifdef INET6
110        snprintf(buf, 50, "%s/%u", ip6addr_string(prefix), plen);
111#else
112        snprintf(buf, 50, "IPv6 addresses not supported");
113#endif
114    buf[49] = '\0';
115    return buf;
116}
117
118static const char *
119format_address(const u_char *prefix)
120{
121    if(memcmp(prefix, v4prefix, 12) == 0)
122        return ipaddr_string(prefix + 12);
123    else
124#ifdef INET6
125        return ip6addr_string(prefix);
126#else
127        return "IPv6 addresses not supported";
128#endif
129}
130
131static int
132network_prefix(int ae, int plen, unsigned int omitted,
133               const unsigned char *p, const unsigned char *dp,
134               unsigned int len, unsigned char *p_r)
135{
136    unsigned pb;
137    unsigned char prefix[16];
138
139    if(plen >= 0)
140        pb = (plen + 7) / 8;
141    else if(ae == 1)
142        pb = 4;
143    else
144        pb = 16;
145
146    if(pb > 16)
147        return -1;
148
149    memset(prefix, 0, 16);
150
151    switch(ae) {
152    case 0: break;
153    case 1:
154        if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
155            return -1;
156        memcpy(prefix, v4prefix, 12);
157        if(omitted) {
158            if (dp == NULL) return -1;
159            memcpy(prefix, dp, 12 + omitted);
160        }
161        if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
162        break;
163    case 2:
164        if(omitted > 16 || (pb > omitted && len < pb - omitted))
165            return -1;
166        if(omitted) {
167            if (dp == NULL) return -1;
168            memcpy(prefix, dp, omitted);
169        }
170        if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
171        break;
172    case 3:
173        if(pb > 8 && len < pb - 8) return -1;
174        prefix[0] = 0xfe;
175        prefix[1] = 0x80;
176        if(pb > 8) memcpy(prefix + 8, p, pb - 8);
177        break;
178    default:
179        return -1;
180    }
181
182    memcpy(p_r, prefix, 16);
183    return 1;
184}
185
186static int
187network_address(int ae, const unsigned char *a, unsigned int len,
188                unsigned char *a_r)
189{
190    return network_prefix(ae, -1, 0, a, NULL, len, a_r);
191}
192
193#define ICHECK(i, l) \
194        if ((i) + (l) > bodylen || (i) + (l) > length) goto corrupt;
195
196static void
197babel_print_v2(const u_char *cp, u_int length) {
198    u_int i;
199    u_short bodylen;
200    u_char v4_prefix[16] =
201        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
202    u_char v6_prefix[16] = {0};
203
204    TCHECK2(*cp, 4);
205    if (length < 4)
206        goto corrupt;
207    bodylen = EXTRACT_16BITS(cp + 2);
208    printf(" (%u)", bodylen);
209
210    /* Process the TLVs in the body */
211    i = 0;
212    while(i < bodylen) {
213        const u_char *message;
214        u_int type, len;
215
216        message = cp + 4 + i;
217        TCHECK2(*message, 2);
218        ICHECK(i, 2);
219        type = message[0];
220        len = message[1];
221
222        TCHECK2(*message, 2 + len);
223        ICHECK(i, 2 + len);
224
225        switch(type) {
226        case MESSAGE_PAD1: {
227            if(!vflag)
228                printf(" pad1");
229            else
230                printf("\n\tPad 1");
231        }
232            break;
233
234        case MESSAGE_PADN: {
235            if(!vflag)
236                printf(" padN");
237            else
238                printf("\n\tPad %d", len + 2);
239        }
240            break;
241
242        case MESSAGE_ACK_REQ: {
243            u_short nonce, interval;
244            if(!vflag)
245                printf(" ack-req");
246            else {
247                printf("\n\tAcknowledgment Request ");
248                if(len < 6) goto corrupt;
249                nonce = EXTRACT_16BITS(message + 4);
250                interval = EXTRACT_16BITS(message + 6);
251                printf("%04x %d", nonce, interval);
252            }
253        }
254            break;
255
256        case MESSAGE_ACK: {
257            u_short nonce;
258            if(!vflag)
259                printf(" ack");
260            else {
261                printf("\n\tAcknowledgment ");
262                if(len < 2) goto corrupt;
263                nonce = EXTRACT_16BITS(message + 2);
264                printf("%04x", nonce);
265            }
266        }
267            break;
268
269        case MESSAGE_HELLO:  {
270            u_short seqno, interval;
271            if(!vflag)
272                printf(" hello");
273            else {
274                printf("\n\tHello ");
275                if(len < 6) goto corrupt;
276                seqno = EXTRACT_16BITS(message + 4);
277                interval = EXTRACT_16BITS(message + 6);
278                printf("seqno %u interval %u", seqno, interval);
279            }
280        }
281            break;
282
283        case MESSAGE_IHU: {
284            unsigned short txcost, interval;
285            if(!vflag)
286                printf(" ihu");
287            else {
288                u_char address[16];
289                int rc;
290                printf("\n\tIHU ");
291                if(len < 6) goto corrupt;
292                txcost = EXTRACT_16BITS(message + 4);
293                interval = EXTRACT_16BITS(message + 6);
294                rc = network_address(message[2], message + 8, len - 6, address);
295                if(rc < 0) { printf("[|babel]"); break; }
296                printf("%s txcost %u interval %d",
297                       format_address(address), txcost, interval);
298            }
299        }
300            break;
301
302        case MESSAGE_ROUTER_ID: {
303            if(!vflag)
304                printf(" router-id");
305            else {
306                printf("\n\tRouter Id");
307                if(len < 10) goto corrupt;
308                printf(" %s", format_id(message + 4));
309            }
310        }
311            break;
312
313        case MESSAGE_NH: {
314            if(!vflag)
315                printf(" nh");
316            else {
317                int rc;
318                u_char nh[16];
319                printf("\n\tNext Hop");
320                if(len < 2) goto corrupt;
321                rc = network_address(message[2], message + 4, len - 2, nh);
322                if(rc < 0) goto corrupt;
323                printf(" %s", format_address(nh));
324            }
325        }
326            break;
327
328        case MESSAGE_UPDATE: {
329            if(!vflag) {
330                printf(" update");
331                if(len < 1)
332                    printf("/truncated");
333                else
334                    printf("%s%s%s",
335                           (message[3] & 0x80) ? "/prefix": "",
336                           (message[3] & 0x40) ? "/id" : "",
337                           (message[3] & 0x3f) ? "/unknown" : "");
338            } else {
339                u_short interval, seqno, metric;
340                u_char plen;
341                int rc;
342                u_char prefix[16];
343                printf("\n\tUpdate");
344                if(len < 10) goto corrupt;
345                plen = message[4] + (message[2] == 1 ? 96 : 0);
346                rc = network_prefix(message[2], message[4], message[5],
347                                    message + 12,
348                                    message[2] == 1 ? v4_prefix : v6_prefix,
349                                    len - 10, prefix);
350                if(rc < 0) goto corrupt;
351                interval = EXTRACT_16BITS(message + 6);
352                seqno = EXTRACT_16BITS(message + 8);
353                metric = EXTRACT_16BITS(message + 10);
354                printf("%s%s%s %s metric %u seqno %u interval %u",
355                       (message[3] & 0x80) ? "/prefix": "",
356                       (message[3] & 0x40) ? "/id" : "",
357                       (message[3] & 0x3f) ? "/unknown" : "",
358                       format_prefix(prefix, plen),
359                       metric, seqno, interval);
360                if(message[3] & 0x80) {
361                    if(message[2] == 1)
362                        memcpy(v4_prefix, prefix, 16);
363                    else
364                        memcpy(v6_prefix, prefix, 16);
365                }
366            }
367        }
368            break;
369
370        case MESSAGE_REQUEST: {
371            if(!vflag)
372                printf(" request");
373            else {
374                int rc;
375                u_char prefix[16], plen;
376                printf("\n\tRequest ");
377                if(len < 2) goto corrupt;
378                plen = message[3] + (message[2] == 1 ? 96 : 0);
379                rc = network_prefix(message[2], message[3], 0,
380                                    message + 4, NULL, len - 2, prefix);
381                if(rc < 0) goto corrupt;
382                plen = message[3] + (message[2] == 1 ? 96 : 0);
383                printf("for %s",
384                       message[2] == 0 ? "any" : format_prefix(prefix, plen));
385            }
386        }
387            break;
388
389        case MESSAGE_MH_REQUEST : {
390            if(!vflag)
391                printf(" mh-request");
392            else {
393                int rc;
394                u_short seqno;
395                u_char prefix[16], plen;
396                printf("\n\tMH-Request ");
397                if(len < 14) goto corrupt;
398                seqno = EXTRACT_16BITS(message + 4);
399                rc = network_prefix(message[2], message[3], 0,
400                                    message + 16, NULL, len - 14, prefix);
401                if(rc < 0) goto corrupt;
402                plen = message[3] + (message[2] == 1 ? 96 : 0);
403                printf("(%u hops) for %s seqno %u id %s",
404                       message[6], format_prefix(prefix, plen),
405                       seqno, format_id(message + 8));
406            }
407        }
408            break;
409        case MESSAGE_TSPC :
410            if(!vflag)
411                printf(" tspc");
412            else {
413                printf("\n\tTS/PC ");
414                if(len < 6) goto corrupt;
415                printf("timestamp %u packetcounter %u", EXTRACT_32BITS (message + 4),
416                       EXTRACT_16BITS(message + 2));
417            }
418            break;
419        case MESSAGE_HMAC : {
420            if(!vflag)
421                printf(" hmac");
422            else {
423                unsigned j;
424                printf("\n\tHMAC ");
425                if(len < 18) goto corrupt;
426                printf("key-id %u digest-%u ", EXTRACT_16BITS(message + 2), len - 2);
427                for (j = 0; j < len - 2; j++)
428                    printf ("%02X", message[4 + j]);
429            }
430        }
431            break;
432        default:
433            if(!vflag)
434                printf(" unknown");
435            else
436                printf("\n\tUnknown message type %d", type);
437        }
438        i += len + 2;
439    }
440    return;
441
442 trunc:
443    printf(" [|babel]");
444    return;
445
446 corrupt:
447    printf(" (corrupt)");
448    return;
449}
Note: See TracBrowser for help on using the repository browser.