校验和 ip 标头分段故障 C

Checksum ip header segmentation fault C

提问人:lomaster 提问时间:7/31/2023 最后编辑:lomaster 更新时间:8/1/2023 访问量:66

问:

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

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

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

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

计算校验和时发生错误,但是如果我删除移位或将其更改为 ,则立即执行所有操作,但数据包不会执行。>> 12

计算函数: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
c tcp 网络编程 freebsd 校验和

评论

0赞 Ingo Leonhardt 7/31/2023
if 是 网络字节顺序 返回的值,您不能将其视为 'ordinary' 。如果机器的字节序与网络字节顺序不同,则该值将被完全错误地解释,例如 255 (0XFF) 变为 65280 (0xFF00)tot_lenhtons()uint16_t
1赞 Gerhardh 7/31/2023
“填写 iph_send->tot_len,如下所示:ip_header->tot_len = htons(packet_length);”你混在一起吗?这与如何匹配?我认为你需要展示更多的代码。ip_headerip_sendstruct ip_header *iph_send = (struct ip_header*)datagram;
0赞 lomaster 7/31/2023
我已经为整个函数添加了代码。
3赞 Andrew Henle 7/31/2023
假设是指向 or 的指针,例如 的代码将通过违反严格别名来调用未定义的行为,并且它还可以通过违反任何特定于平台的对齐要求来调用未定义的行为。诸如此类的代码也存在同样的问题。您使用的是什么编译器,以及您向编译器传递哪些参数?datagramcharvoid(unsigned short *)datagram(struct tcp_header*)(datagram + sizeof(struct ip_header))
0赞 lomaster 7/31/2023
我在“gcc”之前使用“cc”编译器: /usr/bin/cc -I/home/lomaster/nesca4/lib -MD -MT CMakeFiles/nesca4.dir/ncsock/tcp.c.o -MF CMakeFiles/nesca4.dir/ncsock/tcp.c.o.d -o CMakeFiles/nesca4.dir/ncsock/tcp.c.o -c /home/lomaster/nesca4/ncsock/tcp.c

答:

0赞 lomaster 8/1/2023 #1

问题在于缓冲区大小过小。

评论

0赞 Community 8/4/2023
您的答案可以通过额外的支持信息得到改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。