📄 snmpudpipv6domain.c
字号:
if (inet_pton (AF_INET6, peername + 1, (void *) &(addr->sin6_addr))) { DEBUGMSGTL(("netsnmp_sockaddr_in6", "IPv6 address with square brankets\n")); addr->sin6_port = htons(SNMP_PORT); addr->sin6_scope_id = if_index; goto resolved; } } if (scope_id != NULL) { *scope_id = '%'; } *cp = ']'; } } cp = strrchr(peername, ':'); if (cp != NULL) { char *scope_id; unsigned int if_index = 0; *cp = '\0'; scope_id = strchr(peername + 1, '%'); if (scope_id != NULL) { *scope_id = '\0'; if_index = if_nametoindex(scope_id + 1); } if (atoi(cp + 1) != 0 && inet_pton(AF_INET6, peername, (void *) &(addr->sin6_addr))) { DEBUGMSGTL(("netsnmp_sockaddr_in6", "IPv6 address with port suffix :%d\n", atoi(cp + 1))); addr->sin6_port = htons(atoi(cp + 1)); addr->sin6_scope_id = if_index; goto resolved; } if (scope_id != NULL) { *scope_id = '%'; } *cp = ':'; } /* * See if it is JUST an IPv6 address. */ if (inet_pton(AF_INET6, peername, (void *) &(addr->sin6_addr))) { DEBUGMSGTL(("netsnmp_sockaddr_in6", "just IPv6 address\n")); goto resolved; } /* * Well, it must be a hostname then, possibly with an appended :port. * Sort that out first. */ cp = strrchr(peername, ':'); if (cp != NULL) { *cp = '\0'; if (atoi(cp + 1) != 0) { DEBUGMSGTL(("netsnmp_sockaddr_in6", "hostname(?) with port suffix :%d\n", atoi(cp + 1))); addr->sin6_port = htons(atoi(cp + 1)); } else { /* * No idea, looks bogus but we might as well pass the full thing to * the name resolver below. */ *cp = ':'; DEBUGMSGTL(("netsnmp_sockaddr_in6", "hostname(?) with embedded ':'?\n")); } /* * Fall through. */ }#if HAVE_GETADDRINFO memset(&hint, 0, sizeof hint); hint.ai_flags = 0; hint.ai_family = PF_INET6; hint.ai_socktype = SOCK_DGRAM; hint.ai_protocol = 0; err = getaddrinfo(peername, NULL, &hint, &addrs); if (err != 0) { snmp_log(LOG_ERR, "getaddrinfo: %s %s\n", peername, gai_strerror(err)); free(peername); return 0; } DEBUGMSGTL(("netsnmp_sockaddr_in6", "hostname (resolved okay)\n")); memcpy(&addr->sin6_addr, &((struct sockaddr_in6 *) addrs->ai_addr)->sin6_addr, sizeof(struct in6_addr));#elif HAVE_GETIPNODEBYNAME hp = getipnodebyname(peername, AF_INET6, 0, &err); if (hp == NULL) { DEBUGMSGTL(("netsnmp_sockaddr_in6", "hostname (couldn't resolve = %d)\n", err)); free(peername); return 0; } DEBUGMSGTL(("netsnmp_sockaddr_in6", "hostname (resolved okay)\n")); memcpy(&(addr->sin6_addr), hp->h_addr, hp->h_length);#elif HAVE_GETHOSTBYNAME hp = gethostbyname(peername); if (hp == NULL) { DEBUGMSGTL(("netsnmp_sockaddr_in6", "hostname (couldn't resolve)\n")); free(peername); return 0; } else { if (hp->h_addrtype != AF_INET6) { DEBUGMSGTL(("netsnmp_sockaddr_in6", "hostname (not AF_INET6!)\n")); free(peername); return 0; } else { DEBUGMSGTL(("netsnmp_sockaddr_in6", "hostname (resolved okay)\n")); memcpy(&(addr->sin6_addr), hp->h_addr, hp->h_length); } }#else /*HAVE_GETHOSTBYNAME */ /* * There is no name resolving function available. */ snmp_log(LOG_ERR, "no getaddrinfo()/getipnodebyname()/gethostbyname()\n"); free(peername); return 0;#endif /*HAVE_GETHOSTBYNAME */ } else { DEBUGMSGTL(("netsnmp_sockaddr_in6", "NULL peername")); return 0; } resolved: DEBUGMSGTL(("netsnmp_sockaddr_in6", "return { AF_INET6, [%s]:%hu }\n", inet_ntop(AF_INET6, &addr->sin6_addr, debug_addr, sizeof(debug_addr)), ntohs(addr->sin6_port))); free(peername); return 1;}/* * int * inet_make_mask_addr( int pf, void *dst, int masklength ) * convert from bit length specified masklength to network format, * which fills 1 from until specified bit length. * dst is usally the structer of sockaddr_in or sockaddr_in6. * makelength must be an interger from 0 to 32 if pf is PF_INET, * or from 0 to 128 if pf is PF_INET6. * return: * 0 if the input data, masklength was valid for * the specified protocol family. * -1 if the the input data wasn't valid. */intinet_make_mask_addr(int pf, void *dst, int masklength){ unsigned long Mask = 0; int maskBit = 0x80000000L; unsigned char mask = 0; unsigned char maskbit = 0x80L; int i, j, jj; switch (pf) { case PF_INET: if (masklength < 0 || masklength > 32) return -1; ((struct in_addr *) dst)->s_addr = 0; while (masklength--) { Mask |= maskBit; maskBit >>= 1; } ((struct in_addr *) dst)->s_addr = htonl(Mask); break; case PF_INET6: if (masklength < 0 || masklength > 128) return -1; for (i = 0; i < 16; i++) { (*(uint8_t *) (&((struct in6_addr *) dst)->s6_addr[i])) = 0x00; } j = (int) masklength / 8; jj = masklength % 8; for (i = 0; i < j; i++) { (*(uint8_t *) (&((struct in6_addr *) dst)->s6_addr[i])) = 0xff; } while (jj--) { mask |= maskbit; maskbit >>= 1; } (*(uint8_t *) (&((struct in6_addr *) dst)->s6_addr[j])) = mask; break; default: return -1; /* unsupported protocol family */ } return 0;}/* * int * inet_addr_complement( int pf, void *src, void *dst ) * convert from src to dst, which all bits * are bit-compliment of src. * Src, dst are ususally sockaddr_in or sockaddr_in6. * return: * 0 if the input data src and dst have the same size * -1 if the the input data wasn't valid. */intinet_addr_complement(int pf, void *src, void *dst){ int i; if (sizeof(src) != sizeof(dst)) return -1; switch (pf) { case PF_INET: ((struct in_addr *) dst)->s_addr = ~((struct in_addr *) src)->s_addr; break; case PF_INET6: for (i = 0; i < 16; i++) { (*(uint8_t *) (&((struct in6_addr *) dst)->s6_addr[i])) = (~(*(uint8_t *) (&((struct in6_addr *) src)->s6_addr[i]))) & 0xff; } break; default: return -1; } return 0;}/* * int * inet_addr_and( int pf, void *src1, void *src2, void *dst) * take AND operation on src1 and src2, and output the result to dst. * Src1, src2, and dst are ususally sockaddr_in or sockaddr_in6. * return: * 0 if the input data src and dst have the same size * -1 if the the input data are not the same size */intinet_addr_and(int pf, void *src1, void *src2, void *dst){ int i; if (sizeof(src1) != sizeof(src2) || sizeof(src2) != sizeof(dst)) return -1; switch (pf) { case PF_INET: ((struct in_addr *) dst)->s_addr = ((struct in_addr *) src1)->s_addr & ((struct in_addr *) src2)-> s_addr; break; case PF_INET6: for (i = 0; i < 16; i++) { (*(uint8_t *) (&((struct in6_addr *) dst)->s6_addr[i])) = (*(uint8_t *) (&((struct in6_addr *) src1)->s6_addr[i])) & (*(uint8_t *) (&((struct in6_addr *) src2)->s6_addr[i])); } break; default: return -1; } return 0;}/* * int * inet_addrs_consistence (int pf, void *net, void *mask ) * This function checks if the network address net is consistent * with the netmask address, mask. * Net and mask are ususally sockaddr_in or sockaddr_in6. * Note: * Must spefiey protocol family in pf. * return: * 0 if there is no consistence with address "net" and "mask". * -1 if network address is inconsistent with netmask address, for * instance, network address is 192.168.0.128 in spite of netmask, * which is 255.255.255.0. * The case that the size of net and mask are different also returns -1. */intinet_addrs_consistence(int pf, void *net, void *mask){ struct sockaddr_in *tmp, *dst; struct sockaddr_in6 *tmp6, *dst6; int ret; switch (pf) { case PF_INET: tmp = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in)); memset(tmp, 0, sizeof(*tmp)); tmp->sin_family = PF_INET; if (inet_addr_complement (PF_INET, (struct in_addr *) mask, &tmp->sin_addr) != 0) { config_perror("Fail in function of inet_addr_complement()"); free(tmp); return -1; } dst = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in)); memset(dst, 0, sizeof(*dst)); dst->sin_family = PF_INET; if (inet_addr_and (PF_INET, (struct in_addr *) net, &tmp->sin_addr, &dst->sin_addr) != 0) { config_perror("Fail in function of inet_addr_and()"); free(dst); free(tmp); return -1; } ret = ((dst->sin_addr.s_addr == INADDR_ANY) ? 0 : -1); free(dst); free(tmp); break; case PF_INET6: tmp6 = (struct sockaddr_in6 *) malloc(sizeof(struct sockaddr_in6)); memset(tmp6, 0, sizeof(*tmp6)); tmp6->sin6_family = PF_INET6; if (inet_addr_complement (PF_INET6, (struct in6_addr *) mask, &tmp6->sin6_addr) != 0) { config_perror("Fail in function of inet_addr_complement()"); free(tmp6); return -1; } dst6 = (struct sockaddr_in6 *) malloc(sizeof(struct sockaddr_in6)); memset(dst6, 0, sizeof(*dst6)); dst6->sin6_family = PF_INET6; if (inet_addr_and (PF_INET6, (struct in6_addr *) net, &tmp6->sin6_addr, &dst6->sin6_addr)) { config_perror("Fail in function of inet_addr_and()"); free(dst6); free(tmp6); return -1; } ret = (IN6_IS_ADDR_UNSPECIFIED(&dst6->sin6_addr) == 1 ? 0 : -1); free(dst6); free(tmp6); break; default: return -1; } return ret;}/* * int * masked_address_are_equal (pf, from, mask, network) * This function takes AND operation on address "from" and "mask", * and check the result is equal to address "network". * From, net and mask are ususally sockaddr_in or sockaddr_in6. * Note: * Must spefiey protocol family in pf. * return: * 0 if address "from" masked by address "mask" is eqaul to * address "network". * -1 if address "from" masked by address "mask" isn't eqaul to * address "network". For instance, address "from" is * 192.168.0.129 and "mask" is 255.255.255.128. Then, masked * address is 192.168.0.128. If address "network" is 192.168.0.128, * return 0, otherwise -1. * Also retunn -1 if each address family of from, mask, network * isn't the same. */intmasked_address_are_equal(int af, struct sockaddr_storage *from, struct sockaddr_storage *mask, struct sockaddr_storage *network){ struct sockaddr_storage ss; memset(&ss, 0, sizeof(ss)); switch (af) { case PF_INET: if (mask->ss_family != PF_INET || network->ss_family != PF_INET) { return -1; } ss.ss_family = PF_INET; inet_addr_and(PF_INET, &((struct sockaddr_in *) from)->sin_addr, &((struct sockaddr_in *) mask)->sin_addr, &((struct sockaddr_in *) &ss)->sin_addr); if (((struct sockaddr_in *) &ss)->sin_addr.s_addr == ((struct sockaddr_in *) network)->sin_addr.s_addr) { return 0; } else { return -1; } break; case PF_INET6: if (mask->ss_family != PF_INET6 || network->ss_family != PF_INET6) { return -1; } ss.ss_family = PF_INET6; inet_addr_and(PF_INET6,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -