summaryrefslogtreecommitdiff
path: root/nuttx/include/net/uip/uip.h
blob: c662e2ccfc329fe5943f9d9499df628e2245e075 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
/****************************************************************************
 * net/uip/uip.h
 *
 * The uIP header file contains definitions for a number of C macros that
 * are used by uIP programs as well as internal uIP structures and function
 * declarations.
 *
 *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
 *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
 *
 * This logic was leveraged from uIP which also has a BSD-style license:
 *
 *   Author Adam Dunkels <adam@dunkels.com>
 *   Copyright (c) 2001-2003, Adam Dunkels.
 *   All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

#ifndef __NET_UIP_UIP_H
#define __NET_UIP_UIP_H

/****************************************************************************
 * Included Files
 ****************************************************************************/

#include <nuttx/config.h>

#include <sys/types.h>
#include <queue.h>
#include <arpa/inet.h>

#include <net/uip/uipopt.h>
/****************************************************************************
 * Definitions
 ****************************************************************************/

/* The following flags may be set in the set of flags before calling the
 * application callback. The UIP_ACKDATA, UIP_NEWDATA, and UIP_CLOSE flags
 * may be set at the same time, whereas the others are mutualy exclusive.
 */

#define UIP_ACKDATA    (1 << 0) /* Signifies that the outstanding data was acked and the
                                 * application should send out new data instead of retransmitting
                                 * the last data */
#define UIP_NEWDATA    (1 << 1) /* Flags the fact that the peer has sent us new data */
#define UIP_REXMIT     (1 << 2) /* Tells the application to retransmit the data that was last
                                 * sent */
#define UIP_POLL       (1 << 3) /* Used for polling the application, to check if the application
                                 * has data that it wants to send */
#define UIP_CLOSE      (1 << 4) /* The remote host has closed the connection, thus the connection
                                 * has gone away. Or the application signals that it wants to
                                 * close the connection */
#define UIP_ABORT      (1 << 5) /* The remote host has aborted the connection, thus the connection
                                 * has gone away. Or the application signals that it wants to
                                 * abort the connection */
#define UIP_CONNECTED  (1 << 6) /* We have got a connection from a remote host and have set up a
                                 * new connection for it, or an active connection has been
                                 * successfully established */
#define UIP_TIMEDOUT   (1 << 7) /* The connection has been aborted due to too many retransmissions */

#define UIP_DATA_EVENTS (UIP_ACKDATA|UIP_NEWDATA|UIP_REXMIT|UIP_POLL)
#define UIP_CONN_EVENTS (UIP_CLOSE|UIP_ABORT|UIP_CONNECTED|UIP_TIMEDOUT)

/* The buffer size available for user data in the d_buf buffer.
 *
 * This macro holds the available size for user data in the
 * d_buf buffer. The macro is intended to be used for checking
 * bounds of available user data.
 *
 * Example:
 *
 *   snprintf(dev->d_appdata, UIP_APPDATA_SIZE, "%u\n", i);
 */

#define UIP_APPDATA_SIZE (CONFIG_NET_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)

#define UIP_PROTO_ICMP  1
#define UIP_PROTO_TCP   6
#define UIP_PROTO_UDP   17
#define UIP_PROTO_ICMP6 58

/* Header sizes */

#ifdef CONFIG_NET_IPv6
# define UIP_IPH_LEN    40    /* Size of IP header */
#else
# define UIP_IPH_LEN    20    /* Size of IP header */
#endif

/****************************************************************************
 * Public Type Definitions
 ****************************************************************************/

/* Repressentation of an IP address */

typedef in_addr_t uip_ip4addr_t;
typedef uint16 uip_ip6addr_t[8];

#ifdef CONFIG_NET_IPv6
typedef uip_ip6addr_t uip_ipaddr_t;
#else
typedef uip_ip4addr_t uip_ipaddr_t;
#endif

/* The IP header */

struct uip_ip_hdr
{
#ifdef CONFIG_NET_IPv6

  /* IPv6 Ip header */

  uint8  vtc;               /* Bits 0-3: version, bits 4-7: traffic class (MS) */
  uint8  tcf;               /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
  uint16 flow;              /* 16-bit flow label (LS) */
  uint8  len[2];            /* 16-bit Payload length */
  uint8  proto;             /*  8-bit Next header (same as IPv4 protocol field) */
  uint8  ttl;               /*  8-bit Hop limit (like IPv4 TTL field) */
  uip_ip6addr_t srcipaddr;  /* 128-bit Source address */
  uip_ip6addr_t destipaddr; /* 128-bit Destination address */

#else /* CONFIG_NET_IPv6 */

  /* IPv4 IP header */

  uint8  vhl;              /*  8-bit Version (4) and header length (5 or 6) */
  uint8  tos;              /*  8-bit Type of service (e.g., 6=TCP) */
  uint8  len[2];           /* 16-bit Total length */
  uint8  ipid[2];          /* 16-bit Identification */
  uint8  ipoffset[2];      /* 16-bit IP flags + fragment offset */
  uint8  ttl;              /*  8-bit Time to Live */
  uint8  proto;            /*  8-bit Protocol */
  uint16 ipchksum;         /* 16-bit Header checksum */
  uint16 srcipaddr[2];     /* 32-bit Source IP address */
  uint16 destipaddr[2];    /* 32-bit Destination IP address */

#endif /* CONFIG_NET_IPv6 */
};

/* Protocol-specific support */

#include <net/uip/uip-tcp.h>
#include <net/uip/uip-udp.h>
#include <net/uip/uip-icmp.h>

/* The structure holding the uIP statistics that are gathered if
 * CONFIG_NET_STATISTICS is defined.
 */

#ifdef CONFIG_NET_STATISTICS
struct uip_ip_stats_s
{
  uip_stats_t drop;       /* Number of dropped packets at the IP layer */
  uip_stats_t recv;       /* Number of received packets at the IP layer */
  uip_stats_t sent;       /* Number of sent packets at the IP layer */
  uip_stats_t vhlerr;     /* Number of packets dropped due to wrong
                             IP version or header length */
  uip_stats_t hblenerr;   /* Number of packets dropped due to wrong
                             IP length, high byte */
  uip_stats_t lblenerr;   /* Number of packets dropped due to wrong
                             IP length, low byte */
  uip_stats_t fragerr;    /* Number of packets dropped since they
                             were IP fragments */
  uip_stats_t chkerr;     /* Number of packets dropped due to IP
                             checksum errors */
  uip_stats_t protoerr;   /* Number of packets dropped since they
                             were neither ICMP, UDP nor TCP */
};

struct uip_stats
{
  struct uip_ip_stats_s   ip;   /* IP statistics */

#ifdef CONFIG_NET_ICMP
  struct uip_icmp_stats_s icmp; /* ICMP statistics */
#endif

#ifdef CONFIG_NET_TCP
  struct uip_tcp_stats_s  tcp;  /* TCP statistics */
#endif

#ifdef CONFIG_NET_UDP
  struct uip_udp_stats_s  udp;  /* UDP statistics */
#endif
};
#endif /* CONFIG_NET_STATISTICS */

/* Representation of a 48-bit Ethernet address */

struct uip_eth_addr
{
  uint8 addr[6];
};

/****************************************************************************
 * Public Data
 ****************************************************************************/

/* This is the structure in which the statistics are gathered. */

#ifdef CONFIG_NET_STATISTICS
extern struct uip_stats uip_stat;
#endif

/****************************************************************************
 * Public Function Prototypes
 ****************************************************************************/

/* uIP initialization functions
 *
 * The uIP initialization functions are used for booting uIP.
 *
 * This function should be called at boot up to initilize the uIP
 * TCP/IP stack.
 */

extern void uip_initialize(void);

/* This function may be used at boot time to set the initial ip_id.*/

extern void uip_setipid(uint16 id);

/* uIP application functions
 *
 * Functions used by an application running of top of uIP. This includes
 * functions for opening and closing connections, sending and receiving
 * data, etc.
 */

/* Send data on the current connection.
 *
 * This function is used to send out a single segment of TCP
 * data. Only applications that have been invoked by uIP for event
 * processing can send data.
 *
 * The amount of data that actually is sent out after a call to this
 * funcion is determined by the maximum amount of data TCP allows. uIP
 * will automatically crop the data so that only the appropriate
 * amount of data is sent. The function uip_mss() can be used to query
 * uIP for the amount of data that actually will be sent.
 *
 * Note: This function does not guarantee that the sent data will
 * arrive at the destination. If the data is lost in the network, the
 * application will be invoked with the uip_rexmit_event() event being
 * set. The application will then have to resend the data using this
 * function.
 *
 * data A pointer to the data which is to be sent.
 *
 * len The maximum amount of data bytes to be sent.
 */

