📄 ipv6.c
字号:
char *sysctl_buf; struct xinpgen *xig, *oxig;#endif /* defined(__FreeBSD__) && __FreeBSD__ >= 3 */ if (!initialized) { tcpstatemap[TCPS_CLOSED] = 1; tcpstatemap[TCPS_LISTEN] = 2; tcpstatemap[TCPS_SYN_SENT] = 3; tcpstatemap[TCPS_SYN_RECEIVED] = 4; tcpstatemap[TCPS_ESTABLISHED] = 5; tcpstatemap[TCPS_CLOSE_WAIT] = 8; tcpstatemap[TCPS_FIN_WAIT_1] = 6; tcpstatemap[TCPS_CLOSING] = 10; tcpstatemap[TCPS_LAST_ACK] = 9; tcpstatemap[TCPS_FIN_WAIT_2] = 7; tcpstatemap[TCPS_TIME_WAIT] = 11; initialized++; } DEBUGMSGTL(("mibII/ipv6", "var_tcp6: ")); DEBUGMSGOID(("mibII/ipv6", name, *length)); DEBUGMSG(("mibII/ipv6"," %d\n", exact));#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) if (!auto_nlist("tcb6", (char *)&tcb6, sizeof(tcb6))) return NULL; p = (caddr_t)tcb6.in6p_next;#else { const char *tcblist = "net.inet.tcp.pcblist"; int len; if (sysctlbyname(tcblist, 0, &len, 0, 0) < 0) return NULL; if ((sysctl_buf = malloc(len)) == NULL) return NULL; if (sysctlbyname(tcblist, sysctl_buf, &len, 0, 0) < 0) { free(sysctl_buf); return NULL; } oxig = (struct xinpgen *)sysctl_buf; xig = (struct xinpgen *)((char *)oxig + oxig->xig_len); }#endif found = hitnext = 0; memcpy((char *)newname, (char *)vp->name, (int)vp->namelen * sizeof(oid)); while(#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) p && (u_long)p != auto_nlist_value("tcb6")#else xig->xig_len > sizeof(struct xinpgen)#endif ) { DEBUGP("looping: p=%x\n", p);#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) if (klookup((u_long)p, (char *)&in6pcb, sizeof(in6pcb)) < 0)#else in6pcb = ((struct xinpcb *)xig)->xi_inp;#endif { DEBUGP("klookup fail for in6pcb at %x\n", p); break; } if (klookup((u_long)in6pcb.in6p_ppcb, (char *)&tcpcb, sizeof(tcpcb)) < 0) { DEBUGP("klookup fail for tcpcb at %x\n", in6pcb.in6p_ppcb); break; } j = (int)vp->namelen; for (i = 0; i < sizeof(struct in6_addr); i++) newname[j++] = in6pcb.in6p_laddr.s6_addr[i]; newname[j++] = ntohs(in6pcb.in6p_lport); for (i = 0; i < sizeof(struct in6_addr); i++) newname[j++] = in6pcb.in6p_faddr.s6_addr[i]; newname[j++] = ntohs(in6pcb.in6p_fport); if (IN6_IS_ADDR_LINKLOCAL(&in6pcb.in6p_laddr)) newname[j++] = ntohs(*(u_int16_t *)&in6pcb.in6p_laddr.s6_addr[2]); else newname[j++] = 0; /*XXX*/ newname[j++] = tcpstatemap[tcpcb.t_state]; DEBUGMSGTL(("mibII/ipv6", "var_tcp6 newname: ")); DEBUGMSGOID(("mibII/ipv6", newname, *length)); DEBUGMSG(("mibII/ipv6", "\nvar_tcp6 oldname: ")); DEBUGMSGOID(("mibII/ipv6", name, *length)); DEBUGMSG(("mibII/ipv6"," %d\n", exact));#if 1 /* this is very odd but sometimes happen, and cause infinite loop */ if (ntohs(in6pcb.in6p_lport) == 0) goto skip;#endif if (exact) { result = snmp_oid_compare(name, *length, newname, j); if (result == 0) { found++; break; } } else { /* * tcb entries may not be ordered as SNMP scanning code expect. * Therefore, we'll do a guess... * 1. "name" has the previously matched entry. * If "name" is TCP6 MIBs, take the item that is right next * to the item exactly matches to "name". * 2. Otherwise, it is the very first time we entered to TCP6 MIBs. */ memcpy(tmp1, name, vp->namelen * sizeof(oid)); memcpy(tmp2, newname, vp->namelen * sizeof(oid)); tmp1[vp->namelen] = 0; tmp2[vp->namelen] = 0; if (*length == j && snmp_oid_compare(tmp1, vp->namelen, tmp2, vp->namelen) == 0) { if (!hitnext) { result = snmp_oid_compare(name, *length, newname, j); if (result == 0) hitnext++; } else { found++; break; } } else { if (snmp_oid_compare(name, *length, newname, j) < 0) { found++; break; } } }skip:#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) p = (caddr_t)in6pcb.in6p_next;#else xig = (struct xinpgen *)((char *)xig + xig->xig_len);#endif } DEBUGP("found=%d\n", found); if (!found) return NULL; *length = j; memcpy((char *)name, (char *)newname, *length * sizeof(oid)); *write_method = 0; *var_len = sizeof(long); /* default to 'long' results */ /* try looking into the kernel variable */ DEBUGP("magic=%d\n", vp->magic); switch (vp->magic) { case IPV6TCPLOCALADDR: *var_len = sizeof(struct in6_addr); return (u_char *)&in6pcb.in6p_laddr.s6_addr[0]; case IPV6TCPLOCALPORT: long_return = ntohs(in6pcb.in6p_lport); return (u_char *)&long_return; case IPV6TCPREMOTEADDR: *var_len = sizeof(struct in6_addr); return (u_char *)&in6pcb.in6p_faddr.s6_addr[0]; case IPV6TCPREMOTEPORT: long_return = ntohs(in6pcb.in6p_fport); return (u_char *)&long_return; case IPV6TCPIFINDEX: if (IN6_IS_ADDR_LINKLOCAL(&in6pcb.in6p_laddr)) long_return = ntohs(*(u_int16_t *)&in6pcb.in6p_laddr.s6_addr[2]); else long_return = 0; /*XXX*/ return (u_char *)&long_return; case IPV6TCPCONNSTATE: long_return = tcpstatemap[tcpcb.t_state]; return (u_char *)&long_return; default: break; } ERROR_MSG(""); return NULL;}#endif /*TCP6*/#else /* !linux / linux *//* Linux dependent part */static unsigned long linux_read_ip6_stat_ulong(const char *file){ FILE *f; unsigned long value; f = fopen(file, "r"); if (!f) return 0; if (fscanf(f, "%lu", &value) != 1){ fclose(f); return 0; } fclose(f); return value;}void linux_read_ip6_stat(struct ip6_mib *ip6stat){ if (!ip6stat) return; memset(ip6stat, 0, sizeof(*ip6stat)); ip6stat->Ipv6Forwarding = linux_read_ip6_stat_ulong("/proc/sys/net/ipv6/conf/all/forwarding"); ip6stat->Ipv6DefaultHopLimit = linux_read_ip6_stat_ulong("/proc/sys/net/ipv6/conf/default/hop_limit");}u_char *var_ipv6( register struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ int i; static struct ip6_mib ip6stat; if (header_ipv6(vp, name, length, exact, var_len, write_method) == MATCH_FAILED) { return NULL; } linux_read_ip6_stat(&ip6stat); switch(vp->magic){ case IPV6DEFAULTHOPLIMIT: return (u_char *)&ip6stat.Ipv6DefaultHopLimit; case IPV6FORWARDING: return (u_char *)&ip6stat.Ipv6Forwarding; case IPV6INTERFACES:#ifdef HAVE_IF_NAMEINDEX long_return = if_countifindex(); if (long_return < 0) break; return (u_char *)&long_return;#endif break; default: DEBUGMSGTL(("snmpd", "unknonw sub-id %d in var_ipv6\n", vp->magic)); } return NULL;}u_char *var_ifv6Entry( register struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){#ifndef HAVE_IF_NAMEINDEX return NULL;#else int interface; int max; char *p; struct ifreq ifr; int s; max = if_maxifindex(); if (max < 0) return NULL; if (header_ipv6_scan(vp, name, length, exact, var_len, write_method, 1, max) == MATCH_FAILED) { return NULL; } interface = name[*length - 1]; DEBUGP("interface: %d(%s)\n", interface, if_getname(interface)); if (interface > max) return NULL; switch (vp->magic) { case IPV6IFDESCR: p = if_getname(interface); if (p) { *var_len = strlen(p); return p; } break; case IPV6IFLOWLAYER: /* should check if type, this is a hard one... */ *var_len = nullOidLen; return (u_char *)nullOid; case IPV6IFEFFECTMTU: { p = if_getname(interface); if (!p) break; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_addr.sa_family = AF_INET6; strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name)); if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) break; if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0) { close(s); break; } long_return = ifr.ifr_mtu; close(s); return (u_char *)&long_return; } case IPV6IFPHYSADDRESS: { static struct ifreq buf; int ok = 0; p = if_getname(interface); if (!p) break; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_addr.sa_family = AF_INET6; strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name)); if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) break; if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0){ memset(buf.ifr_hwaddr.sa_data, 0, sizeof(buf.ifr_hwaddr.sa_data)); *var_len = 0; } else{ memcpy(buf.ifr_hwaddr.sa_data, ifr.ifr_hwaddr.sa_data, 6); *var_len = (buf.ifr_hwaddr.sa_data[0] | buf.ifr_hwaddr.sa_data[1] | buf.ifr_hwaddr.sa_data[2] | buf.ifr_hwaddr.sa_data[3] | buf.ifr_hwaddr.sa_data[4] | buf.ifr_hwaddr.sa_data[5]) ? 6 : 0; ok = 1; } close(s); return (ok ? ((u_char *)&buf.ifr_hwaddr.sa_data) : NULL); } case IPV6IFADMSTATUS: case IPV6IFOPERSTATUS: { int flag = 0; p = if_getname(interface); if (!p) break; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_addr.sa_family = AF_INET6; strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name)); if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) break; if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0){ close(s); break; } switch(vp->magic){ case IPV6IFADMSTATUS: flag = IFF_RUNNING; break; case IPV6IFOPERSTATUS: flag = IFF_UP; break; } long_return = (ifr.ifr_flags & flag) ? 1 : 2; return (u_char *)&long_return; } } return NULL;#endif}u_char *var_icmpv6Entry( register struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ return NULL;}u_char *var_udp6( register struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ return NULL;}u_char *var_tcp6( register struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ return NULL;}/* misc functions (against broken kernels ) */void linux_if_freenameindex(struct if_nameindex *ifndx){ int i; if (!ifndx) return; for (i=1; ifndx[i].if_index; i++){ free(ifndx[i].if_name); } free(ifndx);}#define linux_freeinternalnameindex(ifni, max) { \ int i; \ for (i=1; i<=max; i++){ \ if (ifni[i].if_name) free(ifni[i].if_name); \ } \ free(ifni); \}#define LINUX_PROC_NET_IFINET6 "/proc/net/if_inet6"struct if_nameindex *linux_if_nameindex(void){ FILE *f; unsigned long if_index; char if_name[256]; struct if_nameindex *ifndx = NULL, *iflist = NULL, *new; int i,j; int maxidx, if_count = 0; f = fopen(LINUX_PROC_NET_IFINET6, "r"); if (f){ if_count = 0; maxidx = -1; while (!feof(f)){ if (fscanf(f, "%*s %lx %*x %*x %*x %s", &if_index, if_name) != 2) continue; if (if_index == 0) continue; if_name[sizeof(if_name)-1] = '\0'; if (maxidx < 0 || maxidx < if_index){ new = realloc(iflist, (sizeof(struct if_nameindex)) * (if_index+2)); if (!new){ linux_freeinternalnameindex(iflist, if_index); if_count = 0; iflist = NULL; break; } iflist = new; for (i=maxidx+1; i<=if_index; i++) memset(&iflist[i], 0, sizeof(struct if_nameindex)); memset(&iflist[if_index+1], 0, sizeof(struct if_nameindex)); maxidx = if_index; } if (iflist[if_index].if_index == 0){ if_count++; iflist[if_index].if_index = if_index; iflist[if_index].if_name = strdup(if_name); if (!iflist[if_index].if_name){ linux_freeinternalnameindex(iflist, if_index); if_count = 0; iflist = NULL; break; } } } fclose(f); if (if_count > 0){ ifndx = malloc(sizeof(struct if_nameindex) * (if_count + 1)); j = 0; for (i=1; i<=maxidx; i++){ if(iflist[i].if_index > 0 && *iflist[i].if_name){ memcpy(&ifndx[j++], &iflist[i], sizeof(struct if_nameindex)); } } ifndx[j].if_index = 0; ifndx[j].if_name = NULL; } free(iflist); } return (ifndx);}#endif /* linux */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -