/* nsp_input.c 1.2 82/05/15 */
#include "../h/protosw.h"
#include "../h/socketvar.h"
#include "../net/dn_systm.h"
#include "../net/nsp_var.h"
#define printd if(nspidebug)printf
* NSP input routine: decode incoming packet and dispatch
* to appropriate socket. Called from the software interrupt
* count occurances of various error conditions.
* Loop pulling packets off the interrupt queue.
IF_DEQUEUE(&nspintrq
, m
);
printd("nsp_input: m 0x%x", m
);
t
= mtod(m
, struct tprh
*);
srcnode
= t
->tprh_srcnode
;
m
->m_len
-= sizeof (struct tprh
); /* use m_adj??? */
m
->m_off
+= sizeof (struct tprh
);
printd(", srcnode %d, len %d", srcnode
, m
->m_len
);
* Switch on the type of the message.
* Got a Data message, possibly with EOM and
* BOM flags set. Call nsp_chkaddr to do ack
* and flow controll processing, then pass the
case NSP_DATA
|NSP_EOM
|NSP_BOM
:
printd(", DATA (%d,%d)", bom
, eom
);
np
= nsp_chkaddr(m
, srcnode
, NSP_DATA
, &segnum
);
* Data messages only valid in Run state
if (np
->n_state
!= NS_RUN
) {
printf(", !RUN (%d)\n", np
->n_state
);
if (SEQ_GTR(segnum
, np
->na_xmtdat
)) {
/* SHOULD DO SEGMENT RECONSTRUCTION HERE */
sbpappend(m
, &np
->n_socket
->sb_rcv
);
np
->n_flags
|= NF_DATACK
;
* Got an interrupt message. Call nsp_chkaddr
* (as usual). Save the interrupt data for the
* GENERATE A SIGNAL OF SOME SORT???
np
= nsp_chkaddr(m
, srcnode
, NSP_INTR
, &segnum
);
* If we are in the Connect Confirm state then
* this Interrupt packet causes the transition
* to the Run state. Otherwise we better be in
if (np
->n_state
== NS_CC
)
else if (np
->n_state
!= NS_RUN
) {
printf(", !RUN %d\n", np
->n_state
);
* If this segment is the one after the last
* other data segment we acked, and there is
* no waiting interrupt message, then queue
if (segnum
== SEQ_ADD(np
->na_xmtoth
, 1) &&
np
->nf_locint
== NFL_EMPTY
) {
printd(", flush old intr data");
printd(", intr data too long\n");
np
->nf_locint
= NFL_INTR
;
np
->na_xmtoth
= segnum
; /* really += 1 */
np
->n_flags
|= NF_OTHACK
;
} else if (SEQ_LEQ(segnum
, np
->na_xmtoth
))
np
->n_flags
|= NF_OTHACK
;
* Got a Link Service message. Process options
* to modify flow control values.
np
= nsp_chkaddr(m
, srcnode
, NSP_LS
, &segnum
);
* If we are in the Connect Confirm state then
* this Link Service packet causes the transition
* to the Run state. Otherwise we better be in
if (np
->n_state
== NS_CC
)
else if (np
->n_state
!= NS_RUN
) {
printd(", !RUN %d\n", np
->n_state
);
printd(", lsf 0x%x, fcval %d", lsf
, fcval
);
switch (lsf
& NSPLS_FCVALINT
) {
if (seqnum
== SEQ_ADD(np
->na_xmtoth
, 1)) {
if (np
->nf_remdat
+ fcval
>= -128 &&
np
->nf_remdat
+ fcval
<= 127) {
np
->n_flags
|= NF_OTHACK
;
switch (lsf
& NSPLS_FCMOD
) {
np
->n_flags
&= ~NF_DATOFF
;
np
->n_flags
|= NF_DATOFF
;
} else if (SEQ_LEQ(segnum
, np
->na_xmtoth
))
np
->n_flags
|= NF_OTHACK
;
if (seqnum
== SEQ_ADD(np
->na_xmtoth
, 1)) {
if (fcval
>= 0 && np
->nf_remint
+fcval
<= 127) {
np
->n_flags
|= NF_OTHACK
;
} else if (SEQ_LEQ(segnum
, np
->na_xmtoth
))
np
->n_flags
|= NF_OTHACK
;
printd(", bad fcvalint");
* Got an acknowledgement for a Data message.
* Nsp_chkaddr processes the ack, nothing else
np
= nsp_chkaddr(m
, srcnode
, NSP_DATACK
, &segnum
);
* Got an acknowledgement for an Other Data message.
* Nsp_chkaddr processes the ack, nothing else to do.
np
= nsp_chkaddr(m
, srcnode
, NSP_OTHACK
, &segnum
);
* Got a Connect Acknowledgement. Just verify
* the address and perform the state transition.
* Got an unknown message, count it and flush it.