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

Subversion Repositories igor

[/] [igor/] [trunk/] [avr/] [eth-test/] [uip/] [uip.c] - Blame information for rev 4

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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