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

Subversion Repositories amber

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

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
//  application is embedded in the FPGA's SRAM and is used      //
11
//  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
 
60
packet_t*   rx_packet_g;
61
socket_t*   socket0_g;
62
socket_t*   socket1_g;
63
 
64
 
65
 
66
socket_t* init_socket(int socket_id)
67
{
68
    socket_t* socket;
69
 
70
    socket = (socket_t*) malloc(sizeof(socket_t));
71
    socket->rx_packet =(packet_t*) malloc(sizeof(packet_t));
72
    init_packet_buffers(socket);
73
 
74
    socket->telnet_txbuf = init_line_buffer(0x80000);
75
    socket->telnet_rxbuf = init_line_buffer(0x1000);
76
 
77
    socket->id = socket_id;
78
 
79
    socket->packets_sent = 0;
80
    socket->packets_received = 0;
81
    socket->packets_resent = 0;
82
 
83
    socket->telnet_sent_opening_message = 0;
84
    socket->telnet_echo_mode = 0;
85
    socket->telnet_connection_state = TELNET_CLOSED;
86
    socket->telnet_options_sent = 0;
87
 
88
    socket->tcp_current_buf = 0;
89
    socket->tcp_reset = 0;
90
    socket->tcp_connection_state = TCP_CLOSED;
91
    socket->tcp_disconnect = 0;
92
    socket->tcp_seq = 0x100;  /* should be random initial seq number for tcp */
93
    socket->tcp_last_seq = socket->tcp_seq;
94
    socket->tcp_last_ack = 0;
95
 
96
    return socket;
97
}
98
 
99
 
100
void init_packet_buffers (socket_t* socket)
101
{
102
    int i;
103
 
104
    /* Create space for an array of pointers */
105
    socket->tcp_buf = malloc (TCP_TX_BUFFERS * sizeof (void *));
106
 
107
    /* Create space for a set of buffers, each pointed to by an element of the array */
108
    for (i=0;i<TCP_TX_BUFFERS;i=i+1) {
109
        socket->tcp_buf[i] = (packet_buffer_t*) malloc (sizeof (packet_buffer_t));
110
        socket->tcp_buf[i]->payload_valid = 0;
111
        socket->tcp_buf[i]->starting_seq = 0;
112
        socket->tcp_buf[i]->ending_seq   = 0;
113
        socket->tcp_buf[i]->len_bytes    = 0;
114
        socket->tcp_buf[i]->ack_received = 0;
115
        }
116
}
117
 
118
 
119
void ethernet_header(char *buf, mac_ip_t* target, unsigned short type)
120
{
121
    /* ethernet header */
122
    /* DA */
123
    buf[ 0] = target->mac[0];
124
    buf[ 1] = target->mac[1];
125
    buf[ 2] = target->mac[2];
126
    buf[ 3] = target->mac[3];
127
    buf[ 4] = target->mac[4];
128
    buf[ 5] = target->mac[5];
129
 
130
    /* SA */
131
    buf[ 6] = self_g.mac[0];
132
    buf[ 7] = self_g.mac[1];
133
    buf[ 8] = self_g.mac[2];
134
    buf[ 9] = self_g.mac[3];
135
    buf[10] = self_g.mac[4];
136
    buf[11] = self_g.mac[5];
137
 
138
    /* type */
139
    buf[12] = type>>8;
140
    buf[13] = type&0xff;
141
}
142
 
143
 
