16939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger/*
26939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * This is a module which is used for logging packets.
36939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger */
46939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
56939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger/* (C) 1999-2001 Paul `Rusty' Russell
66939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
76939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger *
86939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * This program is free software; you can redistribute it and/or modify
96939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * it under the terms of the GNU General Public License version 2 as
106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger * published by the Free Software Foundation.
116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger */
126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/module.h>
156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/spinlock.h>
166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/skbuff.h>
176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/if_arp.h>
186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/ip.h>
196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/ipv6.h>
206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/icmp.h>
216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/udp.h>
226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/tcp.h>
236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/route.h>
246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/netfilter.h>
266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/netfilter/x_tables.h>
276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/netfilter/xt_LOG.h>
286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <linux/netfilter_ipv6/ip6_tables.h>
296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/netfilter/nf_log.h>
306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#include <net/netfilter/xt_log.h>
316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic struct nf_loginfo default_loginfo = {
336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	.type	= NF_LOG_TYPE_LOG,
346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	.u = {
356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.log = {
366939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			.level    = 5,
376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			.logflags = NF_LOG_MASK,
386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		},
396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	},
406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger};
416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic int dump_udp_header(struct sbuff *m, const struct sk_buff *skb,
436939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			   u8 proto, int fragment, unsigned int offset)
446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	struct udphdr _udph;
466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	const struct udphdr *uh;
476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (proto == IPPROTO_UDP)
496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 10 "PROTO=UDP "     */
506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PROTO=UDP ");
516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	else	/* Max length: 14 "PROTO=UDPLITE " */
526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PROTO=UDPLITE ");
536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (fragment)
556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		goto out;
566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 25 "INCOMPLETE [65535 bytes] " */
586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (uh == NULL) {
606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return 1;
636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 20 "SPT=65535 DPT=65535 " */
666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest),
676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		ntohs(uh->len));
686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerout:
706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	return 0;
716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb,
746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			   u8 proto, int fragment, unsigned int offset,
756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			   unsigned int logflags)
766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	struct tcphdr _tcph;
786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	const struct tcphdr *th;
796939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
806939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 10 "PROTO=TCP " */
816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "PROTO=TCP ");
826939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (fragment)
846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return 0;
856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 25 "INCOMPLETE [65535 bytes] " */
876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th == NULL) {
896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return 1;
916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 20 "SPT=65535 DPT=65535 " */
946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest));
956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (logflags & XT_LOG_TCPSEQ)
976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "SEQ=%u ACK=%u ", ntohl(th->seq), ntohl(th->ack_seq));
986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 13 "WINDOW=65535 " */
1006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "WINDOW=%u ", ntohs(th->window));
1016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 9 "RES=0x3C " */
1026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) &
1036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					    TCP_RESERVED_BITS) >> 22));
1046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
1056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th->cwr)
1066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "CWR ");
1076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th->ece)
1086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "ECE ");
1096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th->urg)
1106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "URG ");
1116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th->ack)
1126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "ACK ");
1136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th->psh)
1146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PSH ");
1156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th->rst)
1166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "RST ");
1176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th->syn)
1186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "SYN ");
1196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (th->fin)
1206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "FIN ");
1216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 11 "URGP=65535 " */
1226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
1236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if ((logflags & XT_LOG_TCPOPT) && th->doff*4 > sizeof(struct tcphdr)) {
1256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		u_int8_t _opt[60 - sizeof(struct tcphdr)];
1266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const u_int8_t *op;
1276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		unsigned int i;
1286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		unsigned int optsize = th->doff*4 - sizeof(struct tcphdr);
1296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		op = skb_header_pointer(skb, offset + sizeof(struct tcphdr),
1316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					optsize, _opt);
1326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (op == NULL) {
1336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "OPT (TRUNCATED)");
1346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return 1;
1356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
1366939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 127 "OPT (" 15*4*2chars ") " */
1386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "OPT (");
1396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		for (i = 0; i < optsize; i++)
1406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "%02X", op[i]);
1416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, ") ");
1436939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
1446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	return 0;
1466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
1476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1480626af3139572610b56376580d11eb65d45d9dd7Eric Dumazetstatic void dump_sk_uid_gid(struct sbuff *m, struct sock *sk)
1490626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet{
1500626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet	if (!sk || sk->sk_state == TCP_TIME_WAIT)
1510626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet		return;
1520626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet
1530626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet	read_lock_bh(&sk->sk_callback_lock);
154437589a74b6a590d175f86cf9f7b2efcee7765e7Linus Torvalds	if (sk->sk_socket && sk->sk_socket->file) {
155437589a74b6a590d175f86cf9f7b2efcee7765e7Linus Torvalds		const struct cred *cred = sk->sk_socket->file->f_cred;
1560626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet		sb_add(m, "UID=%u GID=%u ",
157437589a74b6a590d175f86cf9f7b2efcee7765e7Linus Torvalds			from_kuid_munged(&init_user_ns, cred->fsuid),
158437589a74b6a590d175f86cf9f7b2efcee7765e7Linus Torvalds			from_kgid_munged(&init_user_ns, cred->fsgid));
159437589a74b6a590d175f86cf9f7b2efcee7765e7Linus Torvalds	}
1600626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet	read_unlock_bh(&sk->sk_callback_lock);
1610626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet}
1620626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet
1636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger/* One level of recursion won't kill us */
1646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void dump_ipv4_packet(struct sbuff *m,
1656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			const struct nf_loginfo *info,
1666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			const struct sk_buff *skb,
1676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			unsigned int iphoff)
1686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
1696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	struct iphdr _iph;
1706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	const struct iphdr *ih;
1716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	unsigned int logflags;
1726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (info->type == NF_LOG_TYPE_LOG)
1746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		logflags = info->u.log.logflags;
1756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	else
1766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		logflags = NF_LOG_MASK;
1776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
1796939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (ih == NULL) {
1806939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "TRUNCATED");
1816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return;
1826939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
1836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Important fields:
1856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	 * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
1866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
1876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "SRC=%pI4 DST=%pI4 ",
1886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       &ih->saddr, &ih->daddr);
1896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
1916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
1926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
1936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
1946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
1956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 6 "CE DF MF " */
1966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (ntohs(ih->frag_off) & IP_CE)
1976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "CE ");
1986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (ntohs(ih->frag_off) & IP_DF)
1996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "DF ");
2006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (ntohs(ih->frag_off) & IP_MF)
2016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "MF ");
2026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 11 "FRAG:65535 " */
2046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (ntohs(ih->frag_off) & IP_OFFSET)
2056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
2066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if ((logflags & XT_LOG_IPOPT) &&
2086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	    ih->ihl * 4 > sizeof(struct iphdr)) {
2096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const unsigned char *op;
2106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
2116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		unsigned int i, optsize;
2126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		optsize = ih->ihl * 4 - sizeof(struct iphdr);
2146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		op = skb_header_pointer(skb, iphoff+sizeof(_iph),
2156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					optsize, _opt);
2166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (op == NULL) {
2176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "TRUNCATED");
2186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
2196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
2206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 127 "OPT (" 15*4*2chars ") " */
2226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "OPT (");
2236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		for (i = 0; i < optsize; i++)
2246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "%02X", op[i]);
2256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, ") ");
2266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
2276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	switch (ih->protocol) {
2296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_TCP:
2306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (dump_tcp_header(m, skb, ih->protocol,
2316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				    ntohs(ih->frag_off) & IP_OFFSET,
2326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				    iphoff+ih->ihl*4, logflags))
2336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
234417e02bf4280f001464ca55a36e9b3acad94eca4Richard Weinberger		break;
2356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_UDP:
2366939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_UDPLITE:
2376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (dump_udp_header(m, skb, ih->protocol,
2386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				    ntohs(ih->frag_off) & IP_OFFSET,
2396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				    iphoff+ih->ihl*4))
2406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
241417e02bf4280f001464ca55a36e9b3acad94eca4Richard Weinberger		break;
2426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_ICMP: {
2436939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		struct icmphdr _icmph;
2446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct icmphdr *ich;
2456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		static const size_t required_len[NR_ICMP_TYPES+1]
2466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			= { [ICMP_ECHOREPLY] = 4,
2476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_DEST_UNREACH]
2486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    = 8 + sizeof(struct iphdr),
2496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_SOURCE_QUENCH]
2506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    = 8 + sizeof(struct iphdr),
2516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_REDIRECT]
2526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    = 8 + sizeof(struct iphdr),
2536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_ECHO] = 4,
2546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_TIME_EXCEEDED]
2556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    = 8 + sizeof(struct iphdr),
2566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_PARAMETERPROB]
2576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    = 8 + sizeof(struct iphdr),
2586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_TIMESTAMP] = 20,
2596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_TIMESTAMPREPLY] = 20,
2606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_ADDRESS] = 12,
2616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    [ICMP_ADDRESSREPLY] = 12 };
2626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 11 "PROTO=ICMP " */
2646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PROTO=ICMP ");
2656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (ntohs(ih->frag_off) & IP_OFFSET)
2676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
2686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
2706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
2716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					 sizeof(_icmph), &_icmph);
2726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (ich == NULL) {
2736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "INCOMPLETE [%u bytes] ",
2746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       skb->len - iphoff - ih->ihl*4);
2756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
2766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
2776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 18 "TYPE=255 CODE=255 " */
2796939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code);
2806939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
2826939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (ich->type <= NR_ICMP_TYPES &&
2836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		    required_len[ich->type] &&
2846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		    skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
2856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "INCOMPLETE [%u bytes] ",
2866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       skb->len - iphoff - ih->ihl*4);
2876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
2886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
2896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		switch (ich->type) {
2916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMP_ECHOREPLY:
2926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMP_ECHO:
2936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 19 "ID=65535 SEQ=65535 " */
2946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "ID=%u SEQ=%u ",
2956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       ntohs(ich->un.echo.id),
2966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       ntohs(ich->un.echo.sequence));
2976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
2986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
2996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMP_PARAMETERPROB:
3006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 14 "PARAMETER=255 " */
3016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "PARAMETER=%u ",
3026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       ntohl(ich->un.gateway) >> 24);
3036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
3046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMP_REDIRECT:
3056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 24 "GATEWAY=255.255.255.255 " */
3066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway);
3076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Fall through */
3086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMP_DEST_UNREACH:
3096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMP_SOURCE_QUENCH:
3106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMP_TIME_EXCEEDED:
3116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 3+maxlen */
3126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (!iphoff) { /* Only recurse once. */
3136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "[");
3146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				dump_ipv4_packet(m, info, skb,
3156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					    iphoff + ih->ihl*4+sizeof(_icmph));
3166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "] ");
3176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			}
3186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 10 "MTU=65535 " */
3206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (ich->type == ICMP_DEST_UNREACH &&
3216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    ich->code == ICMP_FRAG_NEEDED)
3226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu));
3236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
3246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		break;
3256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
3266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max Length */
3276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_AH: {
3286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		struct ip_auth_hdr _ahdr;
3296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct ip_auth_hdr *ah;
3306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (ntohs(ih->frag_off) & IP_OFFSET)
3326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
3336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 9 "PROTO=AH " */
3356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PROTO=AH ");
3366939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
3386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
3396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					sizeof(_ahdr), &_ahdr);
3406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (ah == NULL) {
3416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "INCOMPLETE [%u bytes] ",
3426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       skb->len - iphoff - ih->ihl*4);
3436939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
3446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
3456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Length: 15 "SPI=0xF1234567 " */
3476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
3486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		break;
3496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
3506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_ESP: {
3516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		struct ip_esp_hdr _esph;
3526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct ip_esp_hdr *eh;
3536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 10 "PROTO=ESP " */
3556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PROTO=ESP ");
3566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (ntohs(ih->frag_off) & IP_OFFSET)
3586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
3596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
3616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
3626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					sizeof(_esph), &_esph);
3636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (eh == NULL) {
3646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "INCOMPLETE [%u bytes] ",
3656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       skb->len - iphoff - ih->ihl*4);
3666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
3676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
3686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Length: 15 "SPI=0xF1234567 " */
3706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "SPI=0x%x ", ntohl(eh->spi));
3716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		break;
3726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
3736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 10 "PROTO 255 " */
3746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	default:
3756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PROTO=%u ", ih->protocol);
3766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
3776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 15 "UID=4294967295 " */
3790626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet	if ((logflags & XT_LOG_UID) && !iphoff)
3800626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet		dump_sk_uid_gid(m, skb->sk);
3816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3826939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 16 "MARK=0xFFFFFFFF " */
3836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (!iphoff && skb->mark)
3846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "MARK=0x%x ", skb->mark);
3856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Proto    Max log string length */
3876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* IP:      40+46+6+11+127 = 230 */
3886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* TCP:     10+max(25,20+30+13+9+32+11+127) = 252 */
3896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* UDP:     10+max(25,20) = 35 */
3906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* UDPLITE: 14+max(25,20) = 39 */
3916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* ICMP:    11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
3926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* ESP:     10+max(25)+15 = 50 */
3936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* AH:      9+max(25)+15 = 49 */
3946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* unknown: 10 */
3956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
3966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* (ICMP allows recursion one level deep) */
3976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* maxlen =  IP + ICMP +  IP + max(TCP,UDP,ICMP,unknown) */
3986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* maxlen = 230+   91  + 230 + 252 = 803 */
3996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
4006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void dump_ipv4_mac_header(struct sbuff *m,
4026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    const struct nf_loginfo *info,
4036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    const struct sk_buff *skb)
4046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
4056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	struct net_device *dev = skb->dev;
4066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	unsigned int logflags = 0;
4076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (info->type == NF_LOG_TYPE_LOG)
4096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		logflags = info->u.log.logflags;
4106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (!(logflags & XT_LOG_MACDECODE))
4126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		goto fallback;
4136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	switch (dev->type) {
4156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case ARPHRD_ETHER:
4166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
4176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		       eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
4186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		       ntohs(eth_hdr(skb)->h_proto));
4196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return;
4206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	default:
4216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		break;
4226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
4236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerfallback:
4256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "MAC=");
4266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (dev->hard_header_len &&
4276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	    skb->mac_header != skb->network_header) {
4286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const unsigned char *p = skb_mac_header(skb);
4296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		unsigned int i;
4306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "%02x", *p++);
4326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		for (i = 1; i < dev->hard_header_len; i++, p++)
4336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, ":%02x", *p);
4346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
4356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, " ");
4366939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
4376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void
4396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerlog_packet_common(struct sbuff *m,
4406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		  u_int8_t pf,
4416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		  unsigned int hooknum,
4426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		  const struct sk_buff *skb,
4436939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		  const struct net_device *in,
4446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		  const struct net_device *out,
4456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		  const struct nf_loginfo *loginfo,
4466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		  const char *prefix)
4476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
44816af511a666827eaf5802144f09e2fb7b0942c99Joe Perches	sb_add(m, KERN_SOH "%c%sIN=%s OUT=%s ",
44916af511a666827eaf5802144f09e2fb7b0942c99Joe Perches	       '0' + loginfo->u.log.level, prefix,
4506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       in ? in->name : "",
4516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       out ? out->name : "");
4526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#ifdef CONFIG_BRIDGE_NETFILTER
4536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (skb->nf_bridge) {
4546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct net_device *physindev;
4556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct net_device *physoutdev;
4566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		physindev = skb->nf_bridge->physindev;
4586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (physindev && in != physindev)
4596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "PHYSIN=%s ", physindev->name);
4606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		physoutdev = skb->nf_bridge->physoutdev;
4616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (physoutdev && out != physoutdev)
4626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "PHYSOUT=%s ", physoutdev->name);
4636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
4646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#endif
4656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
4666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void
4698cdb46da06ea94543a3b2e53e3e92736421d1093Hans Schillstromipt_log_packet(struct net *net,
4708cdb46da06ea94543a3b2e53e3e92736421d1093Hans Schillstrom	       u_int8_t pf,
4716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       unsigned int hooknum,
4726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       const struct sk_buff *skb,
4736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       const struct net_device *in,
4746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       const struct net_device *out,
4756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       const struct nf_loginfo *loginfo,
4766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       const char *prefix)
4776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
47869b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	struct sbuff *m;
47969b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
48069b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	/* FIXME: Disabled from containers until syslog ns is supported */
48169b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	if (!net_eq(net, &init_net))
48269b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng		return;
48369b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
48469b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	m = sb_open();
4856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (!loginfo)
4876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		loginfo = &default_loginfo;
4886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	log_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix);
4906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (in != NULL)
4926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		dump_ipv4_mac_header(m, loginfo, skb);
4936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	dump_ipv4_packet(m, loginfo, skb, 0);
4956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
4966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_close(m);
4976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
4986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
499a0f65a267dd62aef4e003f833ea6290fd1e07b34Pablo Neira Ayuso#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
5006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger/* One level of recursion won't kill us */
5016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void dump_ipv6_packet(struct sbuff *m,
5026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			const struct nf_loginfo *info,
5036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			const struct sk_buff *skb, unsigned int ip6hoff,
5046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			int recurse)
5056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
5066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	u_int8_t currenthdr;
5076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	int fragment;
5086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	struct ipv6hdr _ip6h;
5096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	const struct ipv6hdr *ih;
5106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	unsigned int ptr;
5116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	unsigned int hdrlen = 0;
5126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	unsigned int logflags;
5136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (info->type == NF_LOG_TYPE_LOG)
5156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		logflags = info->u.log.logflags;
5166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	else
5176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		logflags = NF_LOG_MASK;
5186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
5206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (ih == NULL) {
5216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "TRUNCATED");
5226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return;
5236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
5246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
5266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
5276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
5296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
5306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
5316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
5326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       ih->hop_limit,
5336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	       (ntohl(*(__be32 *)ih) & 0x000fffff));
5346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	fragment = 0;
5366939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	ptr = ip6hoff + sizeof(struct ipv6hdr);
5376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	currenthdr = ih->nexthdr;
5386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
5396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		struct ipv6_opt_hdr _hdr;
5406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct ipv6_opt_hdr *hp;
5416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
5436939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (hp == NULL) {
5446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "TRUNCATED");
5456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
5466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
5476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 48 "OPT (...) " */
5496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (logflags & XT_LOG_IPOPT)
5506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "OPT ( ");
5516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		switch (currenthdr) {
5536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case IPPROTO_FRAGMENT: {
5546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			struct frag_hdr _fhdr;
5556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			const struct frag_hdr *fh;
5566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "FRAG:");
5586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
5596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger						&_fhdr);
5606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (fh == NULL) {
5616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "TRUNCATED ");
5626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				return;
5636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			}
5646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 6 "65535 " */
5666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8);
5676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 11 "INCOMPLETE " */
5696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (fh->frag_off & htons(0x0001))
5706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "INCOMPLETE ");
5716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "ID:%08x ", ntohl(fh->identification));
5736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (ntohs(fh->frag_off) & 0xFFF8)
5756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				fragment = 1;
5766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			hdrlen = 8;
5786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5796939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
5806939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
5816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case IPPROTO_DSTOPTS:
5826939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case IPPROTO_ROUTING:
5836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case IPPROTO_HOPOPTS:
5846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (fragment) {
5856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				if (logflags & XT_LOG_IPOPT)
5866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					sb_add(m, ")");
5876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				return;
5886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			}
5896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			hdrlen = ipv6_optlen(hp);
5906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
5916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max Length */
5926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case IPPROTO_AH:
5936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (logflags & XT_LOG_IPOPT) {
5946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				struct ip_auth_hdr _ahdr;
5956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				const struct ip_auth_hdr *ah;
5966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
5976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				/* Max length: 3 "AH " */
5986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "AH ");
5996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				if (fragment) {
6016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					sb_add(m, ")");
6026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					return;
6036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				}
6046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				ah = skb_header_pointer(skb, ptr, sizeof(_ahdr),
6066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger							&_ahdr);
6076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				if (ah == NULL) {
6086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					/*
6096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					 * Max length: 26 "INCOMPLETE [65535
6106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					 *  bytes] )"
6116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					 */
6126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					sb_add(m, "INCOMPLETE [%u bytes] )",
6136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					       skb->len - ptr);
6146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					return;
6156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				}
6166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				/* Length: 15 "SPI=0xF1234567 */
6186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
6196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			}
6216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			hdrlen = (hp->hdrlen+2)<<2;
6236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
6246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case IPPROTO_ESP:
6256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (logflags & XT_LOG_IPOPT) {
6266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				struct ip_esp_hdr _esph;
6276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				const struct ip_esp_hdr *eh;
6286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				/* Max length: 4 "ESP " */
6306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "ESP ");
6316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				if (fragment) {
6336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					sb_add(m, ")");
6346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					return;
6356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				}
6366939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				/*
6386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				 * Max length: 26 "INCOMPLETE [65535 bytes] )"
6396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				 */
6406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				eh = skb_header_pointer(skb, ptr, sizeof(_esph),
6416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger							&_esph);
6426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				if (eh == NULL) {
6436939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					sb_add(m, "INCOMPLETE [%u bytes] )",
6446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					       skb->len - ptr);
6456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					return;
6466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				}
6476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				/* Length: 16 "SPI=0xF1234567 )" */
6496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "SPI=0x%x )", ntohl(eh->spi));
6506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			}
6526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
6536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		default:
6546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 20 "Unknown Ext Hdr 255" */
6556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "Unknown Ext Hdr %u", currenthdr);
6566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
6576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
6586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (logflags & XT_LOG_IPOPT)
6596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, ") ");
6606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		currenthdr = hp->nexthdr;
6626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		ptr += hdrlen;
6636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
6646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	switch (currenthdr) {
6666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_TCP:
6676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (dump_tcp_header(m, skb, currenthdr, fragment, ptr,
6686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		    logflags))
6696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
670417e02bf4280f001464ca55a36e9b3acad94eca4Richard Weinberger		break;
6716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_UDP:
6726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_UDPLITE:
6736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (dump_udp_header(m, skb, currenthdr, fragment, ptr))
6746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
675417e02bf4280f001464ca55a36e9b3acad94eca4Richard Weinberger		break;
6766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case IPPROTO_ICMPV6: {
6776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		struct icmp6hdr _icmp6h;
6786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct icmp6hdr *ic;
6796939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6806939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 13 "PROTO=ICMPv6 " */
6816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PROTO=ICMPv6 ");
6826939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (fragment)
6846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
6856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
6876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
6886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (ic == NULL) {
6896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
6906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			return;
6916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
6926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		/* Max length: 18 "TYPE=255 CODE=255 " */
6946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
6956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
6966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		switch (ic->icmp6_type) {
6976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_ECHO_REQUEST:
6986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_ECHO_REPLY:
6996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 19 "ID=65535 SEQ=65535 " */
7006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "ID=%u SEQ=%u ",
7016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				ntohs(ic->icmp6_identifier),
7026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				ntohs(ic->icmp6_sequence));
7036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
7046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_MGM_QUERY:
7056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_MGM_REPORT:
7066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_MGM_REDUCTION:
7076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			break;
7086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_PARAMPROB:
7106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 17 "POINTER=ffffffff " */
7116939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer));
7126939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Fall through */
7136939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_DEST_UNREACH:
7146939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_PKT_TOOBIG:
7156939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		case ICMPV6_TIME_EXCEED:
7166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 3+maxlen */
7176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (recurse) {
7186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "[");
7196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				dump_ipv6_packet(m, info, skb,
7206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger					    ptr + sizeof(_icmp6h), 0);
7216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "] ");
7226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			}
7236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			/* Max length: 10 "MTU=65535 " */
7256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
7266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu));
7276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
7286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		break;
7296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
7306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 10 "PROTO=255 " */
7316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	default:
7326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "PROTO=%u ", currenthdr);
7336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
7346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 15 "UID=4294967295 " */
7360626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet	if ((logflags & XT_LOG_UID) && recurse)
7370626af3139572610b56376580d11eb65d45d9dd7Eric Dumazet		dump_sk_uid_gid(m, skb->sk);
7386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	/* Max length: 16 "MARK=0xFFFFFFFF " */
740d660164d79b67f879db35a7d61e47d3b99bc714eMichal Kubeček	if (recurse && skb->mark)
7416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "MARK=0x%x ", skb->mark);
7426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
7436939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void dump_ipv6_mac_header(struct sbuff *m,
7456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    const struct nf_loginfo *info,
7466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			    const struct sk_buff *skb)
7476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
7486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	struct net_device *dev = skb->dev;
7496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	unsigned int logflags = 0;
7506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (info->type == NF_LOG_TYPE_LOG)
7526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		logflags = info->u.log.logflags;
7536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (!(logflags & XT_LOG_MACDECODE))
7556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		goto fallback;
7566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	switch (dev->type) {
7586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	case ARPHRD_ETHER:
7596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
7606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		       eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
7616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		       ntohs(eth_hdr(skb)->h_proto));
7626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return;
7636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	default:
7646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		break;
7656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
7666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerfallback:
7686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_add(m, "MAC=");
7696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (dev->hard_header_len &&
7706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	    skb->mac_header != skb->network_header) {
7716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const unsigned char *p = skb_mac_header(skb);
7726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		unsigned int len = dev->hard_header_len;
7736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		unsigned int i;
7746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (dev->type == ARPHRD_SIT) {
7766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			p -= ETH_HLEN;
7776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			if (p < skb->head)
7796939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				p = NULL;
7806939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
7816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7826939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (p != NULL) {
7836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "%02x", *p++);
7846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			for (i = 1; i < len; i++)
7856939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				sb_add(m, ":%02x", *p++);
7866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
7876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, " ");
7886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		if (dev->type == ARPHRD_SIT) {
7906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			const struct iphdr *iph =
7916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				(struct iphdr *)skb_mac_header(skb);
7926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr,
7936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       &iph->daddr);
7946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		}
7956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	} else
7966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		sb_add(m, " ");
7976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
7986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
7996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void
8008cdb46da06ea94543a3b2e53e3e92736421d1093Hans Schillstromip6t_log_packet(struct net *net,
8018cdb46da06ea94543a3b2e53e3e92736421d1093Hans Schillstrom		u_int8_t pf,
8026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		unsigned int hooknum,
8036939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct sk_buff *skb,
8046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct net_device *in,
8056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct net_device *out,
8066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const struct nf_loginfo *loginfo,
8076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		const char *prefix)
8086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
80969b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	struct sbuff *m;
81069b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
81169b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	/* FIXME: Disabled from containers until syslog ns is supported */
81269b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	if (!net_eq(net, &init_net))
81369b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng		return;
81469b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
81569b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	m = sb_open();
8166939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8176939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (!loginfo)
8186939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		loginfo = &default_loginfo;
8196939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8206939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	log_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix);
8216939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8226939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (in != NULL)
8236939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		dump_ipv6_mac_header(m, loginfo, skb);
8246939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8256939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	dump_ipv6_packet(m, loginfo, skb, skb_network_offset(skb), 1);
8266939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8276939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	sb_close(m);
8286939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
8296939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#endif
8306939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8316939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic unsigned int
8326939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerlog_tg(struct sk_buff *skb, const struct xt_action_param *par)
8336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
8346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	const struct xt_log_info *loginfo = par->targinfo;
8356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	struct nf_loginfo li;
8368cdb46da06ea94543a3b2e53e3e92736421d1093Hans Schillstrom	struct net *net = dev_net(par->in ? par->in : par->out);
8376939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8386939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	li.type = NF_LOG_TYPE_LOG;
8396939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	li.u.log.level = loginfo->level;
8406939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	li.u.log.logflags = loginfo->logflags;
8416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (par->family == NFPROTO_IPV4)
8438cdb46da06ea94543a3b2e53e3e92736421d1093Hans Schillstrom		ipt_log_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in,
8446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger			       par->out, &li, loginfo->prefix);
845a0f65a267dd62aef4e003f833ea6290fd1e07b34Pablo Neira Ayuso#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
8466939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	else if (par->family == NFPROTO_IPV6)
8478cdb46da06ea94543a3b2e53e3e92736421d1093Hans Schillstrom		ip6t_log_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in,
8486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger				par->out, &li, loginfo->prefix);
8496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#endif
8506939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	else
8516939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		WARN_ON_ONCE(1);
8526939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8536939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	return XT_CONTINUE;
8546939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
8556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic int log_tg_check(const struct xt_tgchk_param *par)
8576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
8586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	const struct xt_log_info *loginfo = par->targinfo;
8596939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (par->family != NFPROTO_IPV4 && par->family != NFPROTO_IPV6)
8616939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return -EINVAL;
8626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (loginfo->level >= 8) {
8646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		pr_debug("level %u >= 8\n", loginfo->level);
8656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return -EINVAL;
8666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
8676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
8696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		pr_debug("prefix is not null-terminated\n");
8706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		return -EINVAL;
8716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	}
8726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	return 0;
8746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
8756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8766939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic struct xt_target log_tg_regs[] __read_mostly = {
8776939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	{
8786939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.name		= "LOG",
8796939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.family		= NFPROTO_IPV4,
8806939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.target		= log_tg,
8816939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.targetsize	= sizeof(struct xt_log_info),
8826939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.checkentry	= log_tg_check,
8836939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.me		= THIS_MODULE,
8846939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	},
885a0f65a267dd62aef4e003f833ea6290fd1e07b34Pablo Neira Ayuso#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
8866939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	{
8876939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.name		= "LOG",
8886939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.family		= NFPROTO_IPV6,
8896939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.target		= log_tg,
8906939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.targetsize	= sizeof(struct xt_log_info),
8916939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.checkentry	= log_tg_check,
8926939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger		.me		= THIS_MODULE,
8936939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	},
8946939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#endif
8956939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger};
8966939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
8976939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic struct nf_logger ipt_log_logger __read_mostly = {
8986939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	.name		= "ipt_LOG",
8996939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	.logfn		= &ipt_log_packet,
9006939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	.me		= THIS_MODULE,
9016939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger};
9026939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
903a0f65a267dd62aef4e003f833ea6290fd1e07b34Pablo Neira Ayuso#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
9046939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic struct nf_logger ip6t_log_logger __read_mostly = {
9056939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	.name		= "ip6t_LOG",
9066939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	.logfn		= &ip6t_log_packet,
9076939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	.me		= THIS_MODULE,
9086939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger};
9096939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#endif
9106939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
91169b34fb996b2eee3970548cf6eb516d3ecb5eeedGao fengstatic int __net_init log_net_init(struct net *net)
91269b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng{
91369b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	nf_log_set(net, NFPROTO_IPV4, &ipt_log_logger);
91469b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
91569b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	nf_log_set(net, NFPROTO_IPV6, &ip6t_log_logger);
91669b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng#endif
91769b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	return 0;
91869b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng}
91969b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
92069b34fb996b2eee3970548cf6eb516d3ecb5eeedGao fengstatic void __net_exit log_net_exit(struct net *net)
92169b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng{
92269b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	nf_log_unset(net, &ipt_log_logger);
92369b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
92469b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	nf_log_unset(net, &ip6t_log_logger);
92569b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng#endif
92669b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng}
92769b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
92869b34fb996b2eee3970548cf6eb516d3ecb5eeedGao fengstatic struct pernet_operations log_net_ops = {
92969b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	.init = log_net_init,
93069b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	.exit = log_net_exit,
93169b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng};
93269b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
9336939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic int __init log_tg_init(void)
9346939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
9356939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	int ret;
9366939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
93769b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	ret = register_pernet_subsys(&log_net_ops);
93869b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	if (ret < 0)
93969b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng		goto err_pernet;
94069b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
9416939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	ret = xt_register_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
9426939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	if (ret < 0)
94369b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng		goto err_target;
9446939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
9456939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
946a0f65a267dd62aef4e003f833ea6290fd1e07b34Pablo Neira Ayuso#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
9476939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	nf_log_register(NFPROTO_IPV6, &ip6t_log_logger);
9486939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#endif
9496939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	return 0;
95069b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng
95169b34fb996b2eee3970548cf6eb516d3ecb5eeedGao fengerr_target:
95269b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	unregister_pernet_subsys(&log_net_ops);
95369b34fb996b2eee3970548cf6eb516d3ecb5eeedGao fengerr_pernet:
95469b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	return ret;
9556939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
9566939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
9576939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergerstatic void __exit log_tg_exit(void)
9586939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger{
95969b34fb996b2eee3970548cf6eb516d3ecb5eeedGao feng	unregister_pernet_subsys(&log_net_ops);
9606939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	nf_log_unregister(&ipt_log_logger);
961a0f65a267dd62aef4e003f833ea6290fd1e07b34Pablo Neira Ayuso#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
9626939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	nf_log_unregister(&ip6t_log_logger);
9636939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger#endif
9646939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger	xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
9656939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger}
9666939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
9676939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergermodule_init(log_tg_init);
9686939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinbergermodule_exit(log_tg_exit);
9696939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard Weinberger
9706939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_LICENSE("GPL");
9716939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
9726939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
9736939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_DESCRIPTION("Xtables: IPv4/IPv6 packet logging");
9746939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_ALIAS("ipt_LOG");
9756939c33a757bd006c5e0b8b5fd429fc587a4d0f4Richard WeinbergerMODULE_ALIAS("ip6t_LOG");
976