nf_log_common.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. #include <linux/module.h>
  9. #include <linux/spinlock.h>
  10. #include <linux/skbuff.h>
  11. #include <linux/if_arp.h>
  12. #include <linux/ip.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_bridge.h>
  19. #include <linux/netfilter/xt_LOG.h>
  20. #include <net/netfilter/nf_log.h>
  21. int nf_log_dump_udp_header(struct nf_log_buf *m, const struct sk_buff *skb,
  22. u8 proto, int fragment, unsigned int offset)
  23. {
  24. struct udphdr _udph;
  25. const struct udphdr *uh;
  26. if (proto == IPPROTO_UDP)
  27. /* Max length: 10 "PROTO=UDP " */
  28. nf_log_buf_add(m, "PROTO=UDP ");
  29. else /* Max length: 14 "PROTO=UDPLITE " */
  30. nf_log_buf_add(m, "PROTO=UDPLITE ");
  31. if (fragment)
  32. goto out;
  33. /* Max length: 25 "INCOMPLETE [65535 bytes] " */
  34. uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
  35. if (uh == NULL) {
  36. nf_log_buf_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
  37. return 1;
  38. }
  39. /* Max length: 20 "SPT=65535 DPT=65535 " */
  40. nf_log_buf_add(m, "SPT=%u DPT=%u LEN=%u ",
  41. ntohs(uh->source), ntohs(uh->dest), ntohs(uh->len));
  42. out:
  43. return 0;
  44. }
  45. EXPORT_SYMBOL_GPL(nf_log_dump_udp_header);
  46. int nf_log_dump_tcp_header(struct nf_log_buf *m, const struct sk_buff *skb,
  47. u8 proto, int fragment, unsigned int offset,
  48. unsigned int logflags)
  49. {
  50. struct tcphdr _tcph;
  51. const struct tcphdr *th;
  52. /* Max length: 10 "PROTO=TCP " */
  53. nf_log_buf_add(m, "PROTO=TCP ");
  54. if (fragment)
  55. return 0;
  56. /* Max length: 25 "INCOMPLETE [65535 bytes] " */
  57. th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
  58. if (th == NULL) {
  59. nf_log_buf_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
  60. return 1;
  61. }
  62. /* Max length: 20 "SPT=65535 DPT=65535 " */
  63. nf_log_buf_add(m, "SPT=%u DPT=%u ",
  64. ntohs(th->source), ntohs(th->dest));
  65. /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
  66. if (logflags & XT_LOG_TCPSEQ) {
  67. nf_log_buf_add(m, "SEQ=%u ACK=%u ",
  68. ntohl(th->seq), ntohl(th->ack_seq));
  69. }
  70. /* Max length: 13 "WINDOW=65535 " */
  71. nf_log_buf_add(m, "WINDOW=%u ", ntohs(th->window));
  72. /* Max length: 9 "RES=0x3C " */
  73. nf_log_buf_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) &
  74. TCP_RESERVED_BITS) >> 22));
  75. /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
  76. if (th->cwr)
  77. nf_log_buf_add(m, "CWR ");
  78. if (th->ece)
  79. nf_log_buf_add(m, "ECE ");
  80. if (th->urg)
  81. nf_log_buf_add(m, "URG ");
  82. if (th->ack)
  83. nf_log_buf_add(m, "ACK ");
  84. if (th->psh)
  85. nf_log_buf_add(m, "PSH ");
  86. if (th->rst)
  87. nf_log_buf_add(m, "RST ");
  88. if (th->syn)
  89. nf_log_buf_add(m, "SYN ");
  90. if (th->fin)
  91. nf_log_buf_add(m, "FIN ");
  92. /* Max length: 11 "URGP=65535 " */
  93. nf_log_buf_add(m, "URGP=%u ", ntohs(th->urg_ptr));
  94. if ((logflags & XT_LOG_TCPOPT) && th->doff*4 > sizeof(struct tcphdr)) {
  95. u_int8_t _opt[60 - sizeof(struct tcphdr)];
  96. const u_int8_t *op;
  97. unsigned int i;
  98. unsigned int optsize = th->doff*4 - sizeof(struct tcphdr);
  99. op = skb_header_pointer(skb, offset + sizeof(struct tcphdr),
  100. optsize, _opt);
  101. if (op == NULL) {
  102. nf_log_buf_add(m, "OPT (TRUNCATED)");
  103. return 1;
  104. }
  105. /* Max length: 127 "OPT (" 15*4*2chars ") " */
  106. nf_log_buf_add(m, "OPT (");
  107. for (i = 0; i < optsize; i++)
  108. nf_log_buf_add(m, "%02X", op[i]);
  109. nf_log_buf_add(m, ") ");
  110. }
  111. return 0;
  112. }
  113. EXPORT_SYMBOL_GPL(nf_log_dump_tcp_header);
  114. void nf_log_dump_sk_uid_gid(struct nf_log_buf *m, struct sock *sk)
  115. {
  116. if (!sk || !sk_fullsock(sk))
  117. return;
  118. read_lock_bh(&sk->sk_callback_lock);
  119. if (sk->sk_socket && sk->sk_socket->file) {
  120. const struct cred *cred = sk->sk_socket->file->f_cred;
  121. nf_log_buf_add(m, "UID=%u GID=%u ",
  122. from_kuid_munged(&init_user_ns, cred->fsuid),
  123. from_kgid_munged(&init_user_ns, cred->fsgid));
  124. }
  125. read_unlock_bh(&sk->sk_callback_lock);
  126. }
  127. EXPORT_SYMBOL_GPL(nf_log_dump_sk_uid_gid);
  128. void
  129. nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
  130. unsigned int hooknum, const struct sk_buff *skb,
  131. const struct net_device *in,
  132. const struct net_device *out,
  133. const struct nf_loginfo *loginfo, const char *prefix)
  134. {
  135. nf_log_buf_add(m, KERN_SOH "%c%sIN=%s OUT=%s ",
  136. '0' + loginfo->u.log.level, prefix,
  137. in ? in->name : "",
  138. out ? out->name : "");
  139. #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
  140. if (skb->nf_bridge) {
  141. const struct net_device *physindev;
  142. const struct net_device *physoutdev;
  143. physindev = nf_bridge_get_physindev(skb);
  144. if (physindev && in != physindev)
  145. nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
  146. physoutdev = nf_bridge_get_physoutdev(skb);
  147. if (physoutdev && out != physoutdev)
  148. nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name);
  149. }
  150. #endif
  151. }
  152. EXPORT_SYMBOL_GPL(nf_log_dump_packet_common);
  153. static int __init nf_log_common_init(void)
  154. {
  155. return 0;
  156. }
  157. static void __exit nf_log_common_exit(void) {}
  158. module_init(nf_log_common_init);
  159. module_exit(nf_log_common_exit);
  160. MODULE_LICENSE("GPL");