ip_nat_proto_gre.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * ip_nat_proto_gre.c - Version 2.0
  3. *
  4. * NAT protocol helper module for GRE.
  5. *
  6. * GRE is a generic encapsulation protocol, which is generally not very
  7. * suited for NAT, as it has no protocol-specific part as port numbers.
  8. *
  9. * It has an optional key field, which may help us distinguishing two
  10. * connections between the same two hosts.
  11. *
  12. * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784
  13. *
  14. * PPTP is built on top of a modified version of GRE, and has a mandatory
  15. * field called "CallID", which serves us for the same purpose as the key
  16. * field in plain GRE.
  17. *
  18. * Documentation about PPTP can be found in RFC 2637
  19. *
  20. * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
  21. *
  22. * Development of this code funded by Astaro AG (http://www.astaro.com/)
  23. *
  24. */
  25. #include <linux/module.h>
  26. #include <linux/ip.h>
  27. #include <linux/netfilter_ipv4/ip_nat.h>
  28. #include <linux/netfilter_ipv4/ip_nat_rule.h>
  29. #include <linux/netfilter_ipv4/ip_nat_protocol.h>
  30. #include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
  31. MODULE_LICENSE("GPL");
  32. MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
  33. MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
  34. #if 0
  35. #define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
  36. __FUNCTION__, ## args)
  37. #else
  38. #define DEBUGP(x, args...)
  39. #endif
  40. /* is key in given range between min and max */
  41. static int
  42. gre_in_range(const struct ip_conntrack_tuple *tuple,
  43. enum ip_nat_manip_type maniptype,
  44. const union ip_conntrack_manip_proto *min,
  45. const union ip_conntrack_manip_proto *max)
  46. {
  47. __be16 key;
  48. if (maniptype == IP_NAT_MANIP_SRC)
  49. key = tuple->src.u.gre.key;
  50. else
  51. key = tuple->dst.u.gre.key;
  52. return ntohs(key) >= ntohs(min->gre.key)
  53. && ntohs(key) <= ntohs(max->gre.key);
  54. }
  55. /* generate unique tuple ... */
  56. static int
  57. gre_unique_tuple(struct ip_conntrack_tuple *tuple,
  58. const struct ip_nat_range *range,
  59. enum ip_nat_manip_type maniptype,
  60. const struct ip_conntrack *conntrack)
  61. {
  62. static u_int16_t key;
  63. __be16 *keyptr;
  64. unsigned int min, i, range_size;
  65. /* If there is no master conntrack we are not PPTP,
  66. do not change tuples */
  67. if (!conntrack->master)
  68. return 0;
  69. if (maniptype == IP_NAT_MANIP_SRC)
  70. keyptr = &tuple->src.u.gre.key;
  71. else
  72. keyptr = &tuple->dst.u.gre.key;
  73. if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
  74. DEBUGP("%p: NATing GRE PPTP\n", conntrack);
  75. min = 1;
  76. range_size = 0xffff;
  77. } else {
  78. min = ntohs(range->min.gre.key);
  79. range_size = ntohs(range->max.gre.key) - min + 1;
  80. }
  81. DEBUGP("min = %u, range_size = %u\n", min, range_size);
  82. for (i = 0; i < range_size; i++, key++) {
  83. *keyptr = htons(min + key % range_size);
  84. if (!ip_nat_used_tuple(tuple, conntrack))
  85. return 1;
  86. }
  87. DEBUGP("%p: no NAT mapping\n", conntrack);
  88. return 0;
  89. }
  90. /* manipulate a GRE packet according to maniptype */
  91. static int
  92. gre_manip_pkt(struct sk_buff **pskb,
  93. unsigned int iphdroff,
  94. const struct ip_conntrack_tuple *tuple,
  95. enum ip_nat_manip_type maniptype)
  96. {
  97. struct gre_hdr *greh;
  98. struct gre_hdr_pptp *pgreh;
  99. struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
  100. unsigned int hdroff = iphdroff + iph->ihl*4;
  101. /* pgreh includes two optional 32bit fields which are not required
  102. * to be there. That's where the magic '8' comes from */
  103. if (!skb_make_writable(pskb, hdroff + sizeof(*pgreh)-8))
  104. return 0;
  105. greh = (void *)(*pskb)->data + hdroff;
  106. pgreh = (struct gre_hdr_pptp *) greh;
  107. /* we only have destination manip of a packet, since 'source key'
  108. * is not present in the packet itself */
  109. if (maniptype == IP_NAT_MANIP_DST) {
  110. /* key manipulation is always dest */
  111. switch (greh->version) {
  112. case GRE_VERSION_1701:
  113. /* We do not currently NAT any GREv0 packets.
  114. * Try to behave like "ip_nat_proto_unknown" */
  115. break;
  116. case GRE_VERSION_PPTP:
  117. DEBUGP("call_id -> 0x%04x\n",
  118. ntohs(tuple->dst.u.gre.key));
  119. pgreh->call_id = tuple->dst.u.gre.key;
  120. break;
  121. default:
  122. DEBUGP("can't nat unknown GRE version\n");
  123. return 0;
  124. break;
  125. }
  126. }
  127. return 1;
  128. }
  129. /* nat helper struct */
  130. static struct ip_nat_protocol gre = {
  131. .name = "GRE",
  132. .protonum = IPPROTO_GRE,
  133. .manip_pkt = gre_manip_pkt,
  134. .in_range = gre_in_range,
  135. .unique_tuple = gre_unique_tuple,
  136. #if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
  137. defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
  138. .range_to_nfattr = ip_nat_port_range_to_nfattr,
  139. .nfattr_to_range = ip_nat_port_nfattr_to_range,
  140. #endif
  141. };
  142. int __init ip_nat_proto_gre_init(void)
  143. {
  144. return ip_nat_protocol_register(&gre);
  145. }
  146. void __exit ip_nat_proto_gre_fini(void)
  147. {
  148. ip_nat_protocol_unregister(&gre);
  149. }