📄 snmpudpipv6domain.c
字号:
&((struct sockaddr_in6 *) from)->sin6_addr, &((struct sockaddr_in6 *) mask)->sin6_addr, &((struct sockaddr_in6 *) &ss)->sin6_addr); if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *) &ss)->sin6_addr, &((struct sockaddr_in6 *) network)-> sin6_addr) == 1) { return 0; } else { return -1; } break; default: return -1; }}/* * The following functions provide the "com2sec6" configuration token * functionality for compatibility. */#define EXAMPLE_NETWORK "NETWORK"#define EXAMPLE_COMMUNITY "COMMUNITY"typedef struct _com2Sec6Entry { char community[VACMSTRINGLEN]; struct sockaddr_in6 network; struct sockaddr_in6 mask; char secName[VACMSTRINGLEN]; struct _com2Sec6Entry *next;} com2Sec6Entry;com2Sec6Entry *com2Sec6List = NULL, *com2Sec6ListLast = NULL;voidmemmove_com2Sec6Entry(com2Sec6Entry * c, char *secName, char *community, struct sockaddr_in6 net, struct sockaddr_in6 mask){ snprintf(c->secName, strlen(secName) + 1, "%s", secName); snprintf(c->community, strlen(community) + 1, "%s", community); memmove(&c->network, &net, sizeof(net)); memmove(&c->mask, &mask, sizeof(mask)); c->next = NULL;}voidnetsnmp_udp6_parse_security(const char *token, char *param){ char *secName = NULL, *community = NULL, *source = NULL; char *cp = NULL, *strnetwork = NULL, *strmask = NULL; com2Sec6Entry *e = NULL; struct sockaddr_in6 net, mask; struct sockaddr_in tmp; memset(&net, 0, sizeof(net)); memset(&mask, 0, sizeof(mask)); memset(&tmp, 0, sizeof(tmp)); net.sin6_family = AF_INET6; mask.sin6_family = AF_INET6; tmp.sin_family = AF_INET; /* * Get security, source address/netmask and community strings. */ secName = strtok(param, "\t\n "); if (secName == NULL) { config_perror("missing NAME parameter"); return; } else if (strlen(secName) > (VACMSTRINGLEN - 1)) { config_perror("security name too long"); return; } source = strtok(NULL, "\t\n "); if (source == NULL) { config_perror("missing SOURCE parameter"); return; } else if (strncmp(source, EXAMPLE_NETWORK, strlen(EXAMPLE_NETWORK)) == 0) { config_perror("example config NETWORK not properly configured"); return; } community = strtok(NULL, "\t\n "); if (community == NULL) { config_perror("missing COMMUNITY parameter\n"); return; } else if (strncmp (community, EXAMPLE_COMMUNITY, strlen(EXAMPLE_COMMUNITY)) == 0) { config_perror("example config COMMUNITY not properly configured"); return; } else if (strlen(community) > (VACMSTRINGLEN - 1)) { config_perror("community name too long"); return; } /* * Process the source address/netmask string. */ cp = strchr(source, '/'); if (cp != NULL) { /* * Mask given. */ *cp = '\0'; strmask = cp + 1; } /* * Deal with the network part first. */ if ((strcmp(source, "default") == 0) || (strcmp(source, "::") == 0)) { strnetwork = strdup("0::0"); strmask = strdup("0::0"); inet_pton(AF_INET6, strnetwork, &net.sin6_addr); inet_pton(AF_INET6, strmask, &mask.sin6_addr); e = (com2Sec6Entry *) malloc(sizeof(com2Sec6Entry)); if (e == NULL) { config_perror("memory error"); return; } /* * Everything is okay. Copy the parameters to the structure allocated * above and add it to END of the list. */ if (strmask != NULL && strnetwork != NULL) { DEBUGMSGTL(("netsnmp_udp6_parse_security", "<\"%s\", %s/%s> => \"%s\"\n", community, strnetwork, strmask, secName)); free(strmask); free(strnetwork); } else { DEBUGMSGTL(("netsnmp_udp6_parse_security", "Couldn't allocate enough memory\n")); } memmove_com2Sec6Entry(e, secName, community, net, mask); if (com2Sec6ListLast != NULL) { com2Sec6ListLast->next = e; com2Sec6ListLast = e; } else { com2Sec6ListLast = com2Sec6List = e; } } else { /* * Try interpreting as IPv6 address. */ if (inet_pton(AF_INET6, source, &net.sin6_addr) == 1) { if (strmask == NULL || *strmask == '\0') { inet_make_mask_addr(PF_INET6, &mask.sin6_addr, 128); } else { if (strchr(strmask, ':')) { if (inet_pton(PF_INET6, strmask, &net.sin6_addr) != 1) { config_perror("bad mask"); return; } } else { if (inet_make_mask_addr (PF_INET6, &mask.sin6_addr, atoi(strmask)) != 0) { config_perror("bad mask"); return; } } } /* * Check that the network and mask are consistent. */ if (inet_addrs_consistence (PF_INET6, &net.sin6_addr, &mask.sin6_addr) != 0) { config_perror("source/mask mismatch"); return; } e = (com2Sec6Entry *) malloc(sizeof(com2Sec6Entry)); if (e == NULL) { config_perror("memory error"); return; } /* * Everything is okay. Copy the parameters to the structure allocated * above and add it to END of the list. */ if (strmask != NULL && strnetwork != NULL) { DEBUGMSGTL(("netsnmp_udp6_parse_security", "<\"%s\", %s/%s> => \"%s\"\n", community, strnetwork, strmask, secName)); free(strmask); free(strnetwork); } else { DEBUGMSGTL(("netsnmp_udp6_parse_security", "Couldn't allocate enough memory\n")); } memmove_com2Sec6Entry(e, secName, community, net, mask); if (com2Sec6ListLast != NULL) { com2Sec6ListLast->next = e; com2Sec6ListLast = e; } else { com2Sec6ListLast = com2Sec6List = e; } } else { /* * Nope, Must be a hostname. */ struct addrinfo hints, *ai, *res; char hbuf[NI_MAXHOST]; int gai_error; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_INET6; hints.ai_socktype = SOCK_DGRAM; if ((gai_error = getaddrinfo(source, NULL, &hints, &res)) != 0) { config_perror(gai_strerror(gai_error)); return; } for (ai = res; ai != NULL; ai = ai->ai_next) { if (getnameinfo (ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) { config_perror("getnameinfo failed"); } memmove(ai->ai_addr, &net, sizeof(struct sockaddr_in6)); inet_make_mask_addr(AF_INET6, &mask.sin6_addr, 128); e = (com2Sec6Entry *) malloc(sizeof(com2Sec6Entry)); if (e == NULL) { config_perror("memory error"); return; } /* * Everything is okay. Copy the parameters to the structure allocated * above and add it to END of the list. */ DEBUGMSGTL(("netsnmp_udp6_parse_security", "<\"%s\", %s> => \"%s\"\n", community, hbuf, secName)); memmove_com2Sec6Entry(e, secName, community, net, mask); if (com2Sec6ListLast != NULL) { com2Sec6ListLast->next = e; com2Sec6ListLast = e; } else { com2Sec6ListLast = com2Sec6List = e; } } if (res != NULL) freeaddrinfo(res); } /* * free(strnetwork); */ }}voidnetsnmp_udp6_com2Sec6List_free(void){ com2Sec6Entry *e = com2Sec6List; while (e != NULL) { com2Sec6Entry *tmp = e; e = e->next; free(tmp); } com2Sec6List = com2Sec6ListLast = NULL;}voidnetsnmp_udp6_agent_config_tokens_register(void){ register_app_config_handler("com2sec6", netsnmp_udp6_parse_security, netsnmp_udp6_com2Sec6List_free, "name IPv6-network-address[/netmask] community");}/* * Return 0 if there are no com2sec entries, or return 1 if there ARE com2sec * entries. On return, if a com2sec entry matched the passed parameters, * then *secName points at the appropriate security name, or is NULL if the * parameters did not match any com2sec entry. */intnetsnmp_udp6_getSecName(void *opaque, int olength, const char *community, int community_len, char **secName){ com2Sec6Entry *c; struct sockaddr_in6 *from = (struct sockaddr_in6 *) opaque; char *ztcommunity = NULL; char str6[INET6_ADDRSTRLEN]; /* * Special case if there are NO entries (as opposed to no MATCHING * entries). */ if (com2Sec6List == NULL) { DEBUGMSGTL(("netsnmp_udp6_getSecName", "no com2sec entries\n")); if (secName != NULL) { *secName = NULL; } return 0; } /* * If there is no IPv6 source address, * then there can be no valid security name. */ if (opaque == NULL || olength != sizeof(struct sockaddr_in6) || from->sin6_family != PF_INET6) { DEBUGMSGTL(("netsnmp_udp6_getSecName", "no IPv6 source address in PDU?\n")); if (secName != NULL) { *secName = NULL; } return 1; } ztcommunity = (char *) malloc(community_len + 1); if (ztcommunity != NULL) { memcpy(ztcommunity, community, community_len); ztcommunity[community_len] = '\0'; } inet_ntop(AF_INET6, &from->sin6_addr, str6, sizeof(str6)); DEBUGMSGTL(("netsnmp_udp6_getSecName", "resolve <\"%s\", %s>\n", ztcommunity ? ztcommunity : "<malloc error>", str6)); for (c = com2Sec6List; c != NULL; c = c->next) { DEBUGMSGTL(("netsnmp_udp6_getSecName", "compare <\"%s\", 0x%032/0x%032x>", c->community, c->network, c->mask)); if ((community_len == strlen(c->community)) && (memcmp(community, c->community, community_len) == 0) && (masked_address_are_equal(from->sin6_family, (struct sockaddr_storage *) from, (struct sockaddr_storage *) &c->mask, (struct sockaddr_storage *) &c-> network) == 0)) { DEBUGMSG(("netsnmp_udp6_getSecName", "... SUCCESS\n")); if (secName != NULL) { *secName = c->secName; } break; } DEBUGMSG(("netsnmp_udp6_getSecName", "... nope\n")); } if (ztcommunity != NULL) { free(ztcommunity); } return 1;}netsnmp_transport *netsnmp_udp6_create_tstring(const char *string, int local){ struct sockaddr_in6 addr; if (netsnmp_sockaddr_in6(&addr, string, 0)) { return netsnmp_udp6_transport(&addr, local); } else { return NULL; }}/* * See: * * http://www.ietf.org/internet-drafts/draft-ietf-ops-taddress-mib-01.txt * * (or newer equivalent) for details of the TC which we are using for * the mapping here. */netsnmp_transport *netsnmp_udp6_create_ostring(const u_char * o, size_t o_len, int local){ struct sockaddr_in6 addr; if (o_len == 18) { memset((u_char *) & addr, 0, sizeof(struct sockaddr_in6)); addr.sin6_family = AF_INET6; memcpy((u_char *) & (addr.sin6_addr.s6_addr), o, 16); addr.sin6_port = (o[16] << 8) + o[17]; return netsnmp_udp6_transport(&addr, local); } return NULL;}voidnetsnmp_udp6_ctor(void){ udp6Domain.name = netsnmp_UDPIPv6Domain; udp6Domain.name_length = sizeof(netsnmp_UDPIPv6Domain) / sizeof(oid); udp6Domain.f_create_from_tstring = netsnmp_udp6_create_tstring; udp6Domain.f_create_from_ostring = netsnmp_udp6_create_ostring; udp6Domain.prefix = calloc(5, sizeof(char *)); udp6Domain.prefix[0] = "udp6"; udp6Domain.prefix[1] = "ipv6"; udp6Domain.prefix[2] = "udpv6"; udp6Domain.prefix[3] = "udpipv6"; netsnmp_tdomain_register(&udp6Domain);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -