|
|
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;
}