nf_log_ipv4.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* (C) 1999-2001 Paul `Rusty' Russell
  3. * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
  4. */
  5. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/spinlock.h>
  9. #include <linux/skbuff.h>
  10. #include <linux/if_arp.h>
  11. #include <linux/ip.h>
  12. #include <net/ipv6.h>
  13. #include <net/icmp.h>
  14. #include <net/udp.h>
  15. #include <net/tcp.h>
  16. #include <net/route.h>
  17. #include <linux/netfilter.h>
  18. #include <linux/netfilter/xt_LOG.h>
  19. #include <net/netfilter/nf_log.h>
  20. static const struct nf_loginfo default_loginfo = {
  21. .type = NF_LOG_TYPE_LOG,
  22. .u = {
  23. .log = {
  24. .level = LOGLEVEL_NOTICE,
  25. .logflags = NF_LOG_DEFAULT_MASK,
  26. },
  27. },
  28. };
  29. /* One level of recursion won't kill us */
  30. static void dump_ipv4_packet(struct net *net, struct nf_log_buf *m,
  31. const struct nf_loginfo *info,
  32. const struct sk_buff *skb, unsigned int iphoff)
  33. {
  34. struct iphdr _iph;
  35. const struct iphdr *ih;
  36. unsigned int logflags;
  37. if (info->type == NF_LOG_TYPE_LOG)
  38. logflags = info->u.log.logflags;
  39. else
  40. logflags = NF_LOG_DEFAULT_MASK;
  41. ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
  42. if (ih == NULL) {
  43. nf_log_buf_add(m, "TRUNCATED");
  44. return;
  45. }
  46. /* Important fields:
  47. * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
  48. /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
  49. nf_log_buf_add(m, "SRC=%pI4 DST=%pI4 ", &ih->saddr, &ih->daddr);
  50. /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
  51. nf_log_buf_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
  52. ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
  53. ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
  54. /* Max length: 6 "CE DF MF " */
  55. if (ntohs(ih->frag_off) & IP_CE)
  56. nf_log_buf_add(m, "CE ");
  57. if (ntohs(ih->frag_off) & IP_DF)
  58. nf_log_buf_add(m, "DF ");
  59. if (ntohs(ih->frag_off) & IP_MF)
  60. nf_log_buf_add(m, "MF ");
  61. /* Max length: 11 "FRAG:65535 " */
  62. if (ntohs(ih->frag_off) & IP_OFFSET)
  63. nf_log_buf_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
  64. if ((logflags & NF_LOG_IPOPT) &&
  65. ih->ihl * 4 > sizeof(struct iphdr)) {
  66. const unsigned char *op;
  67. unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
  68. unsigned int i, optsize;
  69. optsize = ih->ihl * 4 - sizeof(struct iphdr);
  70. op = skb_header_pointer(skb, iphoff+sizeof(_iph),
  71. optsize, _opt);
  72. if (op == NULL) {
  73. nf_log_buf_add(m, "TRUNCATED");
  74. return;
  75. }
  76. /* Max length: 127 "OPT (" 15*4*2chars ") " */
  77. nf_log_buf_add(m, "OPT (");
  78. for (i = 0; i < optsize; i++)
  79. nf_log_buf_add(m, "%02X", op[i]);
  80. nf_log_buf_add(m, ") ");
  81. }
  82. switch (ih->protocol) {
  83. case IPPROTO_TCP:
  84. if (nf_log_dump_tcp_header(m, skb, ih->protocol,
  85. ntohs(ih->frag_off) & IP_OFFSET,
  86. iphoff+ih->ihl*4, logflags))
  87. return;
  88. break;
  89. case IPPROTO_UDP:
  90. case IPPROTO_UDPLITE:
  91. if (nf_log_dump_udp_header(m, skb, ih->protocol,
  92. ntohs(ih->frag_off) & IP_OFFSET,
  93. iphoff+ih->ihl*4))
  94. return;
  95. break;
  96. case IPPROTO_ICMP: {
  97. struct icmphdr _icmph;
  98. const struct icmphdr *ich;
  99. static const size_t required_len[NR_ICMP_TYPES+1]
  100. = { [ICMP_ECHOREPLY] = 4,
  101. [ICMP_DEST_UNREACH]
  102. = 8 + sizeof(struct iphdr),
  103. [ICMP_SOURCE_QUENCH]
  104. = 8 + sizeof(struct iphdr),
  105. [ICMP_REDIRECT]
  106. = 8 + sizeof(struct iphdr),
  107. [ICMP_ECHO] = 4,
  108. [ICMP_TIME_EXCEEDED]
  109. = 8 + sizeof(struct iphdr),
  110. [ICMP_PARAMETERPROB]
  111. = 8 + sizeof(struct iphdr),
  112. [ICMP_TIMESTAMP] = 20,
  113. [ICMP_TIMESTAMPREPLY] = 20,
  114. [ICMP_ADDRESS] = 12,
  115. [ICMP_ADDRESSREPLY] = 12 };
  116. /* Max length: 11 "PROTO=ICMP " */
  117. nf_log_buf_add(m, "PROTO=ICMP ");
  118. if (ntohs(ih->frag_off) & IP_OFFSET)
  119. break;
  120. /* Max length: 25 "INCOMPLETE [65535 bytes] " */
  121. ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
  122. sizeof(_icmph), &_icmph);
  123. if (ich == NULL) {
  124. nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
  125. skb->len - iphoff - ih->ihl*4);
  126. break;
  127. }
  128. /* Max length: 18 "TYPE=255 CODE=255 " */
  129. nf_log_buf_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code);
  130. /* Max length: 25 "INCOMPLETE [65535 bytes] " */
  131. if (ich->type <= NR_ICMP_TYPES &&
  132. required_len[ich->type] &&
  133. skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
  134. nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
  135. skb->len - iphoff - ih->ihl*4);
  136. break;
  137. }
  138. switch (ich->type) {
  139. case ICMP_ECHOREPLY:
  140. case ICMP_ECHO:
  141. /* Max length: 19 "ID=65535 SEQ=65535 " */
  142. nf_log_buf_add(m, "ID=%u SEQ=%u ",
  143. ntohs(ich->un.echo.id),
  144. ntohs(ich->un.echo.sequence));
  145. break;
  146. case ICMP_PARAMETERPROB:
  147. /* Max length: 14 "PARAMETER=255 " */
  148. nf_log_buf_add(m, "PARAMETER=%u ",
  149. ntohl(ich->un.gateway) >> 24);
  150. break;
  151. case ICMP_REDIRECT:
  152. /* Max length: 24 "GATEWAY=255.255.255.255 " */
  153. nf_log_buf_add(m, "GATEWAY=%pI4 ", &ich->un.gateway);
  154. fallthrough;
  155. case ICMP_DEST_UNREACH:
  156. case ICMP_SOURCE_QUENCH:
  157. case ICMP_TIME_EXCEEDED:
  158. /* Max length: 3+maxlen */
  159. if (!iphoff) { /* Only recurse once. */
  160. nf_log_buf_add(m, "[");
  161. dump_ipv4_packet(net, m, info, skb,
  162. iphoff + ih->ihl*4+sizeof(_icmph));
  163. nf_log_buf_add(m, "] ");
  164. }
  165. /* Max length: 10 "MTU=65535 " */
  166. if (ich->type == ICMP_DEST_UNREACH &&
  167. ich->code == ICMP_FRAG_NEEDED) {
  168. nf_log_buf_add(m, "MTU=%u ",
  169. ntohs(ich->un.frag.mtu));
  170. }
  171. }
  172. break;
  173. }
  174. /* Max Length */
  175. case IPPROTO_AH: {
  176. struct ip_auth_hdr _ahdr;
  177. const struct ip_auth_hdr *ah;
  178. if (ntohs(ih->frag_off) & IP_OFFSET)
  179. break;
  180. /* Max length: 9 "PROTO=AH " */
  181. nf_log_buf_add(m, "PROTO=AH ");
  182. /* Max length: 25 "INCOMPLETE [65535 bytes] " */
  183. ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
  184. sizeof(_ahdr), &_ahdr);
  185. if (ah == NULL) {
  186. nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
  187. skb->len - iphoff - ih->ihl*4);
  188. break;
  189. }
  190. /* Length: 15 "SPI=0xF1234567 " */
  191. nf_log_buf_add(m, "SPI=0x%x ", ntohl(ah->spi));
  192. break;
  193. }
  194. case IPPROTO_ESP: {
  195. struct ip_esp_hdr _esph;
  196. const struct ip_esp_hdr *eh;
  197. /* Max length: 10 "PROTO=ESP " */
  198. nf_log_buf_add(m, "PROTO=ESP ");
  199. if (ntohs(ih->frag_off) & IP_OFFSET)
  200. break;
  201. /* Max length: 25 "INCOMPLETE [65535 bytes] " */
  202. eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
  203. sizeof(_esph), &_esph);
  204. if (eh == NULL) {
  205. nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
  206. skb->len - iphoff - ih->ihl*4);
  207. break;
  208. }
  209. /* Length: 15 "SPI=0xF1234567 " */
  210. nf_log_buf_add(m, "SPI=0x%x ", ntohl(eh->spi));
  211. break;
  212. }
  213. /* Max length: 10 "PROTO 255 " */
  214. default:
  215. nf_log_buf_add(m, "PROTO=%u ", ih->protocol);
  216. }
  217. /* Max length: 15 "UID=4294967295 " */
  218. if ((logflags & NF_LOG_UID) && !iphoff)
  219. nf_log_dump_sk_uid_gid(net, m, skb->sk);
  220. /* Max length: 16 "MARK=0xFFFFFFFF " */
  221. if (!iphoff && skb->mark)
  222. nf_log_buf_add(m, "MARK=0x%x ", skb->mark);
  223. /* Proto Max log string length */
  224. /* IP: 40+46+6+11+127 = 230 */
  225. /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */
  226. /* UDP: 10+max(25,20) = 35 */
  227. /* UDPLITE: 14+max(25,20) = 39 */
  228. /* ICMP: 11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
  229. /* ESP: 10+max(25)+15 = 50 */
  230. /* AH: 9+max(25)+15 = 49 */
  231. /* unknown: 10 */
  232. /* (ICMP allows recursion one level deep) */
  233. /* maxlen = IP + ICMP + IP + max(TCP,UDP,ICMP,unknown) */
  234. /* maxlen = 230+ 91 + 230 + 252 = 803 */
  235. }
  236. static void dump_ipv4_mac_header(struct nf_log_buf *m,
  237. const struct nf_loginfo *info,
  238. const struct sk_buff *skb)
  239. {
  240. struct net_device *dev = skb->dev;
  241. unsigned int logflags = 0;
  242. if (info->type == NF_LOG_TYPE_LOG)
  243. logflags = info->u.log.logflags;
  244. if (!(logflags & NF_LOG_MACDECODE))
  245. goto fallback;
  246. switch (dev->type) {
  247. case ARPHRD_ETHER:
  248. nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
  249. eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
  250. nf_log_dump_vlan(m, skb);
  251. nf_log_buf_add(m, "MACPROTO=%04x ",
  252. ntohs(eth_hdr(skb)->h_proto));
  253. return;
  254. default:
  255. break;
  256. }
  257. fallback:
  258. nf_log_buf_add(m, "MAC=");
  259. if (dev->hard_header_len &&
  260. skb->mac_header != skb->network_header) {
  261. const unsigned char *p = skb_mac_header(skb);
  262. unsigned int i;
  263. nf_log_buf_add(m, "%02x", *p++);
  264. for (i = 1; i < dev->hard_header_len; i++, p++)
  265. nf_log_buf_add(m, ":%02x", *p);
  266. }
  267. nf_log_buf_add(m, " ");
  268. }
  269. static void nf_log_ip_packet(struct net *net, u_int8_t pf,
  270. unsigned int hooknum, const struct sk_buff *skb,
  271. const struct net_device *in,
  272. const struct net_device *out,
  273. const struct nf_loginfo *loginfo,
  274. const char *prefix)
  275. {
  276. struct nf_log_buf *m;
  277. /* FIXME: Disabled from containers until syslog ns is supported */
  278. if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
  279. return;
  280. m = nf_log_buf_open();
  281. if (!loginfo)
  282. loginfo = &default_loginfo;
  283. nf_log_dump_packet_common(m, pf, hooknum, skb, in,
  284. out, loginfo, prefix);
  285. if (in != NULL)
  286. dump_ipv4_mac_header(m, loginfo, skb);
  287. dump_ipv4_packet(net, m, loginfo, skb, 0);
  288. nf_log_buf_close(m);
  289. }
  290. static struct nf_logger nf_ip_logger __read_mostly = {
  291. .name = "nf_log_ipv4",
  292. .type = NF_LOG_TYPE_LOG,
  293. .logfn = nf_log_ip_packet,
  294. .me = THIS_MODULE,
  295. };
  296. static int __net_init nf_log_ipv4_net_init(struct net *net)
  297. {
  298. return nf_log_set(net, NFPROTO_IPV4, &nf_ip_logger);
  299. }
  300. static void __net_exit nf_log_ipv4_net_exit(struct net *net)
  301. {
  302. nf_log_unset(net, &nf_ip_logger);
  303. }
  304. static struct pernet_operations nf_log_ipv4_net_ops = {
  305. .init = nf_log_ipv4_net_init,
  306. .exit = nf_log_ipv4_net_exit,
  307. };
  308. static int __init nf_log_ipv4_init(void)
  309. {
  310. int ret;
  311. ret = register_pernet_subsys(&nf_log_ipv4_net_ops);
  312. if (ret < 0)
  313. return ret;
  314. ret = nf_log_register(NFPROTO_IPV4, &nf_ip_logger);
  315. if (ret < 0) {
  316. pr_err("failed to register logger\n");
  317. goto err1;
  318. }
  319. return 0;
  320. err1:
  321. unregister_pernet_subsys(&nf_log_ipv4_net_ops);
  322. return ret;
  323. }
  324. static void __exit nf_log_ipv4_exit(void)
  325. {
  326. unregister_pernet_subsys(&nf_log_ipv4_net_ops);
  327. nf_log_unregister(&nf_ip_logger);
  328. }
  329. module_init(nf_log_ipv4_init);
  330. module_exit(nf_log_ipv4_exit);
  331. MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
  332. MODULE_DESCRIPTION("Netfilter IPv4 packet logging");
  333. MODULE_LICENSE("GPL");
  334. MODULE_ALIAS_NF_LOGGER(AF_INET, 0);