Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 
  9 #include <linux/types.h>
 10 #include <linux/init.h>
 11 #include <linux/netfilter.h>
 12 #include <linux/ip.h>
 13 #include <linux/icmp.h>
 14 #include <linux/if.h>
 15 
 16 #include <linux/netfilter_ipv4/ip_nat.h>
 17 #include <linux/netfilter_ipv4/ip_nat_core.h>
 18 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 19 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
 20 
 21 static int
 22 icmp_in_range(const struct ip_conntrack_tuple *tuple,
 23               enum ip_nat_manip_type maniptype,
 24               const union ip_conntrack_manip_proto *min,
 25               const union ip_conntrack_manip_proto *max)
 26 {
 27         return (tuple->src.u.icmp.id >= min->icmp.id
 28                 && tuple->src.u.icmp.id <= max->icmp.id);
 29 }
 30 
 31 static int
 32 icmp_unique_tuple(struct ip_conntrack_tuple *tuple,
 33                   const struct ip_nat_range *range,
 34                   enum ip_nat_manip_type maniptype,
 35                   const struct ip_conntrack *conntrack)
 36 {
 37         static u_int16_t id;
 38         unsigned int range_size
 39                 = (unsigned int)range->max.icmp.id - range->min.icmp.id + 1;
 40         unsigned int i;
 41 
 42         /* If no range specified... */
 43         if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED))
 44                 range_size = 0xFFFF;
 45 
 46         for (i = 0; i < range_size; i++, id++) {
 47                 tuple->src.u.icmp.id = range->min.icmp.id + (id % range_size);
 48                 if (!ip_nat_used_tuple(tuple, conntrack))
 49                         return 1;
 50         }
 51         return 0;
 52 }
 53 
 54 static int
 55 icmp_manip_pkt(struct sk_buff **pskb,
 56                unsigned int iphdroff,
 57                const struct ip_conntrack_tuple *tuple,
 58                enum ip_nat_manip_type maniptype)
 59 {
 60         struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
 61         struct icmphdr *hdr;
 62         unsigned int hdroff = iphdroff + iph->ihl*4;
 63 
 64         if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr)))
 65                 return 0;
 66 
 67         hdr = (struct icmphdr *)((*pskb)->data + hdroff);
 68 
 69         hdr->checksum = ip_nat_cheat_check(hdr->un.echo.id ^ 0xFFFF,
 70                                             tuple->src.u.icmp.id,
 71                                             hdr->checksum);
 72         hdr->un.echo.id = tuple->src.u.icmp.id;
 73         return 1;
 74 }
 75 
 76 static unsigned int
 77 icmp_print(char *buffer,
 78            const struct ip_conntrack_tuple *match,
 79            const struct ip_conntrack_tuple *mask)
 80 {
 81         unsigned int len = 0;
 82 
 83         if (mask->src.u.icmp.id)
 84                 len += sprintf(buffer + len, "id=%u ",
 85                                ntohs(match->src.u.icmp.id));
 86 
 87         if (mask->dst.u.icmp.type)
 88                 len += sprintf(buffer + len, "type=%u ",
 89                                ntohs(match->dst.u.icmp.type));
 90 
 91         if (mask->dst.u.icmp.code)
 92                 len += sprintf(buffer + len, "code=%u ",
 93                                ntohs(match->dst.u.icmp.code));
 94 
 95         return len;
 96 }
 97 
 98 static unsigned int
 99 icmp_print_range(char *buffer, const struct ip_nat_range *range)
100 {
101         if (range->min.icmp.id != 0 || range->max.icmp.id != 0xFFFF)
102                 return sprintf(buffer, "id %u-%u ",
103                                ntohs(range->min.icmp.id),
104                                ntohs(range->max.icmp.id));
105         else return 0;
106 }
107 
108 struct ip_nat_protocol ip_nat_protocol_icmp
109 = { "ICMP", IPPROTO_ICMP,
110     icmp_manip_pkt,
111     icmp_in_range,
112     icmp_unique_tuple,
113     icmp_print,
114     icmp_print_range
115 };
116 
  This page was automatically generated by the LXR engine.