Chinaunix首页 | 论坛 | 博客
  • 博客访问: 78145
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 225
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-06 15:31
文章分类

全部博文(29)

文章存档

2015年(18)

2014年(11)

我的朋友

分类: LINUX

2015-01-08 10:14:40

使用时需按情况修改,并添加如iptables -A INPUT -j NFQUEUE --queue-num 0之类的iptables规则                                              

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <errno.h>
  7. #include <termios.h>
  8. #include <netinet/in.h>
  9. #include <linux/types.h>
  10. #include <linux/netfilter.h> /* for NF_ACCEPT */
  11. #include <linux/ip.h>
  12. #include <linux/udp.h>
  13. #include <linux/if_ether.h>
  14. //#include <arpa/inet.h>
  15. #include <asm/byteorder.h>

  16. #include <libnetfilter_queue/libnetfilter_queue.h>
  17. #include <libnetfilter_queue/libnetfilter_queue_udp.h>

  18. #ifdef __LITTLE_ENDIAN
  19. #define IPQUAD(addr) \
  20. ((unsigned char *)&addr)[0], \
  21. ((unsigned char *)&addr)[1], \
  22. ((unsigned char *)&addr)[2], \
  23. ((unsigned char *)&addr)[3]
  24. #else
  25. #define IPQUAD(addr) \
  26. ((unsigned char *)&addr)[3], \
  27. ((unsigned char *)&addr)[2], \
  28. ((unsigned char *)&addr)[1], \
  29. ((unsigned char *)&addr)[0]
  30. #endif

  31. #define IP_HDR_LEN 20
  32. #define UDP_HDR_LEN 8
  33. #define TOT_HDR_LEN 28

  34. struct rtphdr
  35. {
  36.     __u8 cc:4;
  37.     __u8 x:1;
  38.     __u8 p:1;
  39.     __u8 v:2;
  40.     __u8 pt:7;
  41.     __u8 m:1;

  42.     __u16 seq;
  43.     __u16 ts;
  44.     __u32 ssrc;
  45.     __u32 csrc[1];
  46. };

  47. /******************************************************/
  48. long checksum(unsigned short *addr,unsigned int count) {
  49.     register long sum = 0;
  50.     while(count>1){
  51.         sum += *addr++;
  52.         count -= 2;
  53.     }
  54.     if(count > 0)
  55.         sum += *(unsigned char *)addr;
  56.     
  57.     while(sum>>16)
  58.         sum = (sum &0xffff) + (sum>>16);
  59.         
  60.     return ~sum;
  61. }

  62. static u_int16_t ip_checksum(struct iphdr* iph) {
  63.     return checksum((unsigned short *)iph,iph->ihl<<2);
  64. }

  65. static void set_ip_checksum(struct iphdr* iph) {
  66.     iph->check = 0;
  67.     iph->check = checksum((unsigned short *)iph,iph->ihl<<2);;
  68. }

  69. static void set_udp_checksum(struct iphdr *pIph, unsigned short *ipPayload) {
  70.     register unsigned long sum = 0;
  71.     struct udphdr *udphdrp = (struct udphdr*)(ipPayload);
  72.     unsigned short udpLen = htons(udphdrp->len);

  73.     sum += (pIph->saddr>>16)&0xFFFF;
  74.     sum += (pIph->saddr)&0xFFFF;
  75.     sum += (pIph->daddr>>16)&0xFFFF;
  76.     sum += (pIph->daddr)&0xFFFF;
  77.     sum += htons(IPPROTO_UDP);
  78.     sum += udphdrp->len;

  79.     udphdrp->check = 0;
  80.     while(udpLen > 1){
  81.         sum += *ipPayload++;
  82.         udpLen -= 2;
  83.     }

  84.     if(udpLen > 0){
  85.         sum += ((*ipPayload)&htons(0xFF00));
  86.     }
  87.     
  88.     while(sum>>16){
  89.         sum = (sum & 0xFFFF) + (sum>>16);
  90.     }
  91.     
  92.     sum = ~sum;
  93.     udphdrp->check = ((unsigned short)sum == 0x0000)?0xFFFF:(unsigned short)sum;
  94. }
  95. /*********************************************************/

  96. static int is_target_packet(char *data){
  97.     struct iphdr *iph;
  98.     struct udphdr *udph;
  99.     struct rtphdr *rtph;
  100.     int i;
  101.     
  102.     //char* mydata;
  103.     unsigned int dst_port,src_port;
  104.     int result = 0;

  105.     iph = (struct iphdr *)data;
  106.     if(iph)
  107.     {
  108.         if(iph->protocol == IPPROTO_UDP){
  109.             udph = (struct udphdr *)(data+20);
  110.             dst_port = ntohs(udph->dest);
  111.             src_port = ntohs(udph->source);
  112.             if(dst_port != 5060 && src_port != 5060){
  113.                 if(src_port >= 1024 && dst_port >= 1024){
  114.                     if(src_port%2 == 0 && dst_port%2 == 0){
  115.                     i = ntohs(iph->tot_len)-28;
  116.                         if(i > 12){
  117.                             rtph = (struct rtphdr *)(data+28);
  118.                             if(rtph->v == 2){
  119.                                 unsigned int j = rtph->cc;
  120.                                 unsigned int hdrlen = j*4+12;
  121.                                 if(i > hdrlen){
  122.                                     result = 1;
  123.                                 }
  124.                             }
  125.                         }
  126.                     }
  127.                 }
  128.             }
  129.         }
  130.     }
  131.     return result;
  132. }

  133. static void encrypt_payload(char **data) {
  134. }

  135. /* returns packet id */
  136. static u_int32_t edit_pkt (struct nfq_data *tb)
  137. {
  138.     int id = 0;
  139.     struct nfqnl_msg_packet_hdr *ph;
  140.     struct nfqnl_msg_packet_hw *hwph;
  141.     u_int32_t mark,ifi;
  142.     int ret,n,rtp_hdr_len;
  143.     char *data;
  144.     char *rtp_payload;
  145.     char *ip_payload;
  146.     struct iphdr *iph;
  147.     struct udphdr *udph;
  148.     struct rtphdr *rtph;

  149.     ret = nfq_get_payload(tb, &data);
  150.     if (ret >= 0)
  151.         printf("payload_len=%d ", ret);
  152.         
  153.     n = is_target_packet(data);
  154.     if(n == 1){
  155.         iph = (struct iphdr *)(data);
  156.         ip_payload = data + IP_HDR_LEN;
  157.         udph = (struct udphdr *)(data + IP_HDR_LEN);
  158.         rtph = (struct rtphdr *)(data + TOT_HDR_LEN);
  159.         rtp_hdr_len = (rtph->cc)*4+12;
  160.         rtp_payload = data + TOT_HDR_LEN +rtp_hdr_len;
  161.         encrypt_payload(&rtp_payload);
  162.         set_ip_checksum(iph);
  163.         set_udp_checksum(iph,(unsigned short *)ip_payload);
  164.     }
  165.     
  166.     fputc('\n', stdout);

  167.     return id;
  168. }


  169. static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
  170.           struct nfq_data *nfa, void *data)
  171. {
  172.     u_int32_t id = edit_pkt(nfa);
  173.     printf("entering callback\n");
  174.     return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
  175. }

  176. int main(int argc, char **argv)
  177. {
  178.     struct nfq_handle *h;
  179.     struct nfq_q_handle *qh;
  180.     int fd;
  181.     int rv;
  182.     char buf[4096] __attribute__ ((aligned));

  183.     printf("opening library handle\n");
  184.     h = nfq_open();
  185.     if (!h) {
  186.         fprintf(stderr, "error during nfq_open()\n");
  187.         exit(1);
  188.     }

  189.     printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
  190.     if (nfq_unbind_pf(h, AF_INET) < 0) {
  191.         fprintf(stderr, "error during nfq_unbind_pf()\n");
  192.         exit(1);
  193.     }

  194.     printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
  195.     if (nfq_bind_pf(h, AF_INET) < 0) {
  196.         fprintf(stderr, "error during nfq_bind_pf()\n");
  197.         exit(1);
  198.     }

  199.     printf("binding this socket to queue '0'\n");
  200.     qh = nfq_create_queue(h, 0, &cb, NULL);
  201.     if (!qh) {
  202.         fprintf(stderr, "error during nfq_create_queue()\n");
  203.         exit(1);
  204.     }

  205.     printf("setting copy_packet mode\n");
  206.     if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
  207.         fprintf(stderr, "can't set packet_copy mode\n");
  208.         exit(1);
  209.     }

  210.     fd = nfq_fd(h);

  211.     while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
  212.         printf("pkt received\n");
  213.         nfq_handle_packet(h, buf, rv);
  214.     }

  215.     printf("unbinding from queue 0\n");
  216.     nfq_destroy_queue(qh);

  217. #ifdef INSANE
  218.     /* normally, applications SHOULD NOT issue this command, since
  219.      * it detaches other programs/sockets from AF_INET, too ! */
  220.     printf("unbinding from AF_INET\n");
  221.     nfq_unbind_pf(h, AF_INET);
  222. #endif

  223.     printf("closing library handle\n");
  224.     nfq_close(h);

  225.     exit(0);
  226. }
阅读(1963) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

189751725852017-04-09 00:39:05

请问楼主方便留QQ嘛

星闪夜空2016-12-13 20:33:45

请问这个程序你自己测试过没有?它真的能够修改数据包吗?