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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [FreeTCPIP/] [uip.c] - Blame information for rev 606

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 606 jeremybenn
//#define DEBUG_PRINTF( ... ) /*printf(__VA_ARGS__)*/
2
 
3
/**
4
 * \addtogroup uip
5
 * @{
6
 */
7
 
8
/**
9
 * \file
10
 * The uIP TCP/IP stack code.
11
 * \author Adam Dunkels <adam@dunkels.com>
12
 */
13
 
14
/*
15
 * Copyright (c) 2001-2003, Adam Dunkels.
16
 * All rights reserved.
17
 *
18
 * Redistribution and use in source and binary forms, with or without
19
 * modification, are permitted provided that the following conditions
20
 * are met:
21
 * 1. Redistributions of source code must retain the above copyright
22
 *      notice, this list of conditions and the following disclaimer.
23
 * 2. Redistributions in binary form must reproduce the above copyright
24
 *      notice, this list of conditions and the following disclaimer in the
25
 *      documentation and/or other materials provided with the distribution.
26
 * 3. The name of the author may not be used to endorse or promote
27
 *      products derived from this software without specific prior
28
 *      written permission.
29
 *
30
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
31
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
34
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
36
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
38
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
39
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41
 *
42
 * This file is part of the uIP TCP/IP stack.
43
 *
44
 * $Id: uip.c 2 2011-07-17 20:13:17Z filepang@gmail.com $
45
 *
46
 */
47
 
48
/*
49
 * uIP is a small implementation of the IP, UDP and TCP protocols (as
50
 * well as some basic ICMP stuff). The implementation couples the IP,
51
 * UDP, TCP and the application layers very tightly. To keep the size
52
 * of the compiled code down, this code frequently uses the goto
53
 * statement. While it would be possible to break the uip_process()
54
 * function into many smaller functions, this would increase the code
55
 * size because of the overhead of parameter passing and the fact that
56
 * the optimier would not be as efficient.
57
 *
58
 * The principle is that we have a small buffer, called the uip_buf,
59
 * in which the device driver puts an incoming packet. The TCP/IP
60
 * stack parses the headers in the packet, and calls the
61
 * application. If the remote host has sent data to the application,
62
 * this data is present in the uip_buf and the application read the
63
 * data from there. It is up to the application to put this data into
64
 * a byte stream if needed. The application will not be fed with data
65
 * that is out of sequence.
66
 *
67
 * If the application whishes to send data to the peer, it should put
68
 * its data into the uip_buf. The uip_appdata pointer points to the
69
 * first available byte. The TCP/IP stack will calculate the
70
 * checksums, and fill in the necessary header fields and finally send
71
 * the packet back to the peer.
72
*/
73
#include "net/uip.h"
74
#include "net/uipopt.h"
75
#include "net/uip_arp.h"
76
#include "net/uip_arch.h"
77
 
78
/* If UIP_CONF_IPV6 is defined, we compile the uip6.c file instead of this one.
79
Therefore this #ifndef removes the entire compilation output of the uip.c file */
80
#if !UIP_CONF_IPV6
81
 
82
#if UIP_CONF_IPV6
83
        #include "net/uip-neighbor.h"
84
#endif /* UIP_CONF_IPV6 */
85
 
86
#include <string.h>
87
 
88
/*---------------------------------------------------------------------------*/
89
 
90
/* Variable definitions. */
91
 
92
/* The IP address of this host. If it is defined to be fixed (by setting
93
UIP_FIXEDADDR to 1 in uipopt.h), the address is set here. Otherwise, the address */
94
#if UIP_FIXEDADDR > 0
95
        const uip_ipaddr_t      uip_hostaddr = { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 };
96
        const uip_ipaddr_t      uip_draddr = { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 };
97
        const uip_ipaddr_t      uip_netmask = { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 };
98
#else
99
        uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
100
#endif /* UIP_FIXEDADDR */
101
 
102
const uip_ipaddr_t      uip_broadcast_addr =
103
#if UIP_CONF_IPV6
104
        { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
105
#else /* UIP_CONF_IPV6 */
106
        { {     0xff, 0xff, 0xff, 0xff } };
107
#endif /* UIP_CONF_IPV6 */
108
 
109
const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } };
110
 
111
#if UIP_FIXEDETHADDR
112
        const struct uip_eth_addr uip_ethaddr = { { UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5 } };
113
#else
114
        struct uip_eth_addr uip_ethaddr = { { 0, 0, 0, 0, 0, 0 } };
115
#endif
116
 
117
#ifndef UIP_CONF_EXTERNAL_BUFFER
118
        /* The packet buffer that contains incoming packets. */
119
        u8_t uip_buf[ UIP_BUFSIZE + 2 ];
120
#endif /* UIP_CONF_EXTERNAL_BUFFER */
121
 
122
/* The uip_appdata pointer points to application data. */
123
void *uip_appdata;
124
 
125
/* The uip_appdata pointer points to the application data which is to be sent. */
126
void *uip_sappdata;
127
 
128
#if UIP_URGDATA > 0
129
        /* The uip_urgdata pointer points to urgent data (out-of-band data), if
130
        present. */
131
        void *uip_urgdata;
132
        u16_t uip_urglen, uip_surglen;
133
#endif /* UIP_URGDATA > 0 */
134
 
135
/* The uip_len is either 8 or 16 bits, depending on the maximum packet size. */
136
u16_t uip_len, uip_slen;
137
 
138
/* The uip_flags variable is used for communication between the TCP/IP stack
139
and the application program. */
140
u8_t uip_flags;
141
 
142
/* uip_conn always points to the current connection. */
143
struct uip_conn *uip_conn;
144
struct uip_conn uip_conns[ UIP_CONNS ];
145
 
146
/* The uip_conns array holds all TCP connections. */
147
u16_t uip_listenports[UIP_LISTENPORTS];
148
 
149
/* The uip_listenports list all currently listning ports. */
150
#if UIP_UDP
151
        struct uip_udp_conn *uip_udp_conn;
152
        struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
153
#endif /* UIP_UDP */
154
 
155
/* Ths ipid variable is an increasing number that is used for the IP ID field. */
156
static u16_t ipid;
157
 
158
void uip_setipid( u16_t id )
159
{
160
        ipid = id;
161
}
162
 
163
/* The iss variable is used for the TCP initial sequence number. */
164
static u8_t     iss[ 4 ];
165
 
166
#if UIP_ACTIVE_OPEN
167
        /* Keeps track of the last port used for a new connection. */
168
        static u16_t    lastport;
169
#endif /* UIP_ACTIVE_OPEN */
170
 
171
/* Temporary variables. */
172
u8_t uip_acc32[ 4 ];
173
static u8_t     c, opt;
174
static u16_t tmp16;
175
 
176
/* Structures and definitions. */
177
#define TCP_FIN                                                         0x01
178
#define TCP_SYN                                                         0x02
179
#define TCP_RST                                                         0x04
180
#define TCP_PSH                                                         0x08
181
#define TCP_ACK                                                         0x10
182
#define TCP_URG                                                         0x20
183
#define TCP_CTL                                                         0x3f
184
 
185
#define TCP_OPT_END                                                     0        /* End of TCP options list */
186
#define TCP_OPT_NOOP                                            1       /* "No-operation" TCP option */
187
#define TCP_OPT_MSS                                                     2       /* Maximum segment size TCP option */
188
 
189
#define TCP_OPT_MSS_LEN                                         4       /* Length of TCP MSS option. */
190
 
191
#define ICMP_ECHO_REPLY                                         0
192
#define ICMP_ECHO                                                       8
193
 
194
#define ICMP_DEST_UNREACHABLE                           3
195
#define ICMP_PORT_UNREACHABLE                           3
196
 
197
#define ICMP6_ECHO_REPLY                                        129
198
#define ICMP6_ECHO                                                      128
199
#define ICMP6_NEIGHBOR_SOLICITATION                     135
200
#define ICMP6_NEIGHBOR_ADVERTISEMENT            136
201
 
202
#define ICMP6_FLAG_S                                            ( 1 << 6 )
203
#define ICMP6_OPTION_SOURCE_LINK_ADDRESS        1
204
#define ICMP6_OPTION_TARGET_LINK_ADDRESS        2
205
 
206
/* Macros. */
207
#define BUF             ( ( struct uip_tcpip_hdr * ) &uip_buf[UIP_LLH_LEN] )
208
#define FBUF    ( ( struct uip_tcpip_hdr * ) &uip_reassbuf[0] )
209
#define ICMPBUF ( ( struct uip_icmpip_hdr * ) &uip_buf[UIP_LLH_LEN] )
210
#define UDPBUF  ( ( struct uip_udpip_hdr * ) &uip_buf[UIP_LLH_LEN] )
211
 
212
#if UIP_STATISTICS == 1
213
        struct uip_stats        uip_stat;
214
        #define UIP_STAT( s )   s
215
#else
216
        #define UIP_STAT( s )
217
#endif /* UIP_STATISTICS == 1 */
218
 
219
#if UIP_LOGGING == 1
220
        #include <stdio.h>
221
        void    uip_log( char *msg );
222
        #define UIP_LOG( m )    uip_log( m )
223
#else
224
        #define UIP_LOG( m )
225
#endif /* UIP_LOGGING == 1 */
226
 
227
#if !UIP_ARCH_ADD32
228
        void uip_add32( u8_t *op32, u16_t op16 )
229
        {
230
                uip_acc32[3] = op32[3] + ( op16 & 0xff );
231
                uip_acc32[2] = op32[2] + ( op16 >> 8 );
232
                uip_acc32[1] = op32[1];
233
                uip_acc32[0] = op32[0];
234
 
235
                if( uip_acc32[2] < (op16 >> 8) )
236
                {
237
                        ++uip_acc32[1];
238
                        if( uip_acc32[1] == 0 )
239
                        {
240
                                ++uip_acc32[0];
241
                        }
242
                }
243
 
244
                if( uip_acc32[3] < (op16 & 0xff) )
245
                {
246
                        ++uip_acc32[2];
247
                        if( uip_acc32[2] == 0 )
248
                        {
249
                                ++uip_acc32[1];
250
                                if( uip_acc32[1] == 0 )
251
                                {
252
                                        ++uip_acc32[0];
253
                                }
254
                        }
255
                }
256
        }
257
/*---------------------------------------------------------------------------*/
258
#endif /* UIP_ARCH_ADD32 */
259
 
260
#if !UIP_ARCH_CHKSUM
261
 
262
        static u16_t chksum( u16_t sum, const u8_t *data, u16_t len )
263
        {
264
                u16_t           t;
265
                const u8_t      *dataptr;
266
                const u8_t      *last_byte;
267
 
268
                dataptr = data;
269
                last_byte = data + len - 1;
270
 
271
                while( dataptr < last_byte )
272
                {
273
                        /* At least two more bytes */
274
                        t = ( dataptr[ 0 ] << 8 ) + dataptr[ 1 ];
275
                        sum += t;
276
                        if( sum < t )
277
                        {
278
                                sum++;  /* carry */
279
                        }
280
 
281
                        dataptr += 2;
282
                }
283
 
284
                if( dataptr == last_byte )
285
                {
286
                        t = ( dataptr[ 0 ] << 8 ) + 0;
287
                        sum += t;
288
                        if( sum < t )
289
                        {
290
                                sum++;  /* carry */
291
                        }
292
                }
293
 
294
                /* Return sum in host byte order. */
295
                return sum;
296
        }
