source: rtems-libbsd/freebsd/contrib/tcpdump/print-pfsync.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: 11.3 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
5 * Copyright (c) 2002 Michael Shalayeff
6 * Copyright (c) 2001 Daniel Hartmeier
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $OpenBSD: print-pfsync.c,v 1.38 2012/09/19 13:50:36 mikeb Exp $
31 * $OpenBSD: pf_print_state.c,v 1.11 2012/07/08 17:48:37 lteo Exp $
32 */
33
34#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37
38#include <tcpdump-stdinc.h>
39
40#include <sys/endian.h>
41#include <net/if.h>
42#define TCPSTATES
43#include <net/pfvar.h>  /* XXX */
44#include <net/if_pfsync.h>
45#include <netinet/ip.h>
46#include <netinet/tcp_fsm.h>
47
48#include <string.h>
49
50#include "interface.h"
51#include "addrtoname.h"
52
53static void     pfsync_print(struct pfsync_header *, const u_char *, u_int);
54static void     print_src_dst(const struct pfsync_state_peer *,
55                    const struct pfsync_state_peer *, uint8_t);
56static void     print_state(struct pfsync_state *);
57
58#ifdef notyet
59void
60pfsync_if_print(u_char *user, const struct pcap_pkthdr *h,
61    register const u_char *p)
62{
63        u_int caplen = h->caplen;
64
65        ts_print(&h->ts);
66
67        if (caplen < PFSYNC_HDRLEN) {
68                printf("[|pfsync]");
69                goto out;
70        }
71
72        pfsync_print((struct pfsync_header *)p,
73            p + sizeof(struct pfsync_header),
74            caplen - sizeof(struct pfsync_header));
75out:
76        if (xflag) {
77                default_print((const u_char *)p, caplen);
78        }
79        putchar('\n');
80}
81#endif /* notyet */
82
83void
84pfsync_ip_print(const u_char *bp, u_int len)
85{
86        struct pfsync_header *hdr = (struct pfsync_header *)bp;
87
88        if (len < PFSYNC_HDRLEN)
89                printf("[|pfsync]");
90        else
91                pfsync_print(hdr, bp + sizeof(struct pfsync_header),
92                    len - sizeof(struct pfsync_header));
93}
94
95struct pfsync_actions {
96        const char *name;
97        size_t len;
98        void (*print)(const void *);
99};
100
101static void     pfsync_print_clr(const void *);
102static void     pfsync_print_state(const void *);
103static void     pfsync_print_ins_ack(const void *);
104static void     pfsync_print_upd_c(const void *);
105static void     pfsync_print_upd_req(const void *);
106static void     pfsync_print_del_c(const void *);
107static void     pfsync_print_bus(const void *);
108static void     pfsync_print_tdb(const void *);
109
110struct pfsync_actions actions[] = {
111        { "clear all", sizeof(struct pfsync_clr),       pfsync_print_clr },
112        { "insert", sizeof(struct pfsync_state),        pfsync_print_state },
113        { "insert ack", sizeof(struct pfsync_ins_ack),  pfsync_print_ins_ack },
114        { "update", sizeof(struct pfsync_ins_ack),      pfsync_print_state },
115        { "update compressed", sizeof(struct pfsync_upd_c),
116                                                        pfsync_print_upd_c },
117        { "request uncompressed", sizeof(struct pfsync_upd_req),
118                                                        pfsync_print_upd_req },
119        { "delete", sizeof(struct pfsync_state),        pfsync_print_state },
120        { "delete compressed", sizeof(struct pfsync_del_c),
121                                                        pfsync_print_del_c },
122        { "frag insert", 0,                             NULL },
123        { "frag delete", 0,                             NULL },
124        { "bulk update status", sizeof(struct pfsync_bus),
125                                                        pfsync_print_bus },
126        { "tdb", 0,                                     pfsync_print_tdb },
127        { "eof", 0,                                     NULL },
128};
129
130static void
131pfsync_print(struct pfsync_header *hdr, const u_char *bp, u_int len)
132{
133        struct pfsync_subheader *subh;
134        int count, plen, i;
135        u_int alen;
136
137        plen = ntohs(hdr->len);
138
139        printf("PFSYNCv%d len %d", hdr->version, plen);
140
141        if (hdr->version != PFSYNC_VERSION)
142                return;
143
144        plen -= sizeof(*hdr);
145
146        while (plen > 0) {
147                if (len < sizeof(*subh))
148                        break;
149
150                subh = (struct pfsync_subheader *)bp;
151                bp += sizeof(*subh);
152                len -= sizeof(*subh);
153                plen -= sizeof(*subh);
154
155                if (subh->action >= PFSYNC_ACT_MAX) {
156                        printf("\n    act UNKNOWN id %d", subh->action);
157                        return;
158                }
159
160                count = ntohs(subh->count);
161                printf("\n    %s count %d", actions[subh->action].name, count);
162                alen = actions[subh->action].len;
163
164                if (subh->action == PFSYNC_ACT_EOF)
165                        return;
166
167                if (actions[subh->action].print == NULL) {
168                        printf("\n    unimplemented action %hhu", subh->action);
169                        return;
170                }
171
172                for (i = 0; i < count; i++) {
173                        if (len < alen) {
174                                len = 0;
175                                break;
176                        }
177
178                        if (vflag)
179                                actions[subh->action].print(bp);
180
181                        bp += alen;
182                        len -= alen;
183                        plen -= alen;
184                }
185        }
186
187        if (plen > 0) {
188                printf("\n    ...");
189                return;
190        }
191        if (plen < 0) {
192                printf("\n    invalid header length");
193                return;
194        }
195        if (len > 0)
196                printf("\n    invalid packet length");
197}
198
199static void
200pfsync_print_clr(const void *bp)
201{
202        const struct pfsync_clr *clr = bp;
203
204        printf("\n\tcreatorid: %08x", htonl(clr->creatorid));
205        if (clr->ifname[0] != '\0')
206                printf(" interface: %s", clr->ifname);
207}
208
209static void
210pfsync_print_state(const void *bp)
211{
212        struct pfsync_state *st = (struct pfsync_state *)bp;
213
214        putchar('\n');
215        print_state(st);
216}
217
218static void
219pfsync_print_ins_ack(const void *bp)
220{
221        const struct pfsync_ins_ack *iack = bp;
222
223        printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(iack->id),
224            ntohl(iack->creatorid));
225}
226
227static void
228pfsync_print_upd_c(const void *bp)
229{
230        const struct pfsync_upd_c *u = bp;
231
232        printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(u->id),
233            ntohl(u->creatorid));
234        if (vflag > 2) {
235                printf("\n\tTCP? :");
236                print_src_dst(&u->src, &u->dst, IPPROTO_TCP);
237        }
238}
239
240static void
241pfsync_print_upd_req(const void *bp)
242{
243        const struct pfsync_upd_req *ur = bp;
244
245        printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(ur->id),
246            ntohl(ur->creatorid));
247}
248
249static void
250pfsync_print_del_c(const void *bp)
251{
252        const struct pfsync_del_c *d = bp;
253
254        printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(d->id),
255            ntohl(d->creatorid));
256}
257
258static void
259pfsync_print_bus(const void *bp)
260{
261        const struct pfsync_bus *b = bp;
262        uint32_t endtime;
263        int min, sec;
264        const char *status;
265
266        endtime = ntohl(b->endtime);
267        sec = endtime % 60;
268        endtime /= 60;
269        min = endtime % 60;
270        endtime /= 60;
271
272        switch (b->status) {
273        case PFSYNC_BUS_START:
274                status = "start";
275                break;
276        case PFSYNC_BUS_END:
277                status = "end";
278                break;
279        default:
280                status = "UNKNOWN";
281                break;
282        }
283
284        printf("\n\tcreatorid: %08x age: %.2u:%.2u:%.2u status: %s",
285            htonl(b->creatorid), endtime, min, sec, status);
286}
287
288static void
289pfsync_print_tdb(const void *bp)
290{
291        const struct pfsync_tdb *t = bp;
292
293        printf("\n\tspi: 0x%08x rpl: %ju cur_bytes: %ju",
294            ntohl(t->spi), (uintmax_t )be64toh(t->rpl),
295            (uintmax_t )be64toh(t->cur_bytes));
296}
297
298static void
299print_host(struct pf_addr *addr, uint16_t port, sa_family_t af,
300    const char *proto)
301{
302        char buf[48];
303
304        if (inet_ntop(af, addr, buf, sizeof(buf)) == NULL)
305                printf("?");
306        else
307                printf("%s", buf);
308
309        if (port)
310                printf(".%hu", ntohs(port));
311}
312
313static void
314print_seq(const struct pfsync_state_peer *p)
315{
316        if (p->seqdiff)
317                printf("[%u + %u](+%u)", ntohl(p->seqlo),
318                    ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff));
319        else
320                printf("[%u + %u]", ntohl(p->seqlo),
321                    ntohl(p->seqhi) - ntohl(p->seqlo));
322}
323
324static void
325print_src_dst(const struct pfsync_state_peer *src,
326    const struct pfsync_state_peer *dst, uint8_t proto)
327{
328
329        if (proto == IPPROTO_TCP) {
330                if (src->state <= TCPS_TIME_WAIT &&
331                    dst->state <= TCPS_TIME_WAIT)
332                        printf("   %s:%s", tcpstates[src->state],
333                            tcpstates[dst->state]);
334                else if (src->state == PF_TCPS_PROXY_SRC ||
335                    dst->state == PF_TCPS_PROXY_SRC)
336                        printf("   PROXY:SRC");
337                else if (src->state == PF_TCPS_PROXY_DST ||
338                    dst->state == PF_TCPS_PROXY_DST)
339                        printf("   PROXY:DST");
340                else
341                        printf("   <BAD STATE LEVELS %u:%u>",
342                            src->state, dst->state);
343                if (vflag > 1) {
344                        printf("\n\t");
345                        print_seq(src);
346                        if (src->wscale && dst->wscale)
347                                printf(" wscale %u",
348                                    src->wscale & PF_WSCALE_MASK);
349                        printf("  ");
350                        print_seq(dst);
351                        if (src->wscale && dst->wscale)
352                                printf(" wscale %u",
353                                    dst->wscale & PF_WSCALE_MASK);
354                }
355        } else if (proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
356            dst->state < PFUDPS_NSTATES) {
357                const char *states[] = PFUDPS_NAMES;
358
359                printf("   %s:%s", states[src->state], states[dst->state]);
360        } else if (proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
361            dst->state < PFOTHERS_NSTATES) {
362                /* XXX ICMP doesn't really have state levels */
363                const char *states[] = PFOTHERS_NAMES;
364
365                printf("   %s:%s", states[src->state], states[dst->state]);
366        } else {
367                printf("   %u:%u", src->state, dst->state);
368        }
369}
370
371static void
372print_state(struct pfsync_state *s)
373{
374        struct pfsync_state_peer *src, *dst;
375        struct pfsync_state_key *sk, *nk;
376        int min, sec;
377
378        if (s->direction == PF_OUT) {
379                src = &s->src;
380                dst = &s->dst;
381                sk = &s->key[PF_SK_STACK];
382                nk = &s->key[PF_SK_WIRE];
383                if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
384                        sk->port[0] = nk->port[0];
385        } else {
386                src = &s->dst;
387                dst = &s->src;
388                sk = &s->key[PF_SK_WIRE];
389                nk = &s->key[PF_SK_STACK];
390                if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
391                        sk->port[1] = nk->port[1];
392        }
393        printf("\t%s ", s->ifname);
394        printf("proto %u ", s->proto);
395
396        print_host(&nk->addr[1], nk->port[1], s->af, NULL);
397        if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
398            nk->port[1] != sk->port[1]) {
399                printf(" (");
400                print_host(&sk->addr[1], sk->port[1], s->af, NULL);
401                printf(")");
402        }
403        if (s->direction == PF_OUT)
404                printf(" -> ");
405        else
406                printf(" <- ");
407        print_host(&nk->addr[0], nk->port[0], s->af, NULL);
408        if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
409            nk->port[0] != sk->port[0]) {
410                printf(" (");
411                print_host(&sk->addr[0], sk->port[0], s->af, NULL);
412                printf(")");
413        }
414
415        print_src_dst(src, dst, s->proto);
416
417        if (vflag > 1) {
418                uint64_t packets[2];
419                uint64_t bytes[2];
420                uint32_t creation = ntohl(s->creation);
421                uint32_t expire = ntohl(s->expire);
422
423                sec = creation % 60;
424                creation /= 60;
425                min = creation % 60;
426                creation /= 60;
427                printf("\n\tage %.2u:%.2u:%.2u", creation, min, sec);
428                sec = expire % 60;
429                expire /= 60;
430                min = expire % 60;
431                expire /= 60;
432                printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
433
434                bcopy(s->packets[0], &packets[0], sizeof(uint64_t));
435                bcopy(s->packets[1], &packets[1], sizeof(uint64_t));
436                bcopy(s->bytes[0], &bytes[0], sizeof(uint64_t));
437                bcopy(s->bytes[1], &bytes[1], sizeof(uint64_t));
438                printf(", %ju:%ju pkts, %ju:%ju bytes",
439                    be64toh(packets[0]), be64toh(packets[1]),
440                    be64toh(bytes[0]), be64toh(bytes[1]));
441                if (s->anchor != ntohl(-1))
442                        printf(", anchor %u", ntohl(s->anchor));
443                if (s->rule != ntohl(-1))
444                        printf(", rule %u", ntohl(s->rule));
445        }
446        if (vflag > 1) {
447                uint64_t id;
448
449                bcopy(&s->id, &id, sizeof(uint64_t));
450                printf("\n\tid: %016jx creatorid: %08x",
451                    (uintmax_t )be64toh(id), ntohl(s->creatorid));
452        }
453}
Note: See TracBrowser for help on using the repository browser.