我正在尝试发出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。