简体   繁体   English

我如何知道 sendto function 哪个参数无效以及为什么无效?

[英]How can I know the sendto function which argument is invalid and why it is invalid?

TCP connections require three handshakes, I want to send TCP packets with SYN = 1 manually, that is, the first handshake.Here is my code: TCP个连接需要三次握手,我想手动发送TCP个SYN=1的数据包,也就是第一次握手。下面是我的代码:

#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. SendOne 是一个 function,它将 SYN=1 package 发送到 ip:port。GetData 是一个 function,用于生成要发送的缓冲区。 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 .但是,当我在 linux 中运行我的代码时(wsl 版本re 20.04),它是 -1,并且 errno 设置为 22,这意味着invalid arguments

在此处输入图像描述

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。
  2. Is there a way to get more detailed error information, such as which parameter is invalid and why?有没有办法得到更详细的错误信息,比如哪个参数无效,为什么?

I upload my code to the cloud server (CentOS 8), and it will work correctly.我将我的代码上传到云服务器(CentOS 8),它会正常工作。 I don't know why.我不知道为什么。 I guess WSL has made some changes, which makes me waste a day.我猜WSL做了一些改动,让我浪费了一天的时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM