OVH Cloud OVH Cloud

q: ecriture des adresses et reseaux IP

25 réponses
Avatar
david
hello evly body

Voila : je bosse sur un projet perso & free qui touche aux reseaux TCP/IP.

Il s'agit d'un petit demon qui teste si les station d'un reseau sont 'up'.

pour le lancer, je fais :

root # eco -D -t 192.168.100.2
(le -D veut dire 'daemonize' et le -t specifie l'adresse de la cible)

et lorsque la station correspondante (station cible) a la dite adresse
ne repond plus, le demon en prend bonne note et adopte un comportement
adequat.

C'est ce que fait la version actuelle.

Ceci dit, mon objectif est de pouvoir tester non une seule adresse IP,
mais tout un ensemble.

Ainsi, je devrais pouvoir specifier comme cible :

192.168.100.1/255.255.255.0
192.168.200.21
192.168.210.76
et etc.



Et donc, mon probleme est de trouver un algorithme efficace pour
parcourir toute les adresses ainsi définies (stockees dans une variable
de type chaine de caractere avec zero terminal)

voila :)
la definition de ces adresses doit etre faite dans un format standard /
universel.

j'imagine que ce genre de code doit etre tres courant (ah oui, je
developpe ce demon sous Linux) vu tous les fichiers de config et autres
scripts mentionnant des adresses / reseaux IP se trouvant sur mon systeme.
C'est pourquoi il me semble qu'il a du etre etabli un algorithme optimal
pour faire ce boulot, qui ne laissa pas place a quelque obscur bug et
qui suivit une syntaxe universelle.

Alors s'il existe ici une personne qui puisse m'apporter quelque lumiere
a ce sujet, je lui en serai extremement reconnaissant de le faire.

MERCI :)




PS : EVIDEMENT que le code que je cherche a faire sera en C. ben alors !
parce que oui, je sais et s'il en avait ete autrement que je m'en serais
alle sur un autre forum.
Et si je ne mets pas les accents sur les lettres c'est parce que j'ai un
petit pbm de config que je n'ai pas encore resolu et comme je ne
considere pas cela comme etant reellement prioritaire, cela risque de
durer encore un peu. Et alors ? ca ne limite que tres peu dans la
comprehension de ce que j'ecris meme si, par ailleurs, il se peut que ma
presentation des choses fut un peu confuse.
En plus ca va plus vite de ne pas faire les accents quand on tape au
clavier.
D'ailleurs ... mais bon, non. jm'en fous apres tout. je n'empeche
personne d'ajouter les accents qu'il veut sur les lettres qu'il veut moi.
Enfin, quoi qu'il en soit, ce qu'il me faut c'est une reponse a ma
question et non une polemique sur un truc si derisoire, alors hop !
on chasse de son esprit toute idee parasite et on se met au boulot.
Le ou la premier(e) qui m'aura fourni la bonne reponse aura gagne toute
mon estime. Alors ca, si ca n'en vaut pas la peine...

5 réponses

1 2 3
Avatar
david
Pascal Bourguignon wrote:

On peut manipuler les adresses IPv4 comme des entiers non signés sur
32 bits. Ainsi, les calculs avec les masques, et les parcours sont
aisés (utilisation des opérations &, | et ^, ++ et --, etc).



c'est justement ce que j'ai fait.

le demon marche,
l'analyse de l'adresse de reseau/hote aussi (a part le pbm du 112.1 qui
devrait équivaloir à 112.0.0.1 et que j'ai équivaloir à 112.1.0.0, en
suivant les résultat de ipcalc)

je stocke les adresse sur un 'unsigned 32 bits' et c'est très pratique.

J'ai l'habitude de travailler avec des processeurs Intel, du coup je ne
me pose pas la question SMALL-INDIAN/BIG-INDIAN, j'ai procédé comme je
le fais habituellement et ça marche.

Alors je ne vois pas ou se situe le piège ?

