|
|
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.