297
        /*---------------------------------------------------------------------------*/
298
 
299
        u16_t uip_chksum( u16_t *data, u16_t len )
300
        {
301
                return htons( chksum( 0, ( u8_t * ) data, len ) );
302
        }
303
        /*---------------------------------------------------------------------------*/
304
 
305
        #ifndef UIP_ARCH_IPCHKSUM
306
                u16_t uip_ipchksum( void )
307
                {
308
                        u16_t   sum;
309
 
310
                        sum = chksum( 0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN );
311
 
312
                        //DEBUG_PRINTF( "uip_ipchksum: sum 0x%04x\n", sum );
313
                        return( sum == 0 ) ? 0xffff : htons( sum );
314
                }
315
        #endif
316
        /*---------------------------------------------------------------------------*/
317
 
318
        static u16_t upper_layer_chksum( u8_t proto )
319
        {
320
                u16_t   upper_layer_len;
321
                u16_t   sum;
322
 
323
                #if UIP_CONF_IPV6
324
                        upper_layer_len = ( ((u16_t) (BUF->len[ 0 ]) << 8) + BUF->len[ 1 ] );
325
                #else /* UIP_CONF_IPV6 */
326
                        upper_layer_len = ( ((u16_t) (BUF->len[ 0 ]) << 8) + BUF->len[ 1 ] ) - UIP_IPH_LEN;
327
                #endif /* UIP_CONF_IPV6 */
328
 
329
                /* First sum pseudoheader. */
330
 
331
                /* IP protocol and length fields. This addition cannot carry. */
332
                sum = upper_layer_len + proto;
333
 
334
                /* Sum IP source and destination addresses. */
335
                sum = chksum( sum, ( u8_t * ) &BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t) );
336
 
337
                /* Sum TCP header and data. */
338
                sum = chksum( sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_len );
339
 
340
                return( sum == 0 ) ? 0xffff : htons( sum );
341
        }
342
        /*---------------------------------------------------------------------------*/
343
 
344
        #if UIP_CONF_IPV6
345
                u16_t uip_icmp6chksum( void )
346
                {
347
                        return upper_layer_chksum( UIP_PROTO_ICMP6 );
348
                }
349
        #endif /* UIP_CONF_IPV6 */
350
        /*---------------------------------------------------------------------------*/
351
 
352
        u16_t uip_tcpchksum( void )
353
        {
354
                return upper_layer_chksum( UIP_PROTO_TCP );
355
        }
356
        /*---------------------------------------------------------------------------*/
357
 
358
        #if UIP_UDP_CHECKSUMS
359
                u16_t uip_udpchksum( void )
360
                {
361
                        return upper_layer_chksum( UIP_PROTO_UDP );
362
                }
363
        #endif /* UIP_UDP_CHECKSUMS */
364
 
365
#endif /* UIP_ARCH_CHKSUM */
366
/*---------------------------------------------------------------------------*/
367
 
368
void uip_init( void )
369
{
370
        for( c = 0; c < UIP_LISTENPORTS; ++c )
371
        {
372
                uip_listenports[ c ] = 0;
373
        }
374
 
375
        for( c = 0; c < UIP_CONNS; ++c )
376
        {
377
                uip_conns[ c ].tcpstateflags = UIP_CLOSED;
378
        }
379
 
380
        #if UIP_ACTIVE_OPEN
381
                lastport = 1024;
382
        #endif /* UIP_ACTIVE_OPEN */
383
 
384
        #if UIP_UDP
385
                for( c = 0; c < UIP_UDP_CONNS; ++c )
386
                {
387
                        uip_udp_conns[ c ].lport = 0;
388
                }
389
        #endif /* UIP_UDP */
390
 
391
        /* IPv4 initialization. */
392
        #if UIP_FIXEDADDR == 0
393
                /*  uip_hostaddr[ 0 ] = uip_hostaddr[ 1 ] = 0;*/
394
        #endif /* UIP_FIXEDADDR */
395
}
396
/*---------------------------------------------------------------------------*/
397
 
398
#if UIP_ACTIVE_OPEN
399
        struct uip_conn *uip_connect( uip_ipaddr_t *ripaddr, u16_t rport )
400
        {
401
                register struct uip_conn        *conn, *cconn;
402
 
403
                /* Find an unused local port. */
404
        again:
405
                ++lastport;
406
 
407
                if( lastport >= 32000 )
408
                {
409
                        lastport = 4096;
410
                }
411
 
412
                /* Check if this port is already in use, and if so try to find
413
                 another one. */
414
                for( c = 0; c < UIP_CONNS; ++c )
415
                {
416
                        conn = &uip_conns[ c ];
417
                        if( conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(lastport) )
418
                        {
419
                                goto again;
420
                        }
421
                }
422
 
423
                conn = 0;
424
                for( c = 0; c < UIP_CONNS; ++c )
425
                {
426
                        cconn = &uip_conns[ c ];
427
                        if( cconn->tcpstateflags == UIP_CLOSED )
428
                        {
429
                                conn = cconn;
430
                                break;
431
                        }
432
 
433
                        if( cconn->tcpstateflags == UIP_TIME_WAIT )
434
                        {
435
                                if( conn == 0 || cconn->timer > conn->timer )
436
                                {
437
                                        conn = cconn;
438
                                }
439
                        }
440
                }
441
 
442
                if( conn == 0 )
443
                {
444
                        return 0;
445
                }
446
 
447
                conn->tcpstateflags = UIP_SYN_SENT;
448
 
449
                conn->snd_nxt[ 0 ] = iss[ 0 ];
450
                conn->snd_nxt[ 1 ] = iss[ 1 ];
451
                conn->snd_nxt[ 2 ] = iss[ 2 ];
452
                conn->snd_nxt[ 3 ] = iss[ 3 ];
453
 
454
                conn->initialmss = conn->mss = UIP_TCP_MSS;
455
 
456
                conn->len = 1;          /* TCP length of the SYN is one. */
457
                conn->nrtx = 0;
458
                conn->timer = 1;        /* Send the SYN next time around. */
459
                conn->rto = UIP_RTO;
460
                conn->sa = 0;
461
                conn->sv = 16;          /* Initial value of the RTT variance. */
462
                conn->lport = htons( lastport );
463
                conn->rport = rport;
464
                uip_ipaddr_copy( &conn->ripaddr, ripaddr );
465
 
466
                return conn;
467
        }
468
/*---------------------------------------------------------------------------*/
469
#endif /* UIP_ACTIVE_OPEN */
470
 
471
#if UIP_UDP
472
        struct uip_udp_conn *uip_udp_new( const uip_ipaddr_t *ripaddr, u16_t rport )
473
        {
474
                register struct uip_udp_conn    *conn;
475
 
476
                /* Find an unused local port. */
477
        again:
478
                ++lastport;
479
 
480
                if( lastport >= 32000 )
481
                {
482
                        lastport = 4096;
483
                }
484
 
485
                for( c = 0; c < UIP_UDP_CONNS; ++c )
486
                {
487
                        if( uip_udp_conns[ c ].lport == htons(lastport) )
488
                        {
489
                                goto again;
490
                        }
491
                }
492
 
493
                conn = 0;
494
                for( c = 0; c < UIP_UDP_CONNS; ++c )
495
                {
496
                        if( uip_udp_conns[ c ].lport == 0 )
497
                        {
498
                                conn = &uip_udp_conns[ c ];
499
                                break;
500
                        }
501
                }
502
 
503
                if( conn == 0 )
504
                {
505
                        return 0;
506
                }
507
 
508
                conn->lport = HTONS( lastport );
509
                conn->rport = rport;
510
                if( ripaddr == NULL )
511
                {
512
                        memset( &conn->ripaddr, 0, sizeof(uip_ipaddr_t) );
513
                }
514
                else
515
                {
516
                        uip_ipaddr_copy( &conn->ripaddr, ripaddr );
517
                }
518
 
519
                conn->ttl = UIP_TTL;
520
 
521
                return conn;
522
        }
523
/*---------------------------------------------------------------------------*/
524
#endif /* UIP_UDP */
525
 
526
void uip_unlisten( u16_t port )
527
{
528
        for( c = 0; c < UIP_LISTENPORTS; ++c )
529
        {
530
                if( uip_listenports[ c ] == port )
531
                {
532
                        uip_listenports[ c ] = 0;
533
                        return;
534
                }
535
        }
536
}
537
/*---------------------------------------------------------------------------*/
538
 
539
void uip_listen( u16_t port )
540
{
541
        for( c = 0; c < UIP_LISTENPORTS; ++c )
542
        {
543
                if( uip_listenports[ c ] == 0 )
544
                {
545
                        uip_listenports[ c ] = port;
546
                        return;
547
                }
548
        }
549
}
550
/*---------------------------------------------------------------------------*/
551
 
552
/* XXX: IP fragment reassembly: not well-tested. */
553
#if UIP_REASSEMBLY && !UIP_CONF_IPV6
554
        #define UIP_REASS_BUFSIZE       ( UIP_BUFSIZE - UIP_LLH_LEN )
555
        static u8_t                     uip_reassbuf[UIP_REASS_BUFSIZE];
556
        static u8_t                     uip_reassbitmap[UIP_REASS_BUFSIZE / ( 8 * 8 )];
557
        static const u8_t       bitmap_bits[8] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
558
        static u16_t            uip_reasslen;
559
        static u8_t                     uip_reassflags;
560
        #define UIP_REASS_FLAG_LASTFRAG 0x01
561
        static u8_t                     uip_reasstmr;
562
 
563
        #define IP_MF   0x20
564
 
565
        static u8_t uip_reass( void )
