📄 udp.c
字号:
/* * Get the UDP statistics from the kernel... */ auto_nlist(UDPSTAT_SYMBOL, (char *)&udpstat, sizeof (udpstat)); auto_nlist(MIB_UDPCOUNTER_SYMBOL, (char *)&MIB_udpcounter, (MIB_udpMAXCTR+1)*sizeof (counter)); switch (vp->magic){ case UDPINDATAGRAMS: long_return = MIB_udpcounter[1]; return (u_char *) &long_return; case UDPNOPORTS: long_return = MIB_udpcounter[2]; return (u_char *) &long_return; case UDPOUTDATAGRAMS: long_return = MIB_udpcounter[3]; return (u_char *) &long_return; case UDPINERRORS: long_return = udpstat.udps_hdrops + udpstat.udps_badsum +#ifdef STRUCT_UDPSTAT_HAS_UDPS_DISCARD + udpstat.udps_discard +#endif udpstat.udps_badlen; return (u_char *) &long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_udp\n", vp->magic)); } return NULL;}#endif /* hpux */u_char *var_udpEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ int i; oid newname[MAX_OID_LEN], lowest[MAX_OID_LEN], *op; u_char *cp; int LowState; static struct inpcb inpcb, Lowinpcb; memcpy( (char *)newname,(char *)vp->name, (int)vp->namelen * sizeof(oid)); /* find the "next" pseudo-connection */Again:LowState = -1; /* UDP doesn't have 'State', but it's a useful flag */ UDP_Scan_Init(); for (;;) { if ((i = UDP_Scan_Next(&inpcb)) < 0) goto Again; if (i == 0) break; /* Done */ cp = (u_char *)&inpcb.inp_laddr.s_addr; op = newname + 10; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; newname[14] = ntohs(inpcb.inp_lport); if (exact){ if (snmp_oid_compare(newname, 15, name, *length) == 0){ memcpy( (char *)lowest,(char *)newname, 15 * sizeof(oid)); LowState = 0; Lowinpcb = inpcb; break; /* no need to search further */ } } else { if ((snmp_oid_compare(newname, 15, name, *length) > 0) && ((LowState < 0) || (snmp_oid_compare(newname, 15, lowest, 15) < 0))){ /* * if new one is greater than input and closer to input than * previous lowest, save this one as the "next" one. */ memcpy( (char *)lowest,(char *)newname, 15 * sizeof(oid)); LowState = 0; Lowinpcb = inpcb; } } } if (LowState < 0) return(NULL); memcpy( (char *)name,(char *)lowest, ((int)vp->namelen + 10) * sizeof(oid)); *length = vp->namelen + 5; *write_method = 0; *var_len = sizeof(long); switch (vp->magic) { case UDPLOCALADDRESS: return (u_char *) &Lowinpcb.inp_laddr.s_addr; case UDPLOCALPORT: long_return = ntohs(Lowinpcb.inp_lport); return (u_char *) &long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_udpEntry\n", vp->magic)); } return NULL;}#else /* solaris2 - udp */u_char *var_udp(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ mib2_udp_t udpstat; mib2_ip_t ipstat; u_char *ret = (u_char *)&long_return; /* Successful completion */ if (header_udp(vp, name, length, exact, var_len, write_method) == MATCH_FAILED ) return NULL; /* * Get the UDP statistics from the kernel... */ if (getMibstat(MIB_UDP, &udpstat, sizeof(mib2_udp_t), GET_FIRST, &Get_everything, NULL) < 0) return (NULL); /* Things are ugly ... */ switch (vp->magic){ case UDPNOPORTS: if (getMibstat(MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST, &Get_everything, NULL) < 0) return (NULL); /* Things are ugly ... */ long_return = ipstat.udpNoPorts; break; case UDPINDATAGRAMS: long_return = udpstat.udpInDatagrams; break; case UDPOUTDATAGRAMS: long_return = udpstat.udpOutDatagrams; break; case UDPINERRORS: long_return = udpstat.udpInErrors; break; default: ret = NULL; DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_udp\n", vp->magic)); } return (ret);}u_char *var_udpEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ return NULL;}#endif /* solaris2 - udp */ /********************* * * Internal implementation functions * *********************/#ifdef linuxstatic struct inpcb *udp_inpcb_list;#endif#ifndef solaris2static struct inpcb udp_inpcb, *udp_prev;#ifdef PCB_TABLEstatic struct inpcb *udp_head, *udp_next;#endif#if defined(CAN_USE_SYSCTL) && defined(UDPCTL_PCBLIST)static char *udpcb_buf = NULL;static struct xinpgen *xig = NULL;#endif /* !defined(CAN_USE_SYSCTL) || !define(UDPCTL_PCBLIST) */static void UDP_Scan_Init(void){#if !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST)#ifdef PCB_TABLE struct inpcbtable table;#endif#ifndef linux#ifdef PCB_TABLE auto_nlist(UDB_SYMBOL, (char *)&table, sizeof(table)); udp_next = table.inpt_queue.cqh_first; udp_head = udp_prev = (struct inpcb *)&((struct inpcbtable *)auto_nlist_value(UDB_SYMBOL))->inpt_queue.cqh_first;#else auto_nlist(UDB_SYMBOL, (char *)&udp_inpcb, sizeof(udp_inpcb));#if !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) udp_prev = (struct inpcb *) auto_nlist_value(UDB_SYMBOL);#endif#endif#else /* linux */ FILE *in; char line [256]; struct inpcb **pp; struct timeval now; static unsigned long Time_Of_Last_Reload = 0; /* * save some cpu-cycles, and reload after 5 secs... */ gettimeofday (&now, (struct timezone *) 0); if (Time_Of_Last_Reload + 5 > now.tv_sec) { udp_prev = udp_inpcb_list; return; } Time_Of_Last_Reload = now.tv_sec; if (! (in = fopen ("/proc/net/udp", "r"))) { snmp_log(LOG_ERR, "snmpd: cannot open /proc/net/udp ...\n"); udp_prev = 0; return; } /* free old chain: */ while (udp_inpcb_list) { struct inpcb *p = udp_inpcb_list; udp_inpcb_list = udp_inpcb_list->inp_next; free (p); } /* scan proc-file and append: */ pp = &udp_inpcb_list; while (line == fgets (line, sizeof(line), in)) { struct inpcb pcb, *nnew; unsigned int state, lport; if (3 != sscanf (line, "%*d: %x:%x %*x:%*x %x", &pcb.inp_laddr.s_addr, &lport, &state)) continue; if (state != 7) /* fix me: UDP_LISTEN ??? */ continue; pcb.inp_lport = htons ((unsigned short) (lport)); pcb.inp_fport = htons (pcb.inp_fport); nnew = (struct inpcb *) malloc (sizeof (struct inpcb)); if (nnew == NULL) break; *nnew = pcb; nnew->inp_next = 0; *pp = nnew; pp = & nnew->inp_next; } fclose (in); /* first entry to go: */ udp_prev = udp_inpcb_list;#endif /*linux */#else /* !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) */ { size_t len; int cc; int sname[] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_PCBLIST }; if (udpcb_buf) { free(udpcb_buf); udpcb_buf = NULL; } xig = NULL; len = 0; if (sysctl(sname, 4, 0, &len, 0, 0) < 0) { return; } if ((udpcb_buf = malloc(len)) == NULL) { return; } if (sysctl(sname, 4, udpcb_buf, &len, 0, 0) < 0) { free(udpcb_buf); udpcb_buf = NULL; return; } xig = (struct xinpgen *)udpcb_buf; xig = (struct xinpgen *)((char *)xig + xig->xig_len); return; }#endif /* !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) */}static int UDP_Scan_Next(struct inpcb *RetInPcb){#if !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) register struct inpcb *next;#ifndef linux#ifdef PCB_TABLE if (udp_next == udp_head) return 0;#else if ((udp_inpcb.INP_NEXT_SYMBOL == NULL) || (udp_inpcb.INP_NEXT_SYMBOL == (struct inpcb *) auto_nlist_value(UDB_SYMBOL))) { return(0); /* "EOF" */ }#endif#ifdef PCB_TABLE klookup((unsigned long)udp_next, (char *)&udp_inpcb, sizeof(udp_inpcb)); udp_next = udp_inpcb.inp_queue.cqe_next;#else next = udp_inpcb.INP_NEXT_SYMBOL; klookup((unsigned long)next, (char *)&udp_inpcb, sizeof (udp_inpcb));#if !(defined(netbsd1) || defined(freebsd2) || defined(linux) || defined(openbsd2)) if (udp_inpcb.INP_PREV_SYMBOL != udp_prev) /* ??? */ return(-1); /* "FAILURE" */#endif#endif *RetInPcb = udp_inpcb;#if !(defined(netbsd1) || defined(freebsd2) || defined(openbsd2)) udp_prev = next;#endif#else /* linux */ if (!udp_prev) return 0; udp_inpcb = *udp_prev; next = udp_inpcb.inp_next; *RetInPcb = udp_inpcb; udp_prev = next;#endif /* linux */#else /* !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) */ /* Are we done? */ if ((xig == NULL) || (xig->xig_len <= sizeof(struct xinpgen))) return(0); *RetInPcb = ((struct xinpcb *)xig)->xi_inp; /* Prepare for Next read */ xig = (struct xinpgen *)((char *)xig + xig->xig_len);#endif /* !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) */ return(1); /* "OK" */}#endif /* solaris2 */#ifdef linuxstatic voidlinux_read_udp_stat (struct udp_mib *udpstat){ FILE *in = fopen ("/proc/net/snmp", "r"); char line [1024]; memset ((char *) udpstat,(0), sizeof (*udpstat)); if (! in) return; while (line == fgets (line, sizeof(line), in)) { if (4 == sscanf (line, "Udp: %lu %lu %lu %lu\n", &udpstat->UdpInDatagrams, &udpstat->UdpNoPorts, &udpstat->UdpInErrors, &udpstat->UdpOutDatagrams)) break; } fclose (in);}#endif /* linux */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -