2017-05-31 4 views
0

Je souhaite imprimer toutes les adresses IP possibles pour un masque donné. J'ai ce code pour l'obtenir mais il me semble qu'il me manque quelque chose puisque je ne peux pas obtenir la liste des adresses IP. J'ai basé mon code dans this other post.Imprimer toutes les adresses IP en fonction de l'adresse IP et du masque C++

unsigned int ipaddress, subnetmask;  

inet_pton(AF_INET, b->IpAddressList.IpAddress.String, &ipaddress); 
inet_pton(AF_INET, b->IpAddressList.IpMask.String, &subnetmask); 

for (unsigned int i = 1; i<(~subnetmask); i++) { 
    auto ip = ipaddress & (subnetmask + i); 
} 

Exemple: ipaddress = = 255.255.252.0 netmask

172.22.0.65

Je me attends:

 
172.22.0.1 
172.22.0.2 
172.22.0.3 
172.22.0.4 
... 

Mise à jour: J'ai essayé ce code, mais il ne fonctionne pas, soit:

char* ip = "172.22.0.65"; 
char* netmask = "255.255.252.0"; 

struct in_addr ipaddress, subnetmask; 

inet_pton(AF_INET, ip, &ipaddress); 
inet_pton(AF_INET, netmask, &subnetmask); 

unsigned long first_ip = ntohl(ipaddress.s_addr & subnetmask.s_addr); 
unsigned long last_ip = ntohl(ipaddress.s_addr | ~(subnetmask.s_addr)); 

for (unsigned long ip = first_ip; ip <= last_ip; ++ip) { 
    unsigned long theip = htonl(ip); 
    struct in_addr x = { theip }; 
    printf("%s\n", inet_ntoa(x)); 
} 
+0

Si vous connaissez votre code est en C++ ** ** alors pourquoi vous ajoutez également ** C **? –

+0

Modifié pour inclure C et C++ – user1618465

+0

Annulé car les réponses pour C et C++ seront significativement différentes. Voulez les deux, posez deux questions. – user4581301

Répondre

2

Vous pouvez utiliser l'opérateur AND l'adresse IP d'entrée avec le masque d'entrée pour déterminer la première IP dans la plage et au niveau du bit OR l'adresse IP d'entrée à l'inverse de la masque pour déterminer la dernière adresse IP de la plage. Vous pouvez ensuite parcourir les valeurs intermédiaires.

En outre, inet_pton(AF_INET) attend un pointeur vers un struct in_addr, pas un unsigned int.

Essayez ceci:

struct in_addr ipaddress, subnetmask; 

inet_pton(AF_INET, b->IpAddressList.IpAddress.String, &ipaddress); 
inet_pton(AF_INET, b->IpAddressList.IpMask.String, &subnetmask); 

unsigned long first_ip = ntohl(ipaddress.s_addr & subnetmask.s_addr); 
unsigned long last_ip = ntohl(ipaddress.s_addr | ~(subnetmask.s_addr)); 

for (unsigned long ip = first_ip; ip <= last_ip; ++ip) { 
    unsigned long theip = htonl(ip); 
    // use theip as needed... 
} 

Par exemple:

172.22.0.65 & 255.255.252.0 = 172.22.0.0 
172.22.0.65 | 0.0.3.255 = 172.22.3.255 
+0

Salut, il se plaint de "l'erreur C2678: binaire" & ": aucun opérateur trouvé qui prend un opérande de gauche de type 'ULONG '(ou il n'y a pas de conversion acceptable) "sur les lignes qui calculent' first_ip' et 'last_ip'. J'ai essayé de changer 'subnetmask' pour' subnetmask.s_addr' mais la boucle ne fournit pas les IP attendus – user1618465

+0

J'ai oublié d'appliquer 's_addr' sur' subnetmask', et 'ntohl()' et 'htonl()' aux adresses IP générées . Je l'ai réparé. –

+0

J'ai mis à jour le code dans la question parce que votre code ne semble pas fonctionner maintenant non plus. Je définis ip et netmask afin que vous puissiez tester si cela fonctionne bien. Je vous remercie! – user1618465

3

Vous êtes anding l'adresse IP avec le masque de sous-réseau ajouté (essentiellement ored) avec la partie hôte de modification. La préséance est fausse ici. Vous êtes censé et l'adresse IP avec le masque de réseau pour obtenir le réseau partie, puis ou la partie hôte là:

auto ip = (ipaddress & subnetmask) | i; 

En outre, le résultat de inet_pton n'est pas un int mais struct in_addr si YMMV de toute façon. Très probablement, vous devriez utiliser à la place inet_addr comme il retourne un uint32_t:

ip_address = inet_addr("127.0.0.1"); 

Mais à nouveau votre code prévoit que le 127 est l'octet le plus significatif, ce qui est pas sur les systèmes LSB. Ainsi, vous devez échanger ces adresses une fois avec ntohl puis avec htonl.

Ainsi nous obtenons quelque chose comme:

uint32_t ipaddress; 
uint32_t subnetmask; 

ipaddress = ntohl(inet_addr(b->IpAddressList.IpAddress.String)); 
subnetmask = ntohl(inet_addr(b->IpAddressList.IpMask.String)); 

for (uint32_t i = 1; i<(~subnetmask); i++) { 
    uint32_t ip = (ipaddress & subnetmask) | i; 
    struct in_addr x = { htonl(ip) }; 
    printf("%s\n", inet_ntoa(x)); 
} 
+0

En utilisant votre code, l'adresse IP 172.0.0.0 est imprimée tout le temps. ipaddress est 0xac160040 et subnermask est 0xfffffc00. Le bon résultat pour l'exemple que j'ai utilisé dans le post est https://pastebin.com/x4MYei7H – user1618465