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