Je veux poser des questions sur le calcul du réseau IPv6 et du côté hôte.
Par exemple, j'ai l'adresse IPv6 Connaissez-vous un moyen facile de faire un bit bitwise selon IPv4: p> si simple. p> Je veux faire la même chose à l'adresse IPv6. Mais l'adresse IPv6 est de 16 octets, vous ne pouvez donc pas utiliser Y a-t-il une API à faire cela? Ou devrais-je utiliser des tableaux? P> p> 2001: 470: 1f15: 1BCD: 34 :: 41 code> et préfixe
96 code>. P>
et code> entre l'adresse IPv6 et le préfixe? p>
non signé INT code> pour cela. P>
6 Réponses :
Vous pouvez convertir l'adresse en binaire dans l'ordre d'octet de réseau avec inet_pton a >. Puis définissez / effacer les bits un octet à la fois. P>
Menace La IP aime une matrice de 16 octets, ignorez le a écrit le code ici, il n'a donc pas été testé mais je pense que vous pouvez utiliser quelque chose comme ça p> p> masqué / 8 code> octets dans le prochain masque d'octet le plus élevé
masqué% 8 code> BITS, définissez les autres sur < code> 0 code>
Calculer le masque de préfixe Longueur:
bool inet6_lnaof ( struct in6_addr* restrict dst, const struct in6_addr* restrict src, const struct in6_addr* restrict netmask ) { bool has_lna = FALSE; assert (NULL != dst); assert (NULL != src); assert (NULL != netmask); for (unsigned i = 0; i < 16; i++) { dst->s6_addr[i] = src->s6_addr[i] & netmask->s6_addr[i]; has_lna |= (0 != (src->s6_addr[i] & !netmask->s6_addr[i])); } return has_lna; }
Alerte de corruption mémoire! Astuce: Combien de fois votre boucle est-elle itérale si la préfixe est, dise, 3?
@JDEBP testé en multiples de 8 seulement (TM) :-)
gars j'ai résolu mon problème Le code source est ci-dessous l'utiliser et continuer à coder: D: AVERTISSEMENT La fonction suppose que l'adresse IPv6 est valide.,
Mon type est:
Wow, ainsi convolué avec une utilisation ambiguë du mot "masque".
OK, je l'ai fait en C plutôt que C ++, mais cela devrait fonctionner. Aussi, il utilise bswap_64 code>
qui est Afaik une extension GNU, donc peut ne pas fonctionner sur tout.
Il semble être très rapide sur AMD64 et plus vite que la solution actuelle Yasar a proposé: P>
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <arpa/inet.h> #if defined __GNUC__ && __GNUC__ >= 2 #include <byteswap.h> #else #error "Sorry, you need GNU for this" #endif struct split { uint64_t start; uint64_t end; }; void ipv6_prefix (unsigned char *masked, unsigned char *packed, int prefix) { struct split parts; uint64_t mask = 0; unsigned char *p = masked; memset(masked, 0, sizeof(struct in6_addr)); memcpy(&parts, packed, sizeof(parts)); if (prefix <= 64) { mask = bswap_64(bswap_64(parts.start) & ((uint64_t) (~0) << (64 - prefix))); memcpy(masked, &mask, sizeof(uint64_t)); return; } prefix -= 64; memcpy(masked, &(parts.start), sizeof(uint64_t)); p += sizeof(uint64_t); mask = bswap_64(bswap_64(parts.end) & (uint64_t) (~0) << (64 - prefix)); memcpy(p, &mask, sizeof(uint64_t)); } int main (int argc, char **argv) { unsigned char packed[sizeof(struct in6_addr)]; unsigned char masked[sizeof(struct in6_addr)]; char buf[INET6_ADDRSTRLEN], *p; int prefix = 56; if (argc < 2) return 1; if ((p = strchr(argv[1], '/'))) { *p++ = '\0'; prefix = atoi(p); } inet_pton(AF_INET6, argv[1], packed); ipv6_prefix(masked, packed, prefix); inet_ntop(AF_INET6, masked, buf, INET6_ADDRSTRLEN); printf("prefix = %s/%d\n", buf, prefix); return 0; }
Je viens de l'essayer sur une carte virtuelle I686 et c'est nettement plus rapide que cela aussi.
Voici une minuterie simple:
Si vous écrivez 255.255.255.0 AS / 24 AS / 24, le bit tripdling est presque identique.
Notez que vous ne devriez pas utiliser
non signé INT code> pour IPv4 non plus; Vous devriez utiliser
uint32_t code> (ou un typef de celui-ci).