Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30831
  • 博文数量: 6
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 71
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-23 21:40
文章分类

全部博文(6)

文章存档

2014年(2)

2013年(2)

2012年(2)

我的朋友

分类: LINUX

2013-07-07 16:29:44


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <linux/if_ether.h>
  8. #include <linux/sockios.h>
  9. #include <sys/socket.h>
  10. #include <netpacket/packet.h>
  11. #include <net/ethernet.h>
  12. #include <net/if_arp.h>
  13. #include <net/if.h>


  14. #define DESTPORT 80
  15. #define LOCALPORT 0x8888

  16. /* Buffer Size */
  17. #define SND_BUF_SIZE 1024*5

  18. /* Buffer */
  19. static int g_iSendBufSize = SND_BUF_SIZE;

  20. static int g_iRecvBufSize = SND_BUF_SIZE;

  21. static unsigned long seqno, ackno;    //save sequence no and ackment no

  22. extern int errno;

  23. /* Prseuheader */
  24. struct prseuheader
  25. {
  26.     unsigned long s_addr;
  27.     unsigned long d_addr;
  28.     unsigned char zero;
  29.     unsigned char prototp;
  30.     unsigned short len;
  31. };

  32. /* IP Head */
  33. struct IP_Head
  34. {
  35.     unsigned char length:4;
  36.     unsigned char version:4;
  37.     unsigned char tos;
  38.     unsigned short total_length;
  39.     unsigned short id;
  40.     unsigned short flagoff;
  41.     unsigned char ttl;
  42.     unsigned char protocol;
  43.     unsigned short chksum;
  44.     unsigned int source;
  45.     unsigned int dest;
  46. };

  47. /* TCP Head */
  48. struct TCP_Head
  49. {
  50.     unsigned short source_port;
  51.     unsigned short dest_port;
  52.     unsigned int seqno;
  53.     unsigned int ackno;
  54.     unsigned char rev1:4;
  55.     unsigned char len:4;
  56.     unsigned char fin:1;
  57.     unsigned char syn:1;
  58.     unsigned char rst:1;
  59.     unsigned char psh:1;
  60.     unsigned char ack:1;
  61.     unsigned char urg:1;
  62.     unsigned char rev2:2;
  63.     unsigned short winsize;
  64.     unsigned short chksum;
  65.     unsigned short urgent;
  66. };

  67. /* Check sum */
  68. unsigned short
  69. checksum (unsigned short *buffer, int size)
  70. {
  71.     unsigned long cksum = 0;

  72.     while (size > 1)
  73.     {
  74.         cksum += *buffer++;
  75.         size -= 2;
  76.     }
  77.     if (size)
  78.     {
  79.         cksum += *(u_char *) buffer;
  80.     }
  81.     cksum = (cksum >> 16) + (cksum & 0xffff);
  82.     cksum += (cksum >> 16);
  83.     return (unsigned short) (~cksum);
  84. }

  85. //Create SOCK_RAW
  86. int
  87. creat_raw ()
  88. {
  89.     int sk;

  90.     sk = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL));
  91.     if (sk < 0)
  92.     {
  93.         strerror (errno);
  94.         return -1;
  95.     }
  96.     return sk;
  97. }

  98. //Set sock option
  99. int
  100. set_promisc (int sk)
  101. {
  102. //    struct ifreq ifr;
  103. //
  104. //    strcpy (ifr.ifr_name, "eth0");
  105. //    if ((ioctl (sk, SIOCGIFFLAGS, &ifr) == -1))
  106. //    {
  107. //        strerror (errno);
  108. //    }
  109. //    ifr.ifr_flags |= IFF_PROMISC;
  110. //    if (ioctl (sk, SIOCSIFFLAGS, &ifr) == -1)
  111. //    {
  112. //        strerror (errno);
  113. //    }
  114.     return 0;
  115. }

  116. /* fill ip head */
  117. int
  118. fill_iph (unsigned char buffer[])
  119. {
  120.     struct IP_Head *pIph;

  121.     int total_len = sizeof (struct IP_Head) + sizeof (struct TCP_Head);


  122.     pIph = (struct IP_Head *) buffer;

  123.     pIph->length = 5;
  124.     pIph->version = 4;
  125.     pIph->tos = 0;
  126.     pIph->total_length = htons (total_len);
  127.     pIph->id = 0;
  128.     pIph->flagoff = htons (0x4000);
  129.     pIph->ttl = 255;
  130.     pIph->protocol = 6;
  131.     pIph->chksum = 0;
  132.     pIph->source = inet_addr ("192.168.1.2");    //Local PC 写上自己网卡的IP
  133.     pIph->dest = inet_addr ("119.75.217.56");    //remote PC 服务器的IP
  134.     pIph->chksum =
  135.         checksum ((unsigned short *) pIph, sizeof (struct IP_Head));

  136.     return 0;
  137. }

  138. /* fill tcp head */
  139. int
  140. fill_tcp (unsigned char buffer[], unsigned char control)
  141. {
  142.     struct TCP_Head *pTcph;

  143.     pTcph = (struct TCP_Head *) (buffer + sizeof (struct IP_Head));

  144.     pTcph->source_port = htons (LOCALPORT);
  145.     pTcph->dest_port = htons (DESTPORT);
  146.     pTcph->seqno = htonl (seqno);
  147.     pTcph->ackno = htonl (ackno);
  148.     pTcph->rev1 = 0;
  149.     pTcph->len = 5;
  150.     pTcph->fin = control & 0x01 ? 1 : 0;
  151.     pTcph->syn = control & 0x02 ? 1 : 0;
  152.     pTcph->rst = control & 0x04 ? 1 : 0;
  153.     pTcph->psh = control & 0x10 ? 1 : 0;
  154.     pTcph->ack = control & 0x20 ? 1 : 0;
  155.     pTcph->urg = control & 0x40 ? 1 : 0;
  156.     pTcph->rev2 = 0;
  157.     pTcph->winsize = htons (1000);
  158.     pTcph->chksum = 0;
  159.     pTcph->urgent = 0;

  160.     return 0;
  161. }

  162. //send tcp packet
  163. int
  164. sendto_packet (int sk, unsigned char buffer[])
  165. {
  166.     int iRet;

  167.     struct IP_Head *pIph;

  168.     struct TCP_Head *pTcph;

  169.     struct prseuheader theheader;

  170.     char tcpbuff[32];            //it include prseuheader and tcp head

  171.     int total_len = sizeof (struct IP_Head) + sizeof (struct TCP_Head);

  172.     struct sockaddr_ll addr;

  173.     pIph = (struct IP_Head *) buffer;
  174.     pTcph = (struct TCP_Head *) (buffer + sizeof (struct IP_Head));

  175.     bzero (&addr, sizeof (struct sockaddr_ll));
  176.     addr.sll_family = htons (PF_PACKET);
  177.     addr.sll_protocol = htons (ETH_P_IP);
  178.     addr.sll_ifindex = if_nametoindex ("eth0");//换成你的网口的名字
  179.     addr.sll_addr[0] = 0x08;//
  180.     addr.sll_addr[1] = 0x10;//
  181.     addr.sll_addr[2] = 0x74;//换成你的网关的MAC地址就行了
  182.     addr.sll_addr[3] = 0xC9;//
  183.     addr.sll_addr[4] = 0x0B;//
  184.     addr.sll_addr[5] = 0x16;//

  185.     bzero (tcpbuff, 32);
  186.     theheader.s_addr = pIph->source;
  187.     theheader.d_addr = pIph->dest;
  188.     theheader.zero = 0;
  189.     theheader.prototp = 6;
  190.     theheader.len = htons (20);    //the size of TCP head

  191.     memcpy (tcpbuff, &theheader, 12);
  192.     memcpy (tcpbuff + 12, pTcph, 20);
  193.     pTcph->chksum = 0;
  194.     pTcph->chksum = checksum ((unsigned short *) tcpbuff, 32);

  195.     iRet =
  196.         sendto (sk, buffer, total_len, 0, (struct sockaddr *) &addr,
  197.                 sizeof (struct sockaddr_ll));
  198.     if (iRet < 0)
  199.     {
  200.         strerror (errno);
  201.         return -1;
  202.     }

  203.     return 0;
  204. }

  205. //receive tcp packet and display IP Head and TCP Head
  206. int
  207. recvfrom_packet (int sk, unsigned char buffer[])
  208. {
  209.     int iRet;

  210.     int lenfrom = sizeof (struct sockaddr_in);

  211.     struct sockaddr_in addr;

  212.     struct in_addr in;

  213.     struct IP_Head *pIph;

  214.     struct TCP_Head *pTcph;

  215.     fd_set fdR;

  216.     struct timeval timeout;

  217.     //Set Non-block
  218.     bzero (&addr, sizeof (struct sockaddr_in));
  219.     while (1)
  220.     {
  221.         iRet =
  222.             recvfrom (sk, buffer, g_iRecvBufSize, 0,
  223.                      (struct sockaddr *) &addr, &lenfrom);
  224.         if (iRet < 0)
  225.         {
  226.             printf ("error recvfrom\n");
  227.             return -1;
  228.         }
  229.         else
  230.         {
  231.             pIph = (struct IP_Head *) buffer;
  232.             pTcph = (struct TCP_Head *) (buffer + pIph->length * 4);
  233.             if ((pIph->protocol!=6) || ntohs (pTcph->dest_port) != 0x8888)
  234.             {
  235.                 continue;
  236.             }
  237.             //Display IP Head
  238.             printf ("Parse IP......\n");
  239.             printf ("length:%x\n", pIph->length);
  240.             printf ("version:%x\n", pIph->version);
  241.             printf ("tos:%x\n", pIph->tos);
  242.             printf ("total_length:%d\n", ntohs (pIph->total_length));
  243.             printf ("id:%d\n", ntohs (pIph->id));
  244.             printf ("flagoff:%x\n", ntohs (pIph->flagoff));
  245.             printf ("ttl:%d\n", pIph->ttl);
  246.             printf ("protocol:%d\n", pIph->protocol);
  247.             printf ("cksum:%x\n", ntohs (pIph->chksum));
  248.             in.s_addr = pIph->source;
  249.             printf ("SIP:%s\n", inet_ntoa (in));
  250.             in.s_addr = pIph->dest;
  251.             printf ("DIP:%s\n", inet_ntoa (in));

  252.             //Display TCP Head
  253.             printf ("Parse TCP......\n");
  254.             printf ("source_port:%d\n", ntohs (pTcph->source_port));
  255.             printf ("dest_port:%d\n", ntohs (pTcph->dest_port));
  256.             printf ("seqno:%d\n", ntohl (pTcph->seqno));
  257.             printf ("ackno:%d\n", ntohl (pTcph->ackno));
  258.             printf ("len:%d\n", pTcph->len);
  259.             printf ("fin:%d\n", pTcph->fin);
  260.             printf ("syn:%d\n", pTcph->syn);
  261.             printf ("rst:%d\n", pTcph->rst);
  262.             printf ("psh:%d\n", pTcph->psh);
  263.             printf ("ack:%d\n", pTcph->ack);
  264.             printf ("urg:%d\n", pTcph->urg);
  265.             printf ("winsize:%d\n", ntohs (pTcph->winsize));
  266.             printf ("urgent:%d\n", ntohs (pTcph->urgent));
  267.             printf ("\n");

  268.             seqno = ntohl (pTcph->seqno);
  269.             ackno = ntohl (pTcph->ackno);
  270.             
  271.             return;
  272.         }
  273.     }
  274. }

  275. //Main
  276. int
  277. main ()
  278. {
  279.     int sk;

  280.     unsigned char buffers[g_iSendBufSize];    //send buffer

  281.     unsigned char bufferr[g_iRecvBufSize];    //receive buffer

  282.     int iRet;

  283.     unsigned long temp;


  284.     sk = creat_raw ();
  285.     if (sk < 0)
  286.     {
  287.         printf ("Creat socket error.\n");
  288.         return -1;
  289.     }


  290.     iRet = set_promisc (sk);
  291.     if (iRet < 0)
  292.     {
  293.         printf ("Set socket promisc error.\n");
  294.         close (sk);
  295.         return -1;
  296.     }

  297.     //the first
  298.     bzero (buffers, g_iSendBufSize);
  299.     bzero (bufferr, g_iRecvBufSize);

  300.     fill_iph (buffers);
  301.     seqno = 0;
  302.     ackno = 0;
  303.     fill_tcp (buffers, 0x02);
  304.     iRet = sendto_packet (sk, buffers);
  305.     if (iRet < 0)
  306.     {
  307.         printf ("Sendto_packet error.\n");
  308.         close (sk);
  309.         return -1;
  310.     }

  311.     iRet = recvfrom_packet (sk, bufferr);
  312.     if (iRet < 0)
  313.     {
  314.         printf ("Recvfrom_packet error.\n");
  315.         printf ("time is over or error opertion \n");
  316.         close (sk);
  317.         return -1;
  318.     }


  319.     //the third
  320.     bzero (buffers, g_iSendBufSize);
  321.     bzero (bufferr, g_iRecvBufSize);

  322.     fill_iph (buffers);
  323.     temp = seqno;
  324.     seqno = ackno;
  325.     ackno = temp + 1;
  326.     fill_tcp (buffers, 0x20);
  327.     iRet = sendto_packet (sk, buffers);
  328.     if (iRet < 0)
  329.     {
  330.         printf ("Sendto_packet error.\n");
  331.         close (sk);
  332.         return -1;
  333.     }

  334.     close (sk);
  335.     return 0;
  336. }
模拟了一下TCP的三次握手,写得比较粗糙。
主要是创建一个PF_PACKET的套接字,绕过(bypass)系统的协议栈,然后自己构造IP层和TCP层就可以了。
运行之前先执行一下iptables -I INPUT -j DROP把来的数据都扔掉,要不然等服务器发回SYN ACK的时候会被系统的协议栈返回个RST。
可以打开wireshark看效果。
阅读(6540) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~