📄 tcp.c
字号:
return NULL;}#endif /* not HAVE_SYS_TCPIPSTATS_H */u_char *var_tcpEntry(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 State, LowState; static struct inpcb inpcb, Lowinpcb; /* * Allow for a kernel w/o TCP */#ifdef TCPSTAT_SYMBOL#ifndef linux if (auto_nlist_value(TCPSTAT_SYMBOL) == -1) return(NULL);#endif#endif memcpy( (char *)newname,(char *)vp->name, (int)vp->namelen * sizeof(oid)); lowest[0] = 9999; /* find "next" connection */Again:LowState = -1; /* Don't have one yet */ TCP_Scan_Init(); for (;;) { if ((i = TCP_Scan_Next(&State, &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); cp = (u_char *)&inpcb.inp_faddr.s_addr; op = newname + 15; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; newname[19] = ntohs(inpcb.inp_fport); if (exact){ if (snmp_oid_compare(newname, 20, name, *length) == 0){ memcpy( (char *)lowest,(char *)newname, 20 * sizeof(oid)); LowState = State; Lowinpcb = inpcb; break; /* no need to search further */ } } else { if (snmp_oid_compare(newname, 20, name, *length) > 0 && snmp_oid_compare(newname, 20, lowest, 20) < 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, 20 * sizeof(oid)); LowState = State; Lowinpcb = inpcb; } } } if (LowState < 0) return(NULL); memcpy( (char *)name,(char *)lowest, (vp->namelen + 10) * sizeof(oid)); *length = vp->namelen + 10; *write_method = 0; *var_len = sizeof(long); switch (vp->magic) { case TCPCONNSTATE: {#ifndef hpux static int StateMap[]={1, 2, 3, 4, 5, 8, 6, 10, 9, 7, 11};#else static int StateMap[]={1, 2, 3, -1, 4, 5, 8, 6, 10, 9, 7, 11};#endif return (u_char *) &StateMap[LowState]; } case TCPCONNLOCALADDRESS: return (u_char *) &Lowinpcb.inp_laddr.s_addr; case TCPCONNLOCALPORT: long_return = ntohs(Lowinpcb.inp_lport); return (u_char *) &long_return; case TCPCONNREMADDRESS: return (u_char *) &Lowinpcb.inp_faddr.s_addr; case TCPCONNREMPORT: long_return = ntohs(Lowinpcb.inp_fport); return (u_char *) &long_return; } return NULL;}#else /* solaris2 - tcp */static intTCP_Cmp(void *addr, void *ep){ if (memcmp((mib2_tcpConnEntry_t *)ep,(mib2_tcpConnEntry_t *)addr, sizeof(mib2_tcpConnEntry_t)) == 0) return (0); else return (1);}u_char *var_tcp(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ mib2_tcp_t tcpstat; mib2_ip_t ipstat; if (header_tcp(vp, name, length, exact, var_len, write_method) == MATCH_FAILED ) return NULL; /* * Get the TCP statistics from the kernel... */ if (getMibstat(MIB_TCP, &tcpstat, sizeof(mib2_tcp_t), GET_FIRST, &Get_everything, NULL) < 0) return (NULL); /* Things are ugly ... */ switch (vp->magic){ case TCPRTOALGORITHM: long_return = tcpstat.tcpRtoAlgorithm; return(u_char *) &long_return; case TCPRTOMIN: long_return = tcpstat.tcpRtoMin; return(u_char *) &long_return; case TCPRTOMAX: long_return = tcpstat.tcpRtoMax; return(u_char *) &long_return; case TCPMAXCONN: long_return = tcpstat.tcpMaxConn; return(u_char *) &long_return; case TCPACTIVEOPENS: long_return = tcpstat.tcpActiveOpens; return(u_char *) &long_return; case TCPPASSIVEOPENS: long_return = tcpstat.tcpPassiveOpens; return(u_char *) &long_return; case TCPATTEMPTFAILS: long_return = tcpstat.tcpAttemptFails; return(u_char *) &long_return; case TCPESTABRESETS: long_return = tcpstat.tcpEstabResets; return(u_char *) &long_return; case TCPCURRESTAB: long_return = tcpstat.tcpCurrEstab; return(u_char *) &long_return; case TCPINSEGS: long_return = tcpstat.tcpInSegs; return(u_char *) &long_return; case TCPOUTSEGS: long_return = tcpstat.tcpOutSegs; return(u_char *) &long_return; case TCPRETRANSSEGS: long_return = tcpstat.tcpRetransSegs; return(u_char *) &long_return; case TCPINERRS: if (getMibstat(MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST, &Get_everything, NULL) < 0) return (NULL); /* Things are ugly ... */ long_return = ipstat.tcpInErrs; return(u_char *) &long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_tcp\n", vp->magic)); return (NULL); }}u_char *var_tcpEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ oid newname[MAX_OID_LEN], lowest[MAX_OID_LEN], *op; u_char *cp;#define TCP_CONN_LENGTH 20#define TCP_LOCADDR_OFF 10#define TCP_LOCPORT_OFF 14#define TCP_REMADDR_OFF 15#define TCP_REMPORT_OFF 19 mib2_tcpConnEntry_t Lowentry, Nextentry, entry; req_e req_type; int Found = 0; memset (&Lowentry, 0, sizeof (Lowentry)); memcpy( (char *)newname,(char *)vp->name, vp->namelen * sizeof(oid)); if (*length == TCP_CONN_LENGTH) /* Assume that the input name is the lowest */ memcpy( (char *)lowest,(char *)name, TCP_CONN_LENGTH * sizeof(oid)); for (Nextentry.tcpConnLocalAddress = (u_long)-1, req_type = GET_FIRST; ; Nextentry = entry, req_type = GET_NEXT) { if (getMibstat(MIB_TCP_CONN, &entry, sizeof(mib2_tcpConnEntry_t), req_type, &TCP_Cmp, &entry) != 0) break; COPY_IPADDR(cp, (u_char *)&entry.tcpConnLocalAddress, op, newname + TCP_LOCADDR_OFF); newname[TCP_LOCPORT_OFF] = entry.tcpConnLocalPort; COPY_IPADDR(cp, (u_char *)&entry.tcpConnRemAddress, op, newname + TCP_REMADDR_OFF); newname[TCP_REMPORT_OFF] = entry.tcpConnRemPort; if (exact){ if (snmp_oid_compare(newname, TCP_CONN_LENGTH, name, *length) == 0){ memcpy( (char *)lowest,(char *)newname, TCP_CONN_LENGTH * sizeof(oid)); Lowentry = entry; Found++; break; /* no need to search further */ } } else { if ((snmp_oid_compare(newname, TCP_CONN_LENGTH, name, *length) > 0) && ((Nextentry.tcpConnLocalAddress == (u_long)-1) || (snmp_oid_compare(newname, TCP_CONN_LENGTH, lowest, TCP_CONN_LENGTH) < 0) || (snmp_oid_compare(name, *length, lowest, TCP_CONN_LENGTH) == 0))){ /* if new one is greater than input and closer to input than * previous lowest, and is not equal to it, save this one as the "next" one. */ memcpy( (char *)lowest,(char *)newname, TCP_CONN_LENGTH * sizeof(oid)); Lowentry = entry; Found++; } } } if (Found == 0) return(NULL); memcpy((char *)name, (char *)lowest, (vp->namelen + TCP_CONN_LENGTH - TCP_LOCADDR_OFF) * sizeof(oid)); *length = vp->namelen + TCP_CONN_LENGTH - TCP_LOCADDR_OFF; *write_method = 0; *var_len = sizeof(long); switch (vp->magic) { case TCPCONNSTATE: long_return = Lowentry.tcpConnState; return(u_char *) &long_return; case TCPCONNLOCALADDRESS: long_return = Lowentry.tcpConnLocalAddress; return(u_char *) &long_return; case TCPCONNLOCALPORT: long_return = Lowentry.tcpConnLocalPort; return(u_char *) &long_return; case TCPCONNREMADDRESS: long_return = Lowentry.tcpConnRemAddress; return(u_char *) &long_return; case TCPCONNREMPORT: long_return = Lowentry.tcpConnRemPort; return(u_char *) &long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_tcpEntry\n", vp->magic)); return (NULL); }}#endif /* solaris2 - tcp */ /********************* * * Internal implementation functions * *********************/#ifdef linux/* * lucky days. since 1.1.16 the tcp statistics are avail by the proc * file-system. */static voidlinux_read_tcp_stat (struct tcp_mib *tcpstat){ FILE *in = fopen ("/proc/net/snmp", "r"); char line [1024]; memset ((char *) tcpstat, (0), sizeof (*tcpstat)); if (! in) return; while (line == fgets (line, sizeof(line), in)) { if (12 == sscanf (line, "Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", &tcpstat->TcpRtoAlgorithm, &tcpstat->TcpRtoMin, &tcpstat->TcpRtoMax, &tcpstat->TcpMaxConn, &tcpstat->TcpActiveOpens, &tcpstat->TcpPassiveOpens, &tcpstat->TcpAttemptFails, &tcpstat->TcpEstabResets, &tcpstat->TcpCurrEstab, &tcpstat->TcpInSegs, &tcpstat->TcpOutSegs, &tcpstat->TcpRetransSegs)) break; } fclose (in);}#endif /* linux */#ifndef solaris2#ifndef linux/* * Print INTERNET connections */int TCP_Count_Connections (void){ int Established; struct inpcb cb; register struct inpcb *next;#if !(defined(freebsd2) || defined(netbsd2) || defined(openbsd2)) register struct inpcb *prev;#endif struct inpcb inpcb; struct tcpcb tcpcb;Again: /* * Prepare to scan the control blocks */ Established = 0; auto_nlist(TCP_SYMBOL, (char *)&cb, sizeof(struct inpcb)); inpcb = cb;#if !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) prev = (struct inpcb *) auto_nlist_value(TCP_SYMBOL);#endif /* !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) */ /* * Scan the control blocks */#if defined(freebsd2) || defined(netbsd1) || defined(openbsd2) while ((inpcb.INP_NEXT_SYMBOL != NULL) && (inpcb.INP_NEXT_SYMBOL != (struct inpcb *) auto_nlist_value(TCP_SYMBOL))) {#else /* defined(freebsd2) || defined(netbsd1) || defined(openbsd2) */ while (inpcb.INP_NEXT_SYMBOL != (struct inpcb *) auto_nlist_value(TCP_SYMBOL)) {#endif /* defined(freebsd2) || defined(netbsd1) */ next = inpcb.INP_NEXT_SYMBOL; if((klookup((unsigned long)next, (char *)&inpcb, sizeof (inpcb)) == 0)) { snmp_log_perror("TCP_Count_Connections - inpcb"); break; }#if !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) if (inpcb.INP_PREV_SYMBOL != prev) { /* ??? */ sleep(1); goto Again; }#endif /* !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) */ if (inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) {#if !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) prev = next;#endif /* !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) */ continue; } if(klookup((unsigned long)inpcb.inp_ppcb, (char *)&tcpcb, sizeof (tcpcb)) == 0) { snmp_log_perror("TCP_Count_Connections - tcpcb"); break; } if ((tcpcb.t_state == TCPS_ESTABLISHED) || (tcpcb.t_state == TCPS_CLOSE_WAIT)) Established++;#if !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) prev = next;#endif /* !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) */ } return(Established);}#endifstatic struct inpcb tcp_inpcb, *tcp_prev;#ifdef PCB_TABLEstatic struct inpcb *tcp_next, *tcp_head;#endif#ifdef linuxstatic struct inpcb *inpcb_list;#endif#if defined(CAN_USE_SYSCTL) && defined(TCPCTL_PCBLIST)static char *tcpcb_buf = NULL;static struct xinpgen *xig = NULL;#endif /* !defined(CAN_USE_SYSCTL) || !define(TCPCTL_PCBLIST) */void TCP_Scan_Init (void){#if !defined(CAN_USE_SYSCTL) || !defined(TCPCTL_PCBLIST)#ifdef PCB_TABLE struct inpcbtable table;#endif#ifndef linux#ifdef PCB_TABLE auto_nlist(TCP_SYMBOL, (char *)&table, sizeof(table)); tcp_head = tcp_prev = (struct inpcb *)&((struct inpcbtable *)auto_nlist_value(TCP_SYMBOL))->inpt_queue.cqh_first; tcp_next = table.inpt_queue.cqh_first;#else /* PCB_TABLE */ auto_nlist(TCP_SYMBOL, (char *)&tcp_inpcb, sizeof(tcp_inpcb));#if !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2)) tcp_prev = (struct inpcb *) auto_nlist_value(TCP_SYMBOL);#endif#endif /* PCB_TABLE */#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) { tcp_prev = inpcb_list; return; } Time_Of_Last_Reload = now.tv_sec; if (! (in = fopen ("/proc/net/tcp", "r"))) { snmp_log(LOG_ERR, "snmpd: cannot open /proc/net/tcp ...\n"); tcp_prev = NULL; return; } /* free old chain: */ while (inpcb_list) { struct inpcb *p = inpcb_list; inpcb_list = inpcb_list->INP_NEXT_SYMBOL; free (p); } /* scan proc-file and append: */ pp = &inpcb_list; while (line == fgets (line, sizeof(line), in)) { struct inpcb pcb, *nnew; static int linux_states [12] = { 0, 4, 2, 3, 6, 9, 10, 0, 5, 8, 1, 7 }; int state, lp, fp, uid; if (6 != sscanf (line, "%*d: %x:%x %x:%x %x %*X:%*X %*X:%*X %*X %d", &pcb.inp_laddr.s_addr, &lp, &pcb.inp_faddr.s_addr, &fp, &state, &uid)) continue; pcb.inp_lport = htons ((unsigned short) lp); pcb.inp_fport = htons ((unsigned short) fp); pcb.inp_state = (state & 0xf) < 12 ? linux_states [state & 0xf] : 1; pcb.uid = uid; nnew = (struct inpcb *) malloc (sizeof (struct inpcb)); if (nnew == NULL) break; *nnew = pcb; nnew->INP_NEXT_SYMBOL = 0; *pp = nnew; pp = & nnew->INP_NEXT_SYMBOL; } fclose (in); /* first entry to go: */ tcp_prev = inpcb_list;#endif /* linux */#else /* !defined(CAN_USE_SYSCTL) || !defined(TCPCTL_PCBLIST) */ { size_t len; int sname[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_PCBLIST }; if (tcpcb_buf) { free(tcpcb_buf); tcpcb_buf = NULL; } xig = NULL; len = 0; if (sysctl(sname, 4, 0, &len, 0, 0) < 0) { return; } if ((tcpcb_buf = malloc(len)) == NULL) { return; } if (sysctl(sname, 4, tcpcb_buf, &len, 0, 0) < 0) { free(tcpcb_buf); tcpcb_buf = NULL; return; } xig = (struct xinpgen *)tcpcb_buf; xig = (struct xinpgen *)((char *)xig + xig->xig_len); return; }#endif /* !defined(CAN_USE_SYSCTL) || !defined(TCPCTL_PCBLIST) */}int TCP_Scan_Next(int *State, struct inpcb *RetInPcb){#if !defined(CAN_USE_SYSCTL) || !defined(TCPCTL_PCBLIST) register struct inpcb *next;#ifndef linux struct tcpcb tcpcb;#ifdef PCB_TABLE if (tcp_next == tcp_head) {#elif defined(freebsd2) || defined(netbsd1) || defined(openbsd2) if (tcp_inpcb.INP_NEXT_SYMBOL == NULL || tcp_inpcb.INP_NEXT_SYMBOL == (struct inpcb *) auto_nlist_value(TCP_SYMBOL)) {#else if (tcp_inpcb.INP_NEXT_SYMBOL == (struct inpcb *) auto_nlist_value(TCP_SYMBOL)) {#endif return(0); /* "EOF" */ }#ifdef PCB_TABLE klookup((unsigned long)tcp_next, (char *)&tcp_inpcb, sizeof(tcp_inpcb)); tcp_next = tcp_inpcb.inp_queue.cqe_next;#else next = tcp_inpcb.INP_NEXT_SYMBOL; klookup((unsigned long)next, (char *)&tcp_inpcb, sizeof (tcp_inpcb));#if !(defined(netbsd1) || defined(freebsd2)) || defined(openbsd2) if (tcp_inpcb.INP_PREV_SYMBOL != tcp_prev) /* ??? */ return(-1); /* "FAILURE" */#endif /* !(defined(netbsd1) || defined(freebsd2) || defined(openbsd2)) */#endif /* PCB_TABLE */ klookup ( (int)tcp_inpcb.inp_ppcb, (char *)&tcpcb, sizeof (tcpcb)); *State = tcpcb.t_state;#else /* linux */ if (! tcp_prev) return 0; tcp_inpcb = *tcp_prev; *State = tcp_inpcb.inp_state; next = tcp_inpcb.INP_NEXT_SYMBOL;#endif *RetInPcb = tcp_inpcb;#if !(defined(netbsd1) || defined(freebsd2) || defined(openbsd2)) tcp_prev = next;#endif#else /* !defined(CAN_USE_SYSCTL) || !defined(TCPCTL_PCBLIST) */ /* Are we done? */ if ((xig == NULL) || (xig->xig_len <= sizeof(struct xinpgen))) return(0); *State = ((struct xtcpcb *)xig)->xt_tp.t_state; *RetInPcb = ((struct xtcpcb *)xig)->xt_inp; /* Prepare for Next read */ xig = (struct xinpgen *)((char *)xig + xig->xig_len);#endif /* !defined(CAN_USE_SYSCTL) || !defined(TCPCTL_PCBLIST) */ return(1); /* "OK" */}#endif /* solaris2 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -