http://gimel.esc.cam.ac.uk/james/rpld/src/rpld-1.6.tar.gz
[rpld.git] / protocol.c
1 /*************************************************
2 *     rpld - an IBM style RIPL server            *
3 *************************************************/
4
5 /* Copyright (c) 1999,2000, James McKenzie.
6  *                      All rights reserved
7  * Copyright (c) 1998,2000, Christopher Lightfoot.
8  *                      All rights reserved
9  *
10  * By using this file, you agree to the terms and conditions set
11  * forth in the LICENCE file which can be found at the top level of
12  * the rpld distribution.
13  *
14  * IBM is a trademark of IBM corp.
15  *
16  */
17
18
19 static char rcsid[] =
20   "$Id: protocol.c,v 1.20 2000/07/29 23:25:58 root Exp root $";
21
22 /*
23  * $Log: protocol.c,v $
24  * Revision 1.20  2000/07/29 23:25:58  root
25  * #
26  *
27  * Revision 1.19  2000/07/29 23:25:25  root
28  * #
29  *
30  * Revision 1.18  2000/07/29 23:20:02  root
31  * #
32  *
33  * Revision 1.17  2000/07/23 19:07:49  root
34  * #
35  *
36  * Revision 1.16  2000/07/17 11:59:45  root
37  * #
38  *
39  * Revision 1.15  2000/07/17 10:49:20  root
40  * #
41  *
42  * Revision 1.14  2000/07/17 10:45:38  root
43  * #
44  *
45  * Revision 1.13  2000/07/17 10:43:54  root
46  * #
47  *
48  * Revision 1.12  2000/07/17 10:43:34  root
49  * #
50  *
51  * Revision 1.11  2000/07/16 14:05:28  root
52  * #
53  *
54  * Revision 1.10  2000/07/16 13:18:10  root
55  * #
56  *
57  * Revision 1.1  2000/07/16 13:16:33  root
58  * #
59  *
60  * Revision 1.9  1999/09/13 11:17:35  root
61  * \#
62  *
63  * Revision 1.8  1999/09/13 11:08:34  root
64  * \#
65  *
66  * Revision 1.7  1999/09/13 11:05:27  root
67  * \#
68  *
69  * Revision 1.6  1999/09/13 11:04:13  root
70  * \#
71  *
72  */
73
74 #include "project.h"
75
76 /* Process the find frame and xmit a found frame */
77 void
78 find_frame (struct nit *n, struct rpl_packet *in)
79 {
80   struct client *c;
81   struct rpl_packet out;
82
83   c = find_client_by_mac (in->mymac);
84
85   if (!c)
86     {
87       syslog (LOG_ERR, "unknown client %s", ethtoa (in->mymac));
88       return;
89     }
90
91   c->blocknum = 0;
92
93   out.type = RPL_PK_FOUND;
94
95   out.flags =
96     RPL_FL_TMZ | RPL_FL_TSZ | RPL_FL_YOUMAC | RPL_FL_MYMAC | RPL_FL_FRAMELEN |
97     RPL_FL_WHOAMI | RPL_FL_SAP;
98
99   out.themightyzero = in->themightyzero;
100   out.thesmallzero = 0;
101   out.whoami = 0;
102
103   if (in->framelen < c->framelen)
104     {
105       c->framelen = in->framelen;
106     }
107
108   if ((c->blocklen + LLC_RPL_OVERHEAD) > c->framelen)
109     {
110       c->blocklen = c->framelen - LLC_RPL_OVERHEAD;
111       c->blocklen &= ~0x7;
112     }
113
114   c->framelen = out.framelen =
115     (in->framelen > c->framelen) ? c->framelen : in->framelen;
116   out.sap = RPL_SAP;
117
118   bcopy (in->mymac, out.youmac, ETH_ALEN);
119   bcopy (nit_mac (n), out.mymac, ETH_ALEN);
120
121   c->state = ST_FIND;
122
123   rpl_send_packet (n, c->mac, &out);
124
125   c->state = ST_FOUND;
126
127 }
128
129
130 file_data_frame (struct nit *n, struct client *c)
131 {
132   struct rpl_packet out;
133   int i;
134
135   u32 addr = 0x10000;
136
137   if (c->state != ST_FILEDATA)
138     return;
139
140   out.flags = RPL_FL_BLOCK | RPL_FL_ADDR | RPL_FL_DATA;
141   out.type = RPL_PK_FILEDATA;
142
143   out.block = c->blocknum;
144
145   client_get_block (c, &out);
146
147   out.addr.run = c->run_addr;
148
149 #ifdef DEBUG
150   printf ("block %5d, %4d bytes to 0x%08x\n", c->blocknum,
151           out.datalen, out.addr.load);
152 #endif
153
154   if (client_last_block (c))
155     {
156       out.addr.flags = RPL_AD_FLAGS_DONE;
157       c->state = ST_DONE;
158 #ifdef DEBUG
159       printf ("Last block - transfering control to 0x%08x\n", c->run_addr);
160 #endif
161       clients_check_status ();
162     }
163   else
164     {
165       if (c->nospew)
166         out.addr.flags = RPL_AD_FLAGS_ASK_MORE;
167       else
168         out.addr.flags = RPL_AD_FLAGS_MORE;
169     }
170
171
172
173   rpl_send_packet (n, c->mac, &out);
174   c->blocknum++;
175
176   return (i);
177 }
178
179 void
180 send_file_frame (struct nit *n, struct rpl_packet *in)
181 {
182   struct client *c;
183   struct rpl_packet out;
184
185   c = find_client_by_mac (in->mymac);
186
187   if (!c)
188     {
189       printf ("Unknown client\n");
190       return;
191     }
192
193   c->state = ST_SENDFILE;
194
195   c->blocknum = in->block;
196   c->framelen = in->framelen;
197
198   syslog (LOG_ERR, "client %s requested block %d", ethtoa (c->mac),
199           c->blocknum);
200
201   client_calc_offsets (c);
202
203   c->state = ST_FILEDATA;
204
205   clients_check_status ();      /* This will upgrade our condition to downloading */
206
207
208   if (c->nospew)
209     file_data_frame (n, c);
210
211
212 }
213
214 /* rpl.c call this after it's interpreted a packet from the nic */
215 void
216 rpl_packet_recvd_callback (struct nit *n, struct rpl_packet *p)
217 {
218   switch (p->type)
219     {
220     case RPL_PK_FIND:
221
222       if ((p->flags & RPL_FIND_FLAGS) == RPL_FIND_FLAGS)
223         {
224           find_frame (n, p);
225         }
226       else
227         {
228           syslog (LOG_ERR, "Incomplete FIND frame 0x%x vs 0x%x\n",
229                   p->flags, RPL_FIND_FLAGS);
230         }
231     case RPL_PK_FOUND:         /*We're not a client */
232       break;
233     case RPL_PK_SENDFILE:
234       if ((p->flags & RPL_SEND_FILE_FLAGS) == RPL_SEND_FILE_FLAGS)
235         {
236           send_file_frame (n, p);
237         }
238       else
239         {
240           syslog (LOG_ERR,
241                   "Incomplete SEND.FILE.REQUEST frame 0x%x vs 0x%x\n",
242                   p->flags, RPL_SEND_FILE_FLAGS);
243         }
244       break;
245     case RPL_PK_FILEDATA:      /*We're not a client */
246       break;
247     default:
248       syslog (LOG_ERR, "Unknown RPL packet type 0x%04x\n", p->type);
249
250     }
251
252 }