41 #include "contiki-net.h"
43 #include "net/ip/uip-packetqueue.h"
45 #if NETSTACK_CONF_WITH_IPV6
51 #include "net/rpl/rpl.h"
52 #include "net/rpl/rpl-private.h"
57 #define DEBUG DEBUG_NONE
63 #define UIP_LOG(m) uip_log(m)
68 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN + uip_ext_len])
69 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
70 #define UIP_TCP_BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
72 #ifdef UIP_FALLBACK_INTERFACE
73 extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
86 static struct etimer periodic;
88 #if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_REASSEMBLY
102 static struct internal_state {
115 #if NETSTACK_CONF_WITH_IPV6
123 if(outputfunc !=
NULL) {
127 UIP_LOG(
"tcpip_output: Use tcpip_set_outputfunc() to set an output function");
132 tcpip_set_outputfunc(uint8_t (*f)(
const uip_lladdr_t *))
138 static uint8_t (* outputfunc)(void);
142 if(outputfunc !=
NULL) {
145 UIP_LOG(
"tcpip_output: Use tcpip_set_outputfunc() to set an output function");
150 tcpip_set_outputfunc(uint8_t (*f)(
void))
156 #if UIP_CONF_IP_FORWARD
157 unsigned char tcpip_is_forwarding;
160 PROCESS(tcpip_process,
"TCP/IP stack");
163 #if UIP_TCP || UIP_CONF_IP_FORWARD
165 start_periodic_tcp_timer(
void)
174 check_for_tcp_syn(
void)
176 #if UIP_TCP || UIP_CONF_IP_FORWARD
184 (UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
185 start_periodic_tcp_timer();
195 #if UIP_CONF_IP_FORWARD
196 tcpip_is_forwarding = 1;
198 tcpip_is_forwarding = 0;
201 tcpip_is_forwarding = 0;
207 #if UIP_CONF_TCP_SPLIT
210 #if NETSTACK_CONF_WITH_IPV6
213 PRINTF(
"tcpip packet_input output len %d\n",
uip_len);
234 c->appstate.state = appstate;
246 struct listenport *l;
250 if(l->port == port &&
264 struct listenport *l;
304 udp_new(
const uip_ipaddr_t *ripaddr, uint16_t port,
void *appstate)
327 #if NETSTACK_CONF_WITH_IPV6
332 conn =
udp_new(&addr, port, appstate);
364 eventhandler(process_event_t ev, process_data_t data)
368 register struct listenport *l;
373 case PROCESS_EVENT_EXITED:
379 p = (
struct process *)data;
394 for(cptr = &uip_conns[0]; cptr < &uip_conns[
UIP_CONNS]; ++cptr) {
395 if(cptr->appstate.p == p) {
396 cptr->appstate.p = PROCESS_NONE;
406 for(cptr = &uip_udp_conns[0];
416 case PROCESS_EVENT_TIMER:
421 if(data == &periodic &&
430 #if NETSTACK_CONF_WITH_IPV6
434 PRINTF(
"tcpip_output from periodic len %d\n",
uip_len);
436 PRINTF(
"tcpip_output after periodic len %d\n",
uip_len);
442 #if UIP_CONF_IP_FORWARD
447 #if NETSTACK_CONF_WITH_IPV6
448 #if UIP_CONF_IPV6_REASSEMBLY
487 #if NETSTACK_CONF_WITH_IPV6
491 PRINTF(
"tcpip_output from tcp poll len %d\n",
uip_len);
496 start_periodic_tcp_timer();
504 #if NETSTACK_CONF_WITH_IPV6
528 #if NETSTACK_CONF_WITH_IPV6
533 uip_ipaddr_t *nexthop =
NULL;
540 UIP_LOG(
"tcpip_ipv6_output: Packet to big");
546 UIP_LOG(
"tcpip_ipv6_output: Destination address unspecified");
554 #if UIP_CONF_IPV6_RPL && RPL_WITH_NON_STORING
557 if(rpl_srh_get_next_hop(&ipaddr)) {
567 if(nexthop ==
NULL && uip_ds6_is_addr_onlink(&
UIP_IP_BUF->destipaddr)){
571 if(nexthop ==
NULL) {
574 route = uip_ds6_route_lookup(&
UIP_IP_BUF->destipaddr);
578 PRINTF(
"tcpip_ipv6_output: no route found, using default route\n");
579 nexthop = uip_ds6_defrt_choose();
580 if(nexthop ==
NULL) {
581 #ifdef UIP_FALLBACK_INTERFACE
582 PRINTF(
"FALLBACK: removing ext hdrs & setting proto %d %d\n",
585 extern void remove_ext_hdr(
void);
586 uint8_t proto = *((uint8_t *)
UIP_IP_BUF + 40);
594 if(UIP_FALLBACK_INTERFACE.output() < 0) {
595 PRINTF(
"FALLBACK: output error. Reporting DST UNREACH\n");
602 PRINTF(
"tcpip_ipv6_output: Destination off-link but no route\n");
611 nexthop = uip_ds6_route_nexthop(route);
615 if(nexthop ==
NULL) {
616 #if UIP_CONF_IPV6_RPL
621 rpl_instance_t *instance;
623 dag = (rpl_dag_t *)route->state.dag;
625 instance = dag->instance;
627 rpl_repair_root(instance->instance_id);
630 uip_ds6_route_rm(route);
637 #if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
638 if(nexthop !=
NULL) {
639 static uint8_t annotate_last;
640 static uint8_t annotate_has_last = 0;
642 if(annotate_has_last) {
643 printf(
"#L %u 0; red\n", annotate_last);
645 printf(
"#L %u 1; red\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
646 annotate_last = nexthop->u8[
sizeof(uip_ipaddr_t) - 1];
647 annotate_has_last = 1;
654 #if UIP_CONF_IPV6_RPL
655 if(!rpl_finalize_header(nexthop)) {
660 nbr = uip_ds6_nbr_lookup(nexthop);
665 PRINTF(
"tcpip_ipv6_output: failed to add neighbor to cache\n");
668 #if UIP_CONF_IPV6_QUEUE_PKT
670 if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) !=
NULL) {
672 uip_packetqueue_set_buflen(&nbr->packethandle,
uip_len);
681 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->srcipaddr)){
692 PRINTF(
"tcpip_ipv6_output: neighbor not in cache\n");
699 PRINTF(
"tcpip_ipv6_output: nbr cache entry incomplete\n");
700 #if UIP_CONF_IPV6_QUEUE_PKT
703 if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) !=
NULL) {
705 uip_packetqueue_set_buflen(&nbr->packethandle,
uip_len);
713 if(nbr->state == NBR_STALE) {
714 nbr->state = NBR_DELAY;
715 stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
717 PRINTF(
"tcpip_ipv6_output: nbr cache entry stale moving to delay\n");
723 #if UIP_CONF_IPV6_QUEUE_PKT
730 if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
731 uip_len = uip_packetqueue_buflen(&nbr->packethandle);
733 uip_packetqueue_free(&nbr->packethandle);
782 struct listenport *l;
787 l = &s.listenports[0];
790 l->p != PROCESS_NONE) {
799 start_periodic_tcp_timer();
818 s.listenports[i].port = 0;
831 #ifdef UIP_FALLBACK_INTERFACE
832 UIP_FALLBACK_INTERFACE.init();
835 #if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL
841 eventhandler(ev, data);
void uip_log(char *msg)
Print out a uIP log message.
Header file for IPv6 Neighbor discovery (RFC 4861)
uip_len
The length of the packet in the uip_buf buffer.
uint8_t tcpstateflags
TCP state and flags.
void uip_split_output(void)
Handle outgoing packets.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Representation of a uIP TCP connection.
#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
Construct an IP address from four bytes.
static uip_ds6_addr_t * addr
Pointer to a router list entry.
process_event_t tcpip_event
The uIP event.
Header file for IPv6-related data structures.
#define UIP_CONNS
The maximum number of simultaneously open TCP connections.
void etimer_restart(struct etimer *et)
Restart an event timer from the current point in time.
CCIF struct uip_conn * tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Open a TCP connection to the specified IP address and port.
void uip_ds6_send_rs(void)
Send periodic RS to find router.
uip_udp_appstate_t appstate
The application state.
struct uip_udp_conn * udp_broadcast_new(uint16_t port, void *appstate)
Create a new UDP broadcast connection.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define PROCESS_END()
Define the end of a process.
Representation of a uIP UDP connection.
#define PROCESS(name, strname)
Declare a process.
void tcp_listen(uint16_t port)
Open a TCP port.
#define uip_periodic(conn)
Periodic processing for a connection identified by its number.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
void udp_attach(struct uip_udp_conn *conn, void *appstate)
Attach the current process to a UDP connection.
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
void tcpip_poll_tcp(struct uip_conn *conn)
Cause a specified TCP connection to be polled.
#define ICMP6_DST_UNREACH
dest unreachable
uip_ipaddr_t ripaddr
The IP address of the remote host.
An entry in the nbr cache.
#define UIP_IP_BUF
Pointer to IP header.
#define uip_poll_conn(conn)
Request that a particular connection should be polled.
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 3513 a is of type uip_ipaddr_t*
void uip_listen(uint16_t port)
Start listening to the specified port.
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
process_event_t process_alloc_event(void)
Allocate a global event number.
static uip_ds6_route_t * route
The next route to use.
#define uip_create_linklocal_allnodes_mcast(a)
set IP address a to the link local all-nodes multicast address
struct etimer uip_ds6_timer_periodic
Timer for maintenance of data structures.
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
Set up a new UDP connection.
struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
void uip_reass_over(void)
Abandon the reassembly of the current packet.
#define UIP_FW_LOCAL
A non-error message that indicates that a packet should be processed locally.
uint8_t uip_ext_len
The length of the extension headers.
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
Post a synchronous event to a process.
void tcp_unlisten(uint16_t port)
Close a listening TCP port.
void tcpip_ipv6_output(void)
This function does address resolution and then calls tcpip_output.
void tcpip_icmp6_call(uint8_t type)
This function is called at reception of an ICMPv6 packet If an application registered as an ICMPv6 li...
#define NULL
The null pointer.
#define uip_udp_periodic_conn(conn)
Periodic processing for a UDP connection identified by a pointer to its structure.
struct etimer uip_ds6_timer_rs
RS timer, to schedule RS sending.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
void stimer_set(struct stimer *t, unsigned long interval)
Set a timer.
#define PROCESS_YIELD()
Yield the currently running process.
uint8_t icmp6_new(void *appstate)
register an ICMPv6 callback
void tcp_attach(struct uip_conn *conn, void *appstate)
Attach a TCP connection to the current process.
process_event_t tcpip_icmp6_event
The ICMP6 event.
void uip_ds6_periodic(void)
Periodic processing of data structures.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
uint8_t uip_fw_forward(void)
Forward an IP packet in the uip_buf buffer.
uint16_t lport
The local TCP port, in network byte order.
uip_ds6_nbr_t * uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, uint8_t isrouter, uint8_t state, nbr_table_reason_t reason, void *data)
Neighbor Cache basic routines.
#define uip_connected()
Has the connection just been connected?
Module for splitting outbound TCP segments in two to avoid the delayed ACK throughput degradation...
void uip_fw_periodic(void)
Perform periodic processing.
#define CLOCK_SECOND
A second, measured in system clock time.
struct tcpip_uipstate uip_udp_appstate_t
The type of the application state that is to be stored in the uip_conn structure. ...
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
struct uip_conn * uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
struct etimer uip_reass_timer
Timer for reassembly.
uint8_t tcpip_output(const uip_lladdr_t *a)
Output packet to layer 2 The eventual parameter is the MAC address of the destination.
void uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt)
Send a neighbor solicitation, send a Neighbor Advertisement.
uint16_t lport
The local port number in network byte order.
A set of debugging macros for the IP stack
void uip_init(void)
uIP initialization function.
void tcpip_poll_udp(struct uip_udp_conn *conn)
Cause a specified UDP connection to be polled.
void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param)
Send an icmpv6 error message.
struct uip_icmp6_conn uip_icmp6_conns
single possible icmpv6 "connection"
uip_ds6_netif_t uip_ds6_if
The single interface.
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
#define UIP_LISTENPORTS
The maximum number of simultaneously listening TCP ports.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
struct tcpip_uipstate uip_tcp_appstate_t
The type of the application state that is to be stored in the uip_conn structure. ...
#define ICMP6_DST_UNREACH_ADDR
address unreachable
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
An entry in the routing table.
#define UIP_LINK_MTU
The maximum transmission unit at the IP Layer.
#define uip_conn_active(conn)
Macro to determine whether a specific uIP connection is active.
#define uip_input()
Process an incoming packet.
#define PROCESS_BEGIN()
Define the beginning of a process.