📄 tcp.c
字号:
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <string.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#define SRCPORT 3000
#define HEADER_LEN 36
#define PORTS 1024
int i_index;
struct thread_d
{
int syn;
u_int32_t saddr;
u_int32_t daddr;
u_int32_t seq;
};
struct t_tcphdr
{
struct tcphdr thdr;
u_int8_t opt_name;
u_int8_t opt_len;
u_int16_t opt;
};
u_int16_t in_chksum(u_short *addr,int len)
{
u_int32_t sum=0;
u_int16_t *ad=addr,result;
while(len>1)
{
sum+=*ad++;
len-=2;
}
if(len==1)
{
result=0;
*((u_char*)&result)=*(u_char*)ad;
sum+=result;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
result=~sum;
return(result);
}
u_int32_t localIP(int sock)
{
struct ifreq ifr;
struct sockaddr_in *sa;
strcpy(ifr.ifr_name,"eth0");
if(ioctl(sock,SIOCGIFADDR,&ifr)<0)
{
perror("ioctl siogifaddr");
exit(-1);
}
sa=(struct sockaddr_in*)&ifr.ifr_addr;
return sa->sin_addr.s_addr;
}
void *getresponse(void *arg)
{
struct thread_d *arg_r=(struct thread_d*)arg;
u_char ports[PORTS],packet[1024];
fd_set rfd;
struct sockaddr_in sa;
struct in_addr sa_in;
struct iphdr *i_hdr;
struct tcphdr *thdr;
int sock_pck,len,n,i;
u_int32_t seq;
struct timeval tv;
char pchdest[20];
seq=arg_r->seq;
sa_in.s_addr=arg_r->daddr;
strncpy(pchdest,inet_ntoa(sa_in),16);
if((sock_pck=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)))<0)
{
perror("socket packet");
exit(-1);
}
if(!arg_r->syn)
bzero(ports,sizeof(ports));
while(1)
{
bzero(packet,sizeof(packet));
FD_ZERO(&rfd);
FD_SET(sock_pck,&rfd);
tv.tv_sec=0;
tc.tv_usec=500;
if(select(sock_pck+1,&rfd,NULL,NULL,&tv)==0)
if(i_index=(PORTS-1))
break;
else
continue;
if(n=recvfrom(sock_pck,packet,1024,0,&sa,&len)<54)
continue;
i_hdr=(struct iphdr*)(packet+sizeof(struct ethhdr));
if(i_hdr->daddr==arg_r->saddr&&i_hdr->saddr==arg_r->daddr)
{
thdr=(struct tcphdr*)(packet+sizeof(struct ehhhdr)+sizeof(struct iphdr));
if(arg_r->syn&&thdr->ack==1&&thdr->ack_seq==htonl(seq+1)&&thdr->dest==htons(SRCPORT))
{
if(thdr->rst==0)
printf("%s's port %4d is on service\n",pchdest,ntohl(thdr->source));
else if(!arg_r->syn&&thdr->window==0&&(ntohl(thdr->ack_seq)>=seq||ntohl(thdr->ack_seq)<=seq+32120)&&thdr->dest==htons(SRCPORT))
if(thdr->rst==1)
ports[ntohs(thdr->source)]=1;
}
}
if(!arg_r->syn)
for(i=1;i<PORTS;i++)
if(ports[i]==0)
printf("%s's port %4d is on service\n",pchdest,i);
return NULL;
}
}
int main(int argc,char *argv[])
{
struct sockaddr_in sa_to,sa_fr,sa;
struct t_tcphdr *t_hdr;
struct tcphdr *thdr;
struct iphdr *i_hdr;
int syn=0,sock_raw,sock_pck,i,flag,len;
u_char *pseudo,psedoHead[HEADER_LEN],packet[1024];
u_int16_t tcp_len;
u_int32_t seq=getpid()|0x40000000;
const int on=1;
pthread_t tid;
struct thread_d arg;
if(argc!=3)
{
printf("usage:%s[-s -f] remoteIP\n",argv[0]);
exit(-1);
}
if(strcmp(argv[1],"-s")&&strcmp(argv[2],"-f"))
{
printf("usage:%s[-s -f] remoteIP\n",argv[0]);
exit(-1);
}
else if(!strcmp(argv[1],"-s"))
syn=1;
bzero(&sa_to,sizeof(sa_to));
sa_to.sin_family=AF_INET;
if(inet_aton(argv[2],&sa_to.sin_addr)<0)
{
perror("inet_aton");
exit(-1);
}
if((sock_raw=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0)
{
perror("socket raw");
exit(-1);
}
bzeor(&sa_fr,sizeof(sa_fr));
sa_fr.sin_family=AF_INET;
sa_fr.sin_addr.s_addr=localIP(sock_raw);
arg.syn=syn;
arg.saddr=sa_fr.sin_addr.s_addr;
arg.daddr=sa_to.sin_addr.s_addr;
arg.seq=seq;
pthread_create(&tid,NULL,getresponse,&arg);
if(setsockopt(sock_raw,IPPROTO_IP,IP_HDRINCL,&on,sizeof(int))<0)
{
perror("setsockopt ipproto_ip");
exit(-1);
}
if((flag=fcntl(sock_raw,F_GETFL))<0)
{
perror("fcntl F_GETFL");
exit(-1);
}
usleep(50);
for(i=1;i<PORTS;i++)
{
bzero(packet,sizeof(packet));
i_hdr=(struct iphdr*)packet;
i_hdr->ihl=5;
i_hdr->version=4;
i_hdr->frag_off=htons(IP_DF);
i_hdr->ttl=64;
i_hdr->protocol=IPPROTO_TCP;
i_hdr->daddr=sa_to.sin_addr.s_addr;
i_hdr->saddr=sa_fr.sin_addr.s_addr;
t_hdr=(struct t_tcphdr*)(packet+sizeof(struct iphdr));
t_hdr->thdr.source=htons(SRCPORT);
t_hdr->thdr.dest=htons(i);
t_hdr->thdr.seq=htons(seq);
t_hdr->thdr.ack_seq=0;
t_hdr->thdr.doff=5+syn;
t_hdr->thdr.fin=1-syn;
t_hdr->thdr.syn=syn;
t_hdr->thdr.ack=0;
t_hdr->thdr.window=htons(32120);
bzero(pseudoHead,HEADER_LEN);
pseudo=pseudoHead;
memcpy(pseudo,&(i_hdr->saddr),8);
pseudo+=9;
memcpy(pseudo,&(i_hdr->protocol,1);
pseudo++;
usleep(10);
i_index=i;
if(!syn)
{
tcp_len=htons(sizeof(struct tcphdr));
memcpy(pseudo,&tcp_len,2);
pseudo+=2;
memcpy(pseudo,t_hdr,sizeof(struct tcphdr));
t_hdr->thdr.check=in_chksum(u_short*)pseudoHead,HEADER_LEN-4);
if(sendto(sock_raw,packet,sizeof(struct tcphdr)+sizeof(struct iphdr),0,&sa_to,sizeof(sa_to))<0)
perror(sendto);
}
else
{
t_hdr->opt_name=2;
t_hdr->opt_len=4;
t_hdr->opt=htons(1460);
tcp_len=htons(sizeof(struct t_tcphdr));
memcpy(pseudo,&tcp_len,2);
pseudo+=2;
memcpy(pseudo,t_hdr,sizeof(struct t_tcphdr));
t_hdr->thdr.check=in_chksum((u_short*)pseudoHead,HEADER_LEN);
if(sendto(sock_raw,packet,sizeof(struct iphdr)+sizeof(struct t_tcphdr),0,&sa_to,sizeof(sa_to))<0)
perror("sendto");
}
}
printf("sending ended!/n");
pthread_join(tid,NULL);
return 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -