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 utiliseruint32_t code> (ou un typef de celui-ci).