Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4826471
  • 博文数量: 930
  • 博客积分: 12070
  • 博客等级: 上将
  • 技术积分: 11448
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-15 16:57
文章分类

全部博文(930)

文章存档

2011年(60)

2010年(220)

2009年(371)

2008年(279)

分类: LINUX

2010-01-13 14:31:31

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/route.h>
#include <net/icmp.h>
#include <linux/netfilter_ipv4.h>
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kenthy@163.com");

#define ETH "eth0"
#define SIP "192.168.238.180"
#define DIP "192.168.1.101"
#define SPORT 39804
#define DPORT 80

unsigned char SMAC[ETH_ALEN] = {0x00,0x0C,0x29,0x4F,0xDE,0xAC};
unsigned char DMAC[ETH_ALEN] = {0x00,0x50,0x56,0xFA,0x70,0x2A};

static struct nf_hook_ops modify_http;
static int flag = 0;

int cp_dev_xmit_tcp (struct iphdr* o_iph, struct tcphdr* o_tcph, char* pkt,int pkt_len)
{
  struct sk_buff * skb = NULL;
  struct net_device * dev = NULL;
  struct ethhdr * ethdr = NULL;
  struct iphdr * iph = NULL;
  struct tcphdr * tcph = NULL;
  u_char * pdata = NULL;
  int nret = 1;
  int i = 0;
  int ko = 0;
  
  if (NULL == SMAC || NULL == DMAC) goto out;

  dev = dev_get_by_name(ETH);
  if (NULL == dev)
   goto out;

  skb = alloc_skb (pkt_len + 1 + sizeof (struct iphdr) + sizeof (struct tcphdr) + LL_RESERVED_SPACE (dev), GFP_ATOMIC);
  
  if (NULL == skb)
    goto out;
  
  skb_reserve (skb, LL_RESERVED_SPACE (dev));

  skb->dev = dev;
  skb->pkt_type = PACKET_OTHERHOST;
  skb->protocol = __constant_htons(ETH_P_IP);
  skb->ip_summed = CHECKSUM_NONE;
  skb->priority = 0;
  
  skb->nh.iph = (struct iphdr*)skb_put(skb, sizeof (struct iphdr));
  skb->h.th = (struct tcphdr*)skb_put(skb, sizeof (struct tcphdr));
 
  pdata = skb_put (skb, pkt_len+1);
  {
    if (NULL != pkt)
     {
         while(i<=pkt_len)
          {
              if(*pkt == '1' && ko == 0)
                  {
                      pdata[i++] = '1';
          ko++;
          }
              pdata[i++] = *pkt++;
       }
     //     memcpy (pdata, pkt, pkt_len);

    }
  }
  
 
  {
    tcph = (struct tcphdr *) skb->h.th;
    memset (tcph, 0, sizeof (struct tcphdr));
    tcph->source = o_tcph->source;
    tcph->dest = o_tcph->dest;
    tcph->seq = o_tcph->seq;
    tcph->ack_seq = o_tcph->ack_seq;
    tcph->doff = o_tcph->doff;
    tcph->psh = o_tcph->psh;
    tcph->fin = o_tcph->fin;
    tcph->syn = o_tcph->syn;
    tcph->ack = o_tcph->ack;
    tcph->window = o_tcph->window;
    skb->csum = 0;
    tcph->check = 0;
  }
  
  {
    iph = (struct iphdr*) skb->nh.iph;
    iph->version = 4;
    iph->ihl = sizeof(struct iphdr)>>2;
    iph->frag_off = 0;
    iph->protocol = IPPROTO_TCP;
    iph->tos = 0;
    iph->daddr = o_iph->daddr;
    iph->saddr = o_iph->saddr;
    iph->ttl = 0x40;
    iph->tot_len = __constant_htons(skb->len);
    iph->check = 0;
  }
  
  skb->csum = skb_checksum (skb, iph->ihl*4, skb->len - iph->ihl * 4, 0);
  tcph->check = csum_tcpudp_magic (iph->saddr, iph->daddr, skb->len - iph->ihl * 4, IPPROTO_TCP, skb->csum);

  
  skb->mac.raw = skb_push (skb, 14);
  {
    ethdr = (struct ethhdr *)skb->mac.raw;
    memcpy (ethdr->h_dest, DMAC, ETH_ALEN);
    memcpy (ethdr->h_source, SMAC, ETH_ALEN);
    ethdr->h_proto = __constant_htons (ETH_P_IP);
  }

 
  if (0 > dev_queue_xmit(skb)) goto out;
  
  nret = 0;
 out:
  if (0 != nret && NULL != skb) {dev_put (dev); kfree_skb (skb);}
  
  return (nret);
}

int check_http(const unsigned char* haystack, unsigned int len)
{
   if(len<8)
        return 0;

   if(memcmp(haystack, "GET ", 4) == 0)
       {
         printk("%s\n", "HTTP GET");
         return 4;
       }
    else if (memcmp(haystack, "POST ", 5) == 0)
         {
          printk("%s\n", "HTTP POST");
          return 5;
     }
    else if (memcmp(haystack, "OPTIONS ", 8) == 0)
         {
          printk("%s\n", "HTTP OPTINOS");
         return 8;
     }
     else if (memcmp(haystack, "HEAD ", 5) == 0)
         {
          printk("%s\n", "HTTP HEAD");
         return 5;
     }
    else if (memcmp(haystack, "PUT ", 4) == 0)
        {        
          printk("%s\n", "HTTP PUT");
         return 4;
     }
    else if (memcmp(haystack, "DELETE ", 7) == 0)
     {
          printk("%s\n", "HTTP DELETE");
        return 7;
     }
 else if (memcmp(haystack, "CONNECT ", 8) == 0) {
          printk("%s\n", "HTTP CONNECT");
        return 8;
    }
    
    return 0;
}

unsigned int
http(unsigned int hooknum,
                 struct sk_buff** skb,
                 const struct net_device *in,
                 const struct net_device *out,
                 int (*okfn)(struct sk_buff*))
{
    struct iphdr *iph = NULL;
    struct tcphdr *tcph = NULL;
    struct tcphdr _otcph;
    unsigned char* packet;
    int plen;
    int ret = 0;

    iph = ip_hdr(*skb);
    packet =(char*)iph+(iph->ihl*4);
    plen = ntohs(iph->tot_len)-(iph->ihl*4);

    if (iph->protocol == IPPROTO_TCP && flag == 0) {
        tcph = skb_header_pointer(*skb, ip_hdrlen(*skb), sizeof(_otcph), &_otcph);
       
        packet += tcph->doff*4;
        plen -= tcph->doff*4;
     
        ret = check_http(packet, plen);
        if(ret>0)
          printk("ret is %d and is http get\n", ret);
        
        if(plen>0)
         {
              cp_dev_xmit_tcp(iph, tcph, packet, plen);
           flag++;
           return NF_STOLEN;
          }
    }

    return NF_ACCEPT;
}

static int __init init(void)
{
   int ret;
   modify_http.hook = http;
   modify_http.owner = THIS_MODULE;
   modify_http.pf = PF_INET;
   modify_http.hooknum = NF_IP_LOCAL_OUT;
   modify_http.priority = NF_IP_PRI_FIRST;
   
   ret = nf_register_hook(&modify_http);
    if (ret < 0) {
        printk("http detect:can't register http_ops hook!\n");
        return ret;
    }
    printk("insmod http_ops module\n");
    return 0;
}

static void __exit fini(void)
{
  nf_unregister_hook(&modify_http);
  printk("remove http_ops module.\n");
}

module_init(init);
module_exit(fini);

 

大概就是把本机请求为 url/index1.html的修改为url/index11.html  具体怎么修改可以根据自己情况来修改代码

阅读(3229) | 评论(0) | 转发(2) |
0

上一篇:linux nc命令示例

下一篇:几个内核ARP参数

给主人留下些什么吧!~~