1145519Sdarrenr/*	$FreeBSD$	*/
2145510Sdarrenr
3145510Sdarrenr/*
4255332Scy * Copyright (C) 2012 by Darren Reed.
5145510Sdarrenr *
6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
7145510Sdarrenr *
8255332Scy * $Id$
9145510Sdarrenr */
10145510Sdarrenr
11145510Sdarrenr#include "ipf.h"
12145510Sdarrenr
13145510Sdarrenr#ifndef	IP_OFFMASK
14145510Sdarrenr# define	IP_OFFMASK	0x3fff
15145510Sdarrenr#endif
16145510Sdarrenr
17145510Sdarrenr
18255332Scyvoid
19255332Scyprintpacket(dir, m)
20255332Scy	int dir;
21255332Scy	mb_t *m;
22145510Sdarrenr{
23255332Scy	u_short len, off;
24255332Scy	tcphdr_t *tcp;
25255332Scy	ip_t *ip;
26145510Sdarrenr
27255332Scy	ip = MTOD(m, ip_t *);
28255332Scy
29145510Sdarrenr	if (IP_V(ip) == 6) {
30255332Scy#ifdef USE_INET6
31255332Scy		len = ntohs(((ip6_t *)ip)->ip6_plen);
32255332Scy#else
33255332Scy		len = ntohs(((u_short *)ip)[2]);
34255332Scy#endif
35255332Scy		len += 40;
36145510Sdarrenr	} else {
37145510Sdarrenr		len = ntohs(ip->ip_len);
38145510Sdarrenr	}
39255332Scy	ASSERT(len == msgdsize(m));
40145510Sdarrenr
41145510Sdarrenr	if ((opts & OPT_HEX) == OPT_HEX) {
42145510Sdarrenr		u_char *s;
43145510Sdarrenr		int i;
44145510Sdarrenr
45255332Scy		for (; m != NULL; m = m->mb_next) {
46255332Scy			len = m->mb_len;
47255332Scy			for (s = (u_char *)m->mb_data, i = 0; i < len; i++) {
48255332Scy				PRINTF("%02x", *s++ & 0xff);
49255332Scy				if (len - i > 1) {
50255332Scy					i++;
51255332Scy					PRINTF("%02x", *s++ & 0xff);
52255332Scy				}
53255332Scy				putchar(' ');
54145510Sdarrenr			}
55145510Sdarrenr		}
56145510Sdarrenr		putchar('\n');
57170268Sdarrenr		putchar('\n');
58145510Sdarrenr		return;
59145510Sdarrenr	}
60145510Sdarrenr
61145510Sdarrenr	if (IP_V(ip) == 6) {
62255332Scy		printpacket6(dir, m);
63145510Sdarrenr		return;
64145510Sdarrenr	}
65145510Sdarrenr
66255332Scy	if (dir)
67255332Scy		PRINTF("> ");
68255332Scy	else
69255332Scy		PRINTF("< ");
70255332Scy
71255332Scy	PRINTF("%s ", IFNAME(m->mb_ifp));
72255332Scy
73255332Scy	off = ntohs(ip->ip_off);
74145510Sdarrenr	tcp = (struct tcphdr *)((char *)ip + (IP_HL(ip) << 2));
75255332Scy	PRINTF("ip #%d %d(%d) %d", ntohs(ip->ip_id), ntohs(ip->ip_len),
76153881Sguido	       IP_HL(ip) << 2, ip->ip_p);
77145510Sdarrenr	if (off & IP_OFFMASK)
78255332Scy		PRINTF(" @%d", off << 3);
79255332Scy	PRINTF(" %s", inet_ntoa(ip->ip_src));
80145510Sdarrenr	if (!(off & IP_OFFMASK))
81145510Sdarrenr		if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
82255332Scy			PRINTF(",%d", ntohs(tcp->th_sport));
83255332Scy	PRINTF(" > ");
84255332Scy	PRINTF("%s", inet_ntoa(ip->ip_dst));
85145510Sdarrenr	if (!(off & IP_OFFMASK)) {
86145510Sdarrenr		if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
87255332Scy			PRINTF(",%d", ntohs(tcp->th_dport));
88145510Sdarrenr		if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) {
89145510Sdarrenr			putchar(' ');
90145510Sdarrenr			if (tcp->th_flags & TH_FIN)
91145510Sdarrenr				putchar('F');
92145510Sdarrenr			if (tcp->th_flags & TH_SYN)
93145510Sdarrenr				putchar('S');
94145510Sdarrenr			if (tcp->th_flags & TH_RST)
95145510Sdarrenr				putchar('R');
96145510Sdarrenr			if (tcp->th_flags & TH_PUSH)
97145510Sdarrenr				putchar('P');
98145510Sdarrenr			if (tcp->th_flags & TH_ACK)
99145510Sdarrenr				putchar('A');
100145510Sdarrenr			if (tcp->th_flags & TH_URG)
101145510Sdarrenr				putchar('U');
102145510Sdarrenr			if (tcp->th_flags & TH_ECN)
103145510Sdarrenr				putchar('E');
104145510Sdarrenr			if (tcp->th_flags & TH_CWR)
105145510Sdarrenr				putchar('C');
106145510Sdarrenr		}
107145510Sdarrenr	}
108145510Sdarrenr
109145510Sdarrenr	putchar('\n');
110145510Sdarrenr}
111