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