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

Subversion Repositories openrisc

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

powered by: WebSVN 2.1.0

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