extern void uip_send(struct uip_driver_s *dev, const void *buf, int len);

/* The length of any incoming data that is currently avaliable (if avaliable)
 * in the d_appdata buffer.
 *
 * The test function uip_data() must first be used to check if there
 * is any data available at all.
 */

#define uip_datalen(dev)    ((dev)->d_len)

/* uIP tests that can be made to determine in what state the current
 * connection is, and what the application function should do.
 *
 * Is new incoming data available?
 *
 * Will reduce to non-zero if there is new data for the application
 * present at the d_appdata pointer. The size of the data is
 * avaliable through the d_len element.
 */

#define uip_newdata_event(f) ((f) & UIP_NEWDATA)

/* Has previously sent data been acknowledged?
 *
 * Will reduce to non-zero if the previously sent data has been
 * acknowledged by the remote host. This means that the application
 * can send new data.
 */

#define uip_ack_event(f) ((f) & UIP_ACKDATA)

/* Has the connection just been connected?
 *
 * Reduces to non-zero if the current connenetutils/telnetd/telnetd.cction has been connected to
 * a remote host. This will happen both if the connection has been
 * actively opened (with uip_connect()) or passively opened (with
 * uip_listen()).
 */

#define uip_connected_event(f) ((f) & UIP_CONNECTED)

/* Has the connection been closed by the other end?
 *
 * Is non-zero if the connection has been closed by the remote
 * host. The application may then do the necessary clean-ups.
 */

#define uip_close_event(f) ((f) & UIP_CLOSE)

/* Has the connection been aborted by the other end?
 *
 * Non-zero if the current connection has been aborted (reset) by the
 * remote host.
 */

#define uip_abort_event(f) ((f) & UIP_ABORT)

/* Has the connection timed out?
 *
 * Non-zero if the current connection has been aborted due to too many
 * retransmissions.
 */

#define uip_timeout_event(f) ((f) & UIP_TIMEDOUT)

/* Do we need to retransmit previously data?
 *
 * Reduces to non-zero if the previously sent data has been lost in
 * the network, and the application should retransmit it. The
 * application should send the exact same data as it did the last
 * time, using the uip_send() function.
 */

#define uip_rexmit_event(f) ((f) & UIP_REXMIT)

/* Is the connection being polled by uIP?
 *
 * Is non-zero if the reason the application is invoked is that the
 * current connection has been idle for a while and should be
 * polled.
 *
 * The polling event can be used for sending data without having to
 * wait for the remote host to send data.
 */

#define uip_poll_event(f) ((f) & UIP_POLL)

/* uIP convenience and converting functions.
 *
 * These functions can be used for converting between different data
 * formats used by uIP.
 *
 * Construct an IP address from four bytes.
 *
 * This function constructs an IPv4 address in network byte order.
 *
 *   addr  A pointer to a uip_ipaddr_t variable that will be
 *         filled in with the IPv4 address.
 *   addr0 The first octet of the IPv4 address.
 *   addr1 The second octet of the IPv4 address.
 *   addr2 The third octet of the IPv4 address.
 *   addr3 The forth octet of the IPv4 address.
 */

#define uip_ipaddr(addr, addr0, addr1, addr2, addr3) \
  do { \
    addr = HTONL((addr0) << 24 | (addr1) << 16 | (addr2) << 8 | (addr3)); \
  } while(0)

/* Convert an IPv4 address of the form uint16[2] to an in_addr_t */

#ifdef CONFIG_ENDIAN_BIG
#  define uip_ip4addr_conv(addr) (((in_addr_t)((uint16*)addr)[0] << 16) | (in_addr_t)((uint16*)addr)[1])
#else
#  define uip_ip4addr_conv(addr) (((in_addr_t)((uint16*)addr)[1] << 16) | (in_addr_t)((uint16*)addr)[0])
#endif

/* Construct an IPv6 address from eight 16-bit words.
 *
 * This function constructs an IPv6 address.
 */

#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) \
  do { \
    ((uint16*)(addr))[0] = HTONS((addr0)); \
    ((uint16*)(addr))[1] = HTONS((addr1)); \
    ((uint16*)(addr))[2] = HTONS((addr2)); \
    ((uint16*)(addr))[3] = HTONS((addr3)); \
    ((uint16*)(addr))[4] = HTONS((addr4)); \
    ((uint16*)(addr))[5] = HTONS((addr5)); \
    ((uint16*)(addr))[6] = HTONS((addr6)); \
    ((uint16*)(addr))[7] = HTONS((addr7)); \
  } while(0)

