source: rtems-libbsd/freebsd/contrib/tcpdump/print-atalk.c

6-freebsd-12
Last change on this file was d542c19, checked in by Sebastian Huber <sebastian.huber@…>, on 03/11/19 at 08:33:28

tcpdump: Move static variables to special section

This fixes some issues if tcpdump is invoked a second time.

  • Property mode set to 100644
File size: 17.1 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3#ifdef __rtems__
4#include <machine/rtems-bsd-program.h>
5#include "rtems-bsd-tcpdump-namespace.h"
6#endif /* __rtems__ */
7/*
8 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
9 *      The Regents of the University of California.  All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that: (1) source code distributions
13 * retain the above copyright notice and this paragraph in its entirety, (2)
14 * distributions including binary code include the above copyright notice and
15 * this paragraph in its entirety in the documentation or other materials
16 * provided with the distribution, and (3) all advertising materials mentioning
17 * features or use of this software display the following acknowledgement:
18 * ``This product includes software developed by the University of California,
19 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
20 * the University nor the names of its contributors may be used to endorse
21 * or promote products derived from this software without specific prior
22 * written permission.
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 */
27
28/* \summary: AppleTalk printer */
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include <netdissect-stdinc.h>
35
36#include <stdio.h>
37#include <string.h>
38
39#include "netdissect.h"
40#include "addrtoname.h"
41#include "ethertype.h"
42#include "extract.h"
43#include "appletalk.h"
44
45static const char tstr[] = "[|atalk]";
46
47static const struct tok type2str[] = {
48        { ddpRTMP,              "rtmp" },
49        { ddpRTMPrequest,       "rtmpReq" },
50        { ddpECHO,              "echo" },
51        { ddpIP,                "IP" },
52        { ddpARP,               "ARP" },
53        { ddpKLAP,              "KLAP" },
54        { 0,                    NULL }
55};
56
57struct aarp {
58        uint16_t        htype, ptype;
59        uint8_t         halen, palen;
60        uint16_t        op;
61        uint8_t         hsaddr[6];
62        uint8_t         psaddr[4];
63        uint8_t         hdaddr[6];
64        uint8_t         pdaddr[4];
65};
66
67static void atp_print(netdissect_options *, const struct atATP *, u_int);
68static void atp_bitmap_print(netdissect_options *, u_char);
69static void nbp_print(netdissect_options *, const struct atNBP *, u_int, u_short, u_char, u_char);
70static const struct atNBPtuple *nbp_tuple_print(netdissect_options *ndo, const struct atNBPtuple *,
71                                                const u_char *,
72                                                u_short, u_char, u_char);
73static const struct atNBPtuple *nbp_name_print(netdissect_options *, const struct atNBPtuple *,
74                                               const u_char *);
75static const char *ataddr_string(netdissect_options *, u_short, u_char);
76static void ddp_print(netdissect_options *, const u_char *, u_int, int, u_short, u_char, u_char);
77static const char *ddpskt_string(netdissect_options *, int);
78
79/*
80 * Print LLAP packets received on a physical LocalTalk interface.
81 */
82u_int
83ltalk_if_print(netdissect_options *ndo,
84               const struct pcap_pkthdr *h, const u_char *p)
85{
86        u_int hdrlen;
87
88        hdrlen = llap_print(ndo, p, h->len);
89        if (hdrlen == 0) {
90                /* Cut short by the snapshot length. */
91                return (h->caplen);
92        }
93        return (hdrlen);
94}
95
96/*
97 * Print AppleTalk LLAP packets.
98 */
99u_int
100llap_print(netdissect_options *ndo,
101           register const u_char *bp, u_int length)
102{
103        register const struct LAP *lp;
104        register const struct atDDP *dp;
105        register const struct atShortDDP *sdp;
106        u_short snet;
107        u_int hdrlen;
108
109        if (length < sizeof(*lp)) {
110                ND_PRINT((ndo, " [|llap %u]", length));
111                return (length);
112        }
113        if (!ND_TTEST2(*bp, sizeof(*lp))) {
114                ND_PRINT((ndo, " [|llap]"));
115                return (0);     /* cut short by the snapshot length */
116        }
117        lp = (const struct LAP *)bp;
118        bp += sizeof(*lp);
119        length -= sizeof(*lp);
120        hdrlen = sizeof(*lp);
121        switch (lp->type) {
122
123        case lapShortDDP:
124                if (length < ddpSSize) {
125                        ND_PRINT((ndo, " [|sddp %u]", length));
126                        return (length);
127                }
128                if (!ND_TTEST2(*bp, ddpSSize)) {
129                        ND_PRINT((ndo, " [|sddp]"));
130                        return (0);     /* cut short by the snapshot length */
131                }
132                sdp = (const struct atShortDDP *)bp;
133                ND_PRINT((ndo, "%s.%s",
134                    ataddr_string(ndo, 0, lp->src), ddpskt_string(ndo, sdp->srcSkt)));
135                ND_PRINT((ndo, " > %s.%s:",
136                    ataddr_string(ndo, 0, lp->dst), ddpskt_string(ndo, sdp->dstSkt)));
137                bp += ddpSSize;
138                length -= ddpSSize;
139                hdrlen += ddpSSize;
140                ddp_print(ndo, bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
141                break;
142
143        case lapDDP:
144                if (length < ddpSize) {
145                        ND_PRINT((ndo, " [|ddp %u]", length));
146                        return (length);
147                }
148                if (!ND_TTEST2(*bp, ddpSize)) {
149                        ND_PRINT((ndo, " [|ddp]"));
150                        return (0);     /* cut short by the snapshot length */
151                }
152                dp = (const struct atDDP *)bp;
153                snet = EXTRACT_16BITS(&dp->srcNet);
154                ND_PRINT((ndo, "%s.%s", ataddr_string(ndo, snet, dp->srcNode),
155                    ddpskt_string(ndo, dp->srcSkt)));
156                ND_PRINT((ndo, " > %s.%s:",
157                    ataddr_string(ndo, EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
158                    ddpskt_string(ndo, dp->dstSkt)));
159                bp += ddpSize;
160                length -= ddpSize;
161                hdrlen += ddpSize;
162                ddp_print(ndo, bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
163                break;
164
165#ifdef notdef
166        case lapKLAP:
167                klap_print(bp, length);
168                break;
169#endif
170
171        default:
172                ND_PRINT((ndo, "%d > %d at-lap#%d %u",
173                    lp->src, lp->dst, lp->type, length));
174                break;
175        }
176        return (hdrlen);
177}
178
179/*
180 * Print EtherTalk/TokenTalk packets (or FDDITalk, or whatever it's called
181 * when it runs over FDDI; yes, I've seen FDDI captures with AppleTalk
182 * packets in them).
183 */
184void
185atalk_print(netdissect_options *ndo,
186            register const u_char *bp, u_int length)
187{
188        register const struct atDDP *dp;
189        u_short snet;
190
191        if(!ndo->ndo_eflag)
192            ND_PRINT((ndo, "AT "));
193
194        if (length < ddpSize) {
195                ND_PRINT((ndo, " [|ddp %u]", length));
196                return;
197        }
198        if (!ND_TTEST2(*bp, ddpSize)) {
199                ND_PRINT((ndo, " [|ddp]"));
200                return;
201        }
202        dp = (const struct atDDP *)bp;
203        snet = EXTRACT_16BITS(&dp->srcNet);
204        ND_PRINT((ndo, "%s.%s", ataddr_string(ndo, snet, dp->srcNode),
205               ddpskt_string(ndo, dp->srcSkt)));
206        ND_PRINT((ndo, " > %s.%s: ",
207               ataddr_string(ndo, EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
208               ddpskt_string(ndo, dp->dstSkt)));
209        bp += ddpSize;
210        length -= ddpSize;
211        ddp_print(ndo, bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
212}
213
214/* XXX should probably pass in the snap header and do checks like arp_print() */
215void
216aarp_print(netdissect_options *ndo,
217           register const u_char *bp, u_int length)
218{
219        register const struct aarp *ap;
220
221#define AT(member) ataddr_string(ndo, (ap->member[1]<<8)|ap->member[2],ap->member[3])
222
223        ND_PRINT((ndo, "aarp "));
224        ap = (const struct aarp *)bp;
225        if (!ND_TTEST(*ap)) {
226                /* Just bail if we don't have the whole chunk. */
227                ND_PRINT((ndo, " [|aarp]"));
228                return;
229        }
230        if (length < sizeof(*ap)) {
231                ND_PRINT((ndo, " [|aarp %u]", length));
232                return;
233        }
234        if (EXTRACT_16BITS(&ap->htype) == 1 &&
235            EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK &&
236            ap->halen == 6 && ap->palen == 4 )
237                switch (EXTRACT_16BITS(&ap->op)) {
238
239                case 1:                         /* request */
240                        ND_PRINT((ndo, "who-has %s tell %s", AT(pdaddr), AT(psaddr)));
241                        return;
242
243                case 2:                         /* response */
244                        ND_PRINT((ndo, "reply %s is-at %s", AT(psaddr), etheraddr_string(ndo, ap->hsaddr)));
245                        return;
246
247                case 3:                         /* probe (oy!) */
248                        ND_PRINT((ndo, "probe %s tell %s", AT(pdaddr), AT(psaddr)));
249                        return;
250                }
251        ND_PRINT((ndo, "len %u op %u htype %u ptype %#x halen %u palen %u",
252            length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype),
253            EXTRACT_16BITS(&ap->ptype), ap->halen, ap->palen));
254}
255
256/*
257 * Print AppleTalk Datagram Delivery Protocol packets.
258 */
259static void
260ddp_print(netdissect_options *ndo,
261          register const u_char *bp, register u_int length, register int t,
262          register u_short snet, register u_char snode, u_char skt)
263{
264
265        switch (t) {
266
267        case ddpNBP:
268                nbp_print(ndo, (const struct atNBP *)bp, length, snet, snode, skt);
269                break;
270
271        case ddpATP:
272                atp_print(ndo, (const struct atATP *)bp, length);
273                break;
274
275        case ddpEIGRP:
276                eigrp_print(ndo, bp, length);
277                break;
278
279        default:
280                ND_PRINT((ndo, " at-%s %d", tok2str(type2str, NULL, t), length));
281                break;
282        }
283}
284
285static void
286atp_print(netdissect_options *ndo,
287          register const struct atATP *ap, u_int length)
288{
289        char c;
290        uint32_t data;
291
292        if ((const u_char *)(ap + 1) > ndo->ndo_snapend) {
293                /* Just bail if we don't have the whole chunk. */
294                ND_PRINT((ndo, "%s", tstr));
295                return;
296        }
297        if (length < sizeof(*ap)) {
298                ND_PRINT((ndo, " [|atp %u]", length));
299                return;
300        }
301        length -= sizeof(*ap);
302        switch (ap->control & 0xc0) {
303
304        case atpReqCode:
305                ND_PRINT((ndo, " atp-req%s %d",
306                             ap->control & atpXO? " " : "*",
307                             EXTRACT_16BITS(&ap->transID)));
308
309                atp_bitmap_print(ndo, ap->bitmap);
310
311                if (length != 0)
312                        ND_PRINT((ndo, " [len=%u]", length));
313
314                switch (ap->control & (atpEOM|atpSTS)) {
315                case atpEOM:
316                        ND_PRINT((ndo, " [EOM]"));
317                        break;
318                case atpSTS:
319                        ND_PRINT((ndo, " [STS]"));
320                        break;
321                case atpEOM|atpSTS:
322                        ND_PRINT((ndo, " [EOM,STS]"));
323                        break;
324                }
325                break;
326
327        case atpRspCode:
328                ND_PRINT((ndo, " atp-resp%s%d:%d (%u)",
329                             ap->control & atpEOM? "*" : " ",
330                             EXTRACT_16BITS(&ap->transID), ap->bitmap, length));
331                switch (ap->control & (atpXO|atpSTS)) {
332                case atpXO:
333                        ND_PRINT((ndo, " [XO]"));
334                        break;
335                case atpSTS:
336                        ND_PRINT((ndo, " [STS]"));
337                        break;
338                case atpXO|atpSTS:
339                        ND_PRINT((ndo, " [XO,STS]"));
340                        break;
341                }
342                break;
343
344        case atpRelCode:
345                ND_PRINT((ndo, " atp-rel  %d", EXTRACT_16BITS(&ap->transID)));
346
347                atp_bitmap_print(ndo, ap->bitmap);
348
349                /* length should be zero */
350                if (length)
351                        ND_PRINT((ndo, " [len=%u]", length));
352
353                /* there shouldn't be any control flags */
354                if (ap->control & (atpXO|atpEOM|atpSTS)) {
355                        c = '[';
356                        if (ap->control & atpXO) {
357                                ND_PRINT((ndo, "%cXO", c));
358                                c = ',';
359                        }
360                        if (ap->control & atpEOM) {
361                                ND_PRINT((ndo, "%cEOM", c));
362                                c = ',';
363                        }
364                        if (ap->control & atpSTS) {
365                                ND_PRINT((ndo, "%cSTS", c));
366                                c = ',';
367                        }
368                        ND_PRINT((ndo, "]"));
369                }
370                break;
371
372        default:
373                ND_PRINT((ndo, " atp-0x%x  %d (%u)", ap->control,
374                             EXTRACT_16BITS(&ap->transID), length));
375                break;
376        }
377        data = EXTRACT_32BITS(&ap->userData);
378        if (data != 0)
379                ND_PRINT((ndo, " 0x%x", data));
380}
381
382static void
383atp_bitmap_print(netdissect_options *ndo,
384                 register u_char bm)
385{
386        register char c;
387        register int i;
388
389        /*
390         * The '& 0xff' below is needed for compilers that want to sign
391         * extend a u_char, which is the case with the Ultrix compiler.
392         * (gcc is smart enough to eliminate it, at least on the Sparc).
393         */
394        if ((bm + 1) & (bm & 0xff)) {
395                c = '<';
396                for (i = 0; bm; ++i) {
397                        if (bm & 1) {
398                                ND_PRINT((ndo, "%c%d", c, i));
399                                c = ',';
400                        }
401                        bm >>= 1;
402                }
403                ND_PRINT((ndo, ">"));
404        } else {
405                for (i = 0; bm; ++i)
406                        bm >>= 1;
407                if (i > 1)
408                        ND_PRINT((ndo, "<0-%d>", i - 1));
409                else
410                        ND_PRINT((ndo, "<0>"));
411        }
412}
413
414static void
415nbp_print(netdissect_options *ndo,
416          register const struct atNBP *np, u_int length, register u_short snet,
417          register u_char snode, register u_char skt)
418{
419        register const struct atNBPtuple *tp =
420                (const struct atNBPtuple *)((const u_char *)np + nbpHeaderSize);
421        int i;
422        const u_char *ep;
423
424        if (length < nbpHeaderSize) {
425                ND_PRINT((ndo, " truncated-nbp %u", length));
426                return;
427        }
428
429        length -= nbpHeaderSize;
430        if (length < 8) {
431                /* must be room for at least one tuple */
432                ND_PRINT((ndo, " truncated-nbp %u", length + nbpHeaderSize));
433                return;
434        }
435        /* ep points to end of available data */
436        ep = ndo->ndo_snapend;
437        if ((const u_char *)tp > ep) {
438                ND_PRINT((ndo, "%s", tstr));
439                return;
440        }
441        switch (i = np->control & 0xf0) {
442
443        case nbpBrRq:
444        case nbpLkUp:
445                ND_PRINT((ndo, i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:", np->id));
446                if ((const u_char *)(tp + 1) > ep) {
447                        ND_PRINT((ndo, "%s", tstr));
448                        return;
449                }
450                (void)nbp_name_print(ndo, tp, ep);
451                /*
452                 * look for anomalies: the spec says there can only
453                 * be one tuple, the address must match the source
454                 * address and the enumerator should be zero.
455                 */
456                if ((np->control & 0xf) != 1)
457                        ND_PRINT((ndo, " [ntup=%d]", np->control & 0xf));
458                if (tp->enumerator)
459                        ND_PRINT((ndo, " [enum=%d]", tp->enumerator));
460                if (EXTRACT_16BITS(&tp->net) != snet ||
461                    tp->node != snode || tp->skt != skt)
462                        ND_PRINT((ndo, " [addr=%s.%d]",
463                            ataddr_string(ndo, EXTRACT_16BITS(&tp->net),
464                            tp->node), tp->skt));
465                break;
466
467        case nbpLkUpReply:
468                ND_PRINT((ndo, " nbp-reply %d:", np->id));
469
470                /* print each of the tuples in the reply */
471                for (i = np->control & 0xf; --i >= 0 && tp; )
472                        tp = nbp_tuple_print(ndo, tp, ep, snet, snode, skt);
473                break;
474
475        default:
476                ND_PRINT((ndo, " nbp-0x%x  %d (%u)", np->control, np->id, length));
477                break;
478        }
479}
480
481/* print a counted string */
482static const char *
483print_cstring(netdissect_options *ndo,
484              register const char *cp, register const u_char *ep)
485{
486        register u_int length;
487
488        if (cp >= (const char *)ep) {
489                ND_PRINT((ndo, "%s", tstr));
490                return (0);
491        }
492        length = *cp++;
493
494        /* Spec says string can be at most 32 bytes long */
495        if (length > 32) {
496                ND_PRINT((ndo, "[len=%u]", length));
497                return (0);
498        }
499        while ((int)--length >= 0) {
500                if (cp >= (const char *)ep) {
501                        ND_PRINT((ndo, "%s", tstr));
502                        return (0);
503                }
504                ND_PRINT((ndo, "%c", *cp++));
505        }
506        return (cp);
507}
508
509static const struct atNBPtuple *
510nbp_tuple_print(netdissect_options *ndo,
511                register const struct atNBPtuple *tp, register const u_char *ep,
512                register u_short snet, register u_char snode, register u_char skt)
513{
514        register const struct atNBPtuple *tpn;
515
516        if ((const u_char *)(tp + 1) > ep) {
517                ND_PRINT((ndo, "%s", tstr));
518                return 0;
519        }
520        tpn = nbp_name_print(ndo, tp, ep);
521
522        /* if the enumerator isn't 1, print it */
523        if (tp->enumerator != 1)
524                ND_PRINT((ndo, "(%d)", tp->enumerator));
525
526        /* if the socket doesn't match the src socket, print it */
527        if (tp->skt != skt)
528                ND_PRINT((ndo, " %d", tp->skt));
529
530        /* if the address doesn't match the src address, it's an anomaly */
531        if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode)
532                ND_PRINT((ndo, " [addr=%s]",
533                    ataddr_string(ndo, EXTRACT_16BITS(&tp->net), tp->node)));
534
535        return (tpn);
536}
537
538static const struct atNBPtuple *
539nbp_name_print(netdissect_options *ndo,
540               const struct atNBPtuple *tp, register const u_char *ep)
541{
542        register const char *cp = (const char *)tp + nbpTupleSize;
543
544        ND_PRINT((ndo, " "));
545
546        /* Object */
547        ND_PRINT((ndo, "\""));
548        if ((cp = print_cstring(ndo, cp, ep)) != NULL) {
549                /* Type */
550                ND_PRINT((ndo, ":"));
551                if ((cp = print_cstring(ndo, cp, ep)) != NULL) {
552                        /* Zone */
553                        ND_PRINT((ndo, "@"));
554                        if ((cp = print_cstring(ndo, cp, ep)) != NULL)
555                                ND_PRINT((ndo, "\""));
556                }
557        }
558        return ((const struct atNBPtuple *)cp);
559}
560
561
562#define HASHNAMESIZE 4096
563
564struct hnamemem {
565        int addr;
566        char *name;
567        struct hnamemem *nxt;
568};
569
570static struct hnamemem hnametable[HASHNAMESIZE];
571
572static const char *
573ataddr_string(netdissect_options *ndo,
574              u_short atnet, u_char athost)
575{
576        register struct hnamemem *tp, *tp2;
577        register int i = (atnet << 8) | athost;
578        char nambuf[256+1];
579#ifdef __rtems__
580        __section(".rtemsrwset.bsd_prog_tcpdump.content")
581#endif /* __rtems__ */
582        static int first = 1;
583        FILE *fp;
584
585        /*
586         * if this is the first call, see if there's an AppleTalk
587         * number to name map file.
588         */
589        if (first && (first = 0, !ndo->ndo_nflag)
590            && (fp = fopen("/etc/atalk.names", "r"))) {
591                char line[256];
592                int i1, i2;
593
594                while (fgets(line, sizeof(line), fp)) {
595                        if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
596                                continue;
597                        if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3)
598                                /* got a hostname. */
599                                i2 |= (i1 << 8);
600                        else if (sscanf(line, "%d %256s", &i1, nambuf) == 2)
601                                /* got a net name */
602                                i2 = (i1 << 8) | 255;
603                        else
604                                continue;
605
606                        for (tp = &hnametable[i2 & (HASHNAMESIZE-1)];
607                             tp->nxt; tp = tp->nxt)
608                                ;
609                        tp->addr = i2;
610                        tp->nxt = newhnamemem(ndo);
611                        tp->name = strdup(nambuf);
612                        if (tp->name == NULL)
613                                (*ndo->ndo_error)(ndo,
614                                                  "ataddr_string: strdup(nambuf)");
615                }
616                fclose(fp);
617        }
618
619        for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
620                if (tp->addr == i)
621                        return (tp->name);
622
623        /* didn't have the node name -- see if we've got the net name */
624        i |= 255;
625        for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt)
626                if (tp2->addr == i) {
627                        tp->addr = (atnet << 8) | athost;
628                        tp->nxt = newhnamemem(ndo);
629                        (void)snprintf(nambuf, sizeof(nambuf), "%s.%d",
630                            tp2->name, athost);
631                        tp->name = strdup(nambuf);
632                        if (tp->name == NULL)
633                                (*ndo->ndo_error)(ndo,
634                                                  "ataddr_string: strdup(nambuf)");
635                        return (tp->name);
636                }
637
638        tp->addr = (atnet << 8) | athost;
639        tp->nxt = newhnamemem(ndo);
640        if (athost != 255)
641                (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost);
642        else
643                (void)snprintf(nambuf, sizeof(nambuf), "%d", atnet);
644        tp->name = strdup(nambuf);
645        if (tp->name == NULL)
646                (*ndo->ndo_error)(ndo, "ataddr_string: strdup(nambuf)");
647
648        return (tp->name);
649}
650
651static const struct tok skt2str[] = {
652        { rtmpSkt,      "rtmp" },       /* routing table maintenance */
653        { nbpSkt,       "nis" },        /* name info socket */
654        { echoSkt,      "echo" },       /* AppleTalk echo protocol */
655        { zipSkt,       "zip" },        /* zone info protocol */
656        { 0,            NULL }
657};
658
659static const char *
660ddpskt_string(netdissect_options *ndo,
661              register int skt)
662{
663        static char buf[8];
664
665        if (ndo->ndo_nflag) {
666                (void)snprintf(buf, sizeof(buf), "%d", skt);
667                return (buf);
668        }
669        return (tok2str(skt2str, "%d", skt));
670}
671#ifdef __rtems__
672#include "rtems-bsd-tcpdump-print-atalk-data.h"
673#endif /* __rtems__ */
Note: See TracBrowser for help on using the repository browser.