Chinaunix首页 | 论坛 | 博客
  • 博客访问: 743946
  • 博文数量: 769
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 4985
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-15 16:37
文章分类

全部博文(769)

文章存档

2011年(1)

2008年(768)

我的朋友

分类:

2008-10-15 16:40:51

    经常的有人问原始套节口的问题。如何的checksum如何的发送接受,如何的支持tcp和udp等。

    为了较少以后回答这个问题的频率。偶整理了一个完整的代码,包含tcp、udp和ip层如何操作。下面分别给出,希望对大家有所帮助。
    rawsock_utils.h
    [code:1:4fc8f1a596]
    extern void tcp_gen(char *packet,unsigned short sport,
                        unsigned short dport,unsigned long seq,
                        unsigned long ack);

    extern void udp_gen(char *packet,unsigned short sport,
                        unsigned short dport,unsigned short length);

    extern void ip_gen(char *packet,unsigned char protocol,struct in_addr saddr,
                struct in_addr daddr,unsigned short length);

    extern unsigned short trans_check(unsigned char proto,
                                      char *packet,
                                      int length,
                                      struct in_addr source_address,
                                      struct in_addr dest_address);
    [/code:1:4fc8f1a596]
    checksum.h
    [code:1:4fc8f1a596]
    unsigned short in_cksum(unsigned short *addr,int len);
    [/code:1:4fc8f1a596]


    tcp.c
    [code:1:4fc8f1a596]
    #include
    #include

    #include
    #include

    #include
    #include

    #include

    #if defined(LINUX)
    #include
    #include
    #else
    #include
    #include
    #endif

    #include
    #include
    #include

    #include

    int main(int argc,char *argv[])
    {
      unsigned char packet[
    #if !defined(LINUX)
      sizeof(struct ip) +
    #else /* LINUX */
      sizeof(struct iphdr) +
    #endif /* LINUX */
      sizeof(struct tcphdr)];
      struct sockaddr_in mysocket;
      unsigned short sport, dport;
      struct in_addr saddr, daddr;
      struct tcphdr *tcp;
      unsigned long seq, ack;
      int sockd, on = 1;

      if(argc < 5)  {
        fprintf(stderr,"usage: %s source_port source_address dest_port dest_address\n",
        argv[0]);
        exit(1);
      }

      sport = (unsigned short)atoi(argv[1]);
      saddr.s_addr = inet_addr(argv[2]);

      dport = (unsigned short)atoi(argv[3]);
      daddr.s_addr = inet_addr(argv[4]);

      if((sockd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0)  {
        perror("socket");
        exit(1);
      }

      if(setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0)  {
        perror("setsockopt");
        exit(1);
      }

      /* Very bad random sequence number generator */

      srand(getpid());

      seq = rand()%time(NULL);
      ack = rand()%time(NULL);

      ip_gen(packet,IPPROTO_TCP,saddr,daddr,sizeof(packet));

    #if !defined(LINUX)

      tcp = (struct tcphdr *)(packet + sizeof(struct ip));

      tcp_gen((char *)tcp,sport,dport,seq,ack);

    #if !defined(SOLARIS_CKSUM_BUG)
      tcp->th_sum = trans_check(IPPROTO_TCP,(char *)tcp,
        sizeof(struct tcphdr),
        saddr,
        daddr);

    #else /* SOLARIS_CKSUM_BUG */

      tcp->th_sum = sizeof(struct tcphdr);

    #endif /* SOLARIS_CKSUM_BUG */

    #else /* LINUX */

      tcp = (struct tcphdr *)(packet + sizeof(struct iphdr));

      tcp_gen((char *)tcp,sport,dport,seq,ack);

    #if !defined(SOLARIS_CKSUM_BUG)
      tcp->check = trans_check(IPPROTO_TCP,(char *)tcp,
       sizeof(struct tcphdr),
       saddr,
       daddr);
    #else /* SOLARIS_CKSUM_BUG */

      tcp->check = sizeof(struct tcphdr);

    #endif /* SOLARIS_CKSUM_BUG */

    #endif /* LINUX */

      memset(&mysocket,'\0',sizeof(mysocket));

      mysocket.sin_family = AF_INET;
      mysocket.sin_port = htons(dport);
      mysocket.sin_addr = daddr;

      if(sendto(sockd,&packet,sizeof(packet),0x0,(struct sockaddr *)&mysocket,
        sizeof(mysocket)) != sizeof(packet))  {
        perror("sendto");
        exit(1);
      }

      exit(0);
    }
    [/code:1:4fc8f1a596]

    tcp_gen.c
    [code:1:4fc8f1a596]
    #include
    #include

    #include
    #include

    #include
    #include

    #include

    #if defined(LINUX)
    #include
    #else
    #include
    #endif

    #include
    #include

    #if defined(X2_OFF)         /* SCO */
    #define TH_OFFSET 0x50         /* TCP header offset */
    #else
    #define TH_OFFSET 5
    #endif

    #define TCP_WINDOW_SIZE 512 /* Just have it hardcoded. */

    void tcp_gen(char *packet,unsigned short sport,
         unsigned short dport,unsigned long seq,
         unsigned long ack)
    {
      struct tcphdr *tcp;

      tcp = (struct tcphdr *)packet;
      memset((char *)tcp,'\0',sizeof(struct tcphdr));

 

[1]    

【责编:landy】

--------------------next---------------------

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