/* manipulate a GRE packet according to maniptype */ static int gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff, const struct ip_conntrack_tuple *tuple, enum ip_nat_manip_type maniptype) { struct gre_hdr *greh; struct gre_hdr_pptp *pgreh; struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff); unsigned int hdroff = iphdroff + iph->ihl*4; /* pgreh includes two optional 32bit fields which are not required * to be there. That's where the magic '8' comes from */ if (!skb_make_writable(pskb, hdroff + sizeof(*pgreh)-8)) return 0; greh = (void *)(*pskb)->data + hdroff; pgreh = (struct gre_hdr_pptp *) greh; /* we only have destination manip of a packet, since 'source key' * is not present in the packet itself */ if (maniptype == IP_NAT_MANIP_DST) { /* key manipulation is always dest */ switch (greh->version) { case 0: if (!greh->key) { DEBUGP("can't nat GRE w/o key\n"); break; } if (greh->csum) { /* FIXME: Never tested this code... */ *(gre_csum(greh)) = nf_proto_csum_update(*pskb, ~*(gre_key(greh)), tuple->dst.u.gre.key, *(gre_csum(greh)), 0); } *(gre_key(greh)) = tuple->dst.u.gre.key; break; case GRE_VERSION_PPTP: DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); pgreh->call_id = tuple->dst.u.gre.key; break; default: DEBUGP("can't nat unknown GRE version\n"); return 0; break; } } return 1; }
/* manipulate a GRE packet according to maniptype */ static void gre_manip_pkt(struct iphdr *iph, size_t len, const struct ip_conntrack_manip *manip, enum ip_nat_manip_type maniptype) { struct gre_hdr *greh = (struct gre_hdr *)((u_int32_t *)iph+iph->ihl); struct gre_hdr_pptp *pgreh = (struct gre_hdr_pptp *) greh; /* we only have destination manip of a packet, since 'source key' * is not present in the packet itself */ if (maniptype == IP_NAT_MANIP_DST) { /* key manipulation is always dest */ switch (greh->version) { case 0: if (!greh->key) { DEBUGP("can't nat GRE w/o key\n"); break; } if (greh->csum) { /* FIXME: Never tested this code... */ *(gre_csum(greh)) = ip_nat_cheat_check(~*(gre_key(greh)), manip->u.gre.key, *(gre_csum(greh))); } *(gre_key(greh)) = manip->u.gre.key; break; case GRE_VERSION_PPTP: DEBUGP("call_id -> 0x%04x\n", ntohl(manip->u.gre.key)); pgreh->call_id = htons(ntohl(manip->u.gre.key)); break; default: DEBUGP("can't nat unknown GRE version\n"); break; } } }