1 /* nsp_output.c 1.5 82/12/18 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mbuf.h" 6 #include "../h/protosw.h" 7 #include "../h/socket.h" 8 #include "../h/socketvar.h" 9 #include "../netdecnet/dn_systm.h" 10 #include "../netdecnet/nsp.h" 11 #include "../netdecnet/nsp_var.h" 12 #include <errno.h> 13 14 /* 15 * NSP output routine: figure out what should be sent and send it. 16 */ 17 nsp_output(np) 18 register struct nspcb *np; 19 { 20 register struct socket *so = np->n_socket; 21 register int len; 22 int off, flags; 23 register struct mbuf *m; 24 25 26 /* 27 * Determine what type of message to send and send it. 28 */ 29 top: 30 /* interrupt to be sent? */ 31 if (np->n_flags & NF_INTAVAIL) && np->nf_remint > 0 && 32 (np->n_flags & NF_OTHSENT) == 0) { 33 register struct nspi *n; 34 35 m = m_get(M_CANTWAIT, MT_HEADER); 36 if (m == 0) 37 return (0); 38 if (np->nb_xmt) 39 len = np->nb_xmt->m_len; 40 else 41 len = 0; 42 m->m_len = sizeof (struct nspi) + len; 43 m->m_off = MMAXOFF - m->m_len; 44 n = mtod(m, struct nspi *); 45 n->nsp_msgflg = NSP_INTR; 46 n->nsp_dstaddr = np->n_rem; 47 n->nsp_srcaddr = np->n_loc; 48 n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 49 n->nsp_segnum = np->nn_oth; 50 if (len) 51 bcopy((char *)(n + 1), mtod(np->nb_xmt, char *), len); 52 if (tp_output(m, np->n_node)) { 53 (void) m_free(m); 54 return (0); 55 } 56 np->n_flags &= ~(NF_INTAVAIL|NF_OTHACK); 57 np->n_flags |= NF_OTHSENT; 58 if (len) 59 (void) m_free(np->nb_xmt); 60 nsp_insrtq(m, np->nt_oth); 61 goto top; 62 } 63 64 /* interrupt request to be sent? */ 65 if (np->nf_locint == NFL_SEND && (np->n_flags & NF_OTHSENT) == 0) { 66 register struct nspls *n; 67 68 m = m_get(M_CANTWAIT, MT_HEADER); 69 if (m == 0) 70 return (0); 71 m->m_len = sizeof (struct nspls); 72 m->m_off = MMAXOFF - m->m_len; 73 n = mtod(m, struct nspls *); 74 n->nsp_msgflg = NSP_LS; 75 n->nsp_dstaddr = np->n_rem; 76 n->nsp_srcaddr = np->n_loc; 77 n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 78 n->nsp_segnum = np->nn_oth; 79 n->nsp_lsflags = NSPLS_INTREQ | NSPLS_ON; 80 n->nsp_fcval = 1; 81 if (tp_output(m, np->n_node)) { 82 (void) m_free(m); 83 return (0); 84 } 85 np->n_flags &= ~NF_OTHACK; 86 np->n_flags |= NF_OTHSENT; 87 nsp_insrtq(m, np->nt_oth); 88 goto top; 89 } 90 91 /* data request to be sent? */ 92 if (np->nf_locdat > 0 && (np->n_flags & NF_OTHSENT == 0)) { 93 register struct nspls *n; 94 95 m = m_get(M_CANTWAIT, MT_HEADER); 96 if (m == 0) 97 return (0); 98 m->m_len = sizeof (struct nspls); 99 m->m_off = MMAXOFF - m->m_len; 100 n = mtod(m, struct nspls *); 101 n->nsp_msgflg = NSP_LS; 102 n->nsp_dstaddr = np->n_rem; 103 n->nsp_srcaddr = np->n_loc; 104 n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 105 n->nsp_segnum = np->nn_oth; 106 n->nsp_lsflags = NSPLS_DATREQ | NSPLS_ON; 107 n->nsp_fcval = np->nf_locdat; 108 if (tp_output(m, np->n_node)) { 109 (void) m_free(m); 110 return (0); 111 } 112 np->n_flags &= ~NF_OTHACK; 113 np->n_flags |= NF_OTHSENT; 114 nsp_insrtq(m, np->nt_oth); 115 goto top; 116 } 117 118 /* other data ack to be sent? */ 119 if (np->n_flags & NF_OTHACK) { 120 register struct nspack *n; 121 122 m = m_get(M_CANTWAIT, MT_HEADER); 123 if (m == 0) 124 return (0); 125 m->m_len = sizeof (struct nspack); 126 m->m_off = MMAXOFF - m->m_len; 127 n = mtod(m, struct nspack *); 128 n->nsp_msgflg = NSP_OTHACK; 129 n->nsp_dstaddr = np->n_rem; 130 n->nsp_srcaddr = np->n_loc; 131 n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 132 if (tp_output(m, np->n_node)) { 133 (void) m_free(m); 134 return (0); 135 } 136 np->n_flags &= ~NF_OTHACK; 137 (void) m_free(m); 138 goto top; 139 } 140 141 /* data to be sent? */ 142 if () { 143 register struct nspd *n; 144 145 m = nsp_mgetcl(); 146 if (m == 0) 147 return (0); 148 if (len <= np->n_segsize) { 149 m->m_next = so->so_snd.sb_mb; 150 so->so_snd.sb_mb = m->m_next->m_act; 151 } 152 153 /* MORE */ 154 155 } 156 157 /* data ack to be sent? */ 158 if (np->n_flags & NF_DATACK) { 159 register struct nspack *n; 160 161 m = m_get(M_CANTWAIT, MT_HEADER); 162 if (m == 0) 163 return (0); 164 m->m_len = sizeof (struct nspack); 165 m->m_off = MMAXOFF - m->m_len; 166 n = mtod(m, struct nspack *); 167 n->nsp_msgflg = NSP_DATACK; 168 n->nsp_dstaddr = np->n_rem; 169 n->nsp_srcaddr = np->n_loc; 170 n->nsp_acknum = NSPA_ACK | np->na_xmtdat; 171 if (tp_output(m, np->n_node)) { 172 (void) m_free(m); 173 return (0); 174 } 175 np->n_flags &= ~NF_DATACK; 176 (void) m_free(m); 177 goto top; 178 } 179 180 /* 181 * Nothing left to do, return success. 182 */ 183 return (1); 184 } 185