/* tcp_mth.c - method routines for the tcp group */ /* * Copyright 2006-2008 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. */ /* modification history -------------------- 01g,26may08,y_z use ipnet-mib2 interface 01f,10aug07,nlu set IP_STACK to ipnet 01e,02may07,mdk merge from spr-dev for spin45A 01d,20sep06,jbl fix padded instance bug 01c,19sep06,jbl clear up build warnings and errors 01b,11sep06,jbl IPv6 switchability 01a,07sep06,jbl fix htonl() references */ #include "ip_mth.h" #include "ip_mibhand.h" #include "ip_mibleaf.h" #include #include #include #include #include #include #include #include #include /* * Method routines for the tcpConnectionTable: * * tcpConnectionLocalAddressType -- not-accessible * The address type of tcpConnectionLocalAddress. * * tcpConnectionLocalAddress -- not-accessible * The local IP address for this TCP connection. The type * of this address is determined by the value of * tcpConnectionLocalAddressType. * * As this object is used in the index for the * tcpConnectionTable, implementors should be * careful not to create entries that would result in OIDs * with more than 128 subidentifiers; otherwise the information * cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3. * * tcpConnectionLocalPort -- not-accessible * The local port number for this TCP connection. * * tcpConnectionRemAddressType -- not-accessible * The address type of tcpConnectionRemAddress. * * tcpConnectionRemAddress -- not-accessible * The remote IP address for this TCP connection. The type * of this address is determined by the value of * tcpConnectionRemAddressType. * * As this object is used in the index for the * tcpConnectionTable, implementors should be * careful not to create entries that would result in OIDs * with more than 128 subidentifiers; otherwise the information * cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3. * * tcpConnectionRemPort -- not-accessible * The remote port number for this TCP connection. * * tcpConnectionState -- read-write * The state of this TCP connection. * * The value listen(2) is included only for parallelism to the * old tcpConnTable and should not be used. A connection in * LISTEN state should be present in the tcpListenerTable. * * The only value that may be set by a management station is * deleteTCB(12). Accordingly, it is appropriate for an agent * to return a `badValue' response if a management station * attempts to set this object to any other value. * * If a management station sets this object to the value * deleteTCB(12), then the TCB (as defined in [RFC793]) of * the corresponding connection on the managed node is * deleted, resulting in immediate termination of the * connection. * * As an implementation-specific option, a RST segment may be * sent from the managed node to the other TCP endpoint (note, * however, that RST segments are not sent reliably). * * tcpConnectionProcess -- read-only * The system's process ID for the process associated with * this connection, or zero if there is no such process. This * value is expected to be the same as HOST-RESOURCES-MIB:: * hrSWRunIndex or SYSAPPL-MIB::sysApplElmtRunIndex for some * row in the appropriate tables. */ /* An internal routine to retrieve the values of the variables, used * by the method routines tcpConnectionEntry_get and tcpConnectionEntry_next. */ #define ipVersion_unknown 0 #define ipVersion_ipv4 1 #define ipVersion_ipv6 2 #define ipVersion_ipv4z 3 #define ipVersion_ipv6z 4 static void localFree (PTR_T memP) { VB_T * vbp = (VB_T *)memP; SNMP_memory_free (vbp->vb_priv); } typedef struct { int tcount; OIDC_T * tlist; Ipcom_mib2_TcpConnectionEntry * dataPtr; boolean_t getnext; /* FALSE = getexact */ } tcpConnectionEntry_cookie_t; typedef struct { int tcount; OIDC_T * tlist; Ipcom_mib2_TcpListenerEntry * dataPtr; boolean_t getnext; /* FALSE = getexact */ } tcpListenerEntry_cookie_t; typedef struct { Ipcom_mib2_tcp_group tcpGroup; } tcp_data_t; #define tcpConnectionEntry_INSTANCE_LEN 46 static unsigned tcpConnectionEntry_build_instance (Ipcom_mib2_TcpConnectionEntry * data, OIDC_T *instance) { int i ; int j ; i=0; j=0; instance [0] = data->tcpConnectionLocalAddressType; switch (instance [0]) { case ipVersion_unknown: instance [1] = 0; break; case ipVersion_ipv4: instance [j+1] = 4; break; case ipVersion_ipv4z: instance [j+1] = 8; break; case ipVersion_ipv6: instance [j+1] = 16; break; case ipVersion_ipv6z: instance [j+1] = 20; break; default: instance [j+1] = 0; break; } for (i = 0; i < instance [1]; i++) instance [2 + i] = data->tcpConnectionLocalAddress[i]; instance [instance [1] + 2] = data->tcpConnectionLocalPort; j = instance[1]+3; instance [j] = data->tcpConnectionRemAddressType; switch (instance [j]) { case ipVersion_unknown: instance [1] = 0; break; case ipVersion_ipv4: instance [j+1] = 4; break; case ipVersion_ipv4z: instance [j+1] = 8; break; case ipVersion_ipv6: instance [j+1] = 16; break; case ipVersion_ipv6z: instance [j+1] = 20; break; default: instance [j+1] = 0; break; } for (i = 0; i < instance [j+1]; i++) instance [j + 2 + i] = data->tcpConnectionRemAddress[i]; instance [j + instance [j+1] + 2] = data ->tcpConnectionRemPort; return (j + instance [j+1] + 3); } static int tcpConnectionEntry_callback (Ipcom_mib2_TcpConnectionEntry * entry, void *user) { tcpConnectionEntry_cookie_t * cookie = (tcpConnectionEntry_cookie_t *)user; boolean_t stopIterating = FALSE; boolean_t saveData = FALSE; OIDC_T instance [tcpConnectionEntry_INSTANCE_LEN]; unsigned instanceLen = 0; int cmpval = 0; instanceLen = tcpConnectionEntry_build_instance (entry, instance); cmpval = oidcmp2 (instanceLen, instance, cookie->tcount, cookie->tlist); if (cookie->getnext) { if (cmpval > 0) { if (cookie->dataPtr == NULL) saveData = TRUE; else { OIDC_T prevInstance [tcpConnectionEntry_INSTANCE_LEN]; unsigned prevInstanceLen = 0; prevInstanceLen = tcpConnectionEntry_build_instance (cookie->dataPtr, prevInstance); if (oidcmp2 (instanceLen, instance, prevInstanceLen, prevInstance) < 0) saveData = TRUE; } } } else /* Get exact */ { if (cmpval == 0) { saveData = TRUE; stopIterating = TRUE; } } if (saveData) { if (cookie->dataPtr == NULL) cookie->dataPtr = SNMP_memory_alloc (sizeof (Ipcom_mib2_TcpConnectionEntry)); if (cookie->dataPtr != NULL) memcpy (cookie->dataPtr, entry, sizeof (Ipcom_mib2_TcpConnectionEntry)); } /* Return values defined are part of callback API. */ return (stopIterating? 1: 0); } static Ipcom_mib2_TcpConnectionEntry* tcpConnectionEntry_lookup (int tcount, OIDC_T * tlist, boolean_t getnext) { tcpConnectionEntry_cookie_t cookie; /* Make sure the instance length is correct if we need an exact match. */ /* if (!getnext && (tcount != tcpConnectionEntry_INSTANCE_LEN)) return (NULL);*/ cookie.tcount = tcount; cookie.tlist = tlist; cookie.dataPtr = NULL; cookie.getnext = getnext; ipcom_mib2_iterate_tcpConnectionTable (tcpConnectionEntry_callback, (void *)&cookie); return (cookie.dataPtr); } static int tcpConnectionEntry_get_value ( OIDC_T lastmatch, SNMP_PKT_T *pktp, VB_T *vbp, Ipcom_mib2_TcpConnectionEntry * data ) { switch(lastmatch) { case LEAF_tcpConnectionState: getproc_got_int32(pktp, vbp,data->tcpConnectionState); break; case LEAF_tcpConnectionProcess: getproc_got_uint32(pktp, vbp, data->tcpConnectionProcess, VT_GAUGE); break; default: return GEN_ERR; } return NO_ERROR; } /* This is substantially larger than the instance will get... */ void tcpConnectionEntry_get ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipcom_mib2_TcpConnectionEntry* data; int error; /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance (pktp, vbp, tcount, tlist); if ((data = tcpConnectionEntry_lookup (tcount, tlist, FALSE)) == NULL) { for ( ; vbp; vbp = vbp->vb_link) getproc_nosuchins (pktp, vbp); } else { /* retrieve all the values from the same data structure */ for ( ; vbp; vbp = vbp->vb_link) { if ((error = tcpConnectionEntry_get_value (vbp->vb_ml.ml_last_match, pktp, vbp, data)) != NO_ERROR) getproc_error (pktp, vbp, error); } SNMP_memory_free (data); } } void tcpConnectionEntry_next ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipcom_mib2_TcpConnectionEntry* data; OIDC_T best_inst [tcpConnectionEntry_INSTANCE_LEN]; int error; unsigned best_inst_len; /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance (pktp, vbp, tcount, tlist); if ((data = tcpConnectionEntry_lookup (tcount, tlist, TRUE)) != NULL) { best_inst_len = tcpConnectionEntry_build_instance (data, best_inst); /* we found a next so get the values and set the instance for all * the varbinds for this row of this table. */ for ( ; vbp ; vbp = vbp->vb_link) { if ((error = tcpConnectionEntry_get_value (vbp->vb_ml.ml_last_match, pktp, vbp, data)) == NO_ERROR) nextproc_next_instance (pktp, vbp, best_inst_len, best_inst); else nextproc_error (pktp, vbp, error); } SNMP_memory_free (data); } else /* there's no more in this table */ { for ( ; vbp ; vbp = vbp->vb_link ) nextproc_no_next (pktp, vbp); } } void tcpConnectionEntry_test ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipcom_mib2_TcpConnectionEntry *data; VB_T *group_vbp; if ((data = tcpConnectionEntry_lookup (tcount, tlist, FALSE)) == NULL) { testproc_error (pktp, vbp, NO_SUCH_NAME); return; } /* stash the looked up information here for the setproc */ vbp->vb_priv = (PTR_T *)data; vbp->vb_free_priv = (VBPRIVPROC_T *)localFree; /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance (pktp, vbp, tcount, tlist); /* now check each varbind */ for (group_vbp = vbp; group_vbp; group_vbp = group_vbp->vb_link) { switch (group_vbp->vb_ml.ml_last_match) { case LEAF_tcpConnectionState: switch (VB_GET_INT32(group_vbp)) { case VAL_tcpConnectionState_deleteTCB: break; default: testproc_error(pktp, group_vbp, WRONG_VALUE); continue; } testproc_good(pktp, group_vbp); break; default: testproc_error(pktp, group_vbp, GEN_ERR); return; } } } void tcpConnectionEntry_set ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipcom_mib2_TcpConnectionEntry * data = vbp->vb_priv; for ( ; vbp; vbp = vbp->vb_link) { switch (vbp->vb_ml.ml_last_match) { case LEAF_tcpConnectionState: data->tcpConnectionState = VB_GET_INT32(vbp); setproc_good(pktp, vbp); break; default: setproc_error(pktp, vbp, COMMIT_FAILED); return; } } (void)ipcom_mib2_set_tcpConnectionState(data,data->tcpConnectionState); } /* * Method routines for the tcpListenerTable: * * tcpListenerLocalAddressType -- not-accessible * The address type of tcpListenerLocalAddress. The value * should be unknown (0) if connection initiations to all * local IP addresses are accepted. * * tcpListenerLocalAddress -- not-accessible * The local IP address for this TCP connection. * * The value of this object can be represented in three * possible ways, depending on the characteristics of the * listening application: * * 1. For an application willing to accept both IPv4 and * IPv6 datagrams, the value of this object must be * ''h (a zero-length octet-string), with the value * of the corresponding tcpListenerLocalAddressType * object being unknown (0). * * 2. For an application willing to accept only IPv4 or * IPv6 datagrams, the value of this object must be * '0.0.0.0' or '::' respectively, with * tcpListenerLocalAddressType representing the * appropriate address type. * * 3. For an application which is listening for data * destined only to a specific IP address, the value * of this object is the specific local address, with * tcpListenerLocalAddressType representing the * appropriate address type. * * As this object is used in the index for the * tcpListenerTable, implementors should be * careful not to create entries that would result in OIDs * with more than 128 subidentifiers; otherwise the information * cannot be accessed, using SNMPv1, SNMPv2c, or SNMPv3. * * tcpListenerLocalPort -- not-accessible * The local port number for this TCP connection. * * tcpListenerProcess -- read-only * The system's process ID for the process associated with * this listener, or zero if there is no such process. This * value is expected to be the same as HOST-RESOURCES-MIB:: * hrSWRunIndex or SYSAPPL-MIB::sysApplElmtRunIndex for some * row in the appropriate tables. */ /* An internal routine to retrieve the values of the variables, used * by the method routines tcpListenerEntry_get and tcpListenerEntry_next. */ #define tcpListenerEntry_INSTANCE_LEN 23 static unsigned tcpListenerEntry_build_instance (Ipcom_mib2_TcpListenerEntry * data, OIDC_T *instance) { int i ; i=0; instance [0] = data->tcpListenerLocalAddressType; switch (instance [0]) { case ipVersion_ipv4: instance [1] = 4; break; case ipVersion_ipv4z: instance [1] = 8; break; case ipVersion_ipv6: instance [1] = 16; break; case ipVersion_ipv6z: instance [1] = 20; break; default: instance [1] = 0; break; } for (i = 0; i < instance [1]; i++) instance [2 + i] = data->tcpListenerLocalAddress[i]; instance [instance [1] + 2] = data->tcpListenerLocalPort; return (instance[1] + 3); } static int tcpListenerEntry_callback (Ipcom_mib2_TcpListenerEntry * entry, void *user) { tcpListenerEntry_cookie_t * cookie = (tcpListenerEntry_cookie_t *)user; boolean_t stopIterating = FALSE; boolean_t saveData = FALSE; OIDC_T instance [tcpListenerEntry_INSTANCE_LEN]; unsigned instanceLen = 0; int cmpval = 0; instanceLen = tcpListenerEntry_build_instance (entry, instance); cmpval = oidcmp2 (instanceLen, instance, cookie->tcount, cookie->tlist); if (cookie->getnext) { if (cmpval > 0) { if (cookie->dataPtr == NULL) saveData = TRUE; else { OIDC_T prevInstance [tcpListenerEntry_INSTANCE_LEN]; unsigned prevInstanceLen = 0; prevInstanceLen = tcpListenerEntry_build_instance (cookie->dataPtr, prevInstance); if (oidcmp2 (instanceLen, instance, prevInstanceLen, prevInstance) < 0) saveData = TRUE; } } } else /* Get exact */ { if (cmpval == 0) { saveData = TRUE; stopIterating = TRUE; } } if (saveData) { if (cookie->dataPtr == NULL) cookie->dataPtr = SNMP_memory_alloc (sizeof (Ipcom_mib2_TcpListenerEntry)); if (cookie->dataPtr != NULL) memcpy (cookie->dataPtr, entry, sizeof (Ipcom_mib2_TcpListenerEntry)); } /* Return values defined are part of callback API. */ return (stopIterating? 1: 0); } static Ipcom_mib2_TcpListenerEntry* tcpListenerEntry_lookup (int tcount, OIDC_T * tlist, boolean_t getnext) { tcpListenerEntry_cookie_t cookie; /* Make sure the instance length is correct if we need an exact match. */ /*if (!getnext && (tcount != tcpListenerEntry_INSTANCE_LEN)) return (NULL);*/ cookie.tcount = tcount; cookie.tlist = tlist; cookie.dataPtr = NULL; cookie.getnext = getnext; ipcom_mib2_iterate_tcpListenerTable (tcpListenerEntry_callback, (void *)&cookie); return (cookie.dataPtr); } static int tcpListenerEntry_get_value ( OIDC_T lastmatch, SNMP_PKT_T *pktp, VB_T *vbp, Ipcom_mib2_TcpListenerEntry* data) { switch(lastmatch) { case LEAF_tcpListenerProcess: getproc_got_uint32(pktp, vbp, data->tcpListenerProcess, VT_GAUGE); break; default: return GEN_ERR; } return NO_ERROR; } void tcpListenerEntry_get ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipcom_mib2_TcpListenerEntry* data; int error; /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance (pktp, vbp, tcount, tlist); if ((data = tcpListenerEntry_lookup (tcount, tlist, FALSE)) == NULL) { for ( ; vbp; vbp = vbp->vb_link) getproc_nosuchins (pktp, vbp); } else { /* retrieve all the values from the same data structure */ for ( ; vbp; vbp = vbp->vb_link) { if ((error = tcpListenerEntry_get_value (vbp->vb_ml.ml_last_match, pktp, vbp, data)) != NO_ERROR) getproc_error (pktp, vbp, error); } SNMP_memory_free (data); } } void tcpListenerEntry_next ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { Ipcom_mib2_TcpListenerEntry* data; OIDC_T best_inst [tcpListenerEntry_INSTANCE_LEN]; int error; unsigned best_inst_len; /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance (pktp, vbp, tcount, tlist); if ((data = tcpListenerEntry_lookup (tcount, tlist, TRUE)) != NULL) { best_inst_len = tcpListenerEntry_build_instance (data, best_inst); /* we found a next so get the values and set the instance for all * the varbinds for this row of this table. */ for ( ; vbp ; vbp = vbp->vb_link) { if ((error = tcpListenerEntry_get_value (vbp->vb_ml.ml_last_match, pktp, vbp, data)) == NO_ERROR) nextproc_next_instance (pktp, vbp, best_inst_len, best_inst); else nextproc_error (pktp, vbp, error); } SNMP_memory_free (data); } else /* there's no more in this table */ { for ( ; vbp ; vbp = vbp->vb_link ) nextproc_no_next (pktp, vbp); } } /* * Method routines for the tcp variables: * * tcpRtoAlgorithm -- read-only * The algorithm used to determine the timeout value * used for retransmitting unacknowledged octets. * * tcpRtoMin -- read-only * The minimum value permitted by a TCP * implementation for the retransmission timeout, * measured in milliseconds. More refined semantics * for objects of this type depend upon the algorithm * used to determine the retransmission timeout. In * particular, when the timeout algorithm is rsre(3), * an object of this type has the semantics of the * LBOUND quantity described in RFC 793. * * tcpRtoMax -- read-only * The maximum value permitted by a TCP * implementation for the retransmission timeout, * measured in milliseconds. More refined semantics * for objects of this type depend upon the algorithm * used to determine the retransmission timeout. In * particular, when the timeout algorithm is rsre(3), * an object of this type has the semantics of the * UBOUND quantity described in RFC 793. * * tcpMaxConn -- read-only * The limit on the total number of TCP connections * the entity can support. In entities where the * maximum number of connections is dynamic, this * object should contain the value -1. * * tcpActiveOpens -- read-only * The number of times TCP connections have made a * direct transition to the SYN-SENT state from the * CLOSED state. * * tcpPassiveOpens -- read-only * The number of times TCP connections have made a * direct transition to the SYN-RCVD state from the * LISTEN state. * * tcpAttemptFails -- read-only * The number of times TCP connections have made a * direct transition to the CLOSED state from either * the SYN-SENT state or the SYN-RCVD state, plus the * number of times TCP connections have made a direct * transition to the LISTEN state from the SYN-RCVD * state. * * tcpEstabResets -- read-only * The number of times TCP connections have made a * direct transition to the CLOSED state from either * the ESTABLISHED state or the CLOSE-WAIT state. * * tcpCurrEstab -- read-only * The number of TCP connections for which the * current state is either ESTABLISHED or CLOSE- * WAIT. * * tcpInSegs -- read-only * The total number of segments received, including * those received in error. This count includes * segments received on currently established * connections. * * tcpOutSegs -- read-only * The total number of segments sent, including * those on current connections but excluding those * containing only retransmitted octets. * * tcpRetransSegs -- read-only * The total number of segments retransmitted - that * is, the number of TCP segments transmitted * containing one or more previously transmitted * octets. * * tcpInErrs -- read-only * The total number of segments received in error * (e.g., bad TCP checksums). * * tcpOutRsts -- read-only * The number of TCP segments sent containing the * RST flag. * * tcpHCInSegs -- read-only * The total number of segments received, including those * received in error. This count includes segments received * on currently established connections. This object is * the 64-bit equivalent of tcpInSegs. * * Discontinuities in the value of this counter are * indicated via discontinuities in the value of sysUpTime. * * tcpHCOutSegs -- read-only * The total number of segments sent, including those on * current connections but excluding those containing only * retransmitted octets. This object is the 64-bit * equivalent of tcpOutSegs. * * Discontinuities in the value of this counter are * indicated via discontinuities in the value of sysUpTime. */ /* An internal routine to retrieve the values of the variables, used * by the method routines tcp_get and tcp_next. * You need to replace the type STRUCT_tcp with something * appropriate to your system. */ static int tcp_get_value ( OIDC_T lastmatch, SNMP_PKT_T *pktp, VB_T *vbp, tcp_data_t *data ) { switch(lastmatch) { case LEAF_tcpRtoAlgorithm: /* Values: * other(1) = VAL_tcpRtoAlgorithm_other * constant(2) = VAL_tcpRtoAlgorithm_constant * rsre(3) = VAL_tcpRtoAlgorithm_rsre * vanj(4) = VAL_tcpRtoAlgorithm_vanj * rfc2988(5) = VAL_tcpRtoAlgorithm_rfc2988 */ getproc_got_int32(pktp, vbp, data->tcpGroup.tcpRtoAlgorithm); break; case LEAF_tcpRtoMin: getproc_got_int32(pktp, vbp, data->tcpGroup.tcpRtoMin); break; case LEAF_tcpRtoMax: getproc_got_int32(pktp, vbp, data->tcpGroup.tcpRtoMax); break; case LEAF_tcpMaxConn: getproc_got_int32(pktp, vbp, data->tcpGroup.tcpMaxConn); break; case LEAF_tcpActiveOpens: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpActiveOpens, VT_COUNTER); break; case LEAF_tcpPassiveOpens: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpPassiveOpens, VT_COUNTER); break; case LEAF_tcpAttemptFails: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpAttemptFails, VT_COUNTER); break; case LEAF_tcpEstabResets: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpEstabResets, VT_COUNTER); break; case LEAF_tcpCurrEstab: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpCurrEstab, VT_GAUGE); break; case LEAF_tcpInSegs: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpInSegs, VT_COUNTER); break; case LEAF_tcpOutSegs: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpOutSegs, VT_COUNTER); break; case LEAF_tcpRetransSegs: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpRetransSegs, VT_COUNTER); break; case LEAF_tcpInErrs: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpInErrs, VT_COUNTER); break; case LEAF_tcpOutRsts: getproc_got_uint32(pktp, vbp, data->tcpGroup.tcpOutRsts, VT_COUNTER); break; case LEAF_tcpHCInSegs: getproc_got_uint32(pktp, vbp, (UINT_32_T)data->tcpGroup.tcpHCInSegs, VT_COUNTER64); break; case LEAF_tcpHCOutSegs: getproc_got_uint32(pktp, vbp, (UINT_32_T)data->tcpGroup.tcpHCOutSegs, VT_COUNTER64); break; default: return GEN_ERR; } return NO_ERROR; } static int tcp_lookup(tcp_data_t * dataP) { int retVal = 0; retVal |= ipcom_mib2_get_tcp_group(&(dataP->tcpGroup)); return (retVal); } void tcp_get ( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ) { tcp_data_t data; int error; /* find all the varbinds that share the same getproc and instance */ group_by_getproc_and_instance (pktp, vbp, tcount, tlist); /* check that the instance is exactly .0 */ if (!((tcount == 1) && (*tlist == 0))) { for ( ; vbp; vbp = vbp->vb_link) getproc_nosuchins(pktp, vbp); } else if (tcp_lookup(&data) != 0) { for ( ; vbp; vbp = vbp->vb_link) getproc_error(pktp, vbp, GEN_ERR); } else { /* retrieve all the values from the same data structure */ for ( ; vbp; vbp = vbp->vb_link) { if ((error = tcp_get_value (vbp->vb_ml.ml_last_match, pktp, vbp, &data)) != NO_ERROR) getproc_error(pktp, vbp, error); } } }