我怎么能知道sendto函数哪种参数无效,为什么它是无效的?
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,这意味着无效的参数
。
我只想知道:
- 为什么会发生这样的错误?如果很难,我只想知道另一个问题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
.
I just want to know:
- Why did such a mistake occur? If it is hard, I just want to know the other question 2.
- Is there a way to get more detailed error information, such as which parameter is invalid and why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我将代码上传到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.