144
void ip_header(char *buf, mac_ip_t* target, unsigned short ip_len, char ip_proto)
145
{
146
    unsigned short header_checksum;
147
    static unsigned short ip_id = 0;
148
 
149
    /* Version, Header length */
150
    buf[0] = 0x45;
151
 
152
    /* dscp */
153
    buf[1] = 0;
154
 
155
    /* ip len */
156
    buf[2] = ip_len>>8;
157
    buf[3] = ip_len&0xff;
158
 
159
    /* ID */
160
    buf[4] = (ip_id>>8)&0xff;
161
    buf[5] = ip_id&0xff;
162
    //ip_id++;
163
 
164
    /* Fragment */
165
    buf[6] = 0;
166
    buf[7] = 0;
167
 
168
    /* ttl */
169
    buf[8] = 64;
170
 
171
    /* Protocol */
172
    buf[9] = ip_proto;
173
 
174
    /* header checksum */
175
    buf[10] = 0;
176
    buf[11] = 0;
177
 
178
    /* Source IP */
179
    buf[12] = self_g.ip[0];
180
    buf[13] = self_g.ip[1];
181
    buf[14] = self_g.ip[2];
182
    buf[15] = self_g.ip[3];
183
 
184
    /* Destination IP */
185
    buf[16] = target->ip[0];
186
    buf[17] = target->ip[1];
187
    buf[18] = target->ip[2];
188
    buf[19] = target->ip[3];
189
 
190
    /* header checksum */
191
    header_checksum = header_checksum16(buf, 20, 0);
192
    buf[10] = (header_checksum>>8)&0xff;
193
    buf[11] = header_checksum&0xff;
194
}
195
 
196
 
197
void arp_reply(char *buf, mac_ip_t* arp_sender)
198
{
199
 
200
    ethernet_header(buf, arp_sender, 0x0806);
201
 
202
    /* Hardware Type */
203
    buf[14] = 0x00;
204
    buf[15] = 0x01;
205
    /* Protocol Type */
206
    buf[16] = 0x08;
207
    buf[17] = 0x00;
208
    /* HLEN */
209
    buf[18] = 0x06;
210
    /* PLEN */
211
    buf[19] = 0x04;
212
 
213
    /* Operation = Reply */
214
    buf[20] = 0x00;
215
    buf[21] = 0x02;
216
 
217
    /* Sender MAC */
218
    buf[22] = self_g.mac[0];
219
    buf[23] = self_g.mac[1];
220
    buf[24] = self_g.mac[2];
221
    buf[25] = self_g.mac[3];
222
    buf[26] = self_g.mac[4];
223
    buf[27] = self_g.mac[5];
224
 
225
    /* Sender IP */
226
    buf[28] = self_g.ip[0];
227
    buf[29] = self_g.ip[1];
228
    buf[30] = self_g.ip[2];
229
    buf[31] = self_g.ip[3];
230
 
231
    /* Target MAC */
232
    buf[32] = arp_sender->mac[0];
233
    buf[33] = arp_sender->mac[1];
234
    buf[34] = arp_sender->mac[2];
235
    buf[35] = arp_sender->mac[3];
236
    buf[36] = arp_sender->mac[4];
237
    buf[37] = arp_sender->mac[5];
238
 
239
    /* Target IP */
240
    buf[38] = arp_sender->ip[0];
241
    buf[39] = arp_sender->ip[1];
242
    buf[40] = arp_sender->ip[2];
243
    buf[41] = arp_sender->ip[3];
244
    tx_packet(42);
245
}
246
 
247
 
248
void ping_reply(packet_t* rx_packet, int ping_id, int ping_seq, char * rxbuf)
249
{
250
 
251
    int i;
252
    unsigned short header_checksum;
253
    mac_ip_t target;
254
    char * buf = (char*)ETHMAC_TX_BUFFER;
255
 
256
    target.mac[0] = rx_packet->src_mac[0];
257
    target.mac[1] = rx_packet->src_mac[1];
258
    target.mac[2] = rx_packet->src_mac[2];
259
    target.mac[3] = rx_packet->src_mac[3];
260
    target.mac[4] = rx_packet->src_mac[4];
261
    target.mac[5] = rx_packet->src_mac[5];
262
 
263
    target.ip[0]  = rx_packet->src_ip[0];
264
    target.ip[1]  = rx_packet->src_ip[1];
265
    target.ip[2]  = rx_packet->src_ip[2];
266
    target.ip[3]  = rx_packet->src_ip[3];
267
 
268
    ethernet_header(buf, &target, 0x0800);  /*bytes 0 to 13*/
269
    ip_header(&buf[14], &target, rx_packet->ip_len, 1); /* bytes 14 to 33, ip_proto = 1, ICMP*/
270
 
271
    /* ICMP */
272
    /* Type = reply */
273
    buf[34] = 0;
274
 
275
    /* Code = 0 */
276
    buf[35] = 0;
277
 
278
    /* checksum */
279
    buf[36] = 0;
280
    buf[37] = 0;
281
 
282
    /* ID */
283
    buf[38] = ping_id>>8;
284
    buf[39] = ping_id&0xff;
285
 
286
    /* SEQ */
287
    buf[40] = ping_seq>>8;
288
    buf[41] = ping_seq&0xff;
289
 
290
    for (i=8; i< rx_packet->ip_len - rx_packet->ip_header_len*4; i++) {
291
        buf[34+i] = rxbuf[i];
292
        }
293
 
294
    header_checksum = header_checksum16(&buf[34], (rx_packet->ip_len)-20, 0);
295
    buf[36] = (header_checksum>>8)&0xff;
296
    buf[37] = header_checksum&0xff;
297
    tx_packet(rx_packet->ip_len+14);
298
}
299
 
300
 
301
void parse_rx_packet(char * buf, packet_t* rx_packet)
302
{
303
    int i;
304
 
305
    rx_packet->dst_mac[0] = buf[0];
306
    rx_packet->dst_mac[1] = buf[1];
307
    rx_packet->dst_mac[1] = buf[2];
308
    rx_packet->dst_mac[3] = buf[3];
309
    rx_packet->dst_mac[4] = buf[4];
310
    rx_packet->dst_mac[5] = buf[5];
311
 
312
    rx_packet->src_mac[0] = buf[6];
313
    rx_packet->src_mac[1] = buf[7];
314
    rx_packet->src_mac[2] = buf[8];
315
    rx_packet->src_mac[3] = buf[9];
316
    rx_packet->src_mac[4] = buf[10];
317
    rx_packet->src_mac[5] = buf[11];
318
    rx_packet->eth_type   = (buf[12]<<8) + buf[13];
319
 
320
 
321
    /* ARP */
322
    if (rx_packet->eth_type == 0x0806) {
323
        parse_arp_packet(&buf[14]);
324
        }
325
 
326
 
327
    /* Internet Protocol  */
328
    else if (rx_packet->eth_type == 0x0800){
329
        parse_ip_packet(&buf[14], rx_packet);
330
        }
331
}
332
 
333
 
334
void parse_arp_packet(char * buf)
335
{
336
    /* ARP is a broadcast message (mac broadcast address)
337
      asking 'does this IP address belong to you?"
338
    */
339
    int arp_op;
340
    mac_ip_t arp_sender, arp_target;
341
 
342
    arp_op = buf[6]<<8 | buf[7];
343
 
344
    arp_sender.mac[0] = buf[8];
345
    arp_sender.mac[1] = buf[9];
346
    arp_sender.mac[2] = buf[10];
347
    arp_sender.mac[3] = buf[11];
348
    arp_sender.mac[4] = buf[12];
349
    arp_sender.mac[5] = buf[13];
350
 
351
    arp_sender.ip [0] = buf[14];
352
    arp_sender.ip [1] = buf[15];
353
    arp_sender.ip [2] = buf[16];
354
    arp_sender.ip [3] = buf[17];
355
 
356
    arp_target.mac[0] = buf[18];
357
    arp_target.mac[1] = buf[19];
358
    arp_target.mac[2] = buf[20];
359
    arp_target.mac[3] = buf[21];
360
    arp_target.mac[4] = buf[22];
361
    arp_target.mac[5] = buf[23];
362
 
363
    arp_target.ip [0] = buf[24];
364
    arp_target.ip [1] = buf[25];
365
    arp_target.ip [2] = buf[26];
366
    arp_target.ip [3] = buf[27];
367
 
368
    /* Send a reply ? */
369
    if (arp_op==1 &&
370
        arp_target.ip[0]==self_g.ip[0] &&
371
        arp_target.ip[1]==self_g.ip[1] &&
372
        arp_target.ip[2]==self_g.ip[2] &&
373
        arp_target.ip[3]==self_g.ip[3]) {
374
 
375
        // ARP reply
376
        arp_reply((char*)ETHMAC_TX_BUFFER, &arp_sender);
377
        }
378
}
379
 
380
 
381
 
382
void parse_ip_packet(char * buf, packet_t* rx_packet)
383
{
384
    unsigned int ip_version;
385
 
386
    ip_version = buf[0]>>4;
387
    if (ip_version != 4) {
388
        //printf("%s: IP version %d not supported\n", __func__, ip_version);
389
        return;
390
        }
391
 
392
    /* Get destination IP address */
393
    rx_packet->dst_ip[0] = buf[16];
394
    rx_packet->dst_ip[1] = buf[17];
395
    rx_packet->dst_ip[2] = buf[18];
396
    rx_packet->dst_ip[3] = buf[19];
397
 
398
    /* If its not my address then ignore the packet */
399
    if (rx_packet->dst_ip[0] != self_g.ip[0] ||
400
        rx_packet->dst_ip[1] != self_g.ip[1] ||
401
        rx_packet->dst_ip[2] != self_g.ip[2] ||
402
        rx_packet->dst_ip[3] != self_g.ip[3] ) {
403
        return;
404
        }
405
 
406
    rx_packet->ip_len         = buf[ 2]<<8|buf[ 3];
407
    rx_packet->ip_header_len  = buf[0] & 0xf;
408
    rx_packet->ip_proto       = buf[9];
409
    rx_packet->src_ip[0]      = buf[12];
410
    rx_packet->src_ip[1]      = buf[13];
411
    rx_packet->src_ip[2]      = buf[14];
412
    rx_packet->src_ip[3]      = buf[15];
413
 
414
 
415
    /* Ping packets */
416
    if (rx_packet->ip_proto == 1){
417
        parse_ping_packet(&buf[(rx_packet->ip_header_len)*4], rx_packet);
418
        }
419
 
420
    /* TCP packets */
421
    else if (rx_packet->ip_proto == 6){
422
        parse_tcp_packet(&buf[(rx_packet->ip_header_len)*4], rx_packet);
423
        }
424
 
425
    /* UDP packets */
426
    else if (rx_packet->ip_proto == 17){
427
        parse_udp_packet(&buf[(rx_packet->ip_header_len)*4], rx_packet);
428
        }
429
}
430
 
431
 
432
void parse_ping_packet(char * buf, packet_t* rx_packet)
433
{
434
    int ping_id;
435
    int ping_seq;
436
 
437
    ping_id     = buf[4]<<8|buf[5];
438
    ping_seq    = buf[6]<<8|buf[7];
439
 
440
    ping_reply(rx_packet, ping_id, ping_seq, buf);
441
}
442
 
443
 
444
unsigned short header_checksum16(unsigned char *buf, unsigned short len, unsigned int sum)
445
 {
446
     // build the sum of 16bit words
447
     while(len>1) {
448
         sum += 0xFFFF & (*buf<<8|*(buf+1));
449
         buf+=2;
450
         len-=2;
451
         }
452
     // if there is a byte left then add it (padded with zero)
453
     if (len) {
454
         sum += (0xFF & *buf)<<8;
455
         }
456
     // now calculate the sum over the bytes in the sum
457
     // until the result is only 16bit long
458
     while (sum>>16) {
459
         sum = (sum & 0xFFFF)+(sum >> 16);
460
         }
461
 
462
     // build 1's complement:
463
     return( (unsigned short ) sum ^ 0xFFFF);
464
}
465
 

powered by: WebSVN 2.1.0

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