|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 12090 (0x2f3a) Types: TextFile Names: »tcp.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/snmp/tcp.c«
/* tcp.c - MIB realization of the TCP group */ #ifndef lint static char *rcsid = "$Header: /f/osi/snmp/RCS/tcp.c,v 7.1 89/12/11 10:40:40 mrose Exp $"; #endif /* * $Header: /f/osi/snmp/RCS/tcp.c,v 7.1 89/12/11 10:40:40 mrose Exp $ * * Contributed by NYSERNet Inc. This work was partially supported by the * U.S. Defense Advanced Research Projects Agency and the Rome Air Development * Center of the U.S. Air Force Systems Command under contract number * F30602-88-C-0016. * * * $Log: tcp.c,v $ * Revision 7.1 89/12/11 10:40:40 mrose * touch-up * * Revision 7.0 89/11/23 22:23:35 mrose * Release 6.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ #include <stdio.h> #include "mib.h" #ifdef BSD43_Tahoe #include <machine/endian.h> #endif #include "internet.h" #ifdef BSD44 #include <machine/machparam.h> #endif #include <sys/protosw.h> #include <net/route.h> #include <netinet/in_systm.h> #include <netinet/in_pcb.h> #include <netinet/tcp.h> #include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> /* \f */ #define RTOA_VANJ 4 /* tcpRtoAlgorithm */ #define MXCN_NONE (-1) /* tcpMaxConn */ static struct tcpstat tcpstat; static int tcpConnections; /* \f */ #define tcpRtoAlgorithm 0 #define tcpRtoMin 1 #define tcpRtoMax 2 #define tcpMaxConn 3 #define tcpActiveOpens 4 #define tcpPassiveOpens 5 #define tcpAttemptFails 6 #define tcpEstabResets 7 #define tcpCurrEstab 8 #define tcpInSegs 9 #define tcpOutSegs 10 #define tcpRetransSegs 11 #ifndef SUNOS4 #define tcpInErrs 12 #else #undef tcpInErrs 12 #endif #undef tcpOutRsts 13 /* NOT IMPLEMENTED */ static int o_tcp (oi, v, offset) OI oi; register struct type_SNMP_VarBind *v; int offset; { int ifvar; register struct tcpstat *tcps = &tcpstat; register OID oid = oi -> oi_name; register OT ot = oi -> oi_type; static int lastq = -1; ifvar = (int) ot -> ot_info; switch (offset) { case type_SNMP_PDUs_get__request: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1 || oid -> oid_elements[oid -> oid_nelem - 1] != 0) return int_SNMP_error__status_noSuchName; break; case type_SNMP_PDUs_get__next__request: if (oid -> oid_nelem > ot -> ot_name -> oid_nelem + 1) return int_SNMP_error__status_noSuchName; if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { OID new; if ((new = oid_extend (oid, 1)) == NULLOID) return int_SNMP_error__status_genErr; new -> oid_elements[new -> oid_nelem - 1] = 0; if (v -> name) free_SNMP_ObjectName (v -> name); v -> name = new; } else return NOTOK; break; default: return int_SNMP_error__status_genErr; } switch (ifvar) { case tcpCurrEstab: if (get_connections () == NOTOK) return int_SNMP_error__status_genErr; break; default: if (quantum != lastq) { lastq = quantum; if (getkmem (nl + N_TCPSTAT, (caddr_t) tcps, sizeof *tcps) == NOTOK) return int_SNMP_error__status_genErr; } break; } switch (ifvar) { case tcpRtoAlgorithm: return o_integer (oi, v, RTOA_VANJ); case tcpRtoMin: return o_integer (oi, v, TCPTV_MIN * 100); /* milliseconds */ case tcpRtoMax: return o_integer (oi, v, TCPTV_REXMTMAX * 100); /* .. */ case tcpMaxConn: return o_integer (oi, v, MXCN_NONE); case tcpActiveOpens: return o_integer (oi, v, tcps -> tcps_connattempt); case tcpPassiveOpens: return o_integer (oi, v, tcps -> tcps_accepts); case tcpAttemptFails: return o_integer (oi, v, tcps -> tcps_conndrops); case tcpEstabResets: return o_integer (oi, v, tcps -> tcps_drops); case tcpCurrEstab: return o_integer (oi, v, tcpConnections); case tcpInSegs: return o_integer (oi, v, tcps -> tcps_rcvtotal); case tcpOutSegs: return o_integer (oi, v, tcps -> tcps_sndtotal - tcps -> tcps_sndrexmitpack); case tcpRetransSegs: return o_integer (oi, v, tcps -> tcps_sndrexmitpack); #ifdef tcpInErrs case tcpInErrs: return o_integer (oi, v, tcps -> tcps_badsegs); #endif default: return int_SNMP_error__status_noSuchName; } } /* \f */ struct tcptab { #define TT_SIZE 10 /* object instance */ unsigned int tt_instance[TT_SIZE]; struct inpcb tt_pcb; /* protocol control block */ struct tcpcb tt_tcpb; /* TCP info */ struct tcptab *tt_next; }; static struct tcptab *tts = NULL; struct tcptab *get_tcpent (); /* \f */ #define tcpConnState 0 #define tcpConnLocalAddress 1 #define tcpConnLocalPort 2 #define tcpConnRemAddress 3 #define tcpConnRemPort 4 static int o_tcp_conn (oi, v, offset) OI oi; register struct type_SNMP_VarBind *v; int offset; { int ifvar; register int i; register unsigned int *ip, *jp; register struct tcptab *tt; struct sockaddr_in netaddr; register OID oid = oi -> oi_name; register OT ot = oi -> oi_type; if (get_connections () == NOTOK) return int_SNMP_error__status_genErr; ifvar = (int) ot -> ot_info; switch (offset) { case type_SNMP_PDUs_get__request: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + TT_SIZE) return int_SNMP_error__status_noSuchName; if ((tt = get_tcpent (oid -> oid_elements + oid -> oid_nelem - TT_SIZE, 0)) == NULL) return int_SNMP_error__status_noSuchName; break; case type_SNMP_PDUs_get__next__request: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + TT_SIZE && oid -> oid_nelem != ot -> ot_name -> oid_nelem) return int_SNMP_error__status_noSuchName; if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { OID new; if ((tt = tts) == NULL) return NOTOK; if ((new = oid_extend (oid, TT_SIZE)) == NULLOID) return int_SNMP_error__status_genErr; ip = new -> oid_elements + new -> oid_nelem - TT_SIZE; jp = tt -> tt_instance; for (i = TT_SIZE; i > 0; i--) *ip++ = *jp++; if (v -> name) free_SNMP_ObjectName (v -> name); v -> name = new; } else { if ((tt = get_tcpent (ip = oid -> oid_elements + oid -> oid_nelem - TT_SIZE, 1)) == NULL) return NOTOK; jp = tt -> tt_instance; for (i = TT_SIZE; i > 0; i--) *ip++ = *jp++; } break; default: return int_SNMP_error__status_genErr; } switch (ifvar) { case tcpConnState: return o_integer (oi, v, tt -> tt_tcpb.t_state + 1); case tcpConnLocalAddress: netaddr.sin_addr = tt -> tt_pcb.inp_laddr; /* struct copy */ return o_ipaddr (oi, v, &netaddr); case tcpConnLocalPort: return o_integer (oi, v, tt -> tt_pcb.inp_lport & 0xffff); case tcpConnRemAddress: netaddr.sin_addr = tt -> tt_pcb.inp_faddr; /* struct copy */ return o_ipaddr (oi, v, &netaddr); case tcpConnRemPort: return o_integer (oi, v, tt -> tt_pcb.inp_fport & 0xffff); default: return int_SNMP_error__status_noSuchName; } } /* \f */ static int tt_compar (a, b) struct tcptab **a, **b; { return elem_cmp ((*a) -> tt_instance, TT_SIZE, (*b) -> tt_instance, TT_SIZE); } static int get_connections () { register int i; register unsigned int *cp; register struct tcptab *ts, *tp, **tsp; register struct inpcb *ip; struct inpcb *head, tcb; struct nlist nzs; register struct nlist *nz = &nzs; static int first_time = 1; static int lastq = -1; if (quantum == lastq) return OK; lastq = quantum; for (ts = tts; ts; ts = tp) { tp = ts -> tt_next; free ((char *) ts); } tts = NULL; if (getkmem (nl + N_TCB, (char *) &tcb, sizeof tcb) == NOTOK) return NOTOK; head = (struct inpcb *) nl[N_TCB].n_value; tsp = &tts, i = 0; ip = &tcb; while (ip -> inp_next != head) { if ((ts = (struct tcptab *) calloc (1, sizeof *ts)) == NULL) adios (NULLCP, "out of memory"); /* no check needed for duplicate connections... */ *tsp = ts, tsp = &ts -> tt_next, i++; nz -> n_name = "struct inpcb", nz -> n_value = (unsigned long) ip -> inp_next; if (getkmem (nz, (caddr_t) &ts -> tt_pcb, sizeof ts -> tt_pcb) == NOTOK) return NOTOK; ip = &ts -> tt_pcb; nz ->n_name = "struct tcb", nz -> n_value = (unsigned long) ip -> inp_ppcb; if (getkmem (nz, (caddr_t) &ts -> tt_tcpb, sizeof ts -> tt_tcpb) == NOTOK) return NOTOK; cp = ts -> tt_instance; cp += ipaddr2oid (cp, &ts -> tt_pcb.inp_laddr); *cp++ = ts -> tt_pcb.inp_lport & 0xffff; cp += ipaddr2oid (cp, &ts -> tt_pcb.inp_faddr); *cp++ = ts -> tt_pcb.inp_fport & 0xffff; if (debug && first_time) { OIDentifier oids; oids.oid_elements = ts -> tt_instance; oids.oid_nelem = TT_SIZE; advise (LLOG_DEBUG, NULLCP, "add connection: %s", sprintoid (&oids)); } } first_time = 0; if ((tcpConnections = i) > 1) { register struct tcptab **base, **tse; if ((base = (struct tcptab **) malloc ((unsigned) (i * sizeof *base))) == NULL) adios (NULLCP, "out of memory"); tse = base; for (ts = tts; ts; ts = ts -> tt_next) *tse++ = ts; qsort ((char *) base, i, sizeof *base, tt_compar); tsp = base; ts = tts = *tsp++; while (tsp < tse) { ts -> tt_next = *tsp; ts = *tsp++; } ts -> tt_next = NULL; free ((char *) base); } return OK; } /* \f */ static struct tcptab *get_tcpent (ip, isnext) register unsigned int *ip; int isnext; { register struct tcptab *tt; for (tt = tts; tt; tt = tt -> tt_next) switch (elem_cmp (tt -> tt_instance, TT_SIZE, ip, TT_SIZE)) { case 0: return (isnext ? tt -> tt_next : tt); case 1: return (isnext ? tt : NULL); } return NULL; } /* \f */ init_tcp () { register OT ot; if (ot = text2obj ("tcpRtoAlgorithm")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpRtoAlgorithm; if (ot = text2obj ("tcpRtoMin")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpRtoMin; if (ot = text2obj ("tcpRtoMax")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpRtoMax; if (ot = text2obj ("tcpMaxConn")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpMaxConn; if (ot = text2obj ("tcpActiveOpens")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpActiveOpens; if (ot = text2obj ("tcpPassiveOpens")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpPassiveOpens; if (ot = text2obj ("tcpAttemptFails")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpAttemptFails; if (ot = text2obj ("tcpEstabResets")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpEstabResets; if (ot = text2obj ("tcpCurrEstab")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpCurrEstab; if (ot = text2obj ("tcpInSegs")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpInSegs; if (ot = text2obj ("tcpOutSegs")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpOutSegs; if (ot = text2obj ("tcpRetransSegs")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpRetransSegs; #ifdef tcpInErrs if (ot = text2obj ("tcpInErrs")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpInErrs; #endif #ifdef tcpOutRsts if (ot = text2obj ("tcpOutRsts")) ot -> ot_getfnx = o_tcp, ot -> ot_info = (caddr_t) tcpOutRsts; #endif if (ot = text2obj ("tcpConnState")) ot -> ot_getfnx = o_tcp_conn, ot -> ot_info = (caddr_t) tcpConnState; if (ot = text2obj ("tcpConnLocalAddress")) ot -> ot_getfnx = o_tcp_conn, ot -> ot_info = (caddr_t) tcpConnLocalAddress; if (ot = text2obj ("tcpConnLocalPort")) ot -> ot_getfnx = o_tcp_conn, ot -> ot_info = (caddr_t) tcpConnLocalPort; if (ot = text2obj ("tcpConnRemAddress")) ot -> ot_getfnx = o_tcp_conn, ot -> ot_info = (caddr_t) tcpConnRemAddress; if (ot = text2obj ("tcpConnRemPort")) ot -> ot_getfnx = o_tcp_conn, ot -> ot_info = (caddr_t) tcpConnRemPort; }