Far funzionare Linux come un router

maggio 24, 2009 by admin  
Filed under Linux, RETI

       #include <sys/socket.h>
       #include <features.h>    /* for the glibc version number */
       #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
       #include <netpacket/packet.h>
       #include <net/ethernet.h>     /* the L2 protocols */
       #else
       #include <asm/types.h>
       #include <linux/if_packet.h>
       #include <linux/if_ether.h>   /* The L2 protocols */
       #endif
       #include<stdio.h>

#include<stdio.h>
struct rt_entry{
unsigned int dstip;
unsigned int mask;
int interface;
unsigned int nextip;
};   
struct rt_entry rt[10];
int rt_n=0;

int rt_find(unsigned int ip)
{
int i;
for (i=0;i<rt_n;i++)
    if((rt
1\

itt rt_init()
k)==
unsigned char * ptr;
ptr = (unsigned int *) rt[10];
ptr[0]=10;ptr[1]=1;ptr[2]=1;ptr[3]=0;        //per andare alla rete 10.1.1i
ptr = (unsigned int *)&rt[0].mask;
ptr[0]=22;ptr[1]=255;ptr[2]=255;ptr[3]=0;
rt[0].interface = 3;     //interfaccia 3, la 2 è gia occupata
rt[0].nextip = 0;     //convenzione, nella stessa rete

ptr = (struct rt_entry rt[10];
    ptr[0]=147;ptr[1]=162;ptr[2]=35;ptr[3]=0;           //per andare alla rete 10.1.1
    ptr = (unsigned int *)&rt[0].mask;
    ptr[0]=22;ptr[1]=255;ptr[2]=255;ptr[3]=0;
    rt[0].interface = 2;   
    rt[0].nextip = 0;       //convenzione, nella stessa rete
struct arp_entry{
unsigned int ip;
unsigned char mac[6];
};

struct arp_entry arp_t[500];
int arp_t=0;

int arpt_find(unsigned int ip,unsigned char * mac)   //analizza la tabella e ci dice se l’ind è presente
{                                                    //mi dice in che riga è e mi da il mac

for (i=0;i<arp_n;i++){
    if (arp_t[i].ip == ip){
    for (j=0;j<6;j++)
        mac[j]=arp_t[i].mac[j];
    return i;
    }
return -1;
}
}

void arpt_insert(unsigned int ip, unsigned char * mac){
int i;,j;
unsigned char inutile[6]
j= arpt_find(ip,inutile);
if (j==-1){
    j=arp_n;            // la prima libera
    arp_n = arp_n +1;    // incremento la posizione
    }

arp_t[j].ip = ip;
for (i=0;i<6;i++)
    arp_t[j].mac[i] = mac[i]

}

void arpt_print()
{
int i;
unsigned char * ptr;
printf("——–INIZIO———-");
for(i=0;i<arp_n;i++){
    ptr = (unsigned char *) &(arp_t[i].ip);
    printf("%d.%d.%d.%d —–> %x:%x:%x:%x:%x:%x:\n",ptr[0],ptr[1],ptr[2],ptr[3],arp_t[i].mac[0],arp_t[i].mac[1],arp_t[i].mac[2],arp_t[i].mac[3],arp_t[i].mac[4],arp_t[i].mac[5]);
printf("——–FINE————\n")

}

struct ether_frame                //*frame ethernet
{
unsigned char dest[6];            //*indirizzo destinatario di 6 byte
unsigned char sorg[6];            //*indirizzo sorgente  
unsigned short type;              //*tipo pacchetto serve a indicare di che protocollo è il pacchetto
unsigned char payload[1400];      //*dati 
};

struct ip_datagram                //DATAGRAM
{
unsigned char ver_IHL;            //*lunghezza Header in byte
unsigned char TOS;                //*type of service
unsigned short totolen;           //*lunghezza totale
unsigned short id;
unsigned short flags_offs;
unsigned char  ttl;               //*time to live quanti router puo passare
unsigned char protocol;
unsigned short checksum;
unsigned int s_addr;             //*indirizzo sorgente
unsigned int d_addr;             //*indirizzo destinatario
unsigned char payload[1380];
};

struct arp_packet                 //PACCHETTO ARP
{
unsigned short htype;             //
unsigned short ptype;             //tipo protocollo
unsigned char hlen;               //
unsigned char plen;
unsigned short op;
unsigned char srcmac[6];
unsigned char srcip[4];
unsigned char dstmac[6];
unsigned char dstip[4];
};

struct icmp_packet
{
unsigned char type;
unsigned char code;
unsigned short checksum;
unsigned short id;
unsigned short seq_number;
unsigned char payload[20];
};

unsigned short int girashort(unsigned short int n)
{                                                      //per invertire i byte
unsigned char destra, sinistra;
destra  = (unsigned char) n & 0×00FF;                  //metto a 0 primo byte e a 1 il secondo
sinistra = (unsigned char) (n / 256);                    //shifta i bit più significativi a destra di 8 bit
return (destra*256 + sinistra);
};

unsigned char mymac[6] = {0×00,0xA0,0×24,0×82,0xFF,0×1E}; //array con dentro il mio indizizzo MAC
unsigned char myip[4]  = {147,162,35,66};                  //array con dentro il mio indizizzo IP
unsigned char mymasck[4]  = {255,255,255,0};

int s;
struct sockaddr_ll sll;

int sonouguali(unsigned char * b1, unsigned char * b2, int l){ //
    int i;
    for(i=0;i<1;i++)
        if(b1[i]!=b2[i])
            return 0;
    return 1;
}

void invia_arp(int s,unsigned int ip, int interface)  //FUNZIONE che
{                                                      //invio una richiesta a un indirizzo ip  e su *mac
                                                   //mi da l’indirizzo
unsigned char buffer_in[1500];                         //buffer per pacchetto risposta                              
unsigned char buffer[1500];                            //allocare un buffer di memoria
struct ether_frame * eth;                              //puntatore eth
struct arp_packet * arp;                               //puntatore arp che segue la struttura arp_paket
int i;                                                 //servira’ per il for
int n;
int sll_len;                                           //lunghezza della sll di ritorno

eth = (struct ether_frame *) buffer;                   //concatenare pacchetto eternet con pacchetto arp
arp = (struct arp_packet *) eth -> payload;            //arp inizia nel campo payload di eth = buffer +14

arp -> htype = girashort(1);                           //tipo hardware tipe 1=eternet                     
arp -> ptype = girashort(0×0800);                      //tipo di livello 3 0800=IP
arp -> hlen  = 6;                                      //dice  indirizzo hw è di 6 byte
arp -> plen  = 4;                                      //
arp -> op    = girashort(1);                           // 1 = richiesta, 2 = risposta
for (i=0;i<6;i++) arp ->  srcmac[i] = mymac[i];                //nostro indirizzo Mac
for (i=0;i<4;i++) arp ->  srcip[i] = myip[i];                  // "        "      IP
for (i=0;i<6;i++) arp ->  dstmac[i] = 0;                       //indirizzo vuoto destiatario
for (i=0;i<4;i++) arp ->  dstip[i] = ((unsigned char*)&ip)[i]; //indirizzo ip destinatario   

for (i=0; i<6;i++) eth -> dest[i] = 0xFF;                   //indirizzo ethernet che ogni calcolatore lo pensa indirizzato a se = a 1111
for (i=0; i<6;i++) eth-> sorg[i] = mymac[i];
eth -> type = girashort(0×0806);                            //tipo girato dice che è una sequenza di byte di tipo ARP
for (i=0;i<42;i++) printf("%x(%d)",buffer[i], buffer[i]);   //stampo in decimale ed esadecimale
printf("\n");

            }
          }

}
void crea_ethernet (unsigned char * b, unsigned char * sorgmac, unsigned char * destmac,unsigned short type)
{
int i;
struct ether_frame * eth;
eth = (struct ether_frame *) b;
eth -> type = girashort(type);

}

void crea_icmp(unsigned char *b)   
{
int i;   
struct icmp_packet *icmp;
unsigned char b[1500];
icmp=(struct icmp_packet *)b;
icmp->type = 8;
icmp->code = 0;
icmp->checksum = 0;
icmp->seq_number=girashort(1);
icmp->id=0;
for(i=0;i<20;i++) icmp->payload[i]=i;
icmp->checksum = girashort(checksum(b,28));
}

unsigned short checksum(unsigned char *b,int len){                 //
unsigned short *cs;
unsigned int i,somma;
cs = (unsigned short *)b;
somma=0;
     if ((len&1)==1) {              // se len è dispari
    b[len]=0;                   // aggiungere byte e quindi diventa pari
    len=len+1;
        }
for (i=0;i<(len/2);i++){
    somma=somma+girashort(cs[i]);
    if (somma>0xFFFF)
    somma=((somma&0×0000FFFF)+1);  // il bit di overflow viene sommato e poi maschero (solo  bit)
        }   
return (0xFFFF - (unsigned short)somma);
}   
}

void crea_ip(unsigned char * b, unsigned char payloadlen,unsigned int sorg, unsigned int dest,unsigned char prot)
{
struct ip_datagram * ip;
ip = (struct ip_datagram*)b;
ip->vers_IHL = 0×45;
ip->tos = 0;
ip->totlen = girashort(20 + payloadlen);       // non sappiamo ancora, nel nostro caso è 28
ip->id = girashort(0xABCD);
ip->flags_offs = girashort(0);
ip->ttl = 128;
ip->protocol = proto;
ip->checksum = girashort(0);
ip->s_addr = sorg;
ip->d_addr = dest;
ip->checksum = girashort(checksum(b,20));
}

int main()
{
int i;
                                                         //147.162.35.133   
unsigned char indirizzomac[6];                               //area di memoria dove mettere l’indirizzo mac
unsigned int destip;
unsigned int sorgip;
unsigned int mask;
unsigned int gateway;
unsigned char buffer[1500];
struct ip_datagram * ip;
struct ether_datagram * eth;
struct arp_packet * arp;
unsigned char * ptr;
unsigned int ipaddr;
struct sockaddr_ll sll;

s = socket(PF_PACKET, SOCK_RAW, girashort(ETH_P_ALL));      //ETH_P_ALL=prendi tutti i pachhetti ke passano, s ha un intero
if (s == -1 )                                               // -1 vuol dire che canale nn disponibile
      {
             perror("ERRORE NELLA FUNZIONE SOCKET");                 //  il canale non e’ pronto
                exit(1);
              }
sll.sll_ifindex=0;
sll.sll_family = AF_PACKET;
sll_length = sizeof(struct sockaddr_ll);
while( 1 ){

    n=recvfrom(s,buffer,1500,0,(struct sockaddr *)&sll,&sll_length);         //vedere se nel buffer c’è un pacchetto ip o ARP
        eth = (struct ether_frame *) buffer;
    if (eth->type ==girashort(0×0800)){
        printf("Pacchetto Ip ricevuto\n");   
        /*
        decidi_route();     // guardare tabella di routing
            */
        ip = (struct ip_datagram *) eth->payload;
        j = rt_find(ip->d_addr);
        if (j!=-1){
            ip->ttl = ip->ttl -1;
            ip->checksum = 0;
            ip->checksum = girashort(checksum(ip,20));
            if(rt[j].nextip == 0) //destinazione direttamente connessa
                if (arpt_find(ip->d_addr,macaddr)==-1);
                {    //invia richiesta ARP
                    invia_arp(s,ip->d_addr,rt[j].interface);
                }
                else{ //invia pacchetto
                for(i=O;i<6;i++){
                eth->dest[i]=macaddr[i]; //ricavato dalla tabella arp
                eth->sorg[i]=mymac[i];
                sll.sll_family = AF_PACKET;
                sll.sll_ifindex = rt[j].interface;
                n = sendto(s,b,n,0,(struct sockaddr *) &sll, sizeof(struct sockaddr_ll));
                printf("%d numero bytes routati\n",n);
                }
        }
        invia_eth();        // bisogna trovare mac giusto
        */
    }
    else if(eth->type == girashort(0×0806)){    //pacchetto arp
        arp = (struct arp packet *) eth->payload;   
        ptr = (unsigned char *) &ipaddr;
        ptr[0]=arp->scrip[0];   //assegno byte a byte
        ptr[1]=arp->scrip[1];
        ptr[2]=arp->scrip[2];
        ptr[3]=arp->scrip[3];
        arpt_insert(ip,arp->srcmac);     //aggiorna tabella
        arpt_print();               //stampa tabella
    }

}

Technorati Tag: ,,,
Tags: , , ,

Related posts

Comments

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!