c-如何使用原始套接字设置TCP选项(MSS、Window Scale和SACK)



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

这是我的代码:

struct tcp_options_mss{
uint8_t kind;
uint8_t len;
uint16_t mss; 
} __attribute__((packed));

struct tcphdr_mss {
struct tcphdr tcp;
struct tcp_options_mss mss;
};
struct pseudoHeader{ 

unsigned int sourceAddress;
unsigned int destinationAddress;
unsigned char placeHolder; 
unsigned char protocol;
unsigned short tcpLength;
struct tcphdr tcp;
};

unsigned short csum(unsigned short *ptr,int nbytes) {
register long sum;
unsigned short oddbyte;
register short answer;
sum=0;
while(nbytes>1) {
sum+=*ptr++;
nbytes-=2;
}
if(nbytes==1) {
oddbyte=0;
*((u_char*)&oddbyte)=*(u_char*)ptr;
sum+=oddbyte;
}
sum = (sum>>16)+(sum & 0xffff);
sum = sum + (sum>>16);
answer=(short)~sum;

return(answer);
}
int main(void)
{
int s = socket (PF_INET,SOCK_RAW, IPPROTO_TCP);        
char datagram[4096], sourceIP[32];
struct iphdr *iph = (struct iphdr *) datagram;
struct tcphdr_mss *tcp = (struct tcphdr_mss *) (datagram + sizeof(struct ip));

struct pseudoHeader psh; 
strcpy(sourceIP , "192.168.1.45"); 
//Propiedades del socket
sin.sin_family = AF_INET;
sin.sin_port = htons(80); 
sin.sin_addr.s_addr = inet_addr ("192.168.0.10"); 

memset (datagram, 0, 4096); 

iph->ihl = 5; 
iph->version = 4; 
iph->tos = 0; 
iph->tot_len = sizeof (struct ip) + sizeof (struct tcphdr); 
iph->id = htons(54321);
iph->frag_off |= ntohs(IP_DF); 
iph->ttl = 128;
iph->protocol = IPPROTO_TCP; 
iph->check = 0;
iph->saddr = inet_addr ( sourceIP );
iph->daddr = sin.sin_addr.s_addr;
iph->check = csum ((unsigned short *) datagram, 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_addr( sourceIP );
psh.destinationAddress = sin.sin_addr.s_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;
const int *val = &one;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
{
printf ("Error setting IP_HDRINCL. Error number : %d . Error message : %s n" , errno , strerror(errno));
exit(0);
}
//while (1)
//{

if (sendto (s,      
datagram,   
iph->tot_len,   
0,      
(struct sockaddr *) &sin,   
sizeof (sin)) < 0)  
{
printf ("errorn");
}
//Data send successfully
else
{
printf ("Packet Send n");
}
//}

return 0;
}

我正在查看#include <netinet/tcp.h>库的源代码,没有TCP选项的属性。这就是我为MSS添加结构的原因。

当我在Wireshark上看到时,MSS选项没有设置。但是,如果您看到我的代码,则该选项正在设置中。

另一方面,我是否应该同样设置窗口比例和SACK?

我正在研究原始套接字,并考虑如何添加mss选项,这是个好主意。据我所知,我认为你应该更改tcp->tcp.doff到6,如果包括mss,则tcp报头为24B。

最新更新