mpcc ports hang with TS_BUSY; bug report 4.3BSD-tahoe/sys/23
[unix-history] / usr / src / sys / deprecated / netdecnet / tp_input.c
/* tp_input.c 1.3 82/10/09 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/mbuf.h"
#include "../h/protosw.h"
#include "../h/socket.h"
#include "../netdecnet/dn_systm.h"
#include "../net/if.h"
#include "../netdecnet/tp.h"
#include "../netdecnet/tp_var.h"
/*
* Initialize a few of the Transport variables here.
*/
tp_init()
{
tp_host = 244;
tprp.tprp_nn = 255; /* max node number */
}
/*
* Attach a DECnet interface.
* For now, since we are an end node,
* there can only be one.
*/
tp_attach(ifp)
register struct ifnet *ifp;
{
if (tpifp) {
printf("tp: Only one DECnet interface allowed, ");
printf("%s%d ignored\n", ifp->if_name, ifp->if_unit);
return;
}
tpifp = ifp;
}
/*
* Transport input routine. Decode header, process
* initialization messages, flush other control messages,
* and strip route headers and pass to NSP.
*/
tp_input()
{
register struct mbuf *m;
register char *p;
next:
/*
* Get next packet off input queue.
*/
IF_DEQUEUE(&tpintrq, m);
if (m == 0)
return;
p = mtod(m, char *);
switch (*p & TP_MSGTYPE) {
/*
* Transport initialization message from neighbor.
*/
case TP_INIT:
{
register struct tpin *t = (struct tpin *)p;
printf("tpinit: node %d, %d, blksize %d, ver %o.%o.%o\n",
D_SHORT(t->tpin_srcnode), t->tpin_tiinfo,
D_SHORT(t->tpin_blksize),
t->tpin_ver[0], t->tpin_ver[1], t->tpin_ver[2]);
/* perform a few consistency checks */
if (m->m_len < sizeof (struct tpin)) {
tpstat.tps_badinit++;
break;
}
if (D_SHORT(t->tpin_srcnode) > tprp.tprp_nn) {
tpstat.tps_badinit++;
break;
}
if (t->tpin_res != 0) {
tpstat.tps_badinit++;
break;
}
tpstat.tps_init++;
if (tpstate == TPS_TIS) {
tpstate = TPS_RUN;
wakeup((caddr_t)&tpstate);
} else if (tpstate == TPS_HALT) {
tp_linit();
tpstate = TPS_RUN;
}
break;
}
/*
* Route header. Flush bad ones,
* strip good ones and pass to NSP.
*/
case TP_RH:
{
register struct tprh *t = (struct tprh *)p;
/*
* Is it a reasonable route header?
*/
if (tpstate != TPS_RUN) {
printf("tp: not running!\n");
break;
}
if (t->tprh_rtflg & TPRF_EV) {
printf("tp: got P2 ASCII header\n");
tpstat.tps_p2hdr++;
break;
}
if (t->tprh_rtflg & TPRF_RTS) {
printf("tp: got returned packet\n");
tpstat.tps_returned++;
break;
}
if (m->m_len <= sizeof (struct tprh)) {
printf("tp: got short packet, %d\n", m->m_len);
tpstat.tps_shortpacket++;
break;
}
if (D_SHORT(t->tprh_srcnode) > tprp.tprp_nn) {
tpstat.tps_badsrc++;
break;
}
/*
* Is it for us? If so,
* add it to the NSP input queue.
*/
if (D_SHORT(t->tprh_dstnode) != tp_host) {
printf("tp: not for me, %d\n", D_SHORT(t->tprh_dstnode));
tpstat.tps_notforme++;
break;
}
setnspintr();
IF_ENQUEUE(&nspintrq, m);
goto next;
}
/*
* Verification messge. We should never see one
* of these because we never ask for one. Flush it.
*/
case TP_VERIF:
printf("tp: got verification message\n");
tpstat.tps_verif++;
break;
/*
* Hello and test message. Make sure it's
* valid then flush it.
*/
case TP_TEST:
{
register struct tpht *t = (struct tpht *)p;
register int i;
if (D_SHORT(t->tpht_srcnode) > tprp.tprp_nn) {
tpstat.tps_badsrc++;
break;
}
if ((i = t->tpht_cnt) < 0 || i > 128) {
printf("tp: test, bad count, %d\n", i);
tpstat.tps_badtest++;
break;
}
if (m->m_len != sizeof (struct tpht) + i - 1) {
printf("tp: test, bad len, %d\n", m->m_len);
tpstat.tps_bad_test++;
break;
}
for (p = t->tpht_data; i--; p++)
if (*p != 0252) {
printf("tp: test, bad data, %o\n", *p);
tpstat.tps_badtest++;
break;
}
break;
}
/*
* Routing message. We should never get this,
* at least not yet. Just flush it.
*/
case TP_ROUTE:
printf("tp: got routing message\n");
tpstat.tps_route++;
break;
default:
printf("tp: unknown packet type, 0x%x\n", *p);
tpstat.tps_unknown++;
break;
}
/*
* Free the current packet and get the next one.
*/
m_freem(m);
goto next;
}