1*8408Swnj /* nsp_output.c 1.3 82/10/09 */ 26827Ssam 36827Ssam #include "../h/param.h" 46827Ssam #include "../h/systm.h" 56827Ssam #include "../h/mbuf.h" 66827Ssam #include "../h/protosw.h" 76827Ssam #include "../h/socket.h" 86827Ssam #include "../h/socketvar.h" 9*8408Swnj #include "../netdecnet/dn_systm.h" 10*8408Swnj #include "../netdecnet/nsp.h" 11*8408Swnj #include "../netdecnet/nsp_var.h" 12*8408Swnj #include <errno.h> 136827Ssam 146827Ssam /* 156827Ssam * NSP output routine: figure out what should be sent and send it. 166827Ssam */ 176827Ssam nsp_output(np) 186827Ssam register struct nspcb *np; 196827Ssam { 206827Ssam register struct socket *so = np->n_socket; 216827Ssam register int len; 226827Ssam int off, flags; 236827Ssam register struct mbuf *m; 246827Ssam 256827Ssam 266827Ssam /* 276827Ssam * Determine what type of message to send and send it. 286827Ssam */ 296827Ssam top: 306827Ssam /* interrupt to be sent? */ 316827Ssam if (np->n_flags & NF_INTAVAIL) && np->nf_remint > 0 && 326827Ssam (np->n_flags & NF_OTHSENT) == 0) { 336827Ssam register struct nspi *n; 346827Ssam 356827Ssam m = m_get(M_CANTWAIT); 366827Ssam if (m == 0) 376827Ssam return (0); 386827Ssam if (np->nb_xmt) 396827Ssam len = np->nb_xmt->m_len; 406827Ssam else 416827Ssam len = 0; 426827Ssam m->m_len = sizeof (struct nspi) + len; 436827Ssam m->m_off = MMAXOFF - m->m_len; 446827Ssam n = mtod(m, struct nspi *); 456827Ssam n->nsp_msgflg = NSP_INTR; 466827Ssam n->nsp_dstaddr = np->n_rem; 476827Ssam n->nsp_srcaddr = np->n_loc; 486827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 496827Ssam n->nsp_segnum = np->nn_oth; 506827Ssam if (len) 516827Ssam bcopy((char *)(n + 1), mtod(np->nb_xmt, char *), len); 526827Ssam if (tp_output(m, np->n_node)) { 536827Ssam m_free(m); 546827Ssam return (0); 556827Ssam } 566827Ssam np->n_flags &= ~(NF_INTAVAIL|NF_OTHACK); 576827Ssam np->n_flags |= NF_OTHSENT; 586827Ssam if (len) 596827Ssam m_free(np->nb_xmt); 606827Ssam nsp_insrtq(m, np->nt_oth); 616827Ssam goto top; 626827Ssam } 636827Ssam 646827Ssam /* interrupt request to be sent? */ 656827Ssam if (np->nf_locint == NFL_SEND && (np->n_flags & NF_OTHSENT) == 0) { 666827Ssam register struct nspls *n; 676827Ssam 686827Ssam m = m_get(M_CANTWAIT); 696827Ssam if (m == 0) 706827Ssam return (0); 716827Ssam m->m_len = sizeof (struct nspls); 726827Ssam m->m_off = MMAXOFF - m->m_len; 736827Ssam n = mtod(m, struct nspls *); 746827Ssam n->nsp_msgflg = NSP_LS; 756827Ssam n->nsp_dstaddr = np->n_rem; 766827Ssam n->nsp_srcaddr = np->n_loc; 776827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 786827Ssam n->nsp_segnum = np->nn_oth; 796827Ssam n->nsp_lsflags = NSPLS_INTREQ | NSPLS_ON; 806827Ssam n->nsp_fcval = 1; 816827Ssam if (tp_output(m, np->n_node)) { 826827Ssam m_free(m); 836827Ssam return (0); 846827Ssam } 856827Ssam np->n_flags &= ~NF_OTHACK; 866827Ssam np->n_flags |= NF_OTHSENT; 876827Ssam nsp_insrtq(m, np->nt_oth); 886827Ssam goto top; 896827Ssam } 906827Ssam 916827Ssam /* data request to be sent? */ 926827Ssam if (np->nf_locdat > 0 && (np->n_flags & NF_OTHSENT == 0)) { 936827Ssam register struct nspls *n; 946827Ssam 956827Ssam m = m_get(M_CANTWAIT); 966827Ssam if (m == 0) 976827Ssam return (0); 986827Ssam m->m_len = sizeof (struct nspls); 996827Ssam m->m_off = MMAXOFF - m->m_len; 1006827Ssam n = mtod(m, struct nspls *); 1016827Ssam n->nsp_msgflg = NSP_LS; 1026827Ssam n->nsp_dstaddr = np->n_rem; 1036827Ssam n->nsp_srcaddr = np->n_loc; 1046827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 1056827Ssam n->nsp_segnum = np->nn_oth; 1066827Ssam n->nsp_lsflags = NSPLS_DATREQ | NSPLS_ON; 1076827Ssam n->nsp_fcval = np->nf_locdat; 1086827Ssam if (tp_output(m, np->n_node)) { 1096827Ssam m_free(m); 1106827Ssam return (0); 1116827Ssam } 1126827Ssam np->n_flags &= ~NF_OTHACK; 1136827Ssam np->n_flags |= NF_OTHSENT; 1146827Ssam nsp_insrtq(m, np->nt_oth); 1156827Ssam goto top; 1166827Ssam } 1176827Ssam 1186827Ssam /* other data ack to be sent? */ 1196827Ssam if (np->n_flags & NF_OTHACK) { 1206827Ssam register struct nspack *n; 1216827Ssam 1226827Ssam m = m_get(M_CANTWAIT); 1236827Ssam if (m == 0) 1246827Ssam return (0); 1256827Ssam m->m_len = sizeof (struct nspack); 1266827Ssam m->m_off = MMAXOFF - m->m_len; 1276827Ssam n = mtod(m, struct nspack *); 1286827Ssam n->nsp_msgflg = NSP_OTHACK; 1296827Ssam n->nsp_dstaddr = np->n_rem; 1306827Ssam n->nsp_srcaddr = np->n_loc; 1316827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 1326827Ssam if (tp_output(m, np->n_node)) { 1336827Ssam m_free(m); 1346827Ssam return (0); 1356827Ssam } 1366827Ssam np->n_flags &= ~NF_OTHACK; 1376827Ssam m_free(m); 1386827Ssam goto top; 1396827Ssam } 1406827Ssam 1416827Ssam /* data to be sent? */ 1426827Ssam if () { 1436827Ssam register struct nspd *n; 1446827Ssam 1456827Ssam m = nsp_mgetcl(); 1466827Ssam if (m == 0) 1476827Ssam return (0); 1486827Ssam if (len <= np->n_segsize) { 1496827Ssam m->m_next = so->so_snd.sb_mb; 1506827Ssam so->so_snd.sb_mb = m->m_next->m_act; 1516827Ssam } 1526827Ssam 1536827Ssam /* MORE */ 1546827Ssam 1556827Ssam } 1566827Ssam 1576827Ssam /* data ack to be sent? */ 1586827Ssam if (np->n_flags & NF_DATACK) { 1596827Ssam register struct nspack *n; 1606827Ssam 1616827Ssam m = m_get(M_CANTWAIT); 1626827Ssam if (m == 0) 1636827Ssam return (0); 1646827Ssam m->m_len = sizeof (struct nspack); 1656827Ssam m->m_off = MMAXOFF - m->m_len; 1666827Ssam n = mtod(m, struct nspack *); 1676827Ssam n->nsp_msgflg = NSP_DATACK; 1686827Ssam n->nsp_dstaddr = np->n_rem; 1696827Ssam n->nsp_srcaddr = np->n_loc; 1706827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtdat; 1716827Ssam if (tp_output(m, np->n_node)) { 1726827Ssam m_free(m); 1736827Ssam return (0); 1746827Ssam } 1756827Ssam np->n_flags &= ~NF_DATACK; 1766827Ssam m_free(m); 1776827Ssam goto top; 1786827Ssam } 1796827Ssam 1806827Ssam /* 1816827Ssam * Nothing left to do, return success. 1826827Ssam */ 1836827Ssam return (1); 1846827Ssam } 185