Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1007212
  • 博文数量: 442
  • 博客积分: 1146
  • 博客等级: 少尉
  • 技术积分: 1604
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-04 12:52
个人简介

123

文章分类

全部博文(442)

文章存档

2017年(3)

2016年(15)

2015年(132)

2014年(52)

2013年(101)

2012年(110)

2011年(29)

分类: LINUX

2013-10-11 17:09:21

原文地址:一个IP碎片包发送程序 作者:duanjigang

功能:通过IP碎片包的发送来构造一个UDP报文,可以帮助TCP/IP协议的学习者理解IP层分包和传输的原理,而且这个程序能够用来测试防火墙或者IPS的碎片包重组功能。

程序通过修改开关变量能控制发送乱序包和顺序包。
备注:

fragrout和jolt2发送的都是乱序和不完整的ip碎片,不能重组成完整的上层报文,因为他么是用来模拟碎片攻击的,为了通过碎片来发送一个完整的ip包,鄙人对jolt2的代码做了些许修改。

声明:如有转载,请著名出处和作者信息。


  1. //ipdefrag.c mod from jolt2.c by cme@2010-06-11 <duanjigang1983@126.com, QQ:84025840>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <netdb.h>
  7. #include <sys/socket.h>
  8. #include <sys/types.h>
  9. #include <netinet/in.h>
  10. #include <netinet/ip.h>
  11. #include <netinet/ip_icmp.h>
  12. #include <netinet/udp.h>
  13. #include <arpa/inet.h>
  14. #include <getopt.h>
  15. #define DATA_LEN 8
  16. struct
  17. {
  18.  struct iphdr ip;
  19.  union
  20.  {
  21.   struct icmphdr icmp;
  22.   struct udphdr udp;
  23.  } proto;
  24.  char data[DATA_LEN];
  25. } first_pkt;
  26. struct
  27. {
  28.  struct iphdr ip;
  29.  char data[DATA_LEN];
  30. } data;
  31. int icmplen = sizeof(struct icmphdr),
  32. udplen = sizeof(struct udphdr),
  33. iplen = sizeof(struct iphdr),
  34. spf_sck;
  35. //1 按照自然序发送碎片 0 乱序发送碎片
  36. #define send_pkt_in_turns 1
  37. //发送碎片个数
  38. #define send_time 20
  39. void quit(char *reason)
  40. {
  41.  perror(reason);
  42.  close(spf_sck);
  43.  exit(-1);
  44. }
  45. int do_frags (int sck, u_long src_addr, u_long dst_addr, int port)
  46. {
  47.  int bs, psize;
  48.  unsigned long x;
  49.  struct sockaddr_in to;
  50.  u_int16_t seq = 0;
  51.  u_int16_t flag = 8192;
  52.  to.sin_family = AF_INET;
  53.  to.sin_port = 10000;
  54.  to.sin_addr.s_addr = dst_addr;
  55.  
  56.  if (port)
  57.  {
  58.   psize = iplen + udplen + DATA_LEN;
  59.  }
  60.  else
  61.  {
  62.   psize = iplen + icmplen + DATA_LEN;
  63.  }
  64.  memset(&first_pkt, 0, psize);
  65.  
  66.  first_pkt.ip.version = 4;
  67.  first_pkt.ip.ihl = 5;
  68.  first_pkt.ip.tot_len = htons(iplen + icmplen) + 40;
  69.  first_pkt.ip.ttl = 255;
  70.  first_pkt.ip.protocol = (port ? IPPROTO_UDP : IPPROTO_ICMP);
  71.  first_pkt.ip.saddr = src_addr;
  72.  first_pkt.ip.daddr = dst_addr;
  73.  
  74.  
  75.  if (port)
  76.  {
  77.   first_pkt.proto.udp.source = htons(port);
  78.   first_pkt.proto.udp.dest = htons(port);
  79.   first_pkt.proto.udp.len = htons(8);
  80.  } else
  81.  {
  82.   first_pkt.proto.icmp.type = ICMP_ECHO;
  83.   first_pkt.proto.icmp.code = 0;
  84.   first_pkt.proto.icmp.checksum = 0;
  85.  }
  86.  first_pkt.ip.frag_off = htons(8192);
  87.  first_pkt.ip.id = htons(1);
  88.  first_pkt.ip.saddr = src_addr;
  89.  strncpy(first_pkt.data, "aaaaaaaa", 8);
  90.  memcpy(&data.ip, &first_pkt.ip, sizeof(struct iphdr));
  91.  
  92.  for (seq = 1; seq <= send_time; seq++)
  93.  {
  94.   int i = 0;
  95.   char ch;
  96.   switch(seq)
  97.   {
  98.   case 1: //first pkt, frag off is 00100000 00000000
  99.    data.ip.frag_off = htons(flag);
  100.    break;
  101.   case send_time: //last pkt, mf set to 0, frag off is 000xxxxx xxxxxxxx, xx is the seq value
  102.    data.ip.frag_off = htons(send_time); //last pkt mf is set to zero
  103.    break;
  104.   default:// pkt in middle, frag off is 001xxxxx xxxxxxxx
  105.    data.ip.frag_off =
  106.     send_pkt_in_turns ? htons(flag|(seq)):htons(flag|(send_time - seq + 1));
  107.    break;
  108.   }
  109.   ch = 'a' + seq - 1;
  110.   for (i = 0; i < DATA_LEN; i++)
  111.   {
  112.    data.data[i] = ch;
  113.   }
  114.   
  115.   if (seq == 1)
  116.    bs = sendto(sck, &first_pkt, psize, 0,
  117.    (struct sockaddr *) &to, sizeof(struct sockaddr));
  118.   else
  119.    bs = sendto(sck, &data, psize - udplen, 0,
  120.    (struct sockaddr *) &to, sizeof(struct sockaddr));
  121.  }
  122.  return bs;
  123. }
  124. int main(int argc, char *argv[])
  125. {
  126.  u_long src_addr, dst_addr;
  127.  int i, bs=1, port=0;
  128.  char hostname[32];
  129.  if (argc !=4)
  130.  {
  131.   printf ("usage:%s srcaddr dest_port destaddr\n");
  132.   return 0;
  133.  }
  134.  spf_sck = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  135.  if (!spf_sck)
  136.   quit("socket()");
  137.  if (setsockopt(spf_sck, IPPROTO_IP, IP_HDRINCL, (char *)&bs,
  138.   sizeof(bs)) < 0)
  139.   quit("IP_HDRINCL");
  140.  do_frags (spf_sck, inet_addr(argv[1]), inet_addr(argv[3]), atoi(argv[2]));
  141. }

阅读(786) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~