1/* 2 * This is a module which is used for logging packets. 3 */ 4 5/* (C) 2001 Jan Rekorajski <baggins@pld.org.pl> 6 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13#include <linux/module.h> 14#include <linux/skbuff.h> 15#include <linux/if_arp.h> 16#include <linux/ip.h> 17#include <linux/spinlock.h> 18#include <linux/icmpv6.h> 19#include <net/udp.h> 20#include <net/tcp.h> 21#include <net/ipv6.h> 22#include <linux/netfilter.h> 23#include <linux/netfilter/x_tables.h> 24#include <linux/netfilter_ipv6/ip6_tables.h> 25#include <net/netfilter/nf_log.h> 26 27MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>"); 28MODULE_DESCRIPTION("Xtables: IPv6 packet logging to syslog"); 29MODULE_LICENSE("GPL"); 30 31struct in_device; 32#include <net/route.h> 33#include <linux/netfilter_ipv6/ip6t_LOG.h> 34 35/* Use lock to serialize, so printks don't overlap */ 36static DEFINE_SPINLOCK(log_lock); 37 38/* One level of recursion won't kill us */ 39static void dump_packet(const struct nf_loginfo *info, 40 const struct sk_buff *skb, unsigned int ip6hoff, 41 int recurse) 42{ 43 u_int8_t currenthdr; 44 int fragment; 45 struct ipv6hdr _ip6h; 46 const struct ipv6hdr *ih; 47 unsigned int ptr; 48 unsigned int hdrlen = 0; 49 unsigned int logflags; 50 51 if (info->type == NF_LOG_TYPE_LOG) 52 logflags = info->u.log.logflags; 53 else 54 logflags = NF_LOG_MASK; 55 56 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); 57 if (ih == NULL) { 58 printk("TRUNCATED"); 59 return; 60 } 61 62 /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */ 63 printk("SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr); 64 65 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ 66 printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", 67 ntohs(ih->payload_len) + sizeof(struct ipv6hdr), 68 (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20, 69 ih->hop_limit, 70 (ntohl(*(__be32 *)ih) & 0x000fffff)); 71 72 fragment = 0; 73 ptr = ip6hoff + sizeof(struct ipv6hdr); 74 currenthdr = ih->nexthdr; 75 while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) { 76 struct ipv6_opt_hdr _hdr; 77 const struct ipv6_opt_hdr *hp; 78 79 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); 80 if (hp == NULL) { 81 printk("TRUNCATED"); 82 return; 83 } 84 85 /* Max length: 48 "OPT (...) " */ 86 if (logflags & IP6T_LOG_IPOPT) 87 printk("OPT ( "); 88 89 switch (currenthdr) { 90 case IPPROTO_FRAGMENT: { 91 struct frag_hdr _fhdr; 92 const struct frag_hdr *fh; 93 94 printk("FRAG:"); 95 fh = skb_header_pointer(skb, ptr, sizeof(_fhdr), 96 &_fhdr); 97 if (fh == NULL) { 98 printk("TRUNCATED "); 99 return; 100 } 101 102 /* Max length: 6 "65535 " */ 103 printk("%u ", ntohs(fh->frag_off) & 0xFFF8); 104 105 /* Max length: 11 "INCOMPLETE " */ 106 if (fh->frag_off & htons(0x0001)) 107 printk("INCOMPLETE "); 108 109 printk("ID:%08x ", ntohl(fh->identification)); 110 111 if (ntohs(fh->frag_off) & 0xFFF8) 112 fragment = 1; 113 114 hdrlen = 8; 115 116 break; 117 } 118 case IPPROTO_DSTOPTS: 119 case IPPROTO_ROUTING: 120 case IPPROTO_HOPOPTS: 121 if (fragment) { 122 if (logflags & IP6T_LOG_IPOPT) 123 printk(")"); 124 return; 125 } 126 hdrlen = ipv6_optlen(hp); 127 break; 128 /* Max Length */ 129 case IPPROTO_AH: 130 if (logflags & IP6T_LOG_IPOPT) { 131 struct ip_auth_hdr _ahdr; 132 const struct ip_auth_hdr *ah; 133 134 /* Max length: 3 "AH " */ 135 printk("AH "); 136 137 if (fragment) { 138 printk(")"); 139 return; 140 } 141 142 ah = skb_header_pointer(skb, ptr, sizeof(_ahdr), 143 &_ahdr); 144 if (ah == NULL) { 145 /* 146 * Max length: 26 "INCOMPLETE [65535 147 * bytes] )" 148 */ 149 printk("INCOMPLETE [%u bytes] )", 150 skb->len - ptr); 151 return; 152 } 153 154 /* Length: 15 "SPI=0xF1234567 */ 155 printk("SPI=0x%x ", ntohl(ah->spi)); 156 157 } 158 159 hdrlen = (hp->hdrlen+2)<<2; 160 break; 161 case IPPROTO_ESP: 162 if (logflags & IP6T_LOG_IPOPT) { 163 struct ip_esp_hdr _esph; 164 const struct ip_esp_hdr *eh; 165 166 /* Max length: 4 "ESP " */ 167 printk("ESP "); 168 169 if (fragment) { 170 printk(")"); 171 return; 172 } 173 174 /* 175 * Max length: 26 "INCOMPLETE [65535 bytes] )" 176 */ 177 eh = skb_header_pointer(skb, ptr, sizeof(_esph), 178 &_esph); 179 if (eh == NULL) { 180 printk("INCOMPLETE [%u bytes] )", 181 skb->len - ptr); 182 return; 183 } 184 185 /* Length: 16 "SPI=0xF1234567 )" */ 186 printk("SPI=0x%x )", ntohl(eh->spi) ); 187 188 } 189 return; 190 default: 191 /* Max length: 20 "Unknown Ext Hdr 255" */ 192 printk("Unknown Ext Hdr %u", currenthdr); 193 return; 194 } 195 if (logflags & IP6T_LOG_IPOPT) 196 printk(") "); 197 198 currenthdr = hp->nexthdr; 199 ptr += hdrlen; 200 } 201 202 switch (currenthdr) { 203 case IPPROTO_TCP: { 204 struct tcphdr _tcph; 205 const struct tcphdr *th; 206 207 /* Max length: 10 "PROTO=TCP " */ 208 printk("PROTO=TCP "); 209 210 if (fragment) 211 break; 212 213 /* Max length: 25 "INCOMPLETE [65535 bytes] " */ 214 th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph); 215 if (th == NULL) { 216 printk("INCOMPLETE [%u bytes] ", skb->len - ptr); 217 return; 218 } 219 220 /* Max length: 20 "SPT=65535 DPT=65535 " */ 221 printk("SPT=%u DPT=%u ", 222 ntohs(th->source), ntohs(th->dest)); 223 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ 224 if (logflags & IP6T_LOG_TCPSEQ) 225 printk("SEQ=%u ACK=%u ", 226 ntohl(th->seq), ntohl(th->ack_seq)); 227 /* Max length: 13 "WINDOW=65535 " */ 228 printk("WINDOW=%u ", ntohs(th->window)); 229 /* Max length: 9 "RES=0x3C " */ 230 printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); 231 /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ 232 if (th->cwr) 233 printk("CWR "); 234 if (th->ece) 235 printk("ECE "); 236 if (th->urg) 237 printk("URG "); 238 if (th->ack) 239 printk("ACK "); 240 if (th->psh) 241 printk("PSH "); 242 if (th->rst) 243 printk("RST "); 244 if (th->syn) 245 printk("SYN "); 246 if (th->fin) 247 printk("FIN "); 248 /* Max length: 11 "URGP=65535 " */ 249 printk("URGP=%u ", ntohs(th->urg_ptr)); 250 251 if ((logflags & IP6T_LOG_TCPOPT) && 252 th->doff * 4 > sizeof(struct tcphdr)) { 253 u_int8_t _opt[60 - sizeof(struct tcphdr)]; 254 const u_int8_t *op; 255 unsigned int i; 256 unsigned int optsize = th->doff * 4 257 - sizeof(struct tcphdr); 258 259 op = skb_header_pointer(skb, 260 ptr + sizeof(struct tcphdr), 261 optsize, _opt); 262 if (op == NULL) { 263 printk("OPT (TRUNCATED)"); 264 return; 265 } 266 267 /* Max length: 127 "OPT (" 15*4*2chars ") " */ 268 printk("OPT ("); 269 for (i =0; i < optsize; i++) 270 printk("%02X", op[i]); 271 printk(") "); 272 } 273 break; 274 } 275 case IPPROTO_UDP: 276 case IPPROTO_UDPLITE: { 277 struct udphdr _udph; 278 const struct udphdr *uh; 279 280 if (currenthdr == IPPROTO_UDP) 281 /* Max length: 10 "PROTO=UDP " */ 282 printk("PROTO=UDP " ); 283 else /* Max length: 14 "PROTO=UDPLITE " */ 284 printk("PROTO=UDPLITE "); 285 286 if (fragment) 287 break; 288 289 /* Max length: 25 "INCOMPLETE [65535 bytes] " */ 290 uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph); 291 if (uh == NULL) { 292 printk("INCOMPLETE [%u bytes] ", skb->len - ptr); 293 return; 294 } 295 296 /* Max length: 20 "SPT=65535 DPT=65535 " */ 297 printk("SPT=%u DPT=%u LEN=%u ", 298 ntohs(uh->source), ntohs(uh->dest), 299 ntohs(uh->len)); 300 break; 301 } 302 case IPPROTO_ICMPV6: { 303 struct icmp6hdr _icmp6h; 304 const struct icmp6hdr *ic; 305 306 /* Max length: 13 "PROTO=ICMPv6 " */ 307 printk("PROTO=ICMPv6 "); 308 309 if (fragment) 310 break; 311 312 /* Max length: 25 "INCOMPLETE [65535 bytes] " */ 313 ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h); 314 if (ic == NULL) { 315 printk("INCOMPLETE [%u bytes] ", skb->len - ptr); 316 return; 317 } 318 319 /* Max length: 18 "TYPE=255 CODE=255 " */ 320 printk("TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code); 321 322 switch (ic->icmp6_type) { 323 case ICMPV6_ECHO_REQUEST: 324 case ICMPV6_ECHO_REPLY: 325 /* Max length: 19 "ID=65535 SEQ=65535 " */ 326 printk("ID=%u SEQ=%u ", 327 ntohs(ic->icmp6_identifier), 328 ntohs(ic->icmp6_sequence)); 329 break; 330 case ICMPV6_MGM_QUERY: 331 case ICMPV6_MGM_REPORT: 332 case ICMPV6_MGM_REDUCTION: 333 break; 334 335 case ICMPV6_PARAMPROB: 336 /* Max length: 17 "POINTER=ffffffff " */ 337 printk("POINTER=%08x ", ntohl(ic->icmp6_pointer)); 338 /* Fall through */ 339 case ICMPV6_DEST_UNREACH: 340 case ICMPV6_PKT_TOOBIG: 341 case ICMPV6_TIME_EXCEED: 342 /* Max length: 3+maxlen */ 343 if (recurse) { 344 printk("["); 345 dump_packet(info, skb, ptr + sizeof(_icmp6h), 346 0); 347 printk("] "); 348 } 349 350 /* Max length: 10 "MTU=65535 " */ 351 if (ic->icmp6_type == ICMPV6_PKT_TOOBIG) 352 printk("MTU=%u ", ntohl(ic->icmp6_mtu)); 353 } 354 break; 355 } 356 /* Max length: 10 "PROTO=255 " */ 357 default: 358 printk("PROTO=%u ", currenthdr); 359 } 360 361 /* Max length: 15 "UID=4294967295 " */ 362 if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) { 363 read_lock_bh(&skb->sk->sk_callback_lock); 364 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 365 printk("UID=%u GID=%u ", 366 skb->sk->sk_socket->file->f_cred->fsuid, 367 skb->sk->sk_socket->file->f_cred->fsgid); 368 read_unlock_bh(&skb->sk->sk_callback_lock); 369 } 370 371 /* Max length: 16 "MARK=0xFFFFFFFF " */ 372 if (!recurse && skb->mark) 373 printk("MARK=0x%x ", skb->mark); 374} 375 376static void dump_mac_header(const struct nf_loginfo *info, 377 const struct sk_buff *skb) 378{ 379 struct net_device *dev = skb->dev; 380 unsigned int logflags = 0; 381 382 if (info->type == NF_LOG_TYPE_LOG) 383 logflags = info->u.log.logflags; 384 385 if (!(logflags & IP6T_LOG_MACDECODE)) 386 goto fallback; 387 388 switch (dev->type) { 389 case ARPHRD_ETHER: 390 printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ", 391 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, 392 ntohs(eth_hdr(skb)->h_proto)); 393 return; 394 default: 395 break; 396 } 397 398fallback: 399 printk("MAC="); 400 if (dev->hard_header_len && 401 skb->mac_header != skb->network_header) { 402 const unsigned char *p = skb_mac_header(skb); 403 unsigned int len = dev->hard_header_len; 404 unsigned int i; 405 406 if (dev->type == ARPHRD_SIT && 407 (p -= ETH_HLEN) < skb->head) 408 p = NULL; 409 410 if (p != NULL) { 411 printk("%02x", *p++); 412 for (i = 1; i < len; i++) 413 printk(":%02x", p[i]); 414 } 415 printk(" "); 416 417 if (dev->type == ARPHRD_SIT) { 418 const struct iphdr *iph = 419 (struct iphdr *)skb_mac_header(skb); 420 printk("TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr); 421 } 422 } else 423 printk(" "); 424} 425 426static struct nf_loginfo default_loginfo = { 427 .type = NF_LOG_TYPE_LOG, 428 .u = { 429 .log = { 430 .level = 5, 431 .logflags = NF_LOG_MASK, 432 }, 433 }, 434}; 435 436static void 437ip6t_log_packet(u_int8_t pf, 438 unsigned int hooknum, 439 const struct sk_buff *skb, 440 const struct net_device *in, 441 const struct net_device *out, 442 const struct nf_loginfo *loginfo, 443 const char *prefix) 444{ 445 if (!loginfo) 446 loginfo = &default_loginfo; 447 448 spin_lock_bh(&log_lock); 449 printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, 450 prefix, 451 in ? in->name : "", 452 out ? out->name : ""); 453 454 /* MAC logging for input path only. */ 455 if (in && !out) 456 dump_mac_header(loginfo, skb); 457 458 dump_packet(loginfo, skb, skb_network_offset(skb), 1); 459 printk("\n"); 460 spin_unlock_bh(&log_lock); 461} 462 463static unsigned int 464log_tg6(struct sk_buff *skb, const struct xt_action_param *par) 465{ 466 const struct ip6t_log_info *loginfo = par->targinfo; 467 struct nf_loginfo li; 468 469 li.type = NF_LOG_TYPE_LOG; 470 li.u.log.level = loginfo->level; 471 li.u.log.logflags = loginfo->logflags; 472 473 ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, par->out, 474 &li, loginfo->prefix); 475 return XT_CONTINUE; 476} 477 478 479static int log_tg6_check(const struct xt_tgchk_param *par) 480{ 481 const struct ip6t_log_info *loginfo = par->targinfo; 482 483 if (loginfo->level >= 8) { 484 pr_debug("level %u >= 8\n", loginfo->level); 485 return -EINVAL; 486 } 487 if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { 488 pr_debug("prefix not null-terminated\n"); 489 return -EINVAL; 490 } 491 return 0; 492} 493 494static struct xt_target log_tg6_reg __read_mostly = { 495 .name = "LOG", 496 .family = NFPROTO_IPV6, 497 .target = log_tg6, 498 .targetsize = sizeof(struct ip6t_log_info), 499 .checkentry = log_tg6_check, 500 .me = THIS_MODULE, 501}; 502 503static struct nf_logger ip6t_logger __read_mostly = { 504 .name = "ip6t_LOG", 505 .logfn = &ip6t_log_packet, 506 .me = THIS_MODULE, 507}; 508 509static int __init log_tg6_init(void) 510{ 511 int ret; 512 513 ret = xt_register_target(&log_tg6_reg); 514 if (ret < 0) 515 return ret; 516 nf_log_register(NFPROTO_IPV6, &ip6t_logger); 517 return 0; 518} 519 520static void __exit log_tg6_exit(void) 521{ 522 nf_log_unregister(&ip6t_logger); 523 xt_unregister_target(&log_tg6_reg); 524} 525 526module_init(log_tg6_init); 527module_exit(log_tg6_exit); 528