|
|
1.1 ! root 1: /* ! 2: * C H S E N D ! 3: * ! 4: * Chaosnet line discipline - routines to deal with sending out packets. ! 5: * ! 6: * ! 7: * (c) Copyright 1985 Nirvonics, Inc. ! 8: * ! 9: * Written by Kurt Gollhardt ! 10: * Last update Thu Feb 28 14:42:57 1985 ! 11: * ! 12: * This software is the property of Nirvonics, Inc. ! 13: * All rights reserved. ! 14: * ! 15: */ ! 16: ! 17: #include "ch.h" ! 18: #if NCH > 0 ! 19: #include "../h/param.h" ! 20: #include "../h/systm.h" ! 21: #include "../h/stream.h" ! 22: #include "../h/conf.h" ! 23: #include "../chaosld/types.h" ! 24: #include "../chaosld/constants.h" ! 25: #include "../chaosld/globals.h" ! 26: #include "../chaosld/chrouteld.h" ! 27: ! 28: /* ! 29: * Send a STS packet on this connection ! 30: * if allocation fails it is not sent ! 31: */ ! 32: sendsts(conn) ! 33: register struct connection *conn; ! 34: { ! 35: register struct packet *pkt; ! 36: ! 37: if ((pkt = new_packet()) != NOPKT) { ! 38: setconn(conn, pkt); ! 39: setsts(conn, pkt); ! 40: sendctl(pkt); ! 41: } ! 42: } ! 43: ! 44: /* ! 45: * Send a SNS packet on this connection ! 46: * if allocation failed nothing is sent ! 47: */ ! 48: sendsns(conn) ! 49: register struct connection *conn; ! 50: { ! 51: register struct packet *pkt; ! 52: ! 53: if ((pkt = new_packet()) != NOPKT) { ! 54: setconn(conn, pkt); ! 55: pkt->pk_op = SNSOP; ! 56: setack(conn, pkt); ! 57: sendctl(pkt); ! 58: } ! 59: } ! 60: ! 61: /* ! 62: * Send an open in response to an RFC ! 63: */ ! 64: ! 65: sendopn(conn) ! 66: register struct connection *conn; ! 67: { ! 68: register struct packet *pkt; ! 69: ! 70: if ((pkt = new_packet()) != NOPKT) { ! 71: conn->cn_rsts = conn->cn_rwsize >> 1; ! 72: conn->cn_tlast = 0; ! 73: setconn(conn, pkt); ! 74: setsts(conn, pkt); ! 75: pkt->pk_op = OPNOP; ! 76: chld_write(conn, pkt); ! 77: } ! 78: } ! 79: ! 80: /* ! 81: * Sendctl - send a control packet that will not be acknowledged and ! 82: * will not be retransmitted (this actual packet). ! 83: * If anything is wrong (no path, bad subnet) we just throw it ! 84: * away. Remember, next is assumed to be == NOPKT. ! 85: */ ! 86: sendctl(pkt) ! 87: register struct packet *pkt; ! 88: { ! 89: register struct chroute *r; ! 90: ! 91: debug(DSEND, (printf("Sending: %d ", pkt->pk_op), prpkt(pkt, "ctl"), printf("\n"))); ! 92: ch_busy++; ! 93: put_packet(WR(ChaosQ), pkt); ! 94: --ch_busy; ! 95: } ! 96: ! 97: /* ! 98: * Senddata - send a list of controlled packets. ! 99: * Similar to sendctl, but stuffs time, handles a list, and marks ! 100: * the packets as transmitted. ! 101: */ ! 102: senddata(pkt) ! 103: register struct packet *pkt; ! 104: { ! 105: register struct packet *nextpk; ! 106: ! 107: debug(DSEND, (printf("Sending: %d ", pkt->pk_op), prpkt(pkt, "data"), printf("\n"))); ! 108: ch_busy++; ! 109: do { ! 110: pkt->time = Chclock; ! 111: nextpk = pkt->next; ! 112: copy_packet(WR(ChaosQ), pkt); ! 113: xmitdone(pkt); ! 114: } while ((pkt = nextpk) != NOPKT); ! 115: --ch_busy; ! 116: } ! 117: ! 118: /* ! 119: * Send the given RUT packet out on the given tranceiver, which has the given ! 120: * cost. If the "copy" flag is true, make a copy of the packet. ! 121: * Note that if copy is not set, the packet data gets modified. ! 122: */ ! 123: sendrut(pkt, ifp, cost, copy) ! 124: register struct packet *pkt; ! 125: register struct chif *ifp; ! 126: unsigned short cost; ! 127: int copy; ! 128: { ! 129: register struct rut_data *rd; ! 130: struct rut_data *rdend; ! 131: ! 132: pkt->pk_saddr = ifp->my_addr; ! 133: pkt->pk_daddr.ch_subnet = ifp->my_addr.ch_subnet; ! 134: ! 135: rdend = (struct rut_data *)(pkt->data->rptr + pkt->pk_len); ! 136: for (rd = (struct rut_data *)pkt->data->rptr; rd < rdend; rd++) ! 137: rd->rd_cost += cost; ! 138: ! 139: ch_busy++; ! 140: if (copy) { ! 141: copy_packet(WR(ChaosQ), pkt); ! 142: for (rd = (struct rut_data *)pkt->data->rptr; rd < rdend; rd++) ! 143: rd->rd_cost -= cost; ! 144: } else ! 145: put_packet(WR(ChaosQ), pkt); ! 146: --ch_busy; ! 147: } ! 148: ! 149: /* ! 150: * Send a LOS in response to the given packet. ! 151: * Don't bother if the packet is itself a LOS or a CLS since the other ! 152: * end doesn't care anyway and would only return it again. ! 153: * Append the host name to the error message. ! 154: */ ! 155: sendlos(pkt, str, msglen) ! 156: register struct packet *pkt; ! 157: char *str; ! 158: int msglen; ! 159: { ! 160: if (pkt->pk_op == LOSOP || pkt->pk_op == CLSOP) ! 161: free_packet(pkt); ! 162: else { ! 163: register struct block *bp; ! 164: register char *cp; ! 165: register int namelen; ! 166: ! 167: for (namelen = 0, cp = Chmyname; *cp++;) ! 168: ++namelen; ! 169: ! 170: free_pkdata(pkt); ! 171: append_packet(pkt, str, msglen); ! 172: append_packet(pkt, " (from ", 7); ! 173: append_packet(pkt, Chmyname, namelen); ! 174: append_packet(pkt, ")", 1); ! 175: ! 176: pkt->pk_op = LOSOP; ! 177: reflect(pkt); ! 178: } ! 179: } ! 180: ! 181: /* ! 182: * Send a control packet back to its source ! 183: */ ! 184: reflect(pkt) ! 185: register struct packet *pkt; ! 186: { ! 187: register short temp; ! 188: ! 189: temp = pkt->pk_sidx.ci_idx; ! 190: pkt->pk_sidx = pkt->pk_didx; ! 191: pkt->pk_didx.ci_idx = temp; ! 192: temp = pkt->pk_saddr.ch_addr; ! 193: pkt->pk_saddr = pkt->pk_daddr; ! 194: pkt->pk_daddr.ch_addr = temp; ! 195: sendctl(pkt); ! 196: } ! 197: ! 198: /* ! 199: * Indicate that actual transmission of the current packet has been completed. ! 200: * Note that this merely means that we've sent it on to the routing line ! 201: * discipline, and there's no guarantee that it's really gone anywhere. ! 202: * ! 203: * If this is a controlled packet and the connection is open, put the packet ! 204: * on the queue of transmitted packets awaiting acknowledgements, otherwise ! 205: * throw away the packet. ! 206: */ ! 207: xmitdone(pkt) ! 208: register struct packet *pkt; ! 209: { ! 210: register struct connection *conn; ! 211: register struct packet *npkt; ! 212: ! 213: ch_busy++; ! 214: if (CONTROLLED(pkt) && pkt->pk_sidx.ci_tidx < NCH && ! 215: (conn = Chconn[pkt->pk_sidx.ci_tidx]) != NOCONN && ! 216: pkt->pk_sidx.ci_idx == conn->cn_lidx.ci_idx && ! 217: (conn->cn_state == CSOPEN || conn->cn_state == CSRFCSENT) && ! 218: cmp_gt(pkt->pk_pkn, conn->cn_trecvd)) { ! 219: pkt->time = Chclock; ! 220: if ((npkt = conn->cn_thead) == NOPKT || ! 221: cmp_lt(pkt->pk_pkn, npkt->pk_pkn)) { ! 222: pkt->next = npkt; ! 223: conn->cn_thead = pkt; ! 224: } else { ! 225: for(; npkt->next != NOPKT; npkt = npkt->next) ! 226: if(cmp_lt(pkt->pk_pkn, npkt->next->pk_pkn)) ! 227: break; ! 228: pkt->next = npkt->next; ! 229: npkt->next = pkt; ! 230: } ! 231: if(pkt->next == NOPKT) ! 232: conn->cn_ttail = pkt; ! 233: } else ! 234: free_packet(pkt); ! 235: --ch_busy; ! 236: } ! 237: ! 238: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.