📄 tcp.c
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/unxagent/sun/tcp.c,v 1.2 2001/11/09 21:49:04 josh Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** * Copyright 1988-1997 Epilogue Technology Corporation. * Copyright 1998 Integrated Systems, Inc. * All rights reserved. ****************************************************************************//* * $Log: tcp.c,v $ * Revision 1.2 2001/11/09 21:49:04 josh * unxagent demo path adjustment, first pass * * Revision 1.1.1.1 2001/11/05 17:49:17 tneale * Tornado shuffle * * Revision 7.6 2001/01/19 22:25:04 paul * Update copyright. * * Revision 7.5 2000/03/17 00:15:35 meister * Update copyright message * * Revision 7.4 1998/02/25 04:58:25 sra * Update copyrights. * * Revision 7.3 1997/03/20 06:54:16 sra * DFARS-safe copyright text. Zap! * * Revision 7.2 1997/02/25 10:58:16 sra * Update copyright notice, dust under the bed. * * Revision 7.1 1997/01/08 23:01:49 sar * Updated copyright and modified include files to use envoy/h as * appropriate * * Revision 7.0 1996/03/15 22:07:57 sar * Updated revision to 7.0 and copyright to 96 * * Revision 6.0 1995/05/31 21:49:51 sra * Release 6.0. * * Revision 5.3 1995/05/09 17:47:51 sar * Modified the next routine to use OIDC_T's internally and to get rid of * the use of -1 as a tag value allowing us to use the entire 4g range. * * Revision 5.2 1995/04/28 22:24:48 sar * Dropped the static/dymanic flag from the nextproc_no_instance call * * Revision 5.1 1995/03/21 19:36:16 sar * Updated method routines to use new api & scheme * * Revision 5.0 1994/05/16 16:20:43 sar * Updated revision to 5.0 and copyright to include 1994 * * Revision 4.0 1993/06/24 17:34:02 sar * Updated rev to 4.0 copyright to 93 * * Revision 3.2 1993/05/13 22:22:28 sar * Added some defines, includes (<sysent.h> <errno.h> <libc.h>), casts * (struct sockaddr *) and changed memfoo to MEMFOO and objidcmp to * llist_cmp to get rid of warnings from the compiler. * * Revision 3.1 1992/09/01 11:38:36 dab * Fixed up for Mach386 * * Revision 3.0 92/04/03 19:53:44 dab * Release 3.0 * * Revision 2.101 92/02/04 10:47:32 dab * Updated for release 3.0 of SNMP. * * Revision 2.100 92/02/03 16:46:19 dab * Generic unix SNMP agent. * * * Rev 2.0 31 Mar 1990 15:34:26 * Initial revision. * *//* [clearcase]modification history-------------------01a,19apr05,job update copyright notices*/#include <stdio.h>#include <wrn/wm/snmp/engine/asn1.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/auxfuncs.h>#include <sys/param.h>#include <sys/types.h>#include <sys/protosw.h>#include <sys/socket.h>#include <net/route.h>#include <netinet/in.h>#include <net/if.h>#include <netinet/if_ether.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/in_pcb.h>#include <netinet/ip_var.h>#include <netinet/tcp.h>#include <netinet/tcp_timer.h>#include <netinet/tcp_var.h>#include <netinet/tcp_fsm.h>#include "snmpvars.h"#include "general.h"#define LM_tcpRtoAlgorithm 1#define LM_tcpRtoMin 2#define LM_tcpRtoMax 3#define LM_tcpMaxConn 4#define LM_tcpActiveOpens 5#define LM_tcpPassiveOpens 6#define LM_tcpAttemptFails 7#define LM_tcpEstabResets 8#define LM_tcpCurrEstab 9#define LM_tcpInSegs 10#define LM_tcpOutSegs 11#define LM_tcpRetransSegs 12#define LM_tcpInErrs 14#define LM_tcpOutRsts 15#define LM_tcpConnState 1#define LM_tcpConnLocalAddress 2#define LM_tcpConnLocalPort 3#define LM_tcpConnRemAddress 4#define LM_tcpConnRemPort 5#define CACHE_LIFETIME 4#define CSECS_PER_PR_SLOWHZ (100 / PR_SLOWHZ)#define INSTANCE_LEN 10#define LOCAL_ADDR 0#define LOCAL_PORT 4#define REMOTE_ADDR 5#define REMOTE_PORT 9static struct kernel_symbol tcpstat = { "_tcpstat", 0, 0 };static struct tcpstat tcps;static struct kernel_symbol tcp_cons = { "_tcb", 0, 0 };static struct inpcb *tcb = 0;static time_t tcp_cache_time = 0;static int read_tcp_ct(void);static int read_tcp_ct(){time_t now;/* Get the connection table ... */if ((tcb == 0) || ((time(&now) - tcp_cache_time) > CACHE_LIFETIME)) { tcp_cache_time = now; if (find_loc(&tcp_cons) == 0) return -1; (void) read_ct(&tcb, tcp_cons.offset); }return 0;}/****************************************************************************NAME: tcpinfo_getPURPOSE: Find the appropriate entry in the tcp struct and attach information from it to the vbp using the getproc_got_* functions. If we can't find an entry indicate that by calling getproc_nosuchins.PARAMETERS: OIDC_T Last component of the object id leading to the leaf node in the MIB. This is usually the identifier for the particular attribute in the table. int Number of components in the unused part of the object identifier OIDC_T * Unused part of the object identifier SNMP_PKT_T * SNMP packet currently being processed. VB_T * Variable being processed.RETURNS: void****************************************************************************//*ARGSUSED*/void tcpinfo_get(OIDC_T last_match, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp){/* Test the instance information to see if it is well formed, there must be exactly 1 unused component and its value must be 0 */if ((tcount != 1) || (tlist[0] != 0)) { getproc_nosuchins(pktp, vbp); return; }/* see if we can find the tcpstat structure */if (find_loc(&tcpstat) == 0) { getproc_error(pktp, vbp, GEN_ERR); return; }read_bytes((off_t)tcpstat.offset, (char *)&tcps, sizeof(struct tcpstat));switch (last_match) { case LM_tcpRtoAlgorithm: getproc_got_int32(pktp, vbp, 4); break; case LM_tcpRtoMin: getproc_got_int32(pktp, vbp, (INT_32_T)(TCPTV_SRTTDFLT * CSECS_PER_PR_SLOWHZ)); break; case LM_tcpRtoMax: getproc_got_int32(pktp, vbp, (INT_32_T)(TCPTV_MSL * CSECS_PER_PR_SLOWHZ)); break; case LM_tcpMaxConn: getproc_got_int32(pktp, vbp, -1); break; case LM_tcpActiveOpens: getproc_got_uint32(pktp, vbp, (UINT_32_T)tcps.tcps_connects, VT_COUNTER); break; case LM_tcpPassiveOpens: getproc_got_uint32(pktp, vbp, (UINT_32_T)tcps.tcps_accepts, VT_COUNTER); break; case LM_tcpAttemptFails: getproc_got_uint32(pktp, vbp, (UINT_32_T)tcps.tcps_conndrops, VT_COUNTER); break; case LM_tcpEstabResets: getproc_got_uint32(pktp, vbp, (UINT_32_T)tcps.tcps_drops, VT_COUNTER); break; case LM_tcpInSegs: getproc_got_uint32(pktp, vbp, (UINT_32_T)tcps.tcps_rcvtotal, VT_COUNTER); break; case LM_tcpOutSegs: getproc_got_uint32(pktp, vbp, (UINT_32_T)tcps.tcps_sndtotal, VT_COUNTER); break; case LM_tcpRetransSegs: getproc_got_uint32(pktp, vbp, (UINT_32_T)tcps.tcps_sndrexmitpack, VT_COUNTER); break; case LM_tcpInErrs: getproc_got_uint32(pktp, vbp, (UINT_32_T)(tcps.tcps_rcvbadsum + tcps.tcps_rcvbadoff + tcps.tcps_rcvshort), VT_COUNTER); break; case LM_tcpOutRsts: getproc_got_uint32(pktp, vbp, 0, VT_COUNTER); break; }return;}/****************************************************************************NAME: get_tcpCurrEstabPURPOSE: count the nubmer of tcp connections currently established and attache the information to the vbp using the getproc_got_* functions.PARAMETERS: OIDC_T Last component of the object id leading to the leaf node in the MIB. This is usually the identifier for the particular attribute in the table. int Number of components in the unused part of the object identifier OIDC_T * Unused part of the object identifier SNMP_PKT_T * SNMP packet currently being processed. VB_T * Variable being processed.RETURNS: void****************************************************************************//*ARGSUSED*/void get_tcpCurrEstab(OIDC_T last_match, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp){struct tcpcb tcpcb;struct inpcb * pcb;UINT_32_T estab_cnt = 0;/* Test the instance information to see if it is well formed, there must be exactly 1 unused component and its value must be 0 */if ((tcount != 1) || (tlist[0] != 0)) { getproc_nosuchins(pktp, vbp); return; }/* see if we can get the tcp table */if (read_tcp_ct() == -1) { getproc_error(pktp, vbp, GEN_ERR); return; }for (pcb = tcb; pcb; pcb = pcb->inp_next) { read_bytes((off_t)(pcb->inp_ppcb), (char *)&tcpcb, sizeof(tcpcb)); if ((tcpcb.t_state == (short)TCPS_ESTABLISHED) || (tcpcb.t_state == (short)TCPS_CLOSE_WAIT)) estab_cnt++; }getproc_got_uint32(pktp, vbp, estab_cnt, VT_GAUGE);return;}/* Define a table to map from the TCP states as defined in *//* /usr/include/netinet/tcp_fsm.h to those in the TCP/IP MIB. */typedef struct tcpstatemap_s { short tcp_state; short mib_state; } tcpstatemap_t;static tcpstatemap_t tstate_map[TCP_NSTATES] = { {TCPS_CLOSED, 1}, {TCPS_LISTEN, 2}, {TCPS_SYN_SENT, 3}, {TCPS_SYN_RECEIVED, 4}, {TCPS_ESTABLISHED, 5}, {TCPS_CLOSE_WAIT, 8}, {TCPS_FIN_WAIT_1, 6}, {TCPS_CLOSING, 8}, {TCPS_LAST_ACK, 9}, {TCPS_FIN_WAIT_2, 7}, {TCPS_TIME_WAIT, 11}};void get_tcpconn_info(OIDC_T last_match, SNMP_PKT_T *pktp, VB_T *vbp, struct inpcb *pcb){struct tcpcb tcpcb;tcpstatemap_t * tmapp;int i;switch(last_match) { case LM_tcpConnState: read_bytes((off_t)(pcb->inp_ppcb), (char *)&tcpcb, sizeof(tcpcb)); /* Map the internal state numbers to the mib state numbers */ for (i = 0, tmapp = tstate_map; i < TCP_NSTATES; i++, tmapp++) if (tmapp->tcp_state == tcpcb.t_state) { getproc_got_int32(pktp, vbp, tmapp->mib_state); return; } getproc_error(pktp, vbp, GEN_ERR); return; case LM_tcpConnLocalAddress: getproc_got_ip_address(pktp, vbp, pcb->inp_laddr.s_addr); break; case LM_tcpConnLocalPort: getproc_got_int32(pktp, vbp, pcb->inp_lport); break; case LM_tcpConnRemAddress: getproc_got_ip_address(pktp, vbp, pcb->inp_faddr.s_addr); break; case LM_tcpConnRemPort: getproc_got_int32(pktp, vbp, pcb->inp_fport); break; }return;}/****************************************************************************NAME: tcptable_getPURPOSE: Find the appropriate entry in the tcp conn table and attach information from it to the vbp using the getproc_got_* functions. If we can't find an entry indicate that by calling getproc_nosuchins.PARAMETERS: OIDC_T Last component of the object id leading to the leaf node in the MIB. This is usually the identifier for the particular attribute in the table. int Number of components in the unused part of the object identifier OIDC_T * Unused part of the object identifier SNMP_PKT_T * SNMP packet currently being processed. VB_T * Variable being processed.RETURNS: void****************************************************************************//*ARGSUSED*/void tcptable_get(OIDC_T last_match, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp){struct in_addr localip, remoteip;unsigned int localport, remoteport;struct inpcb * pcb;/* Test the instance information to see if it is well formed, there must be exactly 10 unused components which must represent a local ip addr, a local port, a remote addr and a remote port */if ((tcount != INSTANCE_LEN) || oid_to_ip(4, tlist + LOCAL_ADDR, &localip.s_addr) || oid_to_ip(4, tlist + REMOTE_ADDR, &remoteip.s_addr)) { getproc_nosuchins(pktp, vbp); return; }localport = (unsigned int)tlist[LOCAL_PORT];remoteport = (unsigned int)tlist[REMOTE_PORT];if (read_tcp_ct() == -1) { getproc_error(pktp, vbp, GEN_ERR); return; }for (pcb = tcb; pcb; pcb = pcb->inp_next) { if ((localport == pcb->inp_lport) && (localip.s_addr == pcb->inp_laddr.s_addr) && (remoteport == pcb->inp_fport) && (remoteip.s_addr == pcb->inp_faddr.s_addr)) { get_tcpconn_info(last_match, pktp, vbp, pcb); return; } }getproc_nosuchins(pktp, vbp);return;}/****************************************************************************NAME: tcptable_nextPURPOSE: Locate the "next" object in the TCP tablePARAMETERS: OIDC_T Last component of the object id leading to the leaf node in the MIB. This is usually the identifier for the particular attribute in the table. int Number of components in the unused part of the object identifier OIDC_T * Unused part of the object identifier SNMP_PKT_T * SNMP packet currently being processed. VB_T * Variable being processed.RETURNS: void****************************************************************************//*ARGSUSED*/void tcptable_next(OIDC_T last_match, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp){struct inpcb *pcb, *best = 0;OIDC_T bra[INSTANCE_LEN], pra[INSTANCE_LEN];int i; if (read_tcp_ct() == -1) { nextproc_error(pktp, vbp, GEN_ERR); return; } /* Now find the lowest value larger than localip and localport. */for (pcb = tcb; pcb; pcb = pcb->inp_next) { ip_to_rlist(pcb->inp_laddr.s_addr, pra + LOCAL_ADDR); pra[LOCAL_PORT] = pcb->inp_lport; ip_to_rlist(pcb->inp_faddr.s_addr, pra + REMOTE_ADDR); pra[REMOTE_PORT] = pcb->inp_fport; if (oidcmp2(INSTANCE_LEN, pra, tcount, tlist) <= 0) continue; if (!best || (oidorder(pra, bra, INSTANCE_LEN) < 0)) { best = pcb; for (i = 0; i < INSTANCE_LEN; i++) bra[i] = pra[i]; } } if (best) { /* get the value information */ get_tcpconn_info(last_match, pktp, vbp, best); /* and setup the instance information */ nextproc_next_instance(pktp, vbp, INSTANCE_LEN, bra); }else nextproc_no_next(pktp, vbp);return;}inttcp_init(){if (find_loc(&tcp_cons) == 0) return -1;if (find_loc(&tcpstat) == 0) return -1;return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -