如何使用原始套接字设置TCP选项(MSS、窗口缩放和SACK)

如何使用原始套接字设置TCP选项(MSS、窗口缩放和SACK),c,linux,tcp,raw-sockets,C,Linux,Tcp,Raw Sockets,我正在尝试发出TCP/SYN请求 这是我的密码: struct-tcp\u-options\u-mss{ 8类; uint8_t len; uint16_t mss; }_uuu属性_uuu((压缩)); 结构tcphdr\U mss{ 结构tcphdr-tcp; 结构tcp_选项_mss; }; 结构伪头{ 无符号整数源地址; 未签名的int目的地址; 无符号字符占位符; 无符号字符协议; 无符号短tcpLength; 结构tcphdr-tcp; }; 无符号短csum(无符号短*ptr,整数

我正在尝试发出TCP/SYN请求

这是我的密码:

struct-tcp\u-options\u-mss{
8类;
uint8_t len;
uint16_t mss;
}_uuu属性_uuu((压缩));
结构tcphdr\U mss{
结构tcphdr-tcp;
结构tcp_选项_mss;
};
结构伪头{
无符号整数源地址;
未签名的int目的地址;
无符号字符占位符;
无符号字符协议;
无符号短tcpLength;
结构tcphdr-tcp;
};
无符号短csum(无符号短*ptr,整数字节){
注册长和;
无符号短奇字节;
注册简短回答;
总和=0;
而(n字节>1){
总和+=*ptr++;
nbytes-=2;
}
如果(n字节==1){
oddbyte=0;
*((u_char*)和oddbyte)=*(u_char*)ptr;
sum+=oddbyte;
}
总和=(总和>>16)+(总和&0xffff);
总和=总和+(总和>>16);
答案=(短)~sum;
返回(回答);
}
内部主(空)
{
int s=插座(PF_INET、SOCK_RAW、IPPROTO_TCP);
char数据报[4096],sourceIP[32];
结构iphdr*iph=(结构iphdr*)数据报;
struct tcphdr_mss*tcp=(struct tcphdr_mss*)(数据报+sizeof(struct ip));
结构伪头;
strcpy(sourceIP,“192.168.1.45”);
//插座
sin.sin_family=AF_INET;
sin.sin_端口=htons(80);
sin.sin_addr.s_addr=inet_addr(“192.168.0.10”);
memset(数据报,04096);
iph->ihl=5;
iph->version=4;
iph->tos=0;
iph->tot_len=sizeof(struct ip)+sizeof(struct tcphdr);
iph->id=htons(54321);
iph->frag|u off |=ntohs(IP|u DF);
iph->ttl=128;
iph->协议=IPPROTO_TCP;
iph->check=0;
iph->saddr=inet\u addr(sourceIP);
iph->daddr=sin.sin\u addr.s\u addr;
iph->check=csum((无符号短*)数据报,iph->tot_len>>1);
tcp->tcp.source=htons(1883);
tcp->tcp.dest=htons(80);
tcp->tcp.seq=0;
tcp->tcp.ack_seq=0;
tcp->tcp.doff=5;
tcp->tcp.urg=0;
tcp->tcp.ack=0;
tcp->tcp.psh=0;
tcp->tcp.rst=0;
tcp->tcp.syn=1;
tcp->tcp.fin=0;
tcp->tcp.window=htons(5840);
tcp->tcp.check=0;
tcp->tcp.urg_ptr=0;
tcp->mss.kind=2;
tcp->mss.len=2;
tcp->mss.mss=htons(32000);
psh.sourceAddress=inet\u addr(sourceIP);
psh.destinationAddress=sin.sin\u addr.s\u addr;
psh.placeHolder=0;
psh.protocol=IPPROTO_TCP;
psh.tcpLength=htons(20)//
memcpy(&psh.tcp,tcp,sizeof(struct tcphdr));
tcp->tcp.check=csum((unsigned short*)&psh,sizeof(struct pseudoHeader));
int-one=1;
常量int*val=&one;
如果(设置锁定选项(s、IPPROTO_IP、IP_HDRINCL、val、尺寸(一个))<0)
{
printf(“设置IP_HDRINCL时出错。错误号:%d。错误消息:%s\n”,errno,strerror(errno));
出口(0);
}
//而(1)
//{
如果(发送至),
数据报,
iph->tot_len,
0,      
(结构sockaddr*)和sin,
sizeof(sin))<0)
{
printf(“错误\n”);
}
//数据发送成功
其他的
{
printf(“数据包发送”);
}
//}
返回0;
}
我正在查看
#include
库的源代码,TCP选项没有属性。这就是我为MSS添加结构的原因

当我在Wireshark上看到时,未设置MSS选项。但是如果你看到我的代码,这个选项正在设置中

另一方面,我应该做同样的设置窗口规模和袋