~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/netfilter/xt_LOG.c

Version: ~ [ linux-5.15-rc5 ] ~ [ linux-5.14.11 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.72 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.152 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.210 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.250 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.286 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.288 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * This is a module which is used for logging packets.
  3  */
  4 
  5 /* (C) 1999-2001 Paul `Rusty' Russell
  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 
 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 14 #include <linux/module.h>
 15 #include <linux/spinlock.h>
 16 #include <linux/skbuff.h>
 17 #include <linux/if_arp.h>
 18 #include <linux/ip.h>
 19 #include <net/ipv6.h>
 20 #include <net/icmp.h>
 21 #include <net/udp.h>
 22 #include <net/tcp.h>
 23 #include <net/route.h>
 24 
 25 #include <linux/netfilter.h>
 26 #include <linux/netfilter/x_tables.h>
 27 #include <linux/netfilter/xt_LOG.h>
 28 #include <linux/netfilter_ipv6/ip6_tables.h>
 29 #include <net/netfilter/nf_log.h>
 30 #include <net/netfilter/xt_log.h>
 31 
 32 static struct nf_loginfo default_loginfo = {
 33         .type   = NF_LOG_TYPE_LOG,
 34         .u = {
 35                 .log = {
 36                         .level    = 5,
 37                         .logflags = NF_LOG_MASK,
 38                 },
 39         },
 40 };
 41 
 42 static int dump_udp_header(struct sbuff *m, const struct sk_buff *skb,
 43                            u8 proto, int fragment, unsigned int offset)
 44 {
 45         struct udphdr _udph;
 46         const struct udphdr *uh;
 47 
 48         if (proto == IPPROTO_UDP)
 49                 /* Max length: 10 "PROTO=UDP "     */
 50                 sb_add(m, "PROTO=UDP ");
 51         else    /* Max length: 14 "PROTO=UDPLITE " */
 52                 sb_add(m, "PROTO=UDPLITE ");
 53 
 54         if (fragment)
 55                 goto out;
 56 
 57         /* Max length: 25 "INCOMPLETE [65535 bytes] " */
 58         uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
 59         if (uh == NULL) {
 60                 sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
 61 
 62                 return 1;
 63         }
 64 
 65         /* Max length: 20 "SPT=65535 DPT=65535 " */
 66         sb_add(m, "SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest),
 67                 ntohs(uh->len));
 68 
 69 out:
 70         return 0;
 71 }
 72 
 73 static int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb,
 74                            u8 proto, int fragment, unsigned int offset,
 75                            unsigned int logflags)
 76 {
 77         struct tcphdr _tcph;
 78         const struct tcphdr *th;
 79 
 80         /* Max length: 10 "PROTO=TCP " */
 81         sb_add(m, "PROTO=TCP ");
 82 
 83         if (fragment)
 84                 return 0;
 85 
 86         /* Max length: 25 "INCOMPLETE [65535 bytes] " */
 87         th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
 88         if (th == NULL) {
 89                 sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
 90                 return 1;
 91         }
 92 
 93         /* Max length: 20 "SPT=65535 DPT=65535 " */
 94         sb_add(m, "SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest));
 95         /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
 96         if (logflags & XT_LOG_TCPSEQ)
 97                 sb_add(m, "SEQ=%u ACK=%u ", ntohl(th->seq), ntohl(th->ack_seq));
 98 
 99         /* Max length: 13 "WINDOW=65535 " */
100         sb_add(m, "WINDOW=%u ", ntohs(th->window));
101         /* Max length: 9 "RES=0x3C " */
102         sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) &
103                                             TCP_RESERVED_BITS) >> 22));
104         /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
105         if (th->cwr)
106                 sb_add(m, "CWR ");
107         if (th->ece)
108                 sb_add(m, "ECE ");
109         if (th->urg)
110                 sb_add(m, "URG ");
111         if (th->ack)
112                 sb_add(m, "ACK ");
113         if (th->psh)
114                 sb_add(m, "PSH ");
115         if (th->rst)
116                 sb_add(m, "RST ");
117         if (th->syn)
118                 sb_add(m, "SYN ");
119         if (th->fin)
120                 sb_add(m, "FIN ");
121         /* Max length: 11 "URGP=65535 " */
122         sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
123 
124         if ((logflags & XT_LOG_TCPOPT) && th->doff*4 > sizeof(struct tcphdr)) {
125                 u_int8_t _opt[60 - sizeof(struct tcphdr)];
126                 const u_int8_t *op;
127                 unsigned int i;
128                 unsigned int optsize = th->doff*4 - sizeof(struct tcphdr);
129 
130                 op = skb_header_pointer(skb, offset + sizeof(struct tcphdr),
131                                         optsize, _opt);
132                 if (op == NULL) {
133                         sb_add(m, "OPT (TRUNCATED)");
134                         return 1;
135                 }
136 
137                 /* Max length: 127 "OPT (" 15*4*2chars ") " */
138                 sb_add(m, "OPT (");
139                 for (i = 0; i < optsize; i++)
140                         sb_add(m, "%02X", op[i]);
141 
142                 sb_add(m, ") ");
143         }
144 
145         return 0;
146 }
147 
148 static void dump_sk_uid_gid(struct sbuff *m, struct sock *sk)
149 {
150         if (!sk || sk->sk_state == TCP_TIME_WAIT)
151                 return;
152 
153         read_lock_bh(&sk->sk_callback_lock);
154         if (sk->sk_socket && sk->sk_socket->file) {
155                 const struct cred *cred = sk->sk_socket->file->f_cred;
156                 sb_add(m, "UID=%u GID=%u ",
157                         from_kuid_munged(&init_user_ns, cred->fsuid),
158                         from_kgid_munged(&init_user_ns, cred->fsgid));
159         }
160         read_unlock_bh(&sk->sk_callback_lock);
161 }
162 
163 /* One level of recursion won't kill us */
164 static void dump_ipv4_packet(struct sbuff *m,
165                         const struct nf_loginfo *info,
166                         const struct sk_buff *skb,
167                         unsigned int iphoff)
168 {
169         struct iphdr _iph;
170         const struct iphdr *ih;
171         unsigned int logflags;
172 
173         if (info->type == NF_LOG_TYPE_LOG)
174                 logflags = info->u.log.logflags;
175         else
176                 logflags = NF_LOG_MASK;
177 
178         ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
179         if (ih == NULL) {
180                 sb_add(m, "TRUNCATED");
181                 return;
182         }
183 
184         /* Important fields:
185          * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
186         /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
187         sb_add(m, "SRC=%pI4 DST=%pI4 ",
188                &ih->saddr, &ih->daddr);
189 
190         /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
191         sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
192                ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
193                ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
194 
195         /* Max length: 6 "CE DF MF " */
196         if (ntohs(ih->frag_off) & IP_CE)
197                 sb_add(m, "CE ");
198         if (ntohs(ih->frag_off) & IP_DF)
199                 sb_add(m, "DF ");
200         if (ntohs(ih->frag_off) & IP_MF)
201                 sb_add(m, "MF ");
202 
203         /* Max length: 11 "FRAG:65535 " */
204         if (ntohs(ih->frag_off) & IP_OFFSET)
205                 sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
206 
207         if ((logflags & XT_LOG_IPOPT) &&
208             ih->ihl * 4 > sizeof(struct iphdr)) {
209                 const unsigned char *op;
210                 unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
211                 unsigned int i, optsize;
212 
213                 optsize = ih->ihl * 4 - sizeof(struct iphdr);
214                 op = skb_header_pointer(skb, iphoff+sizeof(_iph),
215                                         optsize, _opt);
216                 if (op == NULL) {
217                         sb_add(m, "TRUNCATED");
218                         return;
219                 }
220 
221                 /* Max length: 127 "OPT (" 15*4*2chars ") " */
222                 sb_add(m, "OPT (");
223                 for (i = 0; i < optsize; i++)
224                         sb_add(m, "%02X", op[i]);
225                 sb_add(m, ") ");
226         }
227 
228         switch (ih->protocol) {
229         case IPPROTO_TCP:
230                 if (dump_tcp_header(m, skb, ih->protocol,
231                                     ntohs(ih->frag_off) & IP_OFFSET,
232                                     iphoff+ih->ihl*4, logflags))
233                         return;
234                 break;
235         case IPPROTO_UDP:
236         case IPPROTO_UDPLITE:
237                 if (dump_udp_header(m, skb, ih->protocol,
238                                     ntohs(ih->frag_off) & IP_OFFSET,
239                                     iphoff+ih->ihl*4))
240                         return;
241                 break;
242         case IPPROTO_ICMP: {
243                 struct icmphdr _icmph;
244                 const struct icmphdr *ich;
245                 static const size_t required_len[NR_ICMP_TYPES+1]
246                         = { [ICMP_ECHOREPLY] = 4,
247                             [ICMP_DEST_UNREACH]
248                             = 8 + sizeof(struct iphdr),
249                             [ICMP_SOURCE_QUENCH]
250                             = 8 + sizeof(struct iphdr),
251                             [ICMP_REDIRECT]
252                             = 8 + sizeof(struct iphdr),
253                             [ICMP_ECHO] = 4,
254                             [ICMP_TIME_EXCEEDED]
255                             = 8 + sizeof(struct iphdr),
256                             [ICMP_PARAMETERPROB]
257                             = 8 + sizeof(struct iphdr),
258                             [ICMP_TIMESTAMP] = 20,
259                             [ICMP_TIMESTAMPREPLY] = 20,
260                             [ICMP_ADDRESS] = 12,
261                             [ICMP_ADDRESSREPLY] = 12 };
262 
263                 /* Max length: 11 "PROTO=ICMP " */
264                 sb_add(m, "PROTO=ICMP ");
265 
266                 if (ntohs(ih->frag_off) & IP_OFFSET)
267                         break;
268 
269                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
270                 ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
271                                          sizeof(_icmph), &_icmph);
272                 if (ich == NULL) {
273                         sb_add(m, "INCOMPLETE [%u bytes] ",
274                                skb->len - iphoff - ih->ihl*4);
275                         break;
276                 }
277 
278                 /* Max length: 18 "TYPE=255 CODE=255 " */
279                 sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code);
280 
281                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
282                 if (ich->type <= NR_ICMP_TYPES &&
283                     required_len[ich->type] &&
284                     skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
285                         sb_add(m, "INCOMPLETE [%u bytes] ",
286                                skb->len - iphoff - ih->ihl*4);
287                         break;
288                 }
289 
290                 switch (ich->type) {
291                 case ICMP_ECHOREPLY:
292                 case ICMP_ECHO:
293                         /* Max length: 19 "ID=65535 SEQ=65535 " */
294                         sb_add(m, "ID=%u SEQ=%u ",
295                                ntohs(ich->un.echo.id),
296                                ntohs(ich->un.echo.sequence));
297                         break;
298 
299                 case ICMP_PARAMETERPROB:
300                         /* Max length: 14 "PARAMETER=255 " */
301                         sb_add(m, "PARAMETER=%u ",
302                                ntohl(ich->un.gateway) >> 24);
303                         break;
304                 case ICMP_REDIRECT:
305                         /* Max length: 24 "GATEWAY=255.255.255.255 " */
306                         sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway);
307                         /* Fall through */
308                 case ICMP_DEST_UNREACH:
309                 case ICMP_SOURCE_QUENCH:
310                 case ICMP_TIME_EXCEEDED:
311                         /* Max length: 3+maxlen */
312                         if (!iphoff) { /* Only recurse once. */
313                                 sb_add(m, "[");
314                                 dump_ipv4_packet(m, info, skb,
315                                             iphoff + ih->ihl*4+sizeof(_icmph));
316                                 sb_add(m, "] ");
317                         }
318 
319                         /* Max length: 10 "MTU=65535 " */
320                         if (ich->type == ICMP_DEST_UNREACH &&
321                             ich->code == ICMP_FRAG_NEEDED)
322                                 sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu));
323                 }
324                 break;
325         }
326         /* Max Length */
327         case IPPROTO_AH: {
328                 struct ip_auth_hdr _ahdr;
329                 const struct ip_auth_hdr *ah;
330 
331                 if (ntohs(ih->frag_off) & IP_OFFSET)
332                         break;
333 
334                 /* Max length: 9 "PROTO=AH " */
335                 sb_add(m, "PROTO=AH ");
336 
337                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
338                 ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
339                                         sizeof(_ahdr), &_ahdr);
340                 if (ah == NULL) {
341                         sb_add(m, "INCOMPLETE [%u bytes] ",
342                                skb->len - iphoff - ih->ihl*4);
343                         break;
344                 }
345 
346                 /* Length: 15 "SPI=0xF1234567 " */
347                 sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
348                 break;
349         }
350         case IPPROTO_ESP: {
351                 struct ip_esp_hdr _esph;
352                 const struct ip_esp_hdr *eh;
353 
354                 /* Max length: 10 "PROTO=ESP " */
355                 sb_add(m, "PROTO=ESP ");
356 
357                 if (ntohs(ih->frag_off) & IP_OFFSET)
358                         break;
359 
360                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
361                 eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
362                                         sizeof(_esph), &_esph);
363                 if (eh == NULL) {
364                         sb_add(m, "INCOMPLETE [%u bytes] ",
365                                skb->len - iphoff - ih->ihl*4);
366                         break;
367                 }
368 
369                 /* Length: 15 "SPI=0xF1234567 " */
370                 sb_add(m, "SPI=0x%x ", ntohl(eh->spi));
371                 break;
372         }
373         /* Max length: 10 "PROTO 255 " */
374         default:
375                 sb_add(m, "PROTO=%u ", ih->protocol);
376         }
377 
378         /* Max length: 15 "UID=4294967295 " */
379         if ((logflags & XT_LOG_UID) && !iphoff)
380                 dump_sk_uid_gid(m, skb->sk);
381 
382         /* Max length: 16 "MARK=0xFFFFFFFF " */
383         if (!iphoff && skb->mark)
384                 sb_add(m, "MARK=0x%x ", skb->mark);
385 
386         /* Proto    Max log string length */
387         /* IP:      40+46+6+11+127 = 230 */
388         /* TCP:     10+max(25,20+30+13+9+32+11+127) = 252 */
389         /* UDP:     10+max(25,20) = 35 */
390         /* UDPLITE: 14+max(25,20) = 39 */
391         /* ICMP:    11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
392         /* ESP:     10+max(25)+15 = 50 */
393         /* AH:      9+max(25)+15 = 49 */
394         /* unknown: 10 */
395 
396         /* (ICMP allows recursion one level deep) */
397         /* maxlen =  IP + ICMP +  IP + max(TCP,UDP,ICMP,unknown) */
398         /* maxlen = 230+   91  + 230 + 252 = 803 */
399 }
400 
401 static void dump_ipv4_mac_header(struct sbuff *m,
402                             const struct nf_loginfo *info,
403                             const struct sk_buff *skb)
404 {
405         struct net_device *dev = skb->dev;
406         unsigned int logflags = 0;
407 
408         if (info->type == NF_LOG_TYPE_LOG)
409                 logflags = info->u.log.logflags;
410 
411         if (!(logflags & XT_LOG_MACDECODE))
412                 goto fallback;
413 
414         switch (dev->type) {
415         case ARPHRD_ETHER:
416                 sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
417                        eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
418                        ntohs(eth_hdr(skb)->h_proto));
419                 return;
420         default:
421                 break;
422         }
423 
424 fallback:
425         sb_add(m, "MAC=");
426         if (dev->hard_header_len &&
427             skb->mac_header != skb->network_header) {
428                 const unsigned char *p = skb_mac_header(skb);
429                 unsigned int i;
430 
431                 sb_add(m, "%02x", *p++);
432                 for (i = 1; i < dev->hard_header_len; i++, p++)
433                         sb_add(m, ":%02x", *p);
434         }
435         sb_add(m, " ");
436 }
437 
438 static void
439 log_packet_common(struct sbuff *m,
440                   u_int8_t pf,
441                   unsigned int hooknum,
442                   const struct sk_buff *skb,
443                   const struct net_device *in,
444                   const struct net_device *out,
445                   const struct nf_loginfo *loginfo,
446                   const char *prefix)
447 {
448         sb_add(m, KERN_SOH "%c%sIN=%s OUT=%s ",
449                '' + loginfo->u.log.level, prefix,
450                in ? in->name : "",
451                out ? out->name : "");
452 #ifdef CONFIG_BRIDGE_NETFILTER
453         if (skb->nf_bridge) {
454                 const struct net_device *physindev;
455                 const struct net_device *physoutdev;
456 
457                 physindev = skb->nf_bridge->physindev;
458                 if (physindev && in != physindev)
459                         sb_add(m, "PHYSIN=%s ", physindev->name);
460                 physoutdev = skb->nf_bridge->physoutdev;
461                 if (physoutdev && out != physoutdev)
462                         sb_add(m, "PHYSOUT=%s ", physoutdev->name);
463         }
464 #endif
465 }
466 
467 
468 static void
469 ipt_log_packet(struct net *net,
470                u_int8_t pf,
471                unsigned int hooknum,
472                const struct sk_buff *skb,
473                const struct net_device *in,
474                const struct net_device *out,
475                const struct nf_loginfo *loginfo,
476                const char *prefix)
477 {
478         struct sbuff *m;
479 
480         /* FIXME: Disabled from containers until syslog ns is supported */
481         if (!net_eq(net, &init_net))
482                 return;
483 
484         m = sb_open();
485 
486         if (!loginfo)
487                 loginfo = &default_loginfo;
488 
489         log_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix);
490 
491         if (in != NULL)
492                 dump_ipv4_mac_header(m, loginfo, skb);
493 
494         dump_ipv4_packet(m, loginfo, skb, 0);
495 
496         sb_close(m);
497 }
498 
499 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
500 /* One level of recursion won't kill us */
501 static void dump_ipv6_packet(struct sbuff *m,
502                         const struct nf_loginfo *info,
503                         const struct sk_buff *skb, unsigned int ip6hoff,
504                         int recurse)
505 {
506         u_int8_t currenthdr;
507         int fragment;
508         struct ipv6hdr _ip6h;
509         const struct ipv6hdr *ih;
510         unsigned int ptr;
511         unsigned int hdrlen = 0;
512         unsigned int logflags;
513 
514         if (info->type == NF_LOG_TYPE_LOG)
515                 logflags = info->u.log.logflags;
516         else
517                 logflags = NF_LOG_MASK;
518 
519         ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
520         if (ih == NULL) {
521                 sb_add(m, "TRUNCATED");
522                 return;
523         }
524 
525         /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
526         sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
527 
528         /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
529         sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
530                ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
531                (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
532                ih->hop_limit,
533                (ntohl(*(__be32 *)ih) & 0x000fffff));
534 
535         fragment = 0;
536         ptr = ip6hoff + sizeof(struct ipv6hdr);
537         currenthdr = ih->nexthdr;
538         while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
539                 struct ipv6_opt_hdr _hdr;
540                 const struct ipv6_opt_hdr *hp;
541 
542                 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
543                 if (hp == NULL) {
544                         sb_add(m, "TRUNCATED");
545                         return;
546                 }
547 
548                 /* Max length: 48 "OPT (...) " */
549                 if (logflags & XT_LOG_IPOPT)
550                         sb_add(m, "OPT ( ");
551 
552                 switch (currenthdr) {
553                 case IPPROTO_FRAGMENT: {
554                         struct frag_hdr _fhdr;
555                         const struct frag_hdr *fh;
556 
557                         sb_add(m, "FRAG:");
558                         fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
559                                                 &_fhdr);
560                         if (fh == NULL) {
561                                 sb_add(m, "TRUNCATED ");
562                                 return;
563                         }
564 
565                         /* Max length: 6 "65535 " */
566                         sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8);
567 
568                         /* Max length: 11 "INCOMPLETE " */
569                         if (fh->frag_off & htons(0x0001))
570                                 sb_add(m, "INCOMPLETE ");
571 
572                         sb_add(m, "ID:%08x ", ntohl(fh->identification));
573 
574                         if (ntohs(fh->frag_off) & 0xFFF8)
575                                 fragment = 1;
576 
577                         hdrlen = 8;
578 
579                         break;
580                 }
581                 case IPPROTO_DSTOPTS:
582                 case IPPROTO_ROUTING:
583                 case IPPROTO_HOPOPTS:
584                         if (fragment) {
585                                 if (logflags & XT_LOG_IPOPT)
586                                         sb_add(m, ")");
587                                 return;
588                         }
589                         hdrlen = ipv6_optlen(hp);
590                         break;
591                 /* Max Length */
592                 case IPPROTO_AH:
593                         if (logflags & XT_LOG_IPOPT) {
594                                 struct ip_auth_hdr _ahdr;
595                                 const struct ip_auth_hdr *ah;
596 
597                                 /* Max length: 3 "AH " */
598                                 sb_add(m, "AH ");
599 
600                                 if (fragment) {
601                                         sb_add(m, ")");
602                                         return;
603                                 }
604 
605                                 ah = skb_header_pointer(skb, ptr, sizeof(_ahdr),
606                                                         &_ahdr);
607                                 if (ah == NULL) {
608                                         /*
609                                          * Max length: 26 "INCOMPLETE [65535
610                                          *  bytes] )"
611                                          */
612                                         sb_add(m, "INCOMPLETE [%u bytes] )",
613                                                skb->len - ptr);
614                                         return;
615                                 }
616 
617                                 /* Length: 15 "SPI=0xF1234567 */
618                                 sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
619 
620                         }
621 
622                         hdrlen = (hp->hdrlen+2)<<2;
623                         break;
624                 case IPPROTO_ESP:
625                         if (logflags & XT_LOG_IPOPT) {
626                                 struct ip_esp_hdr _esph;
627                                 const struct ip_esp_hdr *eh;
628 
629                                 /* Max length: 4 "ESP " */
630                                 sb_add(m, "ESP ");
631 
632                                 if (fragment) {
633                                         sb_add(m, ")");
634                                         return;
635                                 }
636 
637                                 /*
638                                  * Max length: 26 "INCOMPLETE [65535 bytes] )"
639                                  */
640                                 eh = skb_header_pointer(skb, ptr, sizeof(_esph),
641                                                         &_esph);
642                                 if (eh == NULL) {
643                                         sb_add(m, "INCOMPLETE [%u bytes] )",
644                                                skb->len - ptr);
645                                         return;
646                                 }
647 
648                                 /* Length: 16 "SPI=0xF1234567 )" */
649                                 sb_add(m, "SPI=0x%x )", ntohl(eh->spi));
650 
651                         }
652                         return;
653                 default:
654                         /* Max length: 20 "Unknown Ext Hdr 255" */
655                         sb_add(m, "Unknown Ext Hdr %u", currenthdr);
656                         return;
657                 }
658                 if (logflags & XT_LOG_IPOPT)
659                         sb_add(m, ") ");
660 
661                 currenthdr = hp->nexthdr;
662                 ptr += hdrlen;
663         }
664 
665         switch (currenthdr) {
666         case IPPROTO_TCP:
667                 if (dump_tcp_header(m, skb, currenthdr, fragment, ptr,
668                     logflags))
669                         return;
670                 break;
671         case IPPROTO_UDP:
672         case IPPROTO_UDPLITE:
673                 if (dump_udp_header(m, skb, currenthdr, fragment, ptr))
674                         return;
675                 break;
676         case IPPROTO_ICMPV6: {
677                 struct icmp6hdr _icmp6h;
678                 const struct icmp6hdr *ic;
679 
680                 /* Max length: 13 "PROTO=ICMPv6 " */
681                 sb_add(m, "PROTO=ICMPv6 ");
682 
683                 if (fragment)
684                         break;
685 
686                 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
687                 ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
688                 if (ic == NULL) {
689                         sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
690                         return;
691                 }
692 
693                 /* Max length: 18 "TYPE=255 CODE=255 " */
694                 sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
695 
696                 switch (ic->icmp6_type) {
697                 case ICMPV6_ECHO_REQUEST:
698                 case ICMPV6_ECHO_REPLY:
699                         /* Max length: 19 "ID=65535 SEQ=65535 " */
700                         sb_add(m, "ID=%u SEQ=%u ",
701                                 ntohs(ic->icmp6_identifier),
702                                 ntohs(ic->icmp6_sequence));
703                         break;
704                 case ICMPV6_MGM_QUERY:
705                 case ICMPV6_MGM_REPORT:
706                 case ICMPV6_MGM_REDUCTION:
707                         break;
708 
709                 case ICMPV6_PARAMPROB:
710                         /* Max length: 17 "POINTER=ffffffff " */
711                         sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer));
712                         /* Fall through */
713                 case ICMPV6_DEST_UNREACH:
714                 case ICMPV6_PKT_TOOBIG:
715                 case ICMPV6_TIME_EXCEED:
716                         /* Max length: 3+maxlen */
717                         if (recurse) {
718                                 sb_add(m, "[");
719                                 dump_ipv6_packet(m, info, skb,
720                                             ptr + sizeof(_icmp6h), 0);
721                                 sb_add(m, "] ");
722                         }
723 
724                         /* Max length: 10 "MTU=65535 " */
725                         if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
726                                 sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu));
727                 }
728                 break;
729         }
730         /* Max length: 10 "PROTO=255 " */
731         default:
732                 sb_add(m, "PROTO=%u ", currenthdr);
733         }
734 
735         /* Max length: 15 "UID=4294967295 " */
736         if ((logflags & XT_LOG_UID) && recurse)
737                 dump_sk_uid_gid(m, skb->sk);
738 
739         /* Max length: 16 "MARK=0xFFFFFFFF " */
740         if (recurse && skb->mark)
741                 sb_add(m, "MARK=0x%x ", skb->mark);
742 }
743 
744 static void dump_ipv6_mac_header(struct sbuff *m,
745                             const struct nf_loginfo *info,
746                             const struct sk_buff *skb)
747 {
748         struct net_device *dev = skb->dev;
749         unsigned int logflags = 0;
750 
751         if (info->type == NF_LOG_TYPE_LOG)
752                 logflags = info->u.log.logflags;
753 
754         if (!(logflags & XT_LOG_MACDECODE))
755                 goto fallback;
756 
757         switch (dev->type) {
758         case ARPHRD_ETHER:
759                 sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
760                        eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
761                        ntohs(eth_hdr(skb)->h_proto));
762                 return;
763         default:
764                 break;
765         }
766 
767 fallback:
768         sb_add(m, "MAC=");
769         if (dev->hard_header_len &&
770             skb->mac_header != skb->network_header) {
771                 const unsigned char *p = skb_mac_header(skb);
772                 unsigned int len = dev->hard_header_len;
773                 unsigned int i;
774 
775                 if (dev->type == ARPHRD_SIT) {
776                         p -= ETH_HLEN;
777 
778                         if (p < skb->head)
779                                 p = NULL;
780                 }
781 
782                 if (p != NULL) {
783                         sb_add(m, "%02x", *p++);
784                         for (i = 1; i < len; i++)
785                                 sb_add(m, ":%02x", *p++);
786                 }
787                 sb_add(m, " ");
788 
789                 if (dev->type == ARPHRD_SIT) {
790                         const struct iphdr *iph =
791                                 (struct iphdr *)skb_mac_header(skb);
792                         sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr,
793                                &iph->daddr);
794                 }
795         } else
796                 sb_add(m, " ");
797 }
798 
799 static void
800 ip6t_log_packet(struct net *net,
801                 u_int8_t pf,
802                 unsigned int hooknum,
803                 const struct sk_buff *skb,
804                 const struct net_device *in,
805                 const struct net_device *out,
806                 const struct nf_loginfo *loginfo,
807                 const char *prefix)
808 {
809         struct sbuff *m;
810 
811         /* FIXME: Disabled from containers until syslog ns is supported */
812         if (!net_eq(net, &init_net))
813                 return;
814 
815         m = sb_open();
816 
817         if (!loginfo)
818                 loginfo = &default_loginfo;
819 
820         log_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix);
821 
822         if (in != NULL)
823                 dump_ipv6_mac_header(m, loginfo, skb);
824 
825         dump_ipv6_packet(m, loginfo, skb, skb_network_offset(skb), 1);
826 
827         sb_close(m);
828 }
829 #endif
830 
831 static unsigned int
832 log_tg(struct sk_buff *skb, const struct xt_action_param *par)
833 {
834         const struct xt_log_info *loginfo = par->targinfo;
835         struct nf_loginfo li;
836         struct net *net = dev_net(par->in ? par->in : par->out);
837 
838         li.type = NF_LOG_TYPE_LOG;
839         li.u.log.level = loginfo->level;
840         li.u.log.logflags = loginfo->logflags;
841 
842         if (par->family == NFPROTO_IPV4)
843                 ipt_log_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in,
844                                par->out, &li, loginfo->prefix);
845 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
846         else if (par->family == NFPROTO_IPV6)
847                 ip6t_log_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in,
848                                 par->out, &li, loginfo->prefix);
849 #endif
850         else
851                 WARN_ON_ONCE(1);
852 
853         return XT_CONTINUE;
854 }
855 
856 static int log_tg_check(const struct xt_tgchk_param *par)
857 {
858         const struct xt_log_info *loginfo = par->targinfo;
859 
860         if (par->family != NFPROTO_IPV4 && par->family != NFPROTO_IPV6)
861                 return -EINVAL;
862 
863         if (loginfo->level >= 8) {
864                 pr_debug("level %u >= 8\n", loginfo->level);
865                 return -EINVAL;
866         }
867 
868         if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
869                 pr_debug("prefix is not null-terminated\n");
870                 return -EINVAL;
871         }
872 
873         return 0;
874 }
875 
876 static struct xt_target log_tg_regs[] __read_mostly = {
877         {
878                 .name           = "LOG",
879                 .family         = NFPROTO_IPV4,
880                 .target         = log_tg,
881                 .targetsize     = sizeof(struct xt_log_info),
882                 .checkentry     = log_tg_check,
883                 .me             = THIS_MODULE,
884         },
885 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
886         {
887                 .name           = "LOG",
888                 .family         = NFPROTO_IPV6,
889                 .target         = log_tg,
890                 .targetsize     = sizeof(struct xt_log_info),
891                 .checkentry     = log_tg_check,
892                 .me             = THIS_MODULE,
893         },
894 #endif
895 };
896 
897 static struct nf_logger ipt_log_logger __read_mostly = {
898         .name           = "ipt_LOG",
899         .logfn          = &ipt_log_packet,
900         .me             = THIS_MODULE,
901 };
902 
903 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
904 static struct nf_logger ip6t_log_logger __read_mostly = {
905         .name           = "ip6t_LOG",
906         .logfn          = &ip6t_log_packet,
907         .me             = THIS_MODULE,
908 };
909 #endif
910 
911 static int __net_init log_net_init(struct net *net)
912 {
913         nf_log_set(net, NFPROTO_IPV4, &ipt_log_logger);
914 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
915         nf_log_set(net, NFPROTO_IPV6, &ip6t_log_logger);
916 #endif
917         return 0;
918 }
919 
920 static void __net_exit log_net_exit(struct net *net)
921 {
922         nf_log_unset(net, &ipt_log_logger);
923 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
924         nf_log_unset(net, &ip6t_log_logger);
925 #endif
926 }
927 
928 static struct pernet_operations log_net_ops = {
929         .init = log_net_init,
930         .exit = log_net_exit,
931 };
932 
933 static int __init log_tg_init(void)
934 {
935         int ret;
936 
937         ret = register_pernet_subsys(&log_net_ops);
938         if (ret < 0)
939                 goto err_pernet;
940 
941         ret = xt_register_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
942         if (ret < 0)
943                 goto err_target;
944 
945         nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
946 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
947         nf_log_register(NFPROTO_IPV6, &ip6t_log_logger);
948 #endif
949         return 0;
950 
951 err_target:
952         unregister_pernet_subsys(&log_net_ops);
953 err_pernet:
954         return ret;
955 }
956 
957 static void __exit log_tg_exit(void)
958 {
959         unregister_pernet_subsys(&log_net_ops);
960         nf_log_unregister(&ipt_log_logger);
961 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
962         nf_log_unregister(&ip6t_log_logger);
963 #endif
964         xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
965 }
966 
967 module_init(log_tg_init);
968 module_exit(log_tg_exit);
969 
970 MODULE_LICENSE("GPL");
971 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
972 MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
973 MODULE_DESCRIPTION("Xtables: IPv4/IPv6 packet logging");
974 MODULE_ALIAS("ipt_LOG");
975 MODULE_ALIAS("ip6t_LOG");
976 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp