const union ip_conntrack_manip_proto *min,
const union ip_conntrack_manip_proto *max)
{
- return (tuple->src.u.icmp.id >= min->icmp.id
- && tuple->src.u.icmp.id <= max->icmp.id);
+ return ntohs(tuple->src.u.icmp.id) >= ntohs(min->icmp.id) &&
+ ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id);
}
static int
const struct ip_conntrack *conntrack)
{
static u_int16_t id;
- unsigned int range_size
- = (unsigned int)range->max.icmp.id - range->min.icmp.id + 1;
+ unsigned int range_size;
unsigned int i;
+ range_size = ntohs(range->max.icmp.id) - ntohs(range->min.icmp.id) + 1;
/* If no range specified... */
if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED))
range_size = 0xFFFF;
for (i = 0; i < range_size; i++, id++) {
- tuple->src.u.icmp.id = range->min.icmp.id + (id % range_size);
+ tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) +
+ (id % range_size));
if (!ip_nat_used_tuple(tuple, conntrack))
return 1;
}
static int
icmp_manip_pkt(struct sk_buff **pskb,
- unsigned int hdroff,
- const struct ip_conntrack_manip *manip,
+ unsigned int iphdroff,
+ const struct ip_conntrack_tuple *tuple,
enum ip_nat_manip_type maniptype)
{
+ struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct icmphdr *hdr;
+ unsigned int hdroff = iphdroff + iph->ihl*4;
- if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr)))
+ if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
return 0;
- hdr = (void *)(*pskb)->data + hdroff;
-
- hdr->checksum = ip_nat_cheat_check(hdr->un.echo.id ^ 0xFFFF,
- manip->u.icmp.id,
- hdr->checksum);
- hdr->un.echo.id = manip->u.icmp.id;
+ hdr = (struct icmphdr *)((*pskb)->data + hdroff);
+ nf_proto_csum_replace2(&hdr->checksum, *pskb,
+ hdr->un.echo.id, tuple->src.u.icmp.id, 0);
+ hdr->un.echo.id = tuple->src.u.icmp.id;
return 1;
}
-static unsigned int
-icmp_print(char *buffer,
- const struct ip_conntrack_tuple *match,
- const struct ip_conntrack_tuple *mask)
-{
- unsigned int len = 0;
-
- if (mask->src.u.icmp.id)
- len += sprintf(buffer + len, "id=%u ",
- ntohs(match->src.u.icmp.id));
-
- if (mask->dst.u.icmp.type)
- len += sprintf(buffer + len, "type=%u ",
- ntohs(match->dst.u.icmp.type));
-
- if (mask->dst.u.icmp.code)
- len += sprintf(buffer + len, "code=%u ",
- ntohs(match->dst.u.icmp.code));
-
- return len;
-}
-
-static unsigned int
-icmp_print_range(char *buffer, const struct ip_nat_range *range)
-{
- if (range->min.icmp.id != 0 || range->max.icmp.id != 0xFFFF)
- return sprintf(buffer, "id %u-%u ",
- ntohs(range->min.icmp.id),
- ntohs(range->max.icmp.id));
- else return 0;
-}
-
-struct ip_nat_protocol ip_nat_protocol_icmp
-= { { NULL, NULL }, "ICMP", IPPROTO_ICMP,
- icmp_manip_pkt,
- icmp_in_range,
- icmp_unique_tuple,
- icmp_print,
- icmp_print_range
+struct ip_nat_protocol ip_nat_protocol_icmp = {
+ .name = "ICMP",
+ .protonum = IPPROTO_ICMP,
+ .me = THIS_MODULE,
+ .manip_pkt = icmp_manip_pkt,
+ .in_range = icmp_in_range,
+ .unique_tuple = icmp_unique_tuple,
+#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+ defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+ .range_to_nfattr = ip_nat_port_range_to_nfattr,
+ .nfattr_to_range = ip_nat_port_nfattr_to_range,
+#endif
};