Advertisement
Guest User

Untitled

a guest
Feb 26th, 2015
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.15 KB | None | 0 0
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/netpoll.h>
  4.  
  5. #include <linux/ip.h>
  6. #include <linux/udp.h>
  7. #include <linux/if_ether.h>
  8. #include <linux/netfilter.h>
  9. #include <linux/netfilter_ipv4.h>
  10.  
  11. #include <net/udp.h>
  12.  
  13.  
  14. /* Used to describe our Netfilter hooks */
  15. struct nf_hook_ops pre_hook;  /* Incoming */
  16. struct nf_hook_ops post_hook;  /* Outgoing */
  17.  
  18.  
  19. unsigned int add_to_queue(struct sk_buff* skb);
  20. void calc_transport_csum(struct sk_buff *skb);
  21. int is_a2s_info_request(uint8_t* data, size_t len);
  22. int is_inet_search_request(uint8_t* data, size_t len);
  23.  
  24.  
  25. /* This is the hook function itself */
  26. unsigned int hook_func(const struct nf_hook_ops *ops,
  27.                         struct sk_buff *skb,
  28.                         const struct net_device *in,
  29.                         const struct net_device *out,
  30.                         int (*okfn)(struct sk_buff *))
  31. {
  32.     struct iphdr* ip_header = ip_hdr(skb);
  33.  
  34.     // Handle only UDP IPv4 packets
  35.     if (
  36.         skb->protocol != htons(ETH_P_IP)
  37.         || ip_header->version != 4
  38.         || ip_header->protocol != IPPROTO_UDP
  39.     ) {
  40.         return NF_ACCEPT;
  41.     }
  42.  
  43.     struct udphdr* udp_header = udp_hdr(skb);
  44.  
  45.     if (out != NULL && strcmp(out->name, "lo") != 0)
  46.     {
  47.         // Redirect all proxy outgoing traffic
  48.  
  49.         uint16_t src_port = ntohs(udp_header->source);
  50.         uint16_t new_src_port = src_port;
  51.  
  52.         switch(src_port)
  53.         {
  54.             case 27921:
  55.                 new_src_port = 27021;
  56.                 break;
  57.             case 27920:
  58.                 new_src_port = 27020;
  59.                 break;
  60.             case 27919:
  61.                 new_src_port = 27019;
  62.                 break;
  63.             case 27918:
  64.                 new_src_port = 27018;
  65.                 break;
  66.             case 27917:
  67.                 new_src_port = 27017;
  68.                 break;
  69.             case 27916:
  70.                 new_src_port = 27016;
  71.                 break;
  72.             case 27915:
  73.                 new_src_port = 27015;
  74.                 break;
  75.         }
  76.  
  77.         if (new_src_port != src_port)
  78.         {
  79.             udp_header->source = htons(new_src_port);
  80.             calc_transport_csum(skb);
  81.         }
  82.     }
  83.     else if (in != NULL && strcmp(in->name, "lo") != 0)
  84.     {
  85.         // Redirect incoming requests to proxy
  86.  
  87.         const size_t IP_UDP_HDR_SIZE = sizeof(struct iphdr) + sizeof(struct udphdr);
  88.  
  89.         size_t data_len = skb->len - IP_UDP_HDR_SIZE;
  90.         uint8_t* data = (uint8_t *)skb_header_pointer(skb, IP_UDP_HDR_SIZE, 0, NULL);
  91.  
  92.         if (is_a2s_info_request(data, data_len) || is_inet_search_request(data, data_len))
  93.         {
  94.             //printk(KERN_INFO "A2S: %d", is_a2s_info_request(data, data_len));
  95.             //printk(KERN_INFO "InetSearch: %d\n", is_inet_search_request(data, data_len));
  96.  
  97.             uint16_t dst_port = ntohs(udp_header->dest);
  98.             uint16_t new_dst_port = dst_port;
  99.  
  100.             switch(dst_port)
  101.             {
  102.                 case 27021:
  103.                     new_dst_port = 27921;
  104.                     break;
  105.                 case 27020:
  106.                     new_dst_port = 27920;
  107.                     break;
  108.                 case 27019:
  109.                     new_dst_port = 27919;
  110.                     break;
  111.                 case 27018:
  112.                     new_dst_port = 27918;
  113.                     break;
  114.                 case 27017:
  115.                     new_dst_port = 27917;
  116.                     break;
  117.                 case 27016:
  118.                     new_dst_port = 27916;
  119.                     break;
  120.                 case 27015:
  121.                     new_dst_port = 27915;
  122.                     break;
  123.             }
  124.  
  125.             if (new_dst_port != dst_port)
  126.             {
  127.                 udp_header->dest = htons(new_dst_port);
  128.                 udp_header->check = 0;
  129.                 //calc_transport_csum(skb);
  130.             }
  131.         }
  132.     }
  133.  
  134.     return NF_ACCEPT;
  135. }
  136.  
  137. unsigned int add_to_queue(struct sk_buff* skb)
  138. {
  139.     // Create eth header to requeue packet again
  140.  
  141.     struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
  142.     skb_reset_mac_header(skb);
  143.     skb->protocol = eth->h_proto = htons(ETH_P_IP);
  144.     memcpy(eth->h_dest, skb->dev->dev_addr, ETH_ALEN);
  145.     memset(eth->h_source, 0xFF, ETH_ALEN);
  146.  
  147.     dev_queue_xmit(skb);
  148.  
  149.     return NF_STOLEN;
  150. }
  151.  
  152.  
  153. void calc_transport_csum(struct sk_buff *skb)
  154. {
  155.     struct iphdr *ip_header = ip_hdr(skb);
  156.     struct udphdr *udp_header = udp_hdr(skb);
  157.  
  158.     int transport_len = skb->len - skb_transport_offset(skb);
  159.  
  160.     ip_header->check = 0;
  161.     ip_send_check(ip_header);
  162.     udp_header->check = 0;
  163.     udp_header->check = ~(csum_tcpudp_magic(ip_header->saddr, ip_header->daddr, transport_len, IPPROTO_UDP, 0));
  164. }
  165.  
  166.  
  167. int is_a2s_info_request(uint8_t* data, size_t len)
  168. {
  169.     static uint8_t payload[] = "\xFF\xFF\xFF\xFFTSource Engine Query";
  170.     static size_t pl_len = sizeof(payload);
  171.  
  172.     if (len < pl_len) {
  173.         return 0;
  174.     }
  175.  
  176.     return memcmp(data, payload, pl_len) == 0;
  177. }
  178.  
  179.  
  180. #define INET_SEARCH_HDR_LEN 17
  181. int is_inet_search_request(uint8_t* data, size_t len)
  182. {
  183.     static uint8_t payload[] = "InetSearchServerDetails";
  184.     static size_t pl_len = sizeof(payload);
  185.  
  186.     if (len < INET_SEARCH_HDR_LEN + pl_len) {
  187.         return 0;
  188.     }
  189.  
  190.     // skip header and compare body only
  191.     return memcmp(&data[INET_SEARCH_HDR_LEN], payload, pl_len) == 0;
  192. }
  193.  
  194.  
  195. /* Initialisation routine */
  196. int init_module()
  197. {
  198.     /* Fill in our hook structure */
  199.     pre_hook.pf = PF_INET;
  200.     pre_hook.hook = hook_func;  /* Handler function */
  201.     pre_hook.priority = NF_IP_PRI_FIRST;  /* Make our function first */
  202.     pre_hook.hooknum  = NF_INET_PRE_ROUTING;  /* First hook for IPv4 */
  203.  
  204.     nf_register_hook(&pre_hook);
  205.  
  206.     post_hook.pf = PF_INET;
  207.     post_hook.hook = hook_func;  /* Handler function */
  208.     post_hook.priority = NF_IP_PRI_FIRST;  /* Make our function first */
  209.     post_hook.hooknum  = NF_INET_POST_ROUTING;  /* First hook for IPv4 */
  210.  
  211.     nf_register_hook(&post_hook);
  212.  
  213.     return 0;
  214. }
  215.    
  216. /* Cleanup routine */
  217. void cleanup_module()
  218. {
  219.     nf_unregister_hook(&pre_hook);
  220.     nf_unregister_hook(&post_hook);
  221. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement