kpacket_parse endiness bugfix
[cor_2_6_31.git] / net / cor / kpacket_parse.c
blobf27e331f3e8d9e559b52f3e7765046c0ac15f800
1 /*
2 * Connection oriented routing
3 * Copyright (C) 2007-2008 Michael Blizek
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA.
21 #include <asm/byteorder.h>
23 #include "cor.h"
25 /* not used, avoid compiler warning
26 * static __u64 pull_u64(struct sk_buff *skb, int convbo)
28 char *ptr = cor_pull_skb(skb, 8);
30 __u64 ret = 0;
32 BUG_ON(0 == ptr);
34 ((char *)&ret)[0] = ptr[0];
35 ((char *)&ret)[1] = ptr[1];
36 ((char *)&ret)[2] = ptr[2];
37 ((char *)&ret)[3] = ptr[3];
38 ((char *)&ret)[4] = ptr[4];
39 ((char *)&ret)[5] = ptr[5];
40 ((char *)&ret)[6] = ptr[6];
41 ((char *)&ret)[7] = ptr[7];
43 if (convbo)
44 return be64_to_cpu(ret);
45 return ret;
46 } */
48 static __u32 pull_u32(struct sk_buff *skb, int convbo)
50 char *ptr = cor_pull_skb(skb, 4);
52 __u32 ret = 0;
54 BUG_ON(0 == ptr);
56 ((char *)&ret)[0] = ptr[0];
57 ((char *)&ret)[1] = ptr[1];
58 ((char *)&ret)[2] = ptr[2];
59 ((char *)&ret)[3] = ptr[3];
61 if (convbo)
62 return be32_to_cpu(ret);
63 return ret;
66 /* not used, avoid compiler warning
67 static __u16 pull_u16(struct sk_buff *skb, int convbo)
69 char *ptr = cor_pull_skb(skb, 2);
71 __u16 ret = 0;
73 BUG_ON(0 == ptr);
75 ((char *)&ret)[0] = ptr[0];
76 ((char *)&ret)[1] = ptr[1];
78 if (convbo)
79 return be16_to_cpu(ret);
80 return ret;
81 } */
83 /* static __u8 pull_u8(struct sk_buff *skb)
85 char *ptr = cor_pull_skb(skb, 1);
86 BUG_ON(0 == ptr);
87 return *ptr;
88 } */
90 #warning todo
91 static void parse_speed(struct neighbor *nb, struct sk_buff *skb,
92 __u8 code, struct conn *rconn)
94 __u16 speed = pull_u32(skb, 1);
97 static void parse_conn_success(struct neighbor *nb, struct sk_buff *skb,
98 __u8 code, struct conn *rconn)
100 struct conn *sconn = rconn->reversedir;
102 BUG_ON(sconn == 0);
104 if (unlikely(unlikely(TARGET_OUT != sconn->targettype) ||
105 unlikely(nb != sconn->target.out.nb) ||
106 unlikely(rconn->target.out.conn_id != 0))) {
107 int conn_id = pull_u32(skb, 1);
108 struct control_msg_out *cm = alloc_control_msg();
109 if (likely(cm != 0))
110 send_reset_conn(cm, nb, conn_id);
111 return;
114 mutex_lock(&(sconn->rcv_lock));
115 sconn->target.out.conn_id = pull_u32(skb, 1);
116 flush_out(sconn);
117 mutex_unlock(&(sconn->rcv_lock));
120 static void parse_reset(struct neighbor *nb, struct sk_buff *skb,
121 __u8 code, struct conn *rconn)
123 rconn->isreset = 1;
124 reset_conn(rconn);
127 static void conn_cmd(struct neighbor *nb, struct sk_buff *skb, __u8 code,
128 void (*parsefunc)(struct neighbor *nb, struct sk_buff *skb,
129 __u8 code, struct conn *rconn))
131 __u32 conn_id = pull_u32(skb, 1);
132 struct conn *rconn = get_conn(conn_id);
134 if (unlikely(rconn == 0))
135 return;
137 BUG_ON(SOURCE_IN != rconn->sourcetype);
138 BUG_ON(0 == rconn->reversedir);
140 if (unlikely(rconn->source.in.nb != nb))
141 return;
143 parsefunc(nb, skb, code, rconn);
146 static void parse_conndata(struct neighbor *nb, struct sk_buff *skb)
148 __u32 conn_id = pull_u32(skb, 1);
149 __u32 seqno = pull_u32(skb, 1);
150 __u32 datalength = pull_u32(skb, 1);
151 char *data = cor_pull_skb(skb, datalength);
153 BUG_ON(data == 0);
155 conn_rcv_buildskb(data, datalength, conn_id, seqno);
158 static void parse_connect(struct neighbor *nb, struct sk_buff *skb)
160 struct conn *rconn;
161 printk(KERN_ERR "pc 1");
162 __u32 conn_id = pull_u32(skb, 1);
163 struct control_msg_out *cm = alloc_control_msg();
165 if (unlikely(cm == 0))
166 return;
168 printk(KERN_ERR "pc 2");
169 rconn = alloc_conn(GFP_KERNEL);
170 printk(KERN_ERR "pc 3");
172 if (unlikely(rconn == 0))
173 goto err;
175 if (conn_init_out(rconn->reversedir, nb)) {
176 goto err;
178 printk(KERN_ERR "pc 4");
179 rconn->reversedir->target.out.conn_id = conn_id;
181 send_connect_success(cm, nb, rconn->reversedir->target.out.conn_id,
182 rconn->source.in.conn_id);
183 printk(KERN_ERR "pc 5");
185 if (0) {
186 err:
187 printk(KERN_ERR "pc 6");
188 send_reset_conn(cm, nb, conn_id);
192 static void kernel_packet2(struct neighbor *nb, struct sk_buff *skb,
193 __u32 seqno)
195 struct control_msg_out *cm = alloc_control_msg();
196 int ack = 0;
198 if (unlikely(cm == 0))
199 return;
201 while (1) {
202 __u32 conn_id;
203 __u32 seqno;
205 __u8 *codeptr = cor_pull_skb(skb, 1);
206 __u8 code;
208 if (codeptr == 0)
209 break;
211 code = *codeptr;
213 printk(KERN_ERR "parse2_1 %d", code);
215 switch (code) {
216 case KP_PADDING:
217 break;
218 case KP_ACK:
219 conn_id = pull_u32(skb, 1);
220 seqno = pull_u32(skb, 1);
221 ack_received(nb, conn_id, seqno);
222 if (conn_id != 0)
223 ack = 1;
224 break;
225 case KP_SPEED:
226 conn_cmd(nb, skb, code, parse_speed);
227 ack = 1;
228 break;
229 case KP_CONNECT:
230 parse_connect(nb, skb);
231 ack = 1;
232 break;
233 case KP_CONNECT_SUCCESS:
234 conn_cmd(nb, skb, code, parse_conn_success);
235 ack = 1;
236 break;
237 case KP_CONN_DATA:
238 parse_conndata(nb, skb);
239 ack = 1;
240 break;
241 case KP_RESET_CONN:
242 conn_cmd(nb, skb, code, parse_reset);
243 ack = 1;
244 break;
245 default:
246 BUG();
250 if (ack)
251 send_ack(cm, nb, 0, seqno);
252 else
253 free_control_msg(cm);
256 void kernel_packet(struct neighbor *nb, struct sk_buff *skb, __u32 seqno)
258 struct sk_buff *skb2 = skb_clone(skb, __GFP_DMA | GFP_KERNEL);
260 while (1) {
261 __u8 *codeptr = cor_pull_skb(skb2, 1);
262 __u8 code;
264 char *lengthptr;
265 __u32 length;
267 if (codeptr == 0)
268 break;
269 code = *codeptr;
271 switch (code) {
272 case KP_PADDING:
273 break;
274 case KP_ACK:
275 if (cor_pull_skb(skb2, 8) == 0)
276 goto discard;
277 break;
278 case KP_SPEED:
279 if (cor_pull_skb(skb2, 6) == 0)
280 goto discard;
281 break;
282 case KP_CONNECT:
283 if (cor_pull_skb(skb2, 4) == 0)
284 goto discard;
285 break;
286 case KP_CONNECT_SUCCESS:
287 if (cor_pull_skb(skb2, 8) == 0)
288 goto discard;
289 break;
290 case KP_CONN_DATA:
291 if (cor_pull_skb(skb2, 8) == 0)
292 goto discard;
293 lengthptr = cor_pull_skb(skb2, 4);
294 if (lengthptr == 0)
295 goto discard;
296 length = ntohl(*((__u32 *)lengthptr));
297 if (cor_pull_skb(skb, length) == 0)
298 goto discard;
299 break;
300 case KP_RESET_CONN:
301 if (cor_pull_skb(skb2, 4) == 0)
302 goto discard;
303 break;
304 default:
305 goto discard;
308 kfree_skb(skb2);
309 kernel_packet2(nb, skb, seqno);
310 kfree_skb(skb);
311 return;
312 discard:
313 kfree_skb(skb2);
314 kfree_skb(skb);