代码之家  ›  专栏  ›  技术社区  ›  lomaster

校验和ip标头分段故障C

  •  0
  • lomaster  · 技术社区  · 3 年前

    校验和ip头分段故障C。 当我开始将程序移动到 freebsd ,一切都是 在linux上工作。

    现在,错误发生在这一行-

    const uint16_t check_sum_ip = checksum_16bit((unsigned short *)datagram, iph_send->tot_len >> 1);
    

    填满 iph_send->tot_len ,如下所示: ip_header->tot_len = htons(packet_length);
    变量本身如下所示: uint16_t tot_len;

    计算校验和时出现错误,但如果我删除移位 >> 1 或将其更改为 2 ,所有操作都会同时执行,但数据包不会继续。

    计算功能 checksum :

    uint16_t checksum_16bit(unsigned short* data, int length)
    {
        uint32_t sum = 0;
        while (length > 1)
        {
            sum += *data++;
            length -= 2;
        }
        if (length == 1) {sum += *((uint8_t*)data);}
    
        sum = (sum >> 16) + (sum & 0xFFFF);
        sum += (sum >> 16);
        return (uint16_t)~sum;
    }    
    

    缓冲区如下所示: char datagram[SEND_BUFFER_SIZE];
    尺寸为: #define SEND_BUFFER_SIZE 2048

    填充缓冲区如下所示:

    struct ip_header *iph_send = (struct ip_header*)datagram;
    struct tcp_header *tcph_send = (struct tcp_header*)(datagram + sizeof(struct ip_header));
    

    所有代码都是;

    int send_tcp_packet(struct tcp_packet_opts* tpo, const char* ip, const int port, const int delay_ms) {
        char datagram[SEND_BUFFER_SIZE];
        memset(datagram, 0, SEND_BUFFER_SIZE);
    
        struct sockaddr_in dest;
        struct pseudo_header psh;
    
        struct ip_header* iph_send = (struct ip_header*)datagram;
        struct tcp_header* tcph_send = (struct tcp_header*)(datagram + sizeof(struct ip_header));
    
        /* Delay, default = 0. */
        struct timespec ts;
        ts.tv_sec = delay_ms / 1000;
        ts.tv_nsec = (delay_ms % 1000) * 1000000;
        nanosleep(&ts, NULL);
    
        /* Creation sock. */
        int sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
        if (sock == -1) {
    #ifdef PRINT_ERRORS
            perror("send_tcp_packet/create-socket-error");
    #endif
            return -1;
        }
    
        /* Let the kernel know that we are sending our IP header 
         * and we don't need to generate it. */
        int one = 1;
        const int* val = &one;
        if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) {
    #ifdef PRINT_ERRORS
            perror("send_tcp_packet/setsockopt-error(IP_HDRINCL)");
    #endif
            close(sock);
            return -1;
        }
    
        /* Fill TCP header. */
        fill_tcp_header(tcph_send, tpo->source_port, port, tpo->seq, 0, WINDOWS_SIZE, 0, 5, 0, tpo->tcpf);
    
        /* Calculate the packet size. */
        const uint16_t packet_length = sizeof(struct ip_header) + sizeof(struct tcp_header);
    
        /* Fill IP header. */
        fill_ip_header(iph_send, tpo->source_ip, ip, packet_length, IPPROTO_TCP, generate_ident(), IP_DF, tpo->ttl, 5, 4, 0);
    
        /* Calculate IP header checksum. */
        const uint16_t check_sum_ip = checksum_16bit((unsigned short*)datagram, iph_send->tot_len >> 1);
        iph_send->check = check_sum_ip;
    
        /* Set target for sendto. */
        dest.sin_family = AF_INET;
        dest.sin_addr.s_addr = inet_addr(ip);
    
        /* Fill pseudo_header for calc fake checksum. */
        psh.source_address = iph_send->saddr;
        psh.dest_address = dest.sin_addr.s_addr;
        psh.placeholder = 0;
        psh.protocol = iph_send->protocol;
        psh.tcp_length = htons(sizeof(struct tcp_header));
        memcpy(&psh.tcp, tcph_send, sizeof(struct tcp_header));
    
        /* Calculate fake checksum. */
        const uint16_t check_sum_tcp = checksum_16bit((unsigned short*)&psh, sizeof(struct pseudo_header));
        tcph_send->check = check_sum_tcp;
    
        /* Send TCP packet. */
        const int send = sendto(sock, datagram, packet_length, 0, (struct sockaddr*)&dest, sizeof(dest));
        if (send == -1) {
    #ifdef PRINT_ERRORS
            perror("send_tcp_packet/sendto-error");
    #endif
            close(sock);
            return -1;
        }
    #ifdef PACKET_TRACE
        printf("TCP & SENT %d bytes on %s: ttl=%d ident=%d window=%d seq=%d sum=%d\n",
               packet_length, ip, iph_send->ttl, iph_send->id, tcph_send->window, tcph_send->seq, iph_send->check);
    #endif
    
        close(sock);
        return 0;
    }
    
    

    Gdb显示如下:

    Invalid permissions for mapped object.
    [Switching to LWP 122755 of process 32002]
    0x00000000002cccfb in checksum_16bit ()
    (gdb) bt
    #0  0x00000000002cccfb in checksum_16bit ()
    #1  0x00000000002cd8b3 in send_tcp_packet ()
    #2  0x0000000000289a6c in scan_ports (ip="142.251.1.139", ports=std::vector of length 2 = {...}, timeout_ms=0) at /home/lomaster/nesca4/nesca4.cc:503
    #3  0x00000000002abd70 in std::__1::__invoke<int (*&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::vector<int, std::__1::allocator<int> >&, int&> (
        __f=@0x801625058: 0x2898d0 <scan_ports(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int)>, 
        __args=@0x801625090: 0, __args=@0x801625090: 0, __args=@0x801625090: 0) at /usr/include/c++/v1/type_traits:3918
    #4  0x00000000002abd17 in std::__1::__apply_functor<int (*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<int, std::__1::allocator<int> >, int>, 0ul, 1ul, 2ul, std::__1::tuple<> >(int (*&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<int, std::__1::allocator<int> >, int>&, std::__1::__tuple_indices<0ul, 1ul, 2ul>, std::__1::tuple<>&&) (
        __f=@0x801625058: 0x2898d0 <scan_ports(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int)>, __bound_args=..., 
        __args=...) at /usr/include/c++/v1/__functional/bind.h:257
    #5  0x00000000002abc90 in std::__1::__bind<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>::operator()<>() (this=0x801625058)
        at /usr/include/c++/v1/__functional/bind.h:292
    #6  0x00000000002abc65 in std::__1::__invoke<std::__1::__bind<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>&> (__f=...) at /usr/include/c++/v1/type_traits:3918
    #7  0x00000000002ab7c1 in std::__1::__packaged_task_func<std::__1::__bind<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>, std::__1::allocator<std::__1::__bind<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&> >, int ()>::operator()() (this=0x801625050) at /usr/include/c++/v1/future:1687
    #8  0x00000000002ae0da in std::__1::__packaged_task_function<int ()>::operator()() const (this=0x8016105e0) at /usr/include/c++/v1/future:1869
    #9  0x00000000002adfb1 in std::__1::packaged_task<int ()>::operator()() (this=0x8016105e0) at /usr/include/c++/v1/future:1960
    #10 0x00000000002adf1d in thread_pool::enqueue<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&)::{lambda()#1}::operator()() const (this=0x7fffdfbfaf08) at /home/lomaster/nesca4/include/nescathread.h:36
    #11 0x00000000002adee5 in std::__1::__invoke<thread_pool::enqueue<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&)::{lambda()#1}&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int)) (__f=...) at /usr/include/c++/v1/type_traits:3918
    #12 0x00000000002ade9d in std::__1::__invoke_void_return_wrapper<void, true>::__call<thread_pool::enqueue<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&)::{lambda()#1}&>(thread_pool::enqueue<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&)::{lambda()#1}&) (__args=...) at /usr/include/c++/v1/__functional/invoke.h:61
    #13 0x00000000002ade6d in std::__1::__function::__alloc_func<thread_pool::enqueue<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&)::{lambda()#1}, std::__1::allocator<thread_pool::enqueue<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&)::{lambda()#1}>, void ()>::operator()() (this=0x7fffdfbfaf08) at /usr/include/c++/v1/__functional/function.h:171
    #14 0x00000000002acf09 in std::__1::__function::__func<thread_pool::enqueue<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&)::{lambda()#1}, std::__1::allocator<thread_pool::enqueue<int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&>(int (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >, int), std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<int, std::__1::allocator<int> >&, int&)::{lambda()#1}>, void ()>::operator()() (this=0x7fffdfbfaf00) at /usr/include/c++/v1/__functional/function.h:345
    #15 0x00000000002c0d72 in std::__1::__function::__value_func<void ()>::operator()() const (this=0x7fffdfbfaf00) at /usr/include/c++/v1/__functional/function.h:498
    #16 0x00000000002c09a5 in std::__1::function<void ()>::operator()() const (this=0x7fffdfbfaf00) at /usr/include/c++/v1/__functional/function.h:1175
    --Type <RET> for more, q to quit, c to continue without paging--
    #17 0x00000000002bf11c in thread_pool::thread_pool(unsigned long)::$_0::operator()() const (this=0x80164a0b8) at /home/lomaster/nesca4/nescathread.cc:26
    #18 0x00000000002befa5 in std::__1::__invoke<thread_pool::thread_pool(unsigned long)::$_0>(thread_pool::thread_pool(unsigned long)::$_0&&) (__f=...) at /usr/include/c++/v1/type_traits:3918
    #19 0x00000000002bef85 in std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, thread_pool::thread_pool(unsigned long)::$_0>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, thread_pool::thread_pool(unsigned long)::$_0>&, std::__1::__tuple_indices<>) (__t=...)
        at /usr/include/c++/v1/thread:280
    #20 0x00000000002bed22 in std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, thread_pool::thread_pool(unsigned long)::$_0> >(void*) (__vp=0x80164a0b0) at /usr/include/c++/v1/thread:291
    #21 0x00000008003f483a in ?? () from /lib/libthr.so.3
    #22 0x0000000000000000 in ?? ()
    Backtrace stopped: Cannot access memory at address 0x7fffdfbfb000
    
    0 回复  |  直到 3 年前
        1
  •  0
  •   lomaster    3 年前

    问题是缓冲区太小。