OU... est-ca à dire que mon code, exécuté sur un motorola produira des
réultats erronés ?

pourtant INTEL=>small indian me semble t'il donc, j'aurai normalement du
faire face auxdits pbm d'ordre...
voila la fonction que j'ai écrite pour convertir un tableau de
char[4][4] en unsigned long (32b sur mon système) :

le paramètre 'len' spécifie le nombre d'éléments de l'adresse fournis
(127.1 => 2élémts, 192.168.100.46 => 4élémts)


/*
------------------------------------------------------------------------- */

unsigned long IPStr2Long(char **str_item, int len)
{
unsigned long addr;
int i,j,k;


addr=0;
j=3;
for (i=0; i<4; i++) {
if (i<len) {
k = atoi(str_item[i]);
if (k>0xFF) { Error(101); return 0; }

addr+=(unsigned long)(k*pow(0x100,j));
j--; } }

return addr;
}
/*
------------------------------------------------------------------------- */

aussi :

unsigned long addr_mask = (unsigned long)((0xFFFFFFFF ^ netw_mask) + 1);

/*
------------------------------------------------------------------------- */

mais encore, pour trouver le nombre de bit d'un mask à partir d'une
notation longue (ex:255.255.255.0) stockée sur un unsigned32b :

bitlen=0;
while ((NetMask&0x80000000)!=0)
{
NetMask=NetMask<<1;
bitlen++;
}

/*
------------------------------------------------------------------------- */



Ce code risque t'il de soufrir de pbms de portabilité ?

Je n'ai pas vu l'ombre d'un indian là... mais ou y sont ?!

Avatar
Pascal Bourguignon
david writes:
[...]
unsigned long IPStr2Long(char **str_item, int len)
{
unsigned long addr;
int i,j,k;


addr=0;
j=3;
for (i=0; i<4; i++) {
if (i<len) {
k = atoi(str_item[i]);
if (k>0xFF) { Error(101); return 0; }

addr+=(unsigned long)(k*pow(0x100,j));
j--; } }

return addr;
}
[...]
Je n'ai pas vu l'ombre d'un indian là... mais ou y sont ?!


C'est que tout le monde n'est pas aussi rigoureux dans sa
programmation: il y en a qui s'amusent à faire des choses comme:

union {
unsigned int adresse;
unsigned char bytes[4];
} ip;
int i;
for(i=0;i<4;i++){
ip.bytes[i]=atoi(str_item[i]);
}
return(ip.address);

ce qui bien sur est faux et ils se plaingnent!

--
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.

Avatar
Pascal Bourguignon
david writes:
addr+=(unsigned long)(k*pow(0x100,j));


On est en entier, alors on peut utiliser plutôt les décallages:
k<<(8*j) sera surement beaucoup plus performant, car même la
multiplication par 8 sera implémentée par le compilateur par un
décallage (il fera k<<(j<<3)).

pow, ça converti tout ça en double et ça fait des multiplications en
virgule flotante à n'en pas finir...

--
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.

Avatar
Laurent Wacrenier
david écrit:
l'analyse de l'adresse de reseau/hote aussi (a part le pbm du 112.1 qui
devrait équivaloir à 112.0.0.1 et que j'ai équivaloir à 112.1.0.0, en
suivant les résultat de ipcalc)

je stocke les adresse sur un 'unsigned 32 bits' et c'est très pratique.


Utilise inet_addr() qui renvoie un in_addr_t que tu convertis en
uint32_t après un passage par ntohl.

Avatar
Laurent Wacrenier
Pascal Bourguignon écrit:
david writes:
addr+=(unsigned long)(k*pow(0x100,j));


On est en entier, alors on peut utiliser plutôt les décallages:
k<<(8*j) sera surement beaucoup plus performant, car même la
multiplication par 8 sera implémentée par le compilateur par un
décallage (il fera k<<(j<<3)).


C'est encore plus performant avec un tableau static de 32 entrées.


1 2 3