566
        {
567
                u16_t   offset, len;
568
                u16_t   i;
569
 
570
                /* If ip_reasstmr is zero, no packet is present in the buffer, so we
571
                 write the IP header of the fragment into the reassembly
572
                 buffer. The timer is updated with the maximum age. */
573
                if( uip_reasstmr == 0 )
574
                {
575
                        memcpy( uip_reassbuf, &BUF->vhl, UIP_IPH_LEN );
576
                        uip_reasstmr = UIP_REASS_MAXAGE;
577
                        uip_reassflags = 0;
578
 
579
                        /* Clear the bitmap. */
580
                        memset( uip_reassbitmap, 0, sizeof(uip_reassbitmap) );
581
                }
582
 
583
                /* Check if the incoming fragment matches the one currently present
584
                 in the reasembly buffer. If so, we proceed with copying the
585
                 fragment into the buffer. */
586
                if
587
                (
588
                        BUF->srcipaddr[ 0 ] == FBUF->srcipaddr[ 0 ] &&
589
                        BUF->srcipaddr[ 1 ] == FBUF->srcipaddr[ 1 ] &&
590
                        BUF->destipaddr[ 0 ] == FBUF->destipaddr[ 0 ] &&
591
                        BUF->destipaddr[ 1 ] == FBUF->destipaddr[ 1 ] &&
592
                        BUF->ipid[ 0 ] == FBUF->ipid[ 0 ] &&
593
                        BUF->ipid[ 1 ] == FBUF->ipid[ 1 ]
594
                )
595
                {
596
                        len = ( BUF->len[ 0 ] << 8 ) + BUF->len[ 1 ] - ( BUF->vhl & 0x0f ) * 4;
597
                        offset = ( ((BUF->ipoffset[ 0 ] & 0x3f) << 8) + BUF->ipoffset[ 1 ] ) * 8;
598
 
599
                        /* If the offset or the offset + fragment length overflows the
600
                   reassembly buffer, we discard the entire packet. */
601
                        if( offset > UIP_REASS_BUFSIZE || offset + len > UIP_REASS_BUFSIZE )
602
                        {
603
                                uip_reasstmr = 0;
604
                                goto nullreturn;
605
                        }
606
 
607
                        /* Copy the fragment into the reassembly buffer, at the right
608
                        offset. */
609
                        memcpy( &uip_reassbuf[UIP_IPH_LEN + offset], ( char * ) BUF + ( int ) ((BUF->vhl & 0x0f) * 4), len );
610
 
611
                        /* Update the bitmap. */
612
                        if( offset / (8 * 8) == (offset + len) / (8 * 8) )
613
                        {
614
                                /* If the two endpoints are in the same byte, we only update
615
                                that byte. */
616
                                uip_reassbitmap[offset / ( 8 * 8 )] |= bitmap_bits[( offset / 8 ) & 7] &~bitmap_bits[( (offset + len) / 8 ) & 7];
617
                        }
618
                        else
619
                        {
620
                                /* If the two endpoints are in different bytes, we update the
621
                                bytes in the endpoints and fill the stuff inbetween with
622
                                0xff. */
623
                                uip_reassbitmap[offset / ( 8 * 8 )] |= bitmap_bits[( offset / 8 ) & 7];
624
                                for( i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i )
625
                                {
626
                                        uip_reassbitmap[i] = 0xff;
627
                                }
628
 
629
                                uip_reassbitmap[( offset + len ) / ( 8 * 8 )] |= ~bitmap_bits[( (offset + len) / 8 ) & 7];
630
                        }
631
 
632
                        /* If this fragment has the More Fragments flag set to zero, we
633
                        know that this is the last fragment, so we can calculate the
634
                        size of the entire packet. We also set the
635
                        IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
636
                        the final fragment. */
637
                        if( (BUF->ipoffset[ 0 ] & IP_MF) == 0 )
638
                        {
639
                                uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
640
                                uip_reasslen = offset + len;
641
                        }
642
 
643
                        /* Finally, we check if we have a full packet in the buffer. We do
644
                        this by checking if we have the last fragment and if all bits
645
                        in the bitmap are set. */
646
                        if( uip_reassflags & UIP_REASS_FLAG_LASTFRAG )
647
                        {
648
                                /* Check all bytes up to and including all but the last byte in
649
                                the bitmap. */
650
                                for( i = 0; i < uip_reasslen / (8 * 8) - 1; ++i )
651
                                {
652
                                        if( uip_reassbitmap[i] != 0xff )
653
                                        {
654
                                                goto nullreturn;
655
                                        }
656
                                }
657
 
658
                                /* Check the last byte in the bitmap. It should contain just the
659
                                right amount of bits. */
660
                                if( uip_reassbitmap[uip_reasslen / (8 * 8)] != (u8_t)~bitmap_bits[uip_reasslen / 8 & 7] )
661
                                {
662
                                        goto nullreturn;
663
                                }
664
 
665
                                /* If we have come this far, we have a full packet in the
666
                                buffer, so we allocate a pbuf and copy the packet into it. We
667
                                also reset the timer. */
668
                                uip_reasstmr = 0;
669
                                memcpy( BUF, FBUF, uip_reasslen );
670
 
671
                                /* Pretend to be a "normal" (i.e., not fragmented) IP packet
672
                                from now on. */
673
                                BUF->ipoffset[ 0 ] = BUF->ipoffset[ 1 ] = 0;
674
                                BUF->len[ 0 ] = uip_reasslen >> 8;
675
                                BUF->len[ 1 ] = uip_reasslen & 0xff;
676
                                BUF->ipchksum = 0;
677
                                BUF->ipchksum = ~( uip_ipchksum() );
678
 
679
                                return uip_reasslen;
680
                        }
681
                }
682
 
683
        nullreturn:
684
 
685
                return 0;
686
        }
687
/*---------------------------------------------------------------------------*/
688
#endif /* UIP_REASSEMBLY */
689
 
690
 
691
static void uip_add_rcv_nxt( u16_t n )
692
{
693
        uip_add32( uip_conn->rcv_nxt, n );
694
        uip_conn->rcv_nxt[ 0 ] = uip_acc32[ 0 ];
695
        uip_conn->rcv_nxt[ 1 ] = uip_acc32[ 1 ];
696
        uip_conn->rcv_nxt[ 2 ] = uip_acc32[ 2 ];
697
        uip_conn->rcv_nxt[ 3 ] = uip_acc32[ 3 ];
698
}
699
/*---------------------------------------------------------------------------*/
700
 
701
void uip_process( u8_t flag )
702
{
703
        register struct uip_conn        *uip_connr = uip_conn;
704
 
705
        #if UIP_UDP
706
                if( flag == UIP_UDP_SEND_CONN )
707
                {
708
                        goto udp_send;
709
                }
710
        #endif /* UIP_UDP */
711
 
712
        uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
713
 
714
        /* Check if we were invoked because of a poll request for a
715
         particular connection. */
716
        if( flag == UIP_POLL_REQUEST )
717
        {
718
                if( (uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && !uip_outstanding(uip_connr) )
719
                {
720
                        uip_flags = UIP_POLL;
721
                        UIP_APPCALL();
722
                        goto appsend;
723
                }
724
 
725
                goto drop;
726
 
727
                /* Check if we were invoked because of the perodic timer fireing. */
728
        }
729
        else if( flag == UIP_TIMER )
730
        {
731
                #if UIP_REASSEMBLY
732
                        if( uip_reasstmr != 0 )
733
                        {
734
                                --uip_reasstmr;
735
                        }
736
                #endif /* UIP_REASSEMBLY */
737
 
738
                /* Increase the initial sequence number. */
739
                if( ++iss[ 3 ] == 0 )
740
                {
741
                        if( ++iss[ 2 ] == 0 )
742
                        {
743
                                if( ++iss[ 1 ] == 0 )
744
                                {
745
                                        ++iss[ 0 ];
746
                                }
747
                        }
748
                }
749
 
750
                /* Reset the length variables. */
751
                uip_len = 0;
752
                uip_slen = 0;
753
 
754
                /* Check if the connection is in a state in which we simply wait
755
                for the connection to time out. If so, we increase the
756
                connection's timer and remove the connection if it times
757
                out. */
758
                if( uip_connr->tcpstateflags == UIP_TIME_WAIT || uip_connr->tcpstateflags == UIP_FIN_WAIT_2 )
759
                {
760
                        ++( uip_connr->timer );
761
                        if( uip_connr->timer == UIP_TIME_WAIT_TIMEOUT )
762
                        {
763
                                uip_connr->tcpstateflags = UIP_CLOSED;
764
                        }
765
                }
766
                else if( uip_connr->tcpstateflags != UIP_CLOSED )
767
                {
768
                        /* If the connection has outstanding data, we increase the
769
                        connection's timer and see if it has reached the RTO value
770
                        in which case we retransmit. */
771
                        if( uip_outstanding(uip_connr) )
772
                        {
773
                                if( uip_connr->timer-- == 0 )
774
                                {
775
                                        if
776
                                        (
777
                                                uip_connr->nrtx == UIP_MAXRTX ||
778
                                                (
779
                                                        (uip_connr->tcpstateflags == UIP_SYN_SENT || uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
780
                                                        uip_connr->nrtx == UIP_MAXSYNRTX
781
                                                )
782
                                        )
783
                                        {
784
                                                uip_connr->tcpstateflags = UIP_CLOSED;
785
 
786
                                                /* We call UIP_APPCALL() with uip_flags set to
787
                                                UIP_TIMEDOUT to inform the application that the
788
                                                connection has timed out. */
789
                                                uip_flags = UIP_TIMEDOUT;
790
                                                UIP_APPCALL();
791
 
792
                                                /* We also send a reset packet to the remote host. */
793
                                                BUF->flags = TCP_RST | TCP_ACK;
794
                                                goto tcp_send_nodata;
795
                                        }
796
 
797
                                        /* Exponential backoff. */
798
                                        uip_connr->timer = UIP_RTO << ( uip_connr->nrtx > 4 ? 4 : uip_connr->nrtx );
799
                                        ++( uip_connr->nrtx );
800
 
801
                                        /* Ok, so we need to retransmit. We do this differently
802
                                        depending on which state we are in. In ESTABLISHED, we
803
                                        call upon the application so that it may prepare the
804
                                        data for the retransmit. In SYN_RCVD, we resend the
805
                                        SYNACK that we sent earlier and in LAST_ACK we have to
806
                                        retransmit our FINACK. */
807
                                                        UIP_STAT( ++uip_stat.tcp.rexmit );
808
                                        switch( uip_connr->tcpstateflags & UIP_TS_MASK )
809
                                        {
810
                                                case UIP_SYN_RCVD:
811
                                                        /* In the SYN_RCVD state, we should retransmit our
812
                                                        SYNACK. */
813
                                                        goto tcp_send_synack;
814
 
815
                                                #if UIP_ACTIVE_OPEN
816
                                                        case UIP_SYN_SENT:
817
                                                                /* In the SYN_SENT state, we retransmit out SYN. */
818
                                                                BUF->flags = 0;
819
                                                                goto tcp_send_syn;
820
                                                #endif /* UIP_ACTIVE_OPEN */
821
 
822
                                                case UIP_ESTABLISHED:
823
                                                        /* In the ESTABLISHED state, we call upon the application
824
                                                        to do the actual retransmit after which we jump into
825
                                                        the code for sending out the packet (the apprexmit
826
                                                        label). */
827
                                                        uip_flags = UIP_REXMIT;
828
                                                        UIP_APPCALL();
829
                                                        goto apprexmit;
830
 
831
                                                case UIP_FIN_WAIT_1:
832
                                                case UIP_CLOSING:
833
                                                case UIP_LAST_ACK:
834
                                                        /* In all these states we should retransmit a FINACK. */
835
                                                        goto tcp_send_finack;
836
                                        }
837
                                }
838
                        }
839
                        else if( (uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED )
840
                        {
841
                                /* If there was no need for a retransmission, we poll the
842
                                application for new data. */
843
                                uip_flags = UIP_POLL;
844
                                UIP_APPCALL();
845
                                goto appsend;
846
                        }
847
                }
848
 
849
                goto drop;
850
        }
851
 
852
        #if UIP_UDP
853
                if( flag == UIP_UDP_TIMER )
854
                {
855
                        if( uip_udp_conn->lport != 0 )
856
                        {
857
                                uip_conn = NULL;
858
                                uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
859
                                uip_len = uip_slen = 0;
860
                                uip_flags = UIP_POLL;
861
                                UIP_UDP_APPCALL();
862
                                goto udp_send;
863
                        }
864
                        else
865
                        {
866
                                goto drop;
867
                        }
868
                }
869
        #endif
870
 
871
        /* This is where the input processing starts. */
872
        UIP_STAT( ++uip_stat.ip.recv );
873
 
874
        /* Start of IP input header processing code. */
875
        #if UIP_CONF_IPV6
876
                /* Check validity of the IP header. */
877
                if( (BUF->vtc & 0xf0) != 0x60 )
878
                {                                       /* IP version and header length. */
879
                        UIP_STAT( ++uip_stat.ip.drop );
880
                        UIP_STAT( ++uip_stat.ip.vhlerr );
881
                        UIP_LOG( "ipv6: invalid version." );
882
                        goto drop;
883
                }
884
 
885
        #else /* UIP_CONF_IPV6 */
886
                /* Check validity of the IP header. */
887
                if( BUF->vhl != 0x45 )
888
                {                                       /* IP version and header length. */
889
                        UIP_STAT( ++uip_stat.ip.drop );
890
                        UIP_STAT( ++uip_stat.ip.vhlerr );
891
                        UIP_LOG( "ip: invalid version or header length." );
892
                        goto drop;
893
                }
894
 
895
        #endif /* UIP_CONF_IPV6 */
896
 
897
        /* Check the size of the packet. If the size reported to us in
898
        uip_len is smaller the size reported in the IP header, we assume
899
        that the packet has been corrupted in transit. If the size of
900
        uip_len is larger than the size reported in the IP packet header,
901
        the packet has been padded and we set uip_len to the correct
902
        value.. */
903
        if( (BUF->len[ 0 ] << 8) + BUF->len[ 1 ] <= uip_len )
904
        {
905
                uip_len = ( BUF->len[ 0 ] << 8 ) + BUF->len[ 1 ];
906
                #if UIP_CONF_IPV6
907
                        /* The length reported in the IPv6 header is the
908
                        length of the payload that follows the
909
                        header. However, uIP uses the uip_len variable
910
                        for holding the size of the entire packet,
911
                        including the IP header. For IPv4 this is not a
912
                        problem as the length field in the IPv4 header
913
                        contains the length of the entire packet. But
914
                        for IPv6 we need to add the size of the IPv6
915
                        header (40 bytes). */
916
                        uip_len += 40;
917
                #endif /* UIP_CONF_IPV6 */
918
        }
919
        else
920
        {
921
                UIP_LOG( "ip: packet shorter than reported in IP header." );
922
                goto drop;
923
        }
924
 
925
        #if !UIP_CONF_IPV6
926
                /* Check the fragment flag. */
927
                if( (BUF->ipoffset[ 0 ] & 0x3f) != 0 || BUF->ipoffset[ 1 ] != 0 )
928
                {
929
                        #if UIP_REASSEMBLY
930
                                uip_len = uip_reass();
931
                                if( uip_len == 0 )
932
                                {
933
                                        goto drop;
934
                                }
935
                        #else /* UIP_REASSEMBLY */
936
                                UIP_STAT( ++uip_stat.ip.drop );
937
                                UIP_STAT( ++uip_stat.ip.fragerr );
938
                                UIP_LOG( "ip: fragment dropped." );
939
                                goto drop;
940
                        #endif /* UIP_REASSEMBLY */
941
                }
942
        #endif /* UIP_CONF_IPV6 */
943
 
944
        if( uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) )
945
        {
946
                /* If we are configured to use ping IP address configuration and
947
                hasn't been assigned an IP address yet, we accept all ICMP
948
                packets. */
949
                #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
950
                        if( BUF->proto == UIP_PROTO_ICMP )
951
                        {
952
                                UIP_LOG( "ip: possible ping config packet received." );
953
                                goto icmp_input;
954
                        }
955
                        else
956
                        {
957
                                UIP_LOG( "ip: packet dropped since no address assigned." );
958
                                goto drop;
959
                        }
960
                #endif /* UIP_PINGADDRCONF */
961
        }
962
        else
963
        {
964
                /* If IP broadcast support is configured, we check for a broadcast
965
                UDP packet, which may be destined to us. */
966
                #if UIP_BROADCAST
967
                        //DEBUG_PRINTF( "UDP IP checksum 0x%04x\n", uip_ipchksum() );
968
                        if( BUF->proto == UIP_PROTO_UDP && uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) /*&& uip_ipchksum() == 0xffff*/ )
969
                        {
970
                                goto udp_input;
971
                        }
972
                #endif /* UIP_BROADCAST */
973
 
974
                /* Check if the packet is destined for our IP address. */
975
                #if !UIP_CONF_IPV6
976
                        if( !uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) )
977
                        {
978
                                UIP_STAT( ++uip_stat.ip.drop );
979
                                goto drop;
980
                        }
981
                #else /* UIP_CONF_IPV6 */
982
                        /* For IPv6, packet reception is a little trickier as we need to
983
                        make sure that we listen to certain multicast addresses (all
984
                        hosts multicast address, and the solicited-node multicast
985
                        address) as well. However, we will cheat here and accept all
986
                        multicast packets that are sent to the ff02::/16 addresses. */
987
                        if( !uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) && BUF->destipaddr.u16[ 0 ] != HTONS(0xff02) )
988
                        {
989
                                UIP_STAT( ++uip_stat.ip.drop );
990
                                goto drop;
991
                        }
992
                #endif /* UIP_CONF_IPV6 */
993
        }
994
 
995
        #if !UIP_CONF_IPV6
996
                if( uip_ipchksum() != 0xffff )
997
                {
998
                        /* Compute and check the IP header checksum. */
999
                        UIP_STAT( ++uip_stat.ip.drop );
1000
                        UIP_STAT( ++uip_stat.ip.chkerr );
1001
                        UIP_LOG( "ip: bad checksum." );
1002
                        goto drop;
1003
                }
1004
        #endif /* UIP_CONF_IPV6 */
1005
 
1006
        if( BUF->proto == UIP_PROTO_TCP )
1007
        {
1008
                /* Check for TCP packet. If so, proceed with TCP input processing. */
1009
                goto tcp_input;
1010
        }
1011
 
1012
        #if UIP_UDP
1013
                if( BUF->proto == UIP_PROTO_UDP )
1014
                {
1015
                        goto udp_input;
1016
                }
1017
        #endif /* UIP_UDP */
1018
 
1019
        #if !UIP_CONF_IPV6
1020
                /* ICMPv4 processing code follows. */
1021
                if( BUF->proto != UIP_PROTO_ICMP )
1022
                {
1023
                        /* We only allow ICMP packets from here. */
1024
                        UIP_STAT( ++uip_stat.ip.drop );
1025
                        UIP_STAT( ++uip_stat.ip.protoerr );
1026
                        UIP_LOG( "ip: neither tcp nor icmp." );
1027
                        goto drop;
1028
                }
1029
 
1030
                #if UIP_PINGADDRCONF
1031
                        icmp_input :
1032
                #endif /* UIP_PINGADDRCONF */
1033
 
1034
                UIP_STAT( ++uip_stat.icmp.recv );
1035
 
1036
                /* ICMP echo (i.e., ping) processing. This is simple, we only change
1037
                 the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
1038
                 checksum before we return the packet. */
1039
                if( ICMPBUF->type != ICMP_ECHO )
1040
                {
1041
                        UIP_STAT( ++uip_stat.icmp.drop );
1042
                        UIP_STAT( ++uip_stat.icmp.typeerr );
1043
                        UIP_LOG( "icmp: not icmp echo." );
1044
                        goto drop;
1045
                }
1046
 
1047
                /* If we are configured to use ping IP address assignment, we use
1048
                 the destination IP address of this ping packet and assign it to
1049
                 ourself. */
1050
                #if UIP_PINGADDRCONF
1051
                        if( uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) )
1052
                        {
1053
                                uip_hostaddr = BUF->destipaddr;
1054
                        }
1055
                #endif /* UIP_PINGADDRCONF */
1056
 
1057
                ICMPBUF->type = ICMP_ECHO_REPLY;
1058
 
1059
                if( ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8)) )
1060
                {
1061
                        ICMPBUF->icmpchksum += HTONS( ICMP_ECHO << 8 ) + 1;
1062
                }
1063
                else
1064
                {
1065
                        ICMPBUF->icmpchksum += HTONS( ICMP_ECHO << 8 );
1066
                }
1067
 
1068
                /* Swap IP addresses. */
1069
                uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr );
1070
                uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr );
1071
 
1072
                UIP_STAT( ++uip_stat.icmp.sent );
1073
                BUF->ttl = UIP_TTL;
1074
                goto ip_send_nolen;
1075
 
1076
                /* End of IPv4 input header processing code. */
1077
 
1078
        #else /* !UIP_CONF_IPV6 */
1079
 
1080
                /* This is IPv6 ICMPv6 processing code. */
1081
 
1082
                //DEBUG_PRINTF( "icmp6_input: length %d\n", uip_len );
1083
                if( BUF->proto != UIP_PROTO_ICMP6 )
1084
                {
1085
                        /* We only allow ICMPv6 packets from here. */
1086
                        UIP_STAT( ++uip_stat.ip.drop );
1087
                        UIP_STAT( ++uip_stat.ip.protoerr );
1088
                        UIP_LOG( "ip: neither tcp nor icmp6." );
1089
                        goto drop;
1090
                }
1091
 
1092
                UIP_STAT( ++uip_stat.icmp.recv );
1093
 
1094
                /* If we get a neighbor solicitation for our address we should send
1095
                 a neighbor advertisement message back. */
1096
                if( ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION )
1097
                {
1098
                        if( uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr) )
1099
                        {
1100
                                if( ICMPBUF->options[ 0 ] == ICMP6_OPTION_SOURCE_LINK_ADDRESS )
1101
                                {
1102
                                        /* Save the sender's address in our neighbor list. */
1103
                                        uip_neighbor_add( &ICMPBUF->srcipaddr, &(ICMPBUF->options[ 2 ]) );
1104
                                }
1105
 
1106
                                /* We should now send a neighbor advertisement back to where the
1107
                                neighbor solicication came from. */
1108
                                ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
1109
                                ICMPBUF->flags = ICMP6_FLAG_S;  /* Solicited flag. */
1110
 
1111
                                ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
1112
 
1113
                                uip_ipaddr_copy( &ICMPBUF->destipaddr, &ICMPBUF->srcipaddr );
1114
                                uip_ipaddr_copy( &ICMPBUF->srcipaddr, &uip_hostaddr );
1115
                                ICMPBUF->options[ 0 ] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
1116
                                ICMPBUF->options[ 1 ] = 1;              /* Options length, 1 = 8 bytes. */
1117
                                memcpy( &(ICMPBUF->options[ 2 ]), &uip_ethaddr, sizeof(uip_ethaddr) );
1118
                                ICMPBUF->icmpchksum = 0;
1119
                                ICMPBUF->icmpchksum = ~uip_icmp6chksum();
1120
 
1121
                                goto send;
1122
                        }
1123
 
1124
                        goto drop;
1125
                }
1126
                else if( ICMPBUF->type == ICMP6_ECHO )
1127
                {
1128
                        /* ICMP echo (i.e., ping) processing. This is simple, we only
1129
                        change the ICMP type from ECHO to ECHO_REPLY and update the
1130
                        ICMP checksum before we return the packet. */
1131
                        ICMPBUF->type = ICMP6_ECHO_REPLY;
1132
 
1133
                        uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr );
1134
                        uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr );
1135
                        ICMPBUF->icmpchksum = 0;
1136
                        ICMPBUF->icmpchksum = ~uip_icmp6chksum();
1137
 
1138
                        UIP_STAT( ++uip_stat.icmp.sent );
1139
                        goto send;
1140
                }
1141
                else
1142
                {
1143
                        //DEBUG_PRINTF( "Unknown icmp6 message type %d\n", ICMPBUF->type );
1144
                        UIP_STAT( ++uip_stat.icmp.drop );
1145
                        UIP_STAT( ++uip_stat.icmp.typeerr );
1146
                        UIP_LOG( "icmp: unknown ICMP message." );
1147
                        goto drop;
1148
                }
1149
 
1150
                /* End of IPv6 ICMP processing. */
1151
        #endif /* !UIP_CONF_IPV6 */
1152
 
1153
        #if UIP_UDP
1154
                /* UDP input processing. */
1155
                udp_input :
1156
                /* UDP processing is really just a hack. We don't do anything to the
1157
                 UDP/IP headers, but let the UDP application do all the hard
1158
                 work. If the application sets uip_slen, it has a packet to
1159
                 send. */
1160
                #if UIP_UDP_CHECKSUMS
1161
                        uip_len = uip_len - UIP_IPUDPH_LEN;
1162
                        uip_appdata = &uip_buf[ UIP_LLH_LEN + UIP_IPUDPH_LEN ];
1163
                        if( UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff )
1164
                        {
1165
                                UIP_STAT( ++uip_stat.udp.drop );
1166
                                UIP_STAT( ++uip_stat.udp.chkerr );
1167
                                UIP_LOG( "udp: bad checksum." );
1168
                                goto drop;
1169
                        }
1170
 
1171
                #else /* UIP_UDP_CHECKSUMS */
1172
                        uip_len = uip_len - UIP_IPUDPH_LEN;
1173
                #endif /* UIP_UDP_CHECKSUMS */
1174
 
1175
                /* Demultiplex this UDP packet between the UDP "connections". */
1176
                for( uip_udp_conn = &uip_udp_conns[ 0 ]; uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; ++uip_udp_conn )
1177
                {
1178
                        /* If the local UDP port is non-zero, the connection is considered
1179
                   to be used. If so, the local port number is checked against the
1180
                   destination port number in the received packet. If the two port
1181
                   numbers match, the remote port number is checked if the
1182
                   connection is bound to a remote port. Finally, if the
1183
                   connection is bound to a remote IP address, the source IP
1184
                   address of the packet is checked. */
1185
                        if
1186
                        (
1187
                                uip_udp_conn->lport != 0 &&
1188
                                UDPBUF->destport == uip_udp_conn->lport &&
1189
                                (uip_udp_conn->rport == 0 || UDPBUF->srcport == uip_udp_conn->rport) &&
1190
                                (
1191
                                        uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) ||
1192
                                        uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) ||
1193
                                        uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr)
1194
                                )
1195
                        )
1196
                        {
1197
                                goto udp_found;
1198
                        }
1199
                }
1200
 
1201
                UIP_LOG( "udp: no matching connection found" );
1202
 
1203
                #if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6
1204
 
1205
                /* Copy fields from packet header into payload of this ICMP packet. */
1206
                memcpy( &(ICMPBUF->payload[ 0 ]), ICMPBUF, UIP_IPH_LEN + 8 );
1207
 
1208
                /* Set the ICMP type and code. */
1209
                ICMPBUF->type = ICMP_DEST_UNREACHABLE;
1210
                ICMPBUF->icode = ICMP_PORT_UNREACHABLE;
1211
 
1212
                /* Calculate the ICMP checksum. */
1213
                ICMPBUF->icmpchksum = 0;
1214
                ICMPBUF->icmpchksum = ~uip_chksum( ( u16_t * ) &(ICMPBUF->type), 36 );
1215
 
1216
                /* Set the IP destination address to be the source address of the
1217
                 original packet. */
1218
                uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr );
1219
 
1220
                /* Set our IP address as the source address. */
1221
                uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr );
1222
 
1223
                /* The size of the ICMP destination unreachable packet is 36 + the
1224
                 size of the IP header (20) = 56. */
1225
                uip_len = 36 + UIP_IPH_LEN;
1226
                ICMPBUF->len[ 0 ] = 0;
1227
                ICMPBUF->len[ 1 ] = ( u8_t ) uip_len;
1228
                ICMPBUF->ttl = UIP_TTL;
1229
                ICMPBUF->proto = UIP_PROTO_ICMP;
1230
 
1231
                goto ip_send_nolen;
1232
        #else /* UIP_CONF_ICMP_DEST_UNREACH */
1233
                goto drop;
1234
        #endif /* UIP_CONF_ICMP_DEST_UNREACH */
1235
 
1236
        udp_found : uip_conn = NULL;
1237
        uip_flags = UIP_NEWDATA;
1238
        uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
1239
        uip_slen = 0;
1240
        UIP_UDP_APPCALL();
1241
 
1242
udp_send:
1243
        if( uip_slen == 0 )
1244
        {
1245
                goto drop;
1246
        }
1247
 
1248
        uip_len = uip_slen + UIP_IPUDPH_LEN;
1249
 
1250
        #if UIP_CONF_IPV6
1251
                /* For IPv6, the IP length field does not include the IPv6 IP header
1252
                 length. */
1253
                BUF->len[ 0 ] = ( (uip_len - UIP_IPH_LEN) >> 8 );
1254
                BUF->len[ 1 ] = ( (uip_len - UIP_IPH_LEN) & 0xff );
1255
        #else /* UIP_CONF_IPV6 */
1256
                BUF->len[ 0 ] = ( uip_len >> 8 );
1257
                BUF->len[ 1 ] = ( uip_len & 0xff );
1258
        #endif /* UIP_CONF_IPV6 */
1259
 
1260
        BUF->ttl = uip_udp_conn->ttl;
1261
        BUF->proto = UIP_PROTO_UDP;
1262
 
1263
        UDPBUF->udplen = HTONS( uip_slen + UIP_UDPH_LEN );
1264
        UDPBUF->udpchksum = 0;
1265
 
1266
        BUF->srcport = uip_udp_conn->lport;
1267
        BUF->destport = uip_udp_conn->rport;
1268
 
1269
        uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr );
1270
        uip_ipaddr_copy( &BUF->destipaddr, &uip_udp_conn->ripaddr );
1271
 
1272
        uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
1273
 
1274
        #if UIP_UDP_CHECKSUMS
1275
                /* Calculate UDP checksum. */
1276
                UDPBUF->udpchksum = ~( uip_udpchksum() );
1277
                if( UDPBUF->udpchksum == 0 )
1278
                {
1279
                        UDPBUF->udpchksum = 0xffff;
1280
                }
1281
        #endif /* UIP_UDP_CHECKSUMS */
1282
                goto ip_send_nolen;
1283
        #endif /* UIP_UDP */
1284
 
1285
        /* TCP input processing. */
1286
        tcp_input : UIP_STAT( ++uip_stat.tcp.recv );
1287
 
1288
        /* Start of TCP input header processing code. */
1289
        if( uip_tcpchksum() != 0xffff )
1290
        {
1291
                /* Compute and check the TCP checksum. */
1292
                UIP_STAT( ++uip_stat.tcp.drop );
1293
                UIP_STAT( ++uip_stat.tcp.chkerr );
1294
                UIP_LOG( "tcp: bad checksum." );
1295
                goto drop;
1296
        }
1297
 
1298
        /* Demultiplex this segment. */
1299
 
1300
        /* First check any active connections. */
1301
        for( uip_connr = &uip_conns[ 0 ]; uip_connr <= &uip_conns[UIP_CONNS - 1]; ++uip_connr )
1302
        {
1303
                if
1304
                (
1305
                        uip_connr->tcpstateflags != UIP_CLOSED &&
1306
                        BUF->destport == uip_connr->lport &&
1307
                        BUF->srcport == uip_connr->rport &&
1308
                        uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->ripaddr)
1309
                )
1310
                {
1311
                        goto found;
1312
                }
1313
        }
1314
 
1315
        /* If we didn't find and active connection that expected the packet,
1316
        either this packet is an old duplicate, or this is a SYN packet
1317
        destined for a connection in LISTEN. If the SYN flag isn't set,
1318
        it is an old packet and we send a RST. */
1319
        if( (BUF->flags & TCP_CTL) != TCP_SYN )
1320
        {
1321
                goto reset;
1322
        }
1323
 
1324
        tmp16 = BUF->destport;
1325
 
1326
        /* Next, check listening connections. */
1327
        for( c = 0; c < UIP_LISTENPORTS; ++c )
1328
        {
1329
                if( tmp16 == uip_listenports[ c ] )
1330
                {
1331
                        goto found_listen;
1332
                }
1333
        }
1334
 
1335
        /* No matching connection found, so we send a RST packet. */
1336
        UIP_STAT( ++uip_stat.tcp.synrst );
1337
 
1338
reset:
1339
        /* We do not send resets in response to resets. */
1340
        if( BUF->flags & TCP_RST )
1341
        {
1342
                goto drop;
1343
        }
1344
 
1345
        UIP_STAT( ++uip_stat.tcp.rst );
1346
 
1347
        BUF->flags = TCP_RST | TCP_ACK;
1348
        uip_len = UIP_IPTCPH_LEN;
1349
        BUF->tcpoffset = 5 << 4;
1350
 
1351
        /* Flip the seqno and ackno fields in the TCP header. */
1352
        c = BUF->seqno[ 3 ];
1353
        BUF->seqno[ 3 ] = BUF->ackno[ 3 ];
1354
        BUF->ackno[ 3 ] = c;
1355
 
1356
        c = BUF->seqno[ 2 ];
1357
        BUF->seqno[ 2 ] = BUF->ackno[ 2 ];
1358
        BUF->ackno[ 2 ] = c;
1359
 
1360
        c = BUF->seqno[ 1 ];
1361
        BUF->seqno[ 1 ] = BUF->ackno[ 1 ];
1362
        BUF->ackno[ 1 ] = c;
1363
 
1364
        c = BUF->seqno[ 0 ];
1365
        BUF->seqno[ 0 ] = BUF->ackno[ 0 ];
1366
        BUF->ackno[ 0 ] = c;
1367
 
1368
        /* We also have to increase the sequence number we are
1369
        acknowledging. If the least significant byte overflowed, we need
1370
        to propagate the carry to the other bytes as well. */
1371
        if( ++BUF->ackno[ 3 ] == 0 )
1372
        {
1373
                if( ++BUF->ackno[ 2 ] == 0 )
1374
                {
1375
                        if( ++BUF->ackno[ 1 ] == 0 )
1376
                        {
1377
                                ++BUF->ackno[ 0 ];
1378
                        }
1379
                }
1380
        }
1381
 
1382
        /* Swap port numbers. */
1383
        tmp16 = BUF->srcport;
1384
        BUF->srcport = BUF->destport;
1385
        BUF->destport = tmp16;
1386
 
1387
        /* Swap IP addresses. */
1388
        uip_ipaddr_copy( &BUF->destipaddr, &BUF->srcipaddr );
1389
        uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr );
1390
 
1391
        /* And send out the RST packet! */
1392
        goto tcp_send_noconn;
1393
 
1394
        /* This label will be jumped to if we matched the incoming packet
1395
        with a connection in LISTEN. In that case, we should create a new
1396
        connection and send a SYNACK in return. */
1397
found_listen:
1398
        /* First we check if there are any connections avaliable. Unused
1399
        connections are kept in the same table as used connections, but
1400
        unused ones have the tcpstate set to CLOSED. Also, connections in
1401
        TIME_WAIT are kept track of and we'll use the oldest one if no
1402
        CLOSED connections are found. Thanks to Eddie C. Dost for a very
1403
        nice algorithm for the TIME_WAIT search. */
1404
        uip_connr = 0;
1405
        for( c = 0; c < UIP_CONNS; ++c )
1406
        {
1407
                if( uip_conns[ c ].tcpstateflags == UIP_CLOSED )
1408
                {
1409
                        uip_connr = &uip_conns[ c ];
1410
                        break;
1411
                }
1412
 
1413
                if( uip_conns[ c ].tcpstateflags == UIP_TIME_WAIT )
1414
                {
1415
                        if( uip_connr == 0 || uip_conns[ c ].timer > uip_connr->timer )
1416
                        {
1417
                                uip_connr = &uip_conns[ c ];
1418
                        }
1419
                }
1420
        }
1421
 
1422
        if( uip_connr == 0 )
1423
        {
1424
                /* All connections are used already, we drop packet and hope that
1425
                the remote end will retransmit the packet at a time when we
1426
                have more spare connections. */
1427
                UIP_STAT( ++uip_stat.tcp.syndrop );
1428
                UIP_LOG( "tcp: found no unused connections." );
1429
                goto drop;
1430
        }
1431
 
1432
        uip_conn = uip_connr;
1433
 
1434
        /* Fill in the necessary fields for the new connection. */
1435
        uip_connr->rto = uip_connr->timer = UIP_RTO;
1436
        uip_connr->sa = 0;
1437
        uip_connr->sv = 4;
1438
        uip_connr->nrtx = 0;
1439
        uip_connr->lport = BUF->destport;
1440
        uip_connr->rport = BUF->srcport;
1441
        uip_ipaddr_copy( &uip_connr->ripaddr, &BUF->srcipaddr );
1442
        uip_connr->tcpstateflags = UIP_SYN_RCVD;
1443
 
1444
        uip_connr->snd_nxt[ 0 ] = iss[ 0 ];
1445
        uip_connr->snd_nxt[ 1 ] = iss[ 1 ];
1446
        uip_connr->snd_nxt[ 2 ] = iss[ 2 ];
1447
        uip_connr->snd_nxt[ 3 ] = iss[ 3 ];
1448
        uip_connr->len = 1;
1449
 
1450
        /* rcv_nxt should be the seqno from the incoming packet + 1. */
1451
        uip_connr->rcv_nxt[ 3 ] = BUF->seqno[ 3 ];
1452
        uip_connr->rcv_nxt[ 2 ] = BUF->seqno[ 2 ];
1453
        uip_connr->rcv_nxt[ 1 ] = BUF->seqno[ 1 ];
1454
        uip_connr->rcv_nxt[ 0 ] = BUF->seqno[ 0 ];
1455
        uip_add_rcv_nxt( 1 );
1456
 
1457
        /* Parse the TCP MSS option, if present. */
1458
        if( (BUF->tcpoffset & 0xf0) > 0x50 )
1459
        {
1460
                for( c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2; )
1461
                {
1462
                        opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
1463
                        if( opt == TCP_OPT_END )
1464
                        {
1465
                                /* End of options. */
1466
                                break;
1467
                        }
1468
                        else if( opt == TCP_OPT_NOOP )
1469
                        {
1470
                                ++c;
1471
 
1472
                                /* NOP option. */
1473
                        }
1474
                        else if( opt == TCP_OPT_MSS && uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN )
1475
                        {
1476
                                /* An MSS option with the right option length. */
1477
                                tmp16 = ( (u16_t) uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8 ) | ( u16_t ) uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
1478
                                uip_connr->initialmss = uip_connr->mss = tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16;
1479
 
1480
                                /* And we are done processing options. */
1481
                                break;
1482
                        }
1483
                        else
1484
                        {
1485
                                /* All other options have a length field, so that we easily
1486
                                can skip past them. */
1487
                                if( uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0 )
1488
                                {
1489
                                        /* If the length field is zero, the options are malformed
1490
                                        and we don't process them further. */
1491
                                        break;
1492
                                }
1493
 
1494
                                c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1495
                        }
1496
                }
1497
        }
1498
 
1499
        /* Our response will be a SYNACK. */
1500
        #if UIP_ACTIVE_OPEN
1501
                tcp_send_synack : BUF->flags = TCP_ACK;
1502
tcp_send_syn:
1503
                BUF->flags |= TCP_SYN;
1504
        #else /* UIP_ACTIVE_OPEN */
1505
                tcp_send_synack : BUF->flags = TCP_SYN | TCP_ACK;
1506
        #endif /* UIP_ACTIVE_OPEN */
1507
 
1508
        /* We send out the TCP Maximum Segment Size option with our
1509
        SYNACK. */
1510
        BUF->optdata[ 0 ] = TCP_OPT_MSS;
1511
        BUF->optdata[ 1 ] = TCP_OPT_MSS_LEN;
1512
        BUF->optdata[ 2 ] = ( UIP_TCP_MSS ) / 256;
1513
        BUF->optdata[ 3 ] = ( UIP_TCP_MSS ) & 255;
1514
        uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
1515
        BUF->tcpoffset = ( (UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4 ) << 4;
1516
        goto tcp_send;
1517
 
1518
        /* This label will be jumped to if we found an active connection. */
1519
found:
1520
        uip_conn = uip_connr;
1521
        uip_flags = 0;
1522
 
1523
        /* We do a very naive form of TCP reset processing; we just accept
1524
        any RST and kill our connection. We should in fact check if the
1525
        sequence number of this reset is wihtin our advertised window
1526
        before we accept the reset. */
1527
        if( BUF->flags & TCP_RST )
1528
        {
1529
                uip_connr->tcpstateflags = UIP_CLOSED;
1530
                UIP_LOG( "tcp: got reset, aborting connection." );
1531
                uip_flags = UIP_ABORT;
1532
                UIP_APPCALL();
1533
                goto drop;
1534
        }
1535
 
1536
        /* Calculate the length of the data, if the application has sent
1537
        any data to us. */
1538
        c = ( BUF->tcpoffset >> 4 ) << 2;
1539
 
1540
        /* uip_len will contain the length of the actual TCP data. This is
1541
        calculated by subtracing the length of the TCP header (in
1542
        c) and the length of the IP header (20 bytes). */
1543
        uip_len = uip_len - c - UIP_IPH_LEN;
1544
 
1545
        /* First, check if the sequence number of the incoming packet is
1546
        what we're expecting next. If not, we send out an ACK with the
1547
        correct numbers in. */
1548
        if( !(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) )
1549
        {
1550
                if
1551
                (
1552
                        (uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
1553
                        (
1554
                                BUF->seqno[ 0 ] != uip_connr->rcv_nxt[ 0 ] ||
1555
                                BUF->seqno[ 1 ] != uip_connr->rcv_nxt[ 1 ] ||
1556
                                BUF->seqno[ 2 ] != uip_connr->rcv_nxt[ 2 ] ||
1557
                                BUF->seqno[ 3 ] != uip_connr->rcv_nxt[ 3 ]
1558
                        )
1559
                )
1560
                {
1561
                        goto tcp_send_ack;
1562
                }
1563
        }
1564
 
1565
        /* Next, check if the incoming segment acknowledges any outstanding
1566
        data. If so, we update the sequence number, reset the length of
1567
        the outstanding data, calculate RTT estimations, and reset the
1568
        retransmission timer. */
1569
        if( (BUF->flags & TCP_ACK) && uip_outstanding(uip_connr) )
1570
        {
1571
                uip_add32( uip_connr->snd_nxt, uip_connr->len );
1572
 
1573
                if
1574
                (
1575
                        BUF->ackno[ 0 ] == uip_acc32[ 0 ] &&
1576
                        BUF->ackno[ 1 ] == uip_acc32[ 1 ] &&
1577
                        BUF->ackno[ 2 ] == uip_acc32[ 2 ] &&
1578
                        BUF->ackno[ 3 ] == uip_acc32[ 3 ]
1579
                )
1580
                {
1581
                        /* Update sequence number. */
1582
                        uip_connr->snd_nxt[ 0 ] = uip_acc32[ 0 ];
1583
                        uip_connr->snd_nxt[ 1 ] = uip_acc32[ 1 ];
1584
                        uip_connr->snd_nxt[ 2 ] = uip_acc32[ 2 ];
1585
                        uip_connr->snd_nxt[ 3 ] = uip_acc32[ 3 ];
1586
 
1587
                        /* Do RTT estimation, unless we have done retransmissions. */
1588
                        if( uip_connr->nrtx == 0 )
1589
                        {
1590
                                signed char m;
1591
                                m = uip_connr->rto - uip_connr->timer;
1592
 
1593
                                /* This is taken directly from VJs original code in his paper */
1594
                                m = m - ( uip_connr->sa >> 3 );
1595
                                uip_connr->sa += m;
1596
                                if( m < 0 )
1597
                                {
1598
                                        m = -m;
1599
                                }
1600
 
1601
                                m = m - ( uip_connr->sv >> 2 );
1602
                                uip_connr->sv += m;
1603
                                uip_connr->rto = ( uip_connr->sa >> 3 ) + uip_connr->sv;
1604
                        }
1605
 
1606
                        /* Set the acknowledged flag. */
1607
                        uip_flags = UIP_ACKDATA;
1608
 
1609
                        /* Reset the retransmission timer. */
1610
                        uip_connr->timer = uip_connr->rto;
1611
 
1612
                        /* Reset length of outstanding data. */
1613
                        uip_connr->len = 0;
1614
                }
1615
        }
1616
 
1617
        /* Do different things depending on in what state the connection is. */
1618
        switch( uip_connr->tcpstateflags & UIP_TS_MASK )
1619
        {
1620
                /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
1621
                implemented, since we force the application to close when the
1622
                peer sends a FIN (hence the application goes directly from
1623
                ESTABLISHED to LAST_ACK). */
1624
                case UIP_SYN_RCVD:
1625
                        /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
1626
                        we are waiting for an ACK that acknowledges the data we sent
1627
                        out the last time. Therefore, we want to have the UIP_ACKDATA
1628
                        flag set. If so, we enter the ESTABLISHED state. */
1629
                        if( uip_flags & UIP_ACKDATA )
1630
                        {
1631
                                uip_connr->tcpstateflags = UIP_ESTABLISHED;
1632
                                uip_flags = UIP_CONNECTED;
1633
                                uip_connr->len = 0;
1634
                                if( uip_len > 0 )
1635
                                {
1636
                                        uip_flags |= UIP_NEWDATA;
1637
                                        uip_add_rcv_nxt( uip_len );
1638
                                }
1639
 
1640
                                uip_slen = 0;
1641
                                UIP_APPCALL();
1642
                                goto appsend;
1643
                        }
1644
 
1645
                        goto drop;
1646
 
1647
                #if UIP_ACTIVE_OPEN
1648
                        case UIP_SYN_SENT:
1649
                                /* In SYN_SENT, we wait for a SYNACK that is sent in response to
1650
                                our SYN. The rcv_nxt is set to sequence number in the SYNACK
1651
                                plus one, and we send an ACK. We move into the ESTABLISHED
1652
                                state. */
1653
                                if( (uip_flags & UIP_ACKDATA) && (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK) )
1654
                                {
1655
                                        /* Parse the TCP MSS option, if present. */
1656
                                        if( (BUF->tcpoffset & 0xf0) > 0x50 )
1657
                                        {
1658
                                                for( c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2; )
1659
                                                {
1660
                                                        opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
1661
                                                        if( opt == TCP_OPT_END )
1662
                                                        {
1663
                                                                /* End of options. */
1664
                                                                break;
1665
                                                        }
1666
                                                        else if( opt == TCP_OPT_NOOP )
1667
                                                        {
1668
                                                                ++c;
1669
 
1670
                                                                /* NOP option. */
1671
                                                        }
1672
                                                        else if( opt == TCP_OPT_MSS && uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN )
1673
                                                        {
1674
                                                                /* An MSS option with the right option length. */
1675
                                                                tmp16 = ( uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8 ) | uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
1676
                                                                uip_connr->initialmss = uip_connr->mss = tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16;
1677
 
1678
                                                                /* And we are done processing options. */
1679
                                                                break;
1680
                                                        }
1681
                                                        else
1682
                                                        {
1683
                                                                /* All other options have a length field, so that we easily
1684
                                                                can skip past them. */
1685
                                                                if( uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0 )
1686
                                                                {
1687
                                                                        /* If the length field is zero, the options are malformed
1688
                                                                        and we don't process them further. */
1689
                                                                        break;
1690
                                                                }
1691
 
1692
                                                                c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
1693
                                                        }
1694
                                                }
1695
                                        }
1696
 
1697
                                        uip_connr->tcpstateflags = UIP_ESTABLISHED;
1698
                                        uip_connr->rcv_nxt[ 0 ] = BUF->seqno[ 0 ];
1699
                                        uip_connr->rcv_nxt[ 1 ] = BUF->seqno[ 1 ];
1700
                                        uip_connr->rcv_nxt[ 2 ] = BUF->seqno[ 2 ];
1701
                                        uip_connr->rcv_nxt[ 3 ] = BUF->seqno[ 3 ];
1702
                                        uip_add_rcv_nxt( 1 );
1703
                                        uip_flags = UIP_CONNECTED | UIP_NEWDATA;
1704
                                        uip_connr->len = 0;
1705
                                        uip_len = 0;
1706
                                        uip_slen = 0;
1707
                                        UIP_APPCALL();
1708
                                        goto appsend;
1709
                                }
1710
 
1711
                                /* Inform the application that the connection failed */
1712
                                uip_flags = UIP_ABORT;
1713
                                UIP_APPCALL();
1714
 
1715
                                /* The connection is closed after we send the RST */
1716
                                uip_conn->tcpstateflags = UIP_CLOSED;
1717
                                goto reset;
1718
                #endif /* UIP_ACTIVE_OPEN */
1719
 
1720
                case UIP_ESTABLISHED:
1721
                        /* In the ESTABLISHED state, we call upon the application to feed
1722
                        data into the uip_buf. If the UIP_ACKDATA flag is set, the
1723
                        application should put new data into the buffer, otherwise we are
1724
                        retransmitting an old segment, and the application should put that
1725
                        data into the buffer.
1726
 
1727
                        If the incoming packet is a FIN, we should close the connection on
1728
                        this side as well, and we send out a FIN and enter the LAST_ACK
1729
                        state. We require that there is no outstanding data; otherwise the
1730
                        sequence numbers will be screwed up. */
1731
                        if( BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED) )
1732
                        {
1733
                                if( uip_outstanding(uip_connr) )
1734
                                {
1735
                                        goto drop;
1736
                                }
1737
 
1738
                                uip_add_rcv_nxt( 1 + uip_len );
1739
                                uip_flags |= UIP_CLOSE;
1740
                                if( uip_len > 0 )
1741
                                {
1742
                                        uip_flags |= UIP_NEWDATA;
1743
                                }
1744
 
1745
                                UIP_APPCALL();
1746
                                uip_connr->len = 1;
1747
                                uip_connr->tcpstateflags = UIP_LAST_ACK;
1748
                                uip_connr->nrtx = 0;
1749
        tcp_send_finack:
1750
                                BUF->flags = TCP_FIN | TCP_ACK;
1751
                                goto tcp_send_nodata;
1752
                        }
1753
 
1754
                        /* Check the URG flag. If this is set, the segment carries urgent
1755
                        data that we must pass to the application. */
1756
                        if( (BUF->flags & TCP_URG) != 0 )
1757
                        {
1758
                                #if UIP_URGDATA > 0
1759
                                        uip_urglen = ( BUF->urgp[ 0 ] << 8 ) | BUF->urgp[ 1 ];
1760
                                        if( uip_urglen > uip_len )
1761
                                        {
1762
                                                /* There is more urgent data in the next segment to come. */
1763
                                                uip_urglen = uip_len;
1764
                                        }
1765
 
1766
                                        uip_add_rcv_nxt( uip_urglen );
1767
                                        uip_len -= uip_urglen;
1768
                                        uip_urgdata = uip_appdata;
1769
                                        uip_appdata += uip_urglen;
1770
                                        }
1771
                                        else
1772
                                        {
1773
                                        uip_urglen = 0;
1774
                                #else /* UIP_URGDATA > 0 */
1775
                                        uip_appdata = ( ( char * ) uip_appdata ) + ( (BUF->urgp[ 0 ] << 8) | BUF->urgp[ 1 ] );
1776
                                        uip_len -= ( BUF->urgp[ 0 ] << 8 ) | BUF->urgp[ 1 ];
1777
                                #endif /* UIP_URGDATA > 0 */
1778
                        }
1779
 
1780
                        /* If uip_len > 0 we have TCP data in the packet, and we flag this
1781
                        by setting the UIP_NEWDATA flag and update the sequence number
1782
                        we acknowledge. If the application has stopped the dataflow
1783
                        using uip_stop(), we must not accept any data packets from the
1784
                        remote host. */
1785
                        if( uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED) )
1786
                        {
1787
                                uip_flags |= UIP_NEWDATA;
1788
                                uip_add_rcv_nxt( uip_len );
1789
                        }
1790
 
1791
                        /* Check if the available buffer space advertised by the other end
1792
                        is smaller than the initial MSS for this connection. If so, we
1793
                        set the current MSS to the window size to ensure that the
1794
                        application does not send more data than the other end can
1795
                        handle.
1796
 
1797
                        If the remote host advertises a zero window, we set the MSS to
1798
                        the initial MSS so that the application will send an entire MSS
1799
                        of data. This data will not be acknowledged by the receiver,
1800
                        and the application will retransmit it. This is called the
1801
                        "persistent timer" and uses the retransmission mechanim.
1802
                        */
1803
                        tmp16 = ( (u16_t) BUF->wnd[ 0 ] << 8 ) + ( u16_t ) BUF->wnd[ 1 ];
1804
                        if( tmp16 > uip_connr->initialmss || tmp16 == 0 )
1805
                        {
1806
                                tmp16 = uip_connr->initialmss;
1807
                        }
1808
 
1809
                        uip_connr->mss = tmp16;
1810
 
1811
                        /* If this packet constitutes an ACK for outstanding data (flagged
1812
                        by the UIP_ACKDATA flag, we should call the application since it
1813
                        might want to send more data. If the incoming packet had data
1814
                        from the peer (as flagged by the UIP_NEWDATA flag), the
1815
                        application must also be notified.
1816
 
1817
                        When the application is called, the global variable uip_len
1818
                        contains the length of the incoming data. The application can
1819
                        access the incoming data through the global pointer
1820
                        uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
1821
                        bytes into the uip_buf array.
1822
 
1823
                        If the application wishes to send any data, this data should be
1824
                        put into the uip_appdata and the length of the data should be
1825
                        put into uip_len. If the application don't have any data to
1826
                        send, uip_len must be set to 0. */
1827
                        if( uip_flags & (UIP_NEWDATA | UIP_ACKDATA) )
1828
                        {
1829
                                uip_slen = 0;
1830
                                UIP_APPCALL();
1831
 
1832
appsend:
1833
                                if( uip_flags & UIP_ABORT )
1834
                                {
1835
                                        uip_slen = 0;
1836
                                        uip_connr->tcpstateflags = UIP_CLOSED;
1837
                                        BUF->flags = TCP_RST | TCP_ACK;
1838
                                        goto tcp_send_nodata;
1839
                                }
1840
 
1841
                                if( uip_flags & UIP_CLOSE )
1842
                                {
1843
                                        uip_slen = 0;
1844
                                        uip_connr->len = 1;
1845
                                        uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
1846
                                        uip_connr->nrtx = 0;
1847
                                        BUF->flags = TCP_FIN | TCP_ACK;
1848
                                        goto tcp_send_nodata;
1849
                                }
1850
 
1851
                                /* If uip_slen > 0, the application has data to be sent. */
1852
                                if( uip_slen > 0 )
1853
                                {
1854
                                        /* If the connection has acknowledged data, the contents of
1855
                                        the ->len variable should be discarded. */
1856
                                        if( (uip_flags & UIP_ACKDATA) != 0 )
1857
                                        {
1858
                                                uip_connr->len = 0;
1859
                                        }
1860
 
1861
                                        /* If the ->len variable is non-zero the connection has
1862
                                        already data in transit and cannot send anymore right
1863
                                        now. */
1864
                                        if( uip_connr->len == 0 )
1865
                                        {
1866
                                                /* The application cannot send more than what is allowed by
1867
                                                the mss (the minumum of the MSS and the available
1868
                                                window). */
1869
                                                if( uip_slen > uip_connr->mss )
1870
                                                {
1871
                                                        uip_slen = uip_connr->mss;
1872
                                                }
1873
 
1874
                                                /* Remember how much data we send out now so that we know
1875
                                                when everything has been acknowledged. */
1876
                                                uip_connr->len = uip_slen;
1877
                                        }
1878
                                        else
1879
                                        {
1880
                                                /* If the application already had unacknowledged data, we
1881
                                                make sure that the application does not send (i.e.,
1882
                                                retransmit) out more than it previously sent out. */
1883
                                                uip_slen = uip_connr->len;
1884
                                        }
1885
                                }
1886
 
1887
                                uip_connr->nrtx = 0;
1888
apprexmit:
1889
                                uip_appdata = uip_sappdata;
1890
 
1891
                                /* If the application has data to be sent, or if the incoming
1892
                                packet had new data in it, we must send out a packet. */
1893
                                if( uip_slen > 0 && uip_connr->len > 0 )
1894
                                {
1895
                                        /* Add the length of the IP and TCP headers. */
1896
                                        uip_len = uip_connr->len + UIP_TCPIP_HLEN;
1897
 
1898
                                        /* We always set the ACK flag in response packets. */
1899
                                        BUF->flags = TCP_ACK | TCP_PSH;
1900
 
1901
                                        /* Send the packet. */
1902
                                        goto tcp_send_noopts;
1903
                                }
1904
 
1905
                                /* If there is no data to send, just send out a pure ACK if
1906
                                there is newdata. */
1907
                                if( uip_flags & UIP_NEWDATA )
1908
                                {
1909
                                        uip_len = UIP_TCPIP_HLEN;
1910
                                        BUF->flags = TCP_ACK;
1911
                                        goto tcp_send_noopts;
1912
                                }
1913
                        }
1914
 
1915
                        goto drop;
1916
 
1917
                case UIP_LAST_ACK:
1918
                        /* We can close this connection if the peer has acknowledged our
1919
                        FIN. This is indicated by the UIP_ACKDATA flag. */
1920
                        if( uip_flags & UIP_ACKDATA )
1921
                        {
1922
                                uip_connr->tcpstateflags = UIP_CLOSED;
1923
                                uip_flags = UIP_CLOSE;
1924
                                UIP_APPCALL();
1925
                        }
1926
 
1927
                        break;
1928
 
1929
                case UIP_FIN_WAIT_1:
1930
                        /* The application has closed the connection, but the remote host
1931
                        hasn't closed its end yet. Thus we do nothing but wait for a
1932
                        FIN from the other side. */
1933
                        if( uip_len > 0 )
1934
                        {
1935
                                uip_add_rcv_nxt( uip_len );
1936
                        }
1937
 
1938
                        if( BUF->flags & TCP_FIN )
1939
                        {
1940
                                if( uip_flags & UIP_ACKDATA )
1941
                                {
1942
                                        uip_connr->tcpstateflags = UIP_TIME_WAIT;
1943
                                        uip_connr->timer = 0;
1944
                                        uip_connr->len = 0;
1945
                                }
1946
                                else
1947
                                {
1948
                                        uip_connr->tcpstateflags = UIP_CLOSING;
1949
                                }
1950
 
1951
                                uip_add_rcv_nxt( 1 );
1952
                                uip_flags = UIP_CLOSE;
1953
                                UIP_APPCALL();
1954
                                goto tcp_send_ack;
1955
                        }
1956
                        else if( uip_flags & UIP_ACKDATA )
1957
                        {
1958
                                uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
1959
                                uip_connr->len = 0;
1960
                                goto drop;
1961
                        }
1962
 
1963
                        if( uip_len > 0 )
1964
                        {
1965
                                goto tcp_send_ack;
1966
                        }
1967
 
1968
                        goto drop;
1969
 
1970
                case UIP_FIN_WAIT_2:
1971
                        if( uip_len > 0 )
1972
                        {
1973
                                uip_add_rcv_nxt( uip_len );
1974
                        }
1975
 
1976
                        if( BUF->flags & TCP_FIN )
1977
                        {
1978
                                uip_connr->tcpstateflags = UIP_TIME_WAIT;
1979
                                uip_connr->timer = 0;
1980
                                uip_add_rcv_nxt( 1 );
1981
                                uip_flags = UIP_CLOSE;
1982
                                UIP_APPCALL();
1983
                                goto tcp_send_ack;
1984
                        }
1985
 
1986
                        if( uip_len > 0 )
1987
                        {
1988
                                goto tcp_send_ack;
1989
                        }
1990
 
1991
                        goto drop;
1992
 
1993
                case UIP_TIME_WAIT:
1994
                        goto tcp_send_ack;
1995
 
1996
                case UIP_CLOSING:
1997
                        if( uip_flags & UIP_ACKDATA )
1998
                        {
1999
                                uip_connr->tcpstateflags = UIP_TIME_WAIT;
2000
                                uip_connr->timer = 0;
2001
                        }
2002
        }
2003
 
2004
        goto drop;
2005
 
2006
        /* We jump here when we are ready to send the packet, and just want
2007
         to set the appropriate TCP sequence numbers in the TCP header. */
2008
tcp_send_ack:
2009
        BUF->flags = TCP_ACK;
2010
 
2011
tcp_send_nodata:
2012
        uip_len = UIP_IPTCPH_LEN;
2013
 
2014
tcp_send_noopts:
2015
        BUF->tcpoffset = ( UIP_TCPH_LEN / 4 ) << 4;
2016
 
2017
        /* We're done with the input processing. We are now ready to send a
2018
        reply. Our job is to fill in all the fields of the TCP and IP
2019
        headers before calculating the checksum and finally send the
2020
        packet. */
2021
tcp_send:
2022
        BUF->ackno[ 0 ] = uip_connr->rcv_nxt[ 0 ];
2023
        BUF->ackno[ 1 ] = uip_connr->rcv_nxt[ 1 ];
2024
        BUF->ackno[ 2 ] = uip_connr->rcv_nxt[ 2 ];
2025
        BUF->ackno[ 3 ] = uip_connr->rcv_nxt[ 3 ];
2026
 
2027
        BUF->seqno[ 0 ] = uip_connr->snd_nxt[ 0 ];
2028
        BUF->seqno[ 1 ] = uip_connr->snd_nxt[ 1 ];
2029
        BUF->seqno[ 2 ] = uip_connr->snd_nxt[ 2 ];
2030
        BUF->seqno[ 3 ] = uip_connr->snd_nxt[ 3 ];
2031
 
2032
        BUF->proto = UIP_PROTO_TCP;
2033
 
2034
        BUF->srcport = uip_connr->lport;
2035
        BUF->destport = uip_connr->rport;
2036
 
2037
        uip_ipaddr_copy( &BUF->srcipaddr, &uip_hostaddr );
2038
        uip_ipaddr_copy( &BUF->destipaddr, &uip_connr->ripaddr );
2039
 
2040
        if( uip_connr->tcpstateflags & UIP_STOPPED )
2041
        {
2042
                /* If the connection has issued uip_stop(), we advertise a zero
2043
                window so that the remote host will stop sending data. */
2044
                BUF->wnd[ 0 ] = BUF->wnd[ 1 ] = 0;
2045
        }
2046
        else
2047
        {
2048
                BUF->wnd[ 0 ] = ( (UIP_RECEIVE_WINDOW) >> 8 );
2049
                BUF->wnd[ 1 ] = ( (UIP_RECEIVE_WINDOW) & 0xff );
2050
        }
2051
 
2052
tcp_send_noconn:
2053
 
2054
        BUF->ttl = UIP_TTL;
2055
 
2056
        #if UIP_CONF_IPV6
2057
                /* For IPv6, the IP length field does not include the IPv6 IP header
2058
                 length. */
2059
                BUF->len[ 0 ] = ( (uip_len - UIP_IPH_LEN) >> 8 );
2060
                BUF->len[ 1 ] = ( (uip_len - UIP_IPH_LEN) & 0xff );
2061
        #else /* UIP_CONF_IPV6 */
2062
                BUF->len[ 0 ] = ( uip_len >> 8 );
2063
                BUF->len[ 1 ] = ( uip_len & 0xff );
2064
        #endif /* UIP_CONF_IPV6 */
2065
 
2066
        BUF->urgp[ 0 ] = BUF->urgp[ 1 ] = 0;
2067
 
2068
        /* Calculate TCP checksum. */
2069
        BUF->tcpchksum = 0;
2070
        BUF->tcpchksum = ~( uip_tcpchksum() );
2071
 
2072
ip_send_nolen:
2073
        #if UIP_CONF_IPV6
2074
                BUF->vtc = 0x60;
2075
                BUF->tcflow = 0x00;
2076
                BUF->flow = 0x00;
2077
        #else /* UIP_CONF_IPV6 */
2078
                BUF->vhl = 0x45;
2079
                BUF->tos = 0;
2080
                BUF->ipoffset[ 0 ] = BUF->ipoffset[ 1 ] = 0;
2081
                ++ipid;
2082
                BUF->ipid[ 0 ] = ipid >> 8;
2083
                BUF->ipid[ 1 ] = ipid & 0xff;
2084
 
2085
                /* Calculate IP checksum. */
2086
                BUF->ipchksum = 0;
2087
                BUF->ipchksum = ~( uip_ipchksum() );
2088
 
2089
                //DEBUG_PRINTF( "uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum() );
2090
        #endif /* UIP_CONF_IPV6 */
2091
 
2092
        UIP_STAT( ++uip_stat.tcp.sent );
2093
 
2094
        #if UIP_CONF_IPV6
2095
send :
2096
        #endif /* UIP_CONF_IPV6 */
2097
 
2098
        //DEBUG_PRINTF( "Sending packet with length %d (%d)\n", uip_len, (BUF->len[ 0 ] << 8) | BUF->len[ 1 ] );
2099
        UIP_STAT( ++uip_stat.ip.sent );
2100
 
2101
        /* Return and let the caller do the actual transmission. */
2102
        uip_flags = 0;
2103
        return;
2104
 
2105
drop:
2106
        uip_len = 0;
2107
        uip_flags = 0;
2108
        return;
2109
}
2110
/*---------------------------------------------------------------------------*/
2111
 
2112
u16_t htons( u16_t val )
2113
{
2114
        return HTONS( val );
2115
}
2116
 
2117
u32_t htonl( u32_t val )
2118
{
2119
        return HTONL( val );
2120
}
2121
/*---------------------------------------------------------------------------*/
2122
 
2123
void uip_send( const void *data, int len )
2124
{
2125
        int copylen;
2126
 
2127
        #define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
2128
 
2129
        copylen = MIN( len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - ( int )
2130
                                           (( char * ) uip_sappdata - ( char * ) &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]) );
2131
        if( copylen > 0 )
2132
        {
2133
                uip_slen = copylen;
2134
                if( data != uip_sappdata )
2135
                {
2136
                        memcpy( uip_sappdata, (data), uip_slen );
2137
                }
2138
        }
2139
}
2140
/*---------------------------------------------------------------------------*/
2141
 
2142
/** @} */
2143
#endif /* UIP_CONF_IPV6 */

powered by: WebSVN 2.1.0

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