2010-05-05 17 views
1
#define IPTOSBUFFERS 12 
char *iptos(u_long in) 
{ 
    static char output[IPTOSBUFFERS][3*4+3+1]; 
    static short which; 
    u_char *p; 

    p = (u_char *)∈ 
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1); 
    _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]),"%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 
    return output[which]; 
} 

Y at-il quelque chose qui me manque pour le comprendre?Pouvez-vous expliquer comment fonctionne cette fonction ip_to_string?

+1

Qu'est-ce que vous ne comprenez pas? On dirait qu'il faut un long unsigned et renvoie la représentation de la chaîne ip, avec un pointeur qui pend, malheureusement. – WhirlWind

+0

Quel est le u_long pour '172.16.48.1'? – user198729

+1

172 * 256^3 + 16 * 256^2 + 48 * 256^1 + 1 – WhirlWind

Répondre

1

Voici une réponse, basée sur ce qui semble être déroutant à partir des commentaires.

Une adresse IP est souvent représentée en interne sous la forme de 32 bits. Il est souvent présenté comme 4 champs décimaux, allant de 0 à 255. Pour convertir de la représentation décimale à la représentation 32 bits, convertissez simplement les champs décimaux en binaires (ou hexadécimaux) de gauche à droite et concaténez-les.

Ainsi, 1.2.3.4 devient les champs 0x01, 0x02, 0x03 et 0x04. Ainsi, la représentation 32 bits (unsigned long) d'eux est: 0x01020304. Bien sûr, ceci est également soumis à l'ordre des octets ...

Pour imprimer une adresse 32 bits sous forme de chaîne, regardez chacun des quatre ensembles de 8 bits qui la composent et imprimez-les en décimal entiers avec des points entre.

2

ci-dessous pour votre annoté plaisir:

// This is the number of IP string buffers. 
#define IPTOSBUFFERS 12 

char *iptos(u_long in) 
{ 
    // 12 buffers, each big enough to hold maximum-sized IP address 
    // and nul terminator. 
    static char output[IPTOSBUFFERS][3*4+3+1]; 

    // Last buffer used. 
    static short which; 

    // Get uns. char pointer to IP address. 
    u_char *p; 
    p = (u_char *)∈ 

    // Move to next string buffer, wrapping if necessary. 
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1); 

    // Output IP address by accessing individual unsigned chars in it. 
    _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]), 
     "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 

    // Return the current buffer. 
    return output[which]; 
} 

Cela fonctionne parce que la représentation d'une adresse IPv4 est une valeur 32 bits dans la mémoire et chacun des quatre segments occupe un octet chacun. Il est donc relativement simple de convertir l'adresse de l'entier 32 bits en un tableau à quatre caractères, puis d'utiliser ce tableau pour extraire les segments individuels. Ceci est, bien sûr, basé sur les types de données ayant des largeurs de bits spécifiques donc ce n'est pas portable.

La chose bizarre est la file d'attente circulaire 12-adresse IP. Peut-être que c'était ainsi que vous pourriez obtenir jusqu'à 12 adresses IP à la fois sans que les chaînes soient remplacées bien que je ne pense pas avoir jamais rencontré une situation où plus de deux (peut-être trois pour un serveur proxy ou pass-thru) requis en même temps. Je ne pense pas que ce soit pour la sécurité des threads puisque la modification à which est intrinsèquement dangereuse dans un environnement threadé.