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