OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [sw/] [boot-loader-ethmac/] [packet.c] - Blame information for rev 80

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 61 csantifort
/*----------------------------------------------------------------
2
//                                                              //
3
//  boot-loader-ethmac.c                                        //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  The main functions for the boot loader application. This    //
10 80 csantifort
//  application is embedded in the FPGA's SRAM and is used      //
11 61 csantifort
//  to load larger applications into the DDR3 memory on         //
12
//  the development board.                                      //
13
//                                                              //
14
//  Author(s):                                                  //
15
//      - Conor Santifort, csantifort.amber@gmail.com           //
16
//                                                              //
17
//////////////////////////////////////////////////////////////////
18
//                                                              //
19
// Copyright (C) 2011 Authors and OPENCORES.ORG                 //
20
//                                                              //
21
// This source file may be used and distributed without         //
22
// restriction provided that this copyright statement is not    //
23
// removed from the file and that any derivative work contains  //
24
// the original copyright notice and the associated disclaimer. //
25
//                                                              //
26
// This source file is free software; you can redistribute it   //
27
// and/or modify it under the terms of the GNU Lesser General   //
28
// Public License as published by the Free Software Foundation; //
29
// either version 2.1 of the License, or (at your option) any   //
30
// later version.                                               //
31
//                                                              //
32
// This source is distributed in the hope that it will be       //
33
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
34
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
35
// PURPOSE.  See the GNU Lesser General Public License for more //
36
// details.                                                     //
37
//                                                              //
38
// You should have received a copy of the GNU Lesser General    //
39
// Public License along with this source; if not, download it   //
40
// from http://www.opencores.org/lgpl.shtml                     //
41
//                                                              //
42
----------------------------------------------------------------*/
43
 
44
 
45
#include "amber_registers.h"
46
#include "address_map.h"
47
#include "line-buffer.h"
48
#include "timer.h"
49
#include "utilities.h"
50
#include "packet.h"
51
#include "tcp.h"
52
 
53
 
54
/* Global variables */
55
mac_ip_t self_g = { {0x00, 0x0e, 0x70, 0x70, 0x70, 0x70},  /* MAC Address  */
56
                    {192, 168, 0, 17}                      /* IPv4 address */
57
                  };
58
 
59
packet_t*   rx_packet_g;
60
 
61
 
62 80 csantifort
void init_packet()
63 61 csantifort
{
64 80 csantifort
    /* receive packet buffer */
65
    rx_packet_g = malloc(sizeof(packet_t));
66 61 csantifort
}
67
 
68
 
69
 
70
void ethernet_header(char *buf, mac_ip_t* target, unsigned short type)
71
{
72
    /* ethernet header */
73
    /* DA */
74
    buf[ 0] = target->mac[0];
75
    buf[ 1] = target->mac[1];
76
    buf[ 2] = target->mac[2];
77
    buf[ 3] = target->mac[3];
78
    buf[ 4] = target->mac[4];
79
    buf[ 5] = target->mac[5];
80 80 csantifort
 
81 61 csantifort
    /* SA */
82
    buf[ 6] = self_g.mac[0];
83
    buf[ 7] = self_g.mac[1];
84
    buf[ 8] = self_g.mac[2];
85
    buf[ 9] = self_g.mac[3];
86
    buf[10] = self_g.mac[4];
87
    buf[11] = self_g.mac[5];
88 80 csantifort
 
89 61 csantifort
    /* type */
90
    buf[12] = type>>8;
91
    buf[13] = type&0xff;
92
}
93
 
94
 
95
void ip_header(char *buf, mac_ip_t* target, unsigned short ip_len, char ip_proto)
96
{
97
    unsigned short header_checksum;
98
    static unsigned short ip_id = 0;
99
 
100
    /* Version, Header length */
101 80 csantifort
    buf[0] = 0x45;
102
 
103 61 csantifort
    /* dscp */
104
    buf[1] = 0;
105 80 csantifort
 
106 61 csantifort
    /* ip len */
107 80 csantifort
    buf[2] = ip_len>>8;
108 61 csantifort
    buf[3] = ip_len&0xff;
109 80 csantifort
 
110 61 csantifort
    /* ID */
111
    buf[4] = (ip_id>>8)&0xff;
112 80 csantifort
    buf[5] = ip_id&0xff;
113 61 csantifort
    //ip_id++;
114 80 csantifort
 
115 61 csantifort
    /* Fragment */
116
    buf[6] = 0;
117
    buf[7] = 0;
118 80 csantifort
 
119 61 csantifort
    /* ttl */
120
    buf[8] = 64;
121 80 csantifort
 
122 61 csantifort
    /* Protocol */
123
    buf[9] = ip_proto;
124 80 csantifort
 
125 61 csantifort
    /* header checksum */
126
    buf[10] = 0;
127
    buf[11] = 0;
128 80 csantifort
 
129 61 csantifort
    /* Source IP */
130
    buf[12] = self_g.ip[0];
131
    buf[13] = self_g.ip[1];
132
    buf[14] = self_g.ip[2];
133
    buf[15] = self_g.ip[3];
134 80 csantifort
 
135 61 csantifort
    /* Destination IP */
136
    buf[16] = target->ip[0];
137
    buf[17] = target->ip[1];
138
    buf[18] = target->ip[2];
139
    buf[19] = target->ip[3];
140 80 csantifort
 
141 61 csantifort
    /* header checksum */
142
    header_checksum = header_checksum16(buf, 20, 0);
143
    buf[10] = (header_checksum>>8)&0xff;
144
    buf[11] = header_checksum&0xff;
145
}
146
 
147
 
148
void arp_reply(char *buf, mac_ip_t* arp_sender)
149
{
150
 
151
    ethernet_header(buf, arp_sender, 0x0806);
152 80 csantifort
 
153 61 csantifort
    /* Hardware Type */
154
    buf[14] = 0x00;
155
    buf[15] = 0x01;
156
    /* Protocol Type */
157
    buf[16] = 0x08;
158
    buf[17] = 0x00;
159
    /* HLEN */
160
    buf[18] = 0x06;
161
    /* PLEN */
162
    buf[19] = 0x04;
163 80 csantifort
 
164 61 csantifort
    /* Operation = Reply */
165
    buf[20] = 0x00;
166
    buf[21] = 0x02;
167 80 csantifort
 
168 61 csantifort
    /* Sender MAC */
169
    buf[22] = self_g.mac[0];
170
    buf[23] = self_g.mac[1];
171
    buf[24] = self_g.mac[2];
172
    buf[25] = self_g.mac[3];
173
    buf[26] = self_g.mac[4];
174
    buf[27] = self_g.mac[5];
175 80 csantifort
 
176 61 csantifort
    /* Sender IP */
177
    buf[28] = self_g.ip[0];
178
    buf[29] = self_g.ip[1];
179
    buf[30] = self_g.ip[2];
180
    buf[31] = self_g.ip[3];
181 80 csantifort
 
182 61 csantifort
    /* Target MAC */
183
    buf[32] = arp_sender->mac[0];
184
    buf[33] = arp_sender->mac[1];
185
    buf[34] = arp_sender->mac[2];
186
    buf[35] = arp_sender->mac[3];
187
    buf[36] = arp_sender->mac[4];
188
    buf[37] = arp_sender->mac[5];
189 80 csantifort
 
190 61 csantifort
    /* Target IP */
191
    buf[38] = arp_sender->ip[0];
192
    buf[39] = arp_sender->ip[1];
193
    buf[40] = arp_sender->ip[2];
194
    buf[41] = arp_sender->ip[3];
195
    tx_packet(42);
196
}
197
 
198
 
199
void ping_reply(packet_t* rx_packet, int ping_id, int ping_seq, char * rxbuf)
200
{
201
 
202
    int i;
203
    unsigned short header_checksum;
204
    mac_ip_t target;
205
    char * buf = (char*)ETHMAC_TX_BUFFER;
206 80 csantifort
 
207 61 csantifort
    target.mac[0] = rx_packet->src_mac[0];
208
    target.mac[1] = rx_packet->src_mac[1];
209
    target.mac[2] = rx_packet->src_mac[2];
210
    target.mac[3] = rx_packet->src_mac[3];
211
    target.mac[4] = rx_packet->src_mac[4];
212
    target.mac[5] = rx_packet->src_mac[5];
213 80 csantifort
 
214 61 csantifort
    target.ip[0]  = rx_packet->src_ip[0];
215
    target.ip[1]  = rx_packet->src_ip[1];
216
    target.ip[2]  = rx_packet->src_ip[2];
217
    target.ip[3]  = rx_packet->src_ip[3];
218
 
219
    ethernet_header(buf, &target, 0x0800);  /*bytes 0 to 13*/
220
    ip_header(&buf[14], &target, rx_packet->ip_len, 1); /* bytes 14 to 33, ip_proto = 1, ICMP*/
221 80 csantifort
 
222 61 csantifort
    /* ICMP */
223
    /* Type = reply */
224
    buf[34] = 0;
225 80 csantifort
 
226 61 csantifort
    /* Code = 0 */
227
    buf[35] = 0;
228 80 csantifort
 
229 61 csantifort
    /* checksum */
230
    buf[36] = 0;
231
    buf[37] = 0;
232 80 csantifort
 
233 61 csantifort
    /* ID */
234
    buf[38] = ping_id>>8;
235
    buf[39] = ping_id&0xff;
236 80 csantifort
 
237 61 csantifort
    /* SEQ */
238
    buf[40] = ping_seq>>8;
239
    buf[41] = ping_seq&0xff;
240
 
241
    for (i=8; i< rx_packet->ip_len - rx_packet->ip_header_len*4; i++) {
242
        buf[34+i] = rxbuf[i];
243
        }
244
 
245
    header_checksum = header_checksum16(&buf[34], (rx_packet->ip_len)-20, 0);
246
    buf[36] = (header_checksum>>8)&0xff;
247
    buf[37] = header_checksum&0xff;
248
    tx_packet(rx_packet->ip_len+14);
249
}
250
 
251
 
252
void parse_rx_packet(char * buf, packet_t* rx_packet)
253
{
254
    int i;
255 80 csantifort
 
256 61 csantifort
    rx_packet->dst_mac[0] = buf[0];
257
    rx_packet->dst_mac[1] = buf[1];
258
    rx_packet->dst_mac[1] = buf[2];
259
    rx_packet->dst_mac[3] = buf[3];
260
    rx_packet->dst_mac[4] = buf[4];
261
    rx_packet->dst_mac[5] = buf[5];
262
 
263
    rx_packet->src_mac[0] = buf[6];
264
    rx_packet->src_mac[1] = buf[7];
265
    rx_packet->src_mac[2] = buf[8];
266
    rx_packet->src_mac[3] = buf[9];
267
    rx_packet->src_mac[4] = buf[10];
268 80 csantifort
    rx_packet->src_mac[5] = buf[11];
269 61 csantifort
    rx_packet->eth_type   = (buf[12]<<8) + buf[13];
270 80 csantifort
 
271
 
272 61 csantifort
    /* ARP */
273
    if (rx_packet->eth_type == 0x0806) {
274
        parse_arp_packet(&buf[14]);
275
        }
276
 
277
 
278
    /* Internet Protocol  */
279
    else if (rx_packet->eth_type == 0x0800){
280
        parse_ip_packet(&buf[14], rx_packet);
281
        }
282
}
283
 
284
 
285
void parse_arp_packet(char * buf)
286
{
287
    /* ARP is a broadcast message (mac broadcast address)
288
      asking 'does this IP address belong to you?"
289
    */
290
    int arp_op;
291
    mac_ip_t arp_sender, arp_target;
292 80 csantifort
 
293 61 csantifort
    arp_op = buf[6]<<8 | buf[7];
294
 
295
    arp_sender.mac[0] = buf[8];
296
    arp_sender.mac[1] = buf[9];
297
    arp_sender.mac[2] = buf[10];
298
    arp_sender.mac[3] = buf[11];
299
    arp_sender.mac[4] = buf[12];
300
    arp_sender.mac[5] = buf[13];
301 80 csantifort
 
302 61 csantifort
    arp_sender.ip [0] = buf[14];
303
    arp_sender.ip [1] = buf[15];
304
    arp_sender.ip [2] = buf[16];
305
    arp_sender.ip [3] = buf[17];
306 80 csantifort
 
307 61 csantifort
    arp_target.mac[0] = buf[18];
308
    arp_target.mac[1] = buf[19];
309
    arp_target.mac[2] = buf[20];
310
    arp_target.mac[3] = buf[21];
311
    arp_target.mac[4] = buf[22];
312
    arp_target.mac[5] = buf[23];
313 80 csantifort
 
314 61 csantifort
    arp_target.ip [0] = buf[24];
315
    arp_target.ip [1] = buf[25];
316
    arp_target.ip [2] = buf[26];
317
    arp_target.ip [3] = buf[27];
318 80 csantifort
 
319 61 csantifort
    /* Send a reply ? */
320 80 csantifort
    if (arp_op==1 &&
321
        arp_target.ip[0]==self_g.ip[0] &&
322
        arp_target.ip[1]==self_g.ip[1] &&
323
        arp_target.ip[2]==self_g.ip[2] &&
324 61 csantifort
        arp_target.ip[3]==self_g.ip[3]) {
325 80 csantifort
 
326 61 csantifort
        // ARP reply
327
        arp_reply((char*)ETHMAC_TX_BUFFER, &arp_sender);
328
        }
329
}
330
 
