作者:互粉-结局_596 | 来源:互联网 | 2023-10-12 09:18
u_short in_cksum(u_short *addr,int len)
{
int nleft=len;
int sum=0;
u_short *w=addr;
u_short answer=0;
while (nleft>1)
{
sum+=*w++;
nleft-=2;
}
if (nleft==1)
{
*(u_char *)(&answer)=*(u_char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum & 0xffff);
sum+=(sum>>16);
answer=~sum;
return(answer);
}
int main(int argc,char *argv[])
{
char *ip = argv[1];
int port =atoi(argv[2]);
int sockRaw;
sockRaw = socket(AF_INET ,SOCK_RAW ,IPPROTO_TCP);
char buffer[40];
struct sockaddr_in target;
struct sockaddr_in source;
target.sin_family=AF_INET;
target.sin_port = htons(port);
inet_aton(ip,&target.sin_addr);
source.sin_family=AF_INET;
source.sin_port = htons(5000);
source.sin_addr.s_addr= htonl(INADDR_ANY);
u_short tcpSize =sizeof(struct tcphdr);
unsigned char netPacket[tcpSize];
struct tcphdr* tcp;
u_char *pPseudoHead;
u_char pseudoHead[12+sizeof(struct tcphdr)];
u_short tcpHeadLen;
memset(netPacket,0,tcpSize);
tcpHeadLen=htons(sizeof(struct tcphdr));
tcp=(struct tcphdr *)netPacket;
tcp->source=htons(5000);
tcp->dest=htons(port);
tcp->seq=htonl(0);
tcp->ack_seq=0;
tcp->doff=5;
tcp->syn=1; /*Syn的标志*/
tcp->window=htons(2048);
tcp->check=0;
tcp->urg_ptr=0;
pPseudoHead=pseudoHead;
memset(pPseudoHead,0,12+sizeof(struct tcphdr));
memcpy(pPseudoHead,&source.sin_addr,4);
pPseudoHead+=4;
memcpy(pPseudoHead,&target.sin_addr,4);
pPseudoHead+=5;
memset(pPseudoHead,6,1);
pPseudoHead++;
memcpy(pPseudoHead,&tcpHeadLen,2);
pPseudoHead+=2;
memcpy(pPseudoHead,tcp,sizeof(struct tcphdr));
tcp->check=in_cksum((u_short *)pseudoHead,sizeof(struct tcphdr)+12);
sendto(sockRaw,netPacket,tcpSize,0,(struct sockaddr *)&target,sizeof(struct sockaddr_in));
}
参数192.168.1.102 21
本机ip:192.168.1.248
用tcpdump抓包结果如下:
192.168.1.248.5000>192.168.1.102.ftp:flags[s],checksum Oxd237(incorrect->OxOf97),seq 0,win 2048,length 0
9 个解决方案
问题解决了····
伪头部的sourceip地址问题,所以会造成checksum incorret
最开始初始的sourceip不能用any
可以使用ioctl 取得接口地址
再gethostname来得到本地ip