我怎么能知道sendto函数哪种参数无效,为什么它是无效的?

发布于 2025-01-31 13:46:53 字数 3366 浏览 2 评论 0原文

TCP连接需要三个握手,我想用Syn = 1手动发送TCP数据包,也就是说,第一个握手。在这里是我的代码:

#include <iostream>
#include <thread>
#include <map>
#include <vector>
#include "PackageData.hpp"
#include "utils.hpp"
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>      // for socket
#include <netinet/tcp.h>    // for tcp
#include <netinet/ip.h>     // for ip

unsigned char* GetData(sockaddr_in addr)
{
    unsigned int len = sizeof(struct ip)+sizeof(struct tcphdr);
    unsigned char * buffer  = new unsigned char [len];
    memset(buffer,0,sizeof(buffer));
    struct ip *ip_ptr;
    struct tcphdr *tcp_ptr;

    ip_ptr = (struct ip *)buffer;
    tcp_ptr = (struct tcphdr *)(buffer+sizeof(struct ip));

    ip_ptr->ip_v = IPVERSION;
    ip_ptr->ip_hl = sizeof(struct ip)>>2;
    ip_ptr->ip_tos = 0;
    ip_ptr->ip_len = htons(len);
    ip_ptr->ip_id = 0;
    ip_ptr->ip_off = 0;
    ip_ptr->ip_ttl = MAXTTL;
    ip_ptr->ip_p = IPPROTO_TCP;
    ip_ptr->ip_sum = 0;
    ip_ptr->ip_dst = addr.sin_addr;


    
    tcp_ptr->dest = addr.sin_port;
    tcp_ptr->seq = 0;
    tcp_ptr->ack_seq = 0;
    tcp_ptr->doff = 5;  
    //res2+urg+ack+psh+rst+syn+fin 8
    //tcp->res2 = 0;
    //tcp->urg = 0;
    //tcp->ack = 0;
    //tcp->psh = 0;
    //tcp->rst = 0;
    tcp_ptr->syn = 1;
    //tcp->fin = 0;
    //tcp->window = 0;


    //random source ip and port to cheat
    uint32_t m_ip = random();
    ip_ptr->ip_src.s_addr = htonl(m_ip);
    tcp_ptr->source = htons(random());
     

    //will be calculated by kernel,just a fake head here 
    ip_ptr->ip_sum = htons(sizeof(struct tcphdr));

    tcp_ptr->check = CheckSum((uint16_t *)buffer+4,sizeof(buffer)-8);

    return buffer;


}
void SendOne(uint32_t ip,int port)
{
        cout<<"send to " <<ip_to_string(ip)<<endl;

        sockaddr_in dst_ip = { 0 };
        dst_ip.sin_family = AF_INET;
        dst_ip.sin_addr.s_addr = inet_addr(ip_to_string(ip).data());
        dst_ip.sin_port = htons(port);
  
        int sock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
        int on = 1;
        int opt =  setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));
        cout<<"sock:"<<sock<<" errno:"<<errno<<" desc:"<<strerror(errno)<<endl;
  

        unsigned char * buffer = GetData(dst_ip);
        unsigned int len = sizeof(struct ip)+sizeof(struct tcphdr);
        int re = sendto(sock, //re is here
        buffer,
        len,
        0,
        (sockaddr*)&dst_ip,
        sizeof(dst_ip));
        cout<<"re:"<<re<<" errno:"<<errno<<" "<<strerror(errno)<<endl;
}

Sendone是将SYN = 1发送到IP:port的函数。生成缓冲区发送的函数。但是,当我在Linux(WSL版本1,Ubuntu 20.04)中运行代码时,它是re is -1,并且将ERRNO设置为22,这意味着无效的参数

我只想知道:

  1. 为什么会发生这样的错误?如果很难,我只想知道另一个问题2。
  2. 是否有一种方法可以获取更详细的错误信息,例如哪个参数无效,为什么?

TCP connections require three handshakes, I want to send TCP packets with SYN = 1 manually, that is, the first handshake.Here is my code:

#include <iostream>
#include <thread>
#include <map>
#include <vector>
#include "PackageData.hpp"
#include "utils.hpp"
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>      // for socket
#include <netinet/tcp.h>    // for tcp
#include <netinet/ip.h>     // for ip

unsigned char* GetData(sockaddr_in addr)
{
    unsigned int len = sizeof(struct ip)+sizeof(struct tcphdr);
    unsigned char * buffer  = new unsigned char [len];
    memset(buffer,0,sizeof(buffer));
    struct ip *ip_ptr;
    struct tcphdr *tcp_ptr;

    ip_ptr = (struct ip *)buffer;
    tcp_ptr = (struct tcphdr *)(buffer+sizeof(struct ip));

    ip_ptr->ip_v = IPVERSION;
    ip_ptr->ip_hl = sizeof(struct ip)>>2;
    ip_ptr->ip_tos = 0;
    ip_ptr->ip_len = htons(len);
    ip_ptr->ip_id = 0;
    ip_ptr->ip_off = 0;
    ip_ptr->ip_ttl = MAXTTL;
    ip_ptr->ip_p = IPPROTO_TCP;
    ip_ptr->ip_sum = 0;
    ip_ptr->ip_dst = addr.sin_addr;


    
    tcp_ptr->dest = addr.sin_port;
    tcp_ptr->seq = 0;
    tcp_ptr->ack_seq = 0;
    tcp_ptr->doff = 5;  
    //res2+urg+ack+psh+rst+syn+fin 8
    //tcp->res2 = 0;
    //tcp->urg = 0;
    //tcp->ack = 0;
    //tcp->psh = 0;
    //tcp->rst = 0;
    tcp_ptr->syn = 1;
    //tcp->fin = 0;
    //tcp->window = 0;


    //random source ip and port to cheat
    uint32_t m_ip = random();
    ip_ptr->ip_src.s_addr = htonl(m_ip);
    tcp_ptr->source = htons(random());
     

    //will be calculated by kernel,just a fake head here 
    ip_ptr->ip_sum = htons(sizeof(struct tcphdr));

    tcp_ptr->check = CheckSum((uint16_t *)buffer+4,sizeof(buffer)-8);

    return buffer;


}
void SendOne(uint32_t ip,int port)
{
        cout<<"send to " <<ip_to_string(ip)<<endl;

        sockaddr_in dst_ip = { 0 };
        dst_ip.sin_family = AF_INET;
        dst_ip.sin_addr.s_addr = inet_addr(ip_to_string(ip).data());
        dst_ip.sin_port = htons(port);
  
        int sock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
        int on = 1;
        int opt =  setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));
        cout<<"sock:"<<sock<<" errno:"<<errno<<" desc:"<<strerror(errno)<<endl;
  

        unsigned char * buffer = GetData(dst_ip);
        unsigned int len = sizeof(struct ip)+sizeof(struct tcphdr);
        int re = sendto(sock, //re is here
        buffer,
        len,
        0,
        (sockaddr*)&dst_ip,
        sizeof(dst_ip));
        cout<<"re:"<<re<<" errno:"<<errno<<" "<<strerror(errno)<<endl;
}

The SendOne is a function that send a SYN=1 package to ip:port.The GetData is a function to generate the buffer to send. However, when I run my code in linux(wsl version 1,ubuntu 20.04),it's re is -1,and the errno was set to 22, which means invalid arguments.

enter image description here

I just want to know:

  1. Why did such a mistake occur? If it is hard, I just want to know the other question 2.
  2. Is there a way to get more detailed error information, such as which parameter is invalid and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

末骤雨初歇 2025-02-07 13:46:53

我将代码上传到Cloud Server(CentOS 8),并且可以正常工作。我不知道为什么。我想WSL做出了一些更改,这使我每天浪费。

I upload my code to the cloud server (CentOS 8), and it will work correctly. I don't know why. I guess WSL has made some changes, which makes me waste a day.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文