/* Copy an IP address to another IP address.
 *
 * Copies an IP address from one place to another.
 *
 * Example:
 *
 *   uip_ipaddr_t ipaddr1, ipaddr2;
 *
 *   uip_ipaddr(&ipaddr1, 192,16,1,2);
 *   uip_ipaddr_copy(&ipaddr2, &ipaddr1);
 *
 * dest The destination for the copy.
 * src The source from where to copy.
 */

#ifndef CONFIG_NET_IPv6
#  define uip_ipaddr_copy(dest, src) \
   do { \
     (dest) = (in_addr_t)(src); \
   } while(0)
#  define uiphdr_ipaddr_copy(dest, src) \
   do { \
     ((uint16*)(dest))[0] = ((uint16*)(src))[0]; \
     ((uint16*)(dest))[1] = ((uint16*)(src))[1]; \
   } while(0)
#else /* !CONFIG_NET_IPv6 */
#  define uip_ipaddr_copy(dest, src)    memcpy(&dest, &src, sizeof(uip_ip6addr_t))
#  define uiphdr_ipaddr_copy(dest, src) uip_ipaddr_copy(dest, src)
#endif /* !CONFIG_NET_IPv6 */

/* Compare two IP addresses
 *
 * Example:
 *
 *   uip_ipaddr_t ipaddr1, ipaddr2;
 *
 *   uip_ipaddr(&ipaddr1, 192,16,1,2);
 *   if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
 *      printf("They are the same");
 *   }
 *
 * addr1 The first IP address.
 * addr2 The second IP address.
 */

#ifndef CONFIG_NET_IPv6
#  define uip_ipaddr_cmp(addr1, addr2)    (addr1 == addr2)
#  define uiphdr_ipaddr_cmp(addr1, addr2) uip_ipaddr_cmp(uip_ip4addr_conv(addr1), uip_ip4addr_conv(addr2))
#else /* !CONFIG_NET_IPv6 */
#  define uip_ipaddr_cmp(addr1, addr2)    (memcmp(&addr1, &addr2, sizeof(uip_ip6addr_t)) == 0)
#  define uiphdr_ipaddr_cmp(addr1, addr2) uip_ipaddr_cmp(addr, addr2)
#endif /* !CONFIG_NET_IPv6 */

/* Compare two IP addresses with netmasks
 *
 * Compares two IP addresses with netmasks. The masks are used to mask
 * out the bits that are to be compared.
 *
 * Example:
 *
 *   uip_ipaddr_t ipaddr1, ipaddr2, mask;
 *
 *   uip_ipaddr(&mask, 255,255,255,0);
 *   uip_ipaddr(&ipaddr1, 192,16,1,2);
 *   uip_ipaddr(&ipaddr2, 192,16,1,3);
 *   if(uip_ipaddr_maskcmp(ipaddr1, ipaddr2, &mask))
 *     {
 *       printf("They are the same");
 *     }
 *
 * addr1 The first IP address.
 * addr2 The second IP address.
 * mask The netmask.
 */

#ifndef CONFIG_NET_IPv6
#  define uip_ipaddr_maskcmp(addr1, addr2, mask) \
  (((in_addr_t)(addr1) & (in_addr_t)(mask)) == \
   ((in_addr_t)(addr2) & (in_addr_t)(mask)))
#else
extern boolean uip_ipaddr_maskcmp(uip_addr_t addr1, uip_addr_t addr2,
                                  uip_addr_t mask);
#endif

/* Mask out the network part of an IP address.
 *
 * Masks out the network part of an IP address, given the address and
 * the netmask.
 *
 * Example:
 *
 *   uip_ipaddr_t ipaddr1, ipaddr2, netmask;
 *
 *   uip_ipaddr(&ipaddr1, 192,16,1,2);
 *   uip_ipaddr(&netmask, 255,255,255,0);
 *   uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
 *
 * In the example above, the variable "ipaddr2" will contain the IP
 * address 192.168.1.0.
 *
 * dest Where the result is to be placed.
 * src The IP address.
 * mask The netmask.
 */

#define uip_ipaddr_mask(dest, src, mask) \
  do { \
    (in_addr_t)(dest) = (in_addr_t)(src) & (in_addr_t)(mask); \
  } while(0)

#endif /* __NET_UIP_UIP_H */