331
 
332
 
333
void parse_ip_packet(char * buf, packet_t* rx_packet)
334
{
335
    unsigned int ip_version;
336 80 csantifort
 
337 61 csantifort
    ip_version = buf[0]>>4;
338
    if (ip_version != 4) {
339
        //printf("%s: IP version %d not supported\n", __func__, ip_version);
340
        return;
341
        }
342 80 csantifort
 
343 61 csantifort
    /* Get destination IP address */
344
    rx_packet->dst_ip[0] = buf[16];
345
    rx_packet->dst_ip[1] = buf[17];
346
    rx_packet->dst_ip[2] = buf[18];
347
    rx_packet->dst_ip[3] = buf[19];
348
 
349
    /* If its not my address then ignore the packet */
350 80 csantifort
    if (rx_packet->dst_ip[0] != self_g.ip[0] ||
351
        rx_packet->dst_ip[1] != self_g.ip[1] ||
352
        rx_packet->dst_ip[2] != self_g.ip[2] ||
353 61 csantifort
        rx_packet->dst_ip[3] != self_g.ip[3] ) {
354
        return;
355
        }
356 80 csantifort
 
357 61 csantifort
    rx_packet->ip_len         = buf[ 2]<<8|buf[ 3];
358
    rx_packet->ip_header_len  = buf[0] & 0xf;
359
    rx_packet->ip_proto       = buf[9];
360
    rx_packet->src_ip[0]      = buf[12];
361
    rx_packet->src_ip[1]      = buf[13];
362
    rx_packet->src_ip[2]      = buf[14];
363
    rx_packet->src_ip[3]      = buf[15];
364
 
365 80 csantifort
 
366
    /* Ping packets */
367 61 csantifort
    if (rx_packet->ip_proto == 1){
368
        parse_ping_packet(&buf[(rx_packet->ip_header_len)*4], rx_packet);
369
        }
370 80 csantifort
 
371 61 csantifort
    /* TCP packets */
372
    else if (rx_packet->ip_proto == 6){
373
        parse_tcp_packet(&buf[(rx_packet->ip_header_len)*4], rx_packet);
374
        }
375 80 csantifort
 
376 61 csantifort
    /* UDP packets */
377
    else if (rx_packet->ip_proto == 17){
378
        parse_udp_packet(&buf[(rx_packet->ip_header_len)*4], rx_packet);
379
        }
380
}
381
 
382
 
383
void parse_ping_packet(char * buf, packet_t* rx_packet)
384
{
385
    int ping_id;
386
    int ping_seq;
387
 
388
    ping_id     = buf[4]<<8|buf[5];
389
    ping_seq    = buf[6]<<8|buf[7];
390 80 csantifort
 
391 61 csantifort
    ping_reply(rx_packet, ping_id, ping_seq, buf);
392
}
393
 
394
 
395
unsigned short header_checksum16(unsigned char *buf, unsigned short len, unsigned int sum)
396
 {
397
     // build the sum of 16bit words
398
     while(len>1) {
399
         sum += 0xFFFF & (*buf<<8|*(buf+1));
400
         buf+=2;
401
         len-=2;
402
         }
403
     // if there is a byte left then add it (padded with zero)
404
     if (len) {
405
         sum += (0xFF & *buf)<<8;
406
         }
407
     // now calculate the sum over the bytes in the sum
408
     // until the result is only 16bit long
409
     while (sum>>16) {
410
         sum = (sum & 0xFFFF)+(sum >> 16);
411
         }
412 80 csantifort
 
413 61 csantifort
     // build 1's complement:
414
     return( (unsigned short ) sum ^ 0xFFFF);
415
}
416
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.