jeudi 28 juin 2007

Checksum IP et TCP

Voici des functions permettant de faire le checksum d'entête IP et TCP.

Tout d'abord la fonction de checksum IP :

/*compute internet checksum. thanks to frameip.com*/
static unsigned short ADchecksum(unsigned short *addr, int len)
{

int nleft=len;
int sum=0;
/*short pour pouvoir prendre les données deux par deux (char => 1 byte short => 2 bytes)*/
unsigned short *w=addr;
unsigned short answer=0;

while(nleft>1){
sum+=*w++;
nleft-=2;
}
if(nleft==1){
/*cast en char pour prendre bien que le dernier octet et pas de la merde qui pourrait se trouver après*/
sum +=*((unsigned char *)w);
}
while(sum>>16){
sum = (sum>>16)+(sum & 0xffff);
}
answer=~sum;
return answer;
}



Pour le checksum tcp, il faut une pseudo entête :

/*thanks to www.frameip.com*/
struct ADpseudo_entete
{
unsigned int ip_source; // Adresse ip source
unsigned int ip_destination; // Adresse ip destination
char mbz; // Champs à 0
char type; // Type de protocole (6->TCP et 17->UDP)
unsigned short length; // htons(Entete TCP ou UDP + Data )
}ADpseudo_entete;


Ensuite la fonction de checksum elle-même :

/*compute tcp checksum. thanks to frameip.com*/
static unsigned short ADchecksum_tcp(struct iphdr *iph, struct tcphdr *tcph)
{
struct ADpseudo_entete *pseudo_tcp = malloc(sizeof(struct ADpseudo_entete));

unsigned short check = 0;

char end[2];
int data_length,pseudo_length,total_length;

pseudo_tcp->ip_source = iph->saddr;
pseudo_tcp->ip_destination = iph->daddr;
pseudo_tcp->mbz = 0;
pseudo_tcp->type = IPPROTO_TCP;

/*total length in bytes*/
total_length = ntohs(iph->tot_len) - iph->ihl*4;

pseudo_length = sizeof(struct ADpseudo_entete);
data_length = total_length - tcph->doff*4;

pseudo_tcp->length = htons(total_length);

int data_len = total_length + pseudo_length;
unsigned char donnees[data_len];

memcpy(donnees,(unsigned char*) pseudo_tcp,pseudo_length);
memcpy(donnees+pseudo_length,(unsigned char*) tcph,total_length);

check = ADchecksum((unsigned short*)donnees,data_len);
return check;
}

2 commentaires:

Nicolas Stefaniuk a dit…

C'est en quel langage ? A l'oeil je dirais du C mais je ne suis pas sûr... Enfin c'est suffisement pas évident pour le préciser, je pense.

Bisous.

Lionel a dit…

Voui c'est du C.