Chinaunix首页 | 论坛 | 博客
  • 博客访问: 757879
  • 博文数量: 144
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1150
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-17 14:32
个人简介

小公司研发总监,既当司令也当兵!

文章分类

全部博文(144)

分类: LINUX

2015-06-10 21:32:27

内核模式实现DNS拦截(或代为回复)。注意,内核需要在2.6.31版本以上

点击(此处)折叠或打开

  1. #include <linux/vermagic.h>
  2. #include <linux/compiler.h>
  3. #include <linux/sockios.h>
  4. #include <linux/inetdevice.h>
  5. #include <linux/netdevice.h>
  6. #include <linux/types.h>
  7. #include <linux/skbuff.h>
  8. #include <linux/if_ether.h>
  9. #include <linux/netfilter.h>
  10. #include <linux/netfilter_ipv4.h>
  11. #include <linux/string.h>

  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/init.h>
  15. #include <linux/workqueue.h>
  16. #include <linux/in.h>
  17. #include <linux/inet.h>
  18. #include <linux/socket.h>
  19. #include <linux/ip.h>
  20. #include <linux/udp.h>
  21. #include <net/sock.h>
  22. #include <net/route.h>
  23. #include <net/ip.h>
  24. #include <net/flow.h>

  25. #include <linux/version.h>

  26. #include "iDNS_intercept.h"

  27. static unsigned int idns_intercept_handler( unsigned int hooknum,
  28.                             struct sk_buff *skb,
  29.                             const struct net_device *in,
  30.                             const struct net_device *out,
  31.                             int ( *okfn )(struct sk_buff *) );


  32. static struct nf_hook_ops idns_hook_ops = {
  33.     .hook    =    idns_intercept_handler,
  34.     .owner    =    THIS_MODULE,
  35.     .pf        =    PF_INET,
  36.     .hooknum =    NF_INET_PRE_ROUTING,
  37.     .priority    =    NF_IP_PRI_NAT_DST - 1,/*    after DNAT */
  38. };


  39. static unsigned char query_str[] = {
  40.         0x03,
  41.         0x77,0x77,0x77,    /* www */
  42.         0x05,
  43.         0x6c,0x6f,0x67,0x69,0x6e,    /* login */
  44.         0x03,
  45.         0x6e,0x65,0x74,    /* net */
  46.         0x00
  47. };

  48. #define DNS_QUERY_LEN    sizeof( query_str)


  49. static unsigned int idns_intercept_handler( unsigned int hooknum,
  50.                             struct sk_buff *skb,
  51.                             const struct net_device *in,
  52.                             const struct net_device *out,
  53.                             int ( *okfn )(struct sk_buff *) )
  54. {
  55.     struct sk_buff *pskb = skb;
  56.     struct iphdr *iph = ip_hdr(pskb);
  57.     struct udphdr *udp_hdr;
  58.     DNS_HEADER *dns_hdr;

  59.     unsigned char * dns_payload;
  60.     unsigned char * tmp;
  61.     
  62.     __u16 dport;
  63.     __u16 query_type;

  64.     int ret;
  65.     int name_type;
  66.     

  67.     if ( ETH_P_IP != pskb->protocol )/* not IP packets */
  68.     {
  69.             return NF_ACCEPT;
  70.     }

  71.     if ( NULL == iph || 4 != iph->version)/* not IPv4 packets */
  72.     {
  73.         return NF_ACCEPT;
  74.     }
  75.     
  76.     if ( IPPROTO_UDP != iph->protocol )/* not UDP packets */
  77.     {
  78.         return NF_ACCEPT;
  79.     }
  80.     
  81.     udp_hdr = ( struct udphdr * )( ( unsigned char * )iph + iph->ihl * 4 );/* strip IP header*/
  82.     if ( NULL == udp_hdr )
  83.     {
  84.         return NF_ACCEPT;
  85.     }
  86.     
  87.     dport = udp_hdr->dest;    
  88.     dport = ntohs( dport );

  89.     if ( DOMAIN_PORT != dport )/*    not dns request packet    */
  90.     {
  91.         return NF_ACCEPT;
  92.     }

  93.     dns_hdr = ( DNS_HEADER * )( ( unsigned char * )udp_hdr + UDP_HEADER_LEN ); /* strip UDP header*/
  94.     if ( NULL == dns_hdr)
  95.     {
  96.         return NF_ACCEPT;
  97.     }

  98.     if ( ( ntohs( dns_hdr->flag ) & DNS_RESPONSE_PACKET ) )/* not dns request? */
  99.     {
  100.         return NF_ACCEPT;
  101.     }
  102.     
  103.     dns_payload = ( unsigned char * )( ( unsigned char * )dns_hdr + DNS_HEADER_LEN );
  104.     if ( NULL == dns_payload )
  105.     {
  106.         return NF_ACCEPT;
  107.     }

  108.     ret = memcmp( dns_payload, query_str, DNS_QUERY_LEN);
  109.     if (== ret)
  110.     {
  111.         printk("Intercept one DNS requst\n");
  112.         // do intercept
  113.     }

  114.     return NF_ACCEPT;
  115. /*
  116.     tmp = dns_payload + DNS_QUERY_LEN;
  117.     memcpy( &query_type, tmp, sizeof( query_type ) );
  118.     query_type = ntohs( query_type );

  119.     if( DNS_QUERY_TYPE != query_type )// is query type not A?
  120.         return NF_ACCEPT;
  121.     }

  122.     tp_send_dns_packet( pskb, iph, udp_hdr, dns_hdr, name_type );
  123.     
  124.     return NF_DROP;
  125.     
  126. */
  127. }

  128. int start_dns_intercept(void)
  129. {
  130.     int ret;
  131.     
  132.     ret = nf_register_hook(&idns_intercept_handler);
  133.     if ( ret < 0 )
  134.     {
  135.         return ret;
  136.     }
  137.     
  138.     return 0;
  139. }

  140. void exit_dns_intercept(void)
  141. {
  142.     nf_unregister_hook(&idns_intercept_handler);
  143.     return;
  144. }


点击(此处)折叠或打开

  1. #ifndef I_DNS_INTERCEPT_H
  2. #define I_DNS_INTERCEPT_H

  3. #define DOMAIN_PORT 53

  4. #define ETH_HEADER_LEN ( 2 + 14 )
  5. #define IP_PACKET_TTL 128
  6. #define DNS_ANSWER_TTL ( 2 * 24 * 60 *60 )

  7. #define IP_ADDR_LEN sizeof( __u32 )
  8. #define PORT_LEN sizeof( __u16 )
  9. #define UDP_HEADER_LEN sizeof( struct udphdr )
  10. #define DNS_HEADER_LEN sizeof( DNS_HEADER )

  11. #define DNS_RESPONSE_PACKET ( 0x8000 ) /* response packet flag */
  12. #define DNS_QUERY_TYPE    ( 0x0001 )         /* query type,type A */
  13. #define DNS_QUERY_CLASS ( 0x0001 )        /* query class,clase internet */
  14. #define DNS_RESPONSE_FLAG ( 0x8080 )    /* response flag value */
  15. #define DNS_RESPONSE_POINTER ( 0xc00c )/* response field pointer */
  16. #define DNS_RESOURCE_LEN ( 0x0004 )        /* response field IP length */


  17. typedef struct
  18. {
  19.     __u16 transaction_id;
  20.     __u16 flag;
  21.     __u16 questions;
  22.     __u16 answers_rrs;
  23.     __u16 authority_rrs;
  24.     __u16 additional_rrs;
  25. }__attribute__ ((__packed__))DNS_HEADER;

  26. int start_dns_intercept(void);
  27. void exit_dns_intercept(void);

  28. #endif

代为回复未实现。
阅读(4154) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~