美文网首页
2019-12-07 IP header的结构由RFC 791定

2019-12-07 IP header的结构由RFC 791定

作者: 阿群1986 | 来源:发表于2019-12-07 17:38 被阅读0次
    https://abcdxyzk.github.io/blog/2015/04/14/kernel-net-sock-raw/

    IP报头格式

    IP header的结构由RFC 791定义,如图(标尺每个数字代表一个bit位):
        0                   1                   2                   3 
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |Version|  IHL  |Type of Service|          Total Length         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |         Identification        |Flags|      Fragment Offset    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Time to Live |    Protocol   |         Header Checksum       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                       Source Address                          |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Destination Address                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Options                    |    Padding    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
    然后TCP header的结构是由RFC 793定义的:
        0                   1                   2                   3 
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |          Source Port          |       Destination Port        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                        Sequence Number                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Acknowledgment Number                      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Data |           |U|A|P|R|S|F|                               |
       | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
       |       |           |G|K|H|T|N|N|                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           Checksum            |         Urgent Pointer        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Options                    |    Padding    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    

    摘自:

    1. https://www.binarytides.com/raw-sockets-c-code-linux/

    2. https://www.binarytides.com/raw-socket-programming-in-python-linux/

    3. https://wordpress.youran.me/python-raw-socket-programming/

    /*
        Raw TCP packets
        Silver Moon (m00n.silv3r@gmail.com)
    */
    #include<stdio.h>   //for printf
    #include<string.h> //memset
    #include<sys/socket.h>  //for socket ofcourse
    #include<stdlib.h> //for exit(0);
    #include<errno.h> //For errno - the error number
    #include<netinet/tcp.h> //Provides declarations for tcp header
    #include<netinet/ip.h>  //Provides declarations for ip header
    
    /* 
        96 bit (12 bytes) pseudo header needed for tcp header checksum calculation 
    */
    struct pseudo_header
    {
        u_int32_t source_address;
        u_int32_t dest_address;
        u_int8_t placeholder;
        u_int8_t protocol;
        u_int16_t tcp_length;
    };
    
    /*
        Generic checksum calculation function
    */
    unsigned short csum(unsigned short *ptr,int nbytes) 
    {
        register long sum;
        unsigned short oddbyte;
        register short answer;
    
        sum=0;
        while(nbytes>1) {
            sum+=*ptr++;
            nbytes-=2;
        }
        if(nbytes==1) {
            oddbyte=0;
            *((u_char*)&amp;oddbyte)=*(u_char*)ptr;
            sum+=oddbyte;
        }
    
        sum = (sum>>16)+(sum &amp; 0xffff);
        sum = sum + (sum>>16);
        answer=(short)~sum;
        
        return(answer);
    }
    
    int main (void)
    {
        //Create a raw socket
        int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
        
        if(s == -1)
        {
            //socket creation failed, may be because of non-root privileges
            perror("Failed to create socket");
            exit(1);
        }
        
        //Datagram to represent the packet
        char datagram[4096] , source_ip[32] , *data , *pseudogram;
        
        //zero out the packet buffer
        memset (datagram, 0, 4096);
        
        //IP header
        struct iphdr *iph = (struct iphdr *) datagram;
        
        //TCP header
        struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip));
        struct sockaddr_in sin;
        struct pseudo_header psh;
        
        //Data part
        data = datagram + sizeof(struct iphdr) + sizeof(struct tcphdr);
        strcpy(data , "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        
        //some address resolution
        strcpy(source_ip , "192.168.1.2");
        sin.sin_family = AF_INET;
        sin.sin_port = htons(80);
        sin.sin_addr.s_addr = inet_addr ("1.2.3.4");
        
        //Fill in the IP Header
        iph->ihl = 5;
        iph->version = 4;
        iph->tos = 0;
        iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + strlen(data);
        iph->id = htonl (54321);    //Id of this packet
        iph->frag_off = 0;
        iph->ttl = 255;
        iph->protocol = IPPROTO_TCP;
        iph->check = 0;     //Set to 0 before calculating checksum
        iph->saddr = inet_addr ( source_ip );   //Spoof the source ip address
        iph->daddr = sin.sin_addr.s_addr;
        
        //Ip checksum
        iph->check = csum ((unsigned short *) datagram, iph->tot_len);
        
        //TCP Header
        tcph->source = htons (1234);
        tcph->dest = htons (80);
        tcph->seq = 0;
        tcph->ack_seq = 0;
        tcph->doff = 5; //tcp header size
        tcph->fin=0;
        tcph->syn=1;
        tcph->rst=0;
        tcph->psh=0;
        tcph->ack=0;
        tcph->urg=0;
        tcph->window = htons (5840);    /* maximum allowed window size */
        tcph->check = 0;    //leave checksum 0 now, filled later by pseudo header
        tcph->urg_ptr = 0;
        
        //Now the TCP checksum
        psh.source_address = inet_addr( source_ip );
        psh.dest_address = sin.sin_addr.s_addr;
        psh.placeholder = 0;
        psh.protocol = IPPROTO_TCP;
        psh.tcp_length = htons(sizeof(struct tcphdr) + strlen(data) );
        
        int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + strlen(data);
        pseudogram = malloc(psize);
        
        memcpy(pseudogram , (char*) &amp;psh , sizeof (struct pseudo_header));
        memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr) + strlen(data));
        
        tcph->check = csum( (unsigned short*) pseudogram , psize);
        
        //IP_HDRINCL to tell the kernel that headers are included in the packet
        int one = 1;
        const int *val = &amp;one;
        
        if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
        {
            perror("Error setting IP_HDRINCL");
            exit(0);
        }
        
        //loop if you want to flood :)
        while (1)
        {
            //Send the packet
            if (sendto (s, datagram, iph->tot_len , 0, (struct sockaddr *) &amp;sin, sizeof (sin)) < 0)
            {
                perror("sendto failed");
            }
            //Data send successfully
            else
            {
                printf ("Packet Send. Length : %d \n" , iph->tot_len);
            }
        }
        
        return 0;
    }
    
    //Complete
    

    相关文章

      网友评论

          本文标题:2019-12-07 IP header的结构由RFC 791定

          本文链接:https://www.haomeiwen.com/subject/rxiugctx.html