nf_log_ipv4.c 10 KB

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