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