2012-04-23 14 views
5

Eventuali duplicati:
IP Address to Integer - CConversione di indirizzi IP a intero

Come faccio a convertire un indirizzo IP a intero, che ha la seguente forma: A.B. . o A.B.C. * o A. .. * O .. . Voglio scrivere un programma C che può determinare se un indirizzo IP è un sottoinsieme di un altro. ad esempio, l'indirizzo IP 192.168.125.5 è un sottoinsieme di 192.168. .. Ora voglio convertire entrambi gli indirizzi IP in interi unici e successivamente verificare se uno è un sottoinsieme dell'altro. C'è un modo per ottenere questo?

+0

Non lo sai vuoi convertire gli indirizzi IP in numeri interi. Per cominciare, funziona solo con IPv4. Si desidera convertirli in array di byte della lunghezza appropriata e quindi eseguire operazioni di maschera di rete su di essi. – EJP

+0

usa 'inet_pton()' se la tua piattaforma ce l'ha. – Jasen

risposta

7

Un indirizzo IP, ad es. 192.168.0.1 può essere scritto come un intero facilmente scrivendolo in esadecimale che diventa 0xC0 0xA8 0x00 0x01 o solo 0xC0A80001

Quindi è solo un caso di corrispondenza dei bit, quindi si costruisce una subnet mask corrispondente, 255.255.0.0 che è solo 0xFFFF0000 e si può verificare che sia partita facendo:

0xC0A80001 & 0xFFFF0000 == 0xC0A80000 & 0xFFFF0000 

in cui una parte del test di uguaglianza è la "roba di base che ti interessano" e l'altro lato è un vero e proprio indirizzo, con una data maschera essendo il uguale su entrambi i lati.

In generale, è possibile creare una maschera adatta impostando le cose che '*' sono 0 e le cose che sono numeri effettivi da 0xFF, se si desiderano maschere a grana fine è difficile esprimere con '*'.

1

Il modo più semplice e non generale è quello di utilizzare sscanf (con int a, b, c, d): sscanf(ip, "%d.%d.%d.%d", &a, &b, &c, &d); ma funziona solo se si dispone IP con con tutte le sezioni: 10.47.100.1

In caso contrario, è comunque possibile utilizzare il valore restituito di sscanf, che indica il numero di corrispondenze riuscite a trovare (o EOF).

Dopo aver raggiunto i 4 numeri è possibile controllare la relazione di sottogruppi.

+0

No, voglio convertire gli indirizzi IP in numeri interi e quindi verificare la relazione sottoinsieme .... – mmuttam

+0

Puoi ancora costruire un numero intero dal 4 che hai ottenuto. La parte difficile è analizzare i numeri interi. Più tardi, puoi spostarli a sinistra, come altri hanno suggerito qui. –

0

Un singolo intero (supponendo 32 bit) non è sufficiente per rappresentare ciò che si sta delineando. Hai bisogno di più informazioni per poter esprimere gli asterischi.

Ad esempio, è possibile avere una coppia (indirizzo, maschera di rete), in cui la maschera di rete è un singolo numero intero piccolo che rappresenta il numero di bit validi di ordine elevato, ad esempio un indirizzo di rete come "10.0. 0.0 "potrebbe essere rappresentato dalla coppia (0x0a000000, 8). Se vuoi davvero avere i caratteri jolly "ovunque" nell'indirizzo per qualche motivo, hai bisogno di un set completo di un bit di flag per bit di indirizzo, quindi due interi a 32 bit. Quindi potresti rappresentare qualcosa come "192.168 ." come coppia (0xc0a80000, 0xffff0000).

12

Quello che si desidera è determinare se un indirizzo IP si trova in una sottorete e per fare ciò si desidera applicare una maschera di rete. Probabilmente ci sono già (certamente) biblioteche là fuori per fare quello che vuoi. Questo è se vuoi girare il tuo.

Se questo indirizzo IP proviene da una fonte attendibile (vale a dire, non è un utente), allora si può semplicemente estrarre l'indirizzo IP da un C-stringa standard facendo qualcosa di simile:

char ipAddressString[16] = "192.168.125.5" 
char netMaskString[16] = "255.255.0.0" 
char subnetString[16] = "192.168.0.0" 

uint32_t ipAddress = parseIPV4string(ipAddressString); 
uint32_t netmask = parseIPV4string(netmaskString); 
uint32_t subnet = parseIPV4string(subnetString); 

if (ipAddress & netmask == subnet) { 
    return true; 
} 

uint32_t parseIPV4string(char* ipAddress) { 
    char ipbytes[4]; 
    sscanf(ipAddress, "%uhh.%uhh.%uhh.%uhh", &ipbytes[3], &ipbytes[2], &ipbytes[1], &ipbytes[0]); 
    return ipbytes[0] | ipbytes[1] << 8 | ipbytes[2] << 16 | ipbytes[3] << 24; 
} 
+0

Bello, grazie anche per la logica del parser! –

+1

La lettura di un int (% d) in un puntatore char (ipbytes [x]) causa errori gravi mentre sscanf scrive sizeof (int) byte nella memoria indicata da ipbytes [x]. Questo esempio è molto pericoloso. – Zac

+2

@Zac come imbarazzante! Ho corretto l'errore. – OmnipotentEntity

Problemi correlati