Far funzionare Linux come un router
#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
}
}
Tags: C, Linux, Programmazione, Router

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