1/*	$FreeBSD$	*/
2
3/*
4 * Copyright (C) 2012 by Darren Reed.
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 *
8 * $Id$
9 */
10
11#include "ipf.h"
12
13#ifndef	IP_OFFMASK
14# define	IP_OFFMASK	0x3fff
15#endif
16
17
18void
19printpacket(dir, m)
20	int dir;
21	mb_t *m;
22{
23	u_short len, off;
24	tcphdr_t *tcp;
25	ip_t *ip;
26
27	ip = MTOD(m, ip_t *);
28
29	if (IP_V(ip) == 6) {
30#ifdef USE_INET6
31		len = ntohs(((ip6_t *)ip)->ip6_plen);
32#else
33		len = ntohs(((u_short *)ip)[2]);
34#endif
35		len += 40;
36	} else {
37		len = ntohs(ip->ip_len);
38	}
39	ASSERT(len == msgdsize(m));
40
41	if ((opts & OPT_HEX) == OPT_HEX) {
42		u_char *s;
43		int i;
44
45		for (; m != NULL; m = m->mb_next) {
46			len = m->mb_len;
47			for (s = (u_char *)m->mb_data, i = 0; i < len; i++) {
48				PRINTF("%02x", *s++ & 0xff);
49				if (len - i > 1) {
50					i++;
51					PRINTF("%02x", *s++ & 0xff);
52				}
53				putchar(' ');
54			}
55		}
56		putchar('\n');
57		putchar('\n');
58		return;
59	}
60
61	if (IP_V(ip) == 6) {
62		printpacket6(dir, m);
63		return;
64	}
65
66	if (dir)
67		PRINTF("> ");
68	else
69		PRINTF("< ");
70
71	PRINTF("%s ", IFNAME(m->mb_ifp));
72
73	off = ntohs(ip->ip_off);
74	tcp = (struct tcphdr *)((char *)ip + (IP_HL(ip) << 2));
75	PRINTF("ip #%d %d(%d) %d", ntohs(ip->ip_id), ntohs(ip->ip_len),
76	       IP_HL(ip) << 2, ip->ip_p);
77	if (off & IP_OFFMASK)
78		PRINTF(" @%d", off << 3);
79	PRINTF(" %s", inet_ntoa(ip->ip_src));
80	if (!(off & IP_OFFMASK))
81		if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
82			PRINTF(",%d", ntohs(tcp->th_sport));
83	PRINTF(" > ");
84	PRINTF("%s", inet_ntoa(ip->ip_dst));
85	if (!(off & IP_OFFMASK)) {
86		if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
87			PRINTF(",%d", ntohs(tcp->th_dport));
88		if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) {
89			putchar(' ');
90			if (tcp->th_flags & TH_FIN)
91				putchar('F');
92			if (tcp->th_flags & TH_SYN)
93				putchar('S');
94			if (tcp->th_flags & TH_RST)
95				putchar('R');
96			if (tcp->th_flags & TH_PUSH)
97				putchar('P');
98			if (tcp->th_flags & TH_ACK)
99				putchar('A');
100			if (tcp->th_flags & TH_URG)
101				putchar('U');
102			if (tcp->th_flags & TH_ECN)
103				putchar('E');
104			if (tcp->th_flags & TH_CWR)
105				putchar('C');
106		}
107	}
108
109	putchar('\n');
110}
111