41 #include "contiki-net.h"
43 #include "net/ip/uip-packetqueue.h"
52 #define DEBUG DEBUG_NONE
58 #define UIP_LOG(m) uip_log(m)
63 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN + uip_ext_len])
64 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
65 #define UIP_TCP_BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
67 #ifdef UIP_FALLBACK_INTERFACE
68 extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
77 process_event_t tcpip_icmp6_event;
81 static struct etimer periodic;
83 #if UIP_CONF_IPV6 && UIP_CONF_IPV6_REASSEMBLY
85 extern struct etimer uip_reass_timer;
97 static struct internal_state {
118 if(outputfunc !=
NULL) {
122 UIP_LOG(
"tcpip_output: Use tcpip_set_outputfunc() to set an output function");
127 tcpip_set_outputfunc(uint8_t (*f)(
const uip_lladdr_t *))
133 static uint8_t (* outputfunc)(void);
137 if(outputfunc !=
NULL) {
140 UIP_LOG(
"tcpip_output: Use tcpip_set_outputfunc() to set an output function");
145 tcpip_set_outputfunc(uint8_t (*f)(
void))
151 #if UIP_CONF_IP_FORWARD
152 unsigned char tcpip_is_forwarding;
155 PROCESS(tcpip_process,
"TCP/IP stack");
159 start_periodic_tcp_timer(
void)
167 check_for_tcp_syn(
void)
169 #if UIP_TCP || UIP_CONF_IP_FORWARD
177 (UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
178 start_periodic_tcp_timer();
186 #if UIP_CONF_IP_FORWARD
188 tcpip_is_forwarding = 1;
190 tcpip_is_forwarding = 0;
194 #if UIP_CONF_TCP_SPLIT
200 PRINTF(
"tcpip packet_input forward output len %d\n",
uip_len);
206 tcpip_is_forwarding = 0;
213 #if UIP_CONF_TCP_SPLIT
219 PRINTF(
"tcpip packet_input output len %d\n",
uip_len);
252 static unsigned char i;
253 struct listenport *l;
257 if(l->port == port &&
270 static unsigned char i;
271 struct listenport *l;
311 udp_new(
const uip_ipaddr_t *ripaddr, uint16_t port,
void *appstate)
339 conn =
udp_new(&addr, port, appstate);
349 icmp6_new(
void *appstate) {
350 if(uip_icmp6_conns.appstate.p == PROCESS_NONE) {
352 uip_icmp6_conns.appstate.state =
appstate;
359 tcpip_icmp6_call(uint8_t type)
361 if(uip_icmp6_conns.appstate.p != PROCESS_NONE) {
371 eventhandler(process_event_t ev, process_data_t data)
374 static unsigned char i;
375 register struct listenport *l;
380 case PROCESS_EVENT_EXITED:
386 p = (
struct process *)data;
401 for(cptr = &uip_conns[0]; cptr < &uip_conns[
UIP_CONNS]; ++cptr) {
413 for(cptr = &uip_udp_conns[0];
423 case PROCESS_EVENT_TIMER:
428 if(data == &periodic &&
432 if(uip_conn_active(i)) {
441 PRINTF(
"tcpip_output from periodic len %d\n",
uip_len);
443 PRINTF(
"tcpip_output after periodic len %d\n",
uip_len);
449 #if UIP_CONF_IP_FORWARD
455 #if UIP_CONF_IPV6_REASSEMBLY
459 if(data == &uip_reass_timer &&
481 if(data == &uip_ds6_timer_periodic &&
498 PRINTF(
"tcpip_output from tcp poll len %d\n",
uip_len);
503 start_periodic_tcp_timer();
510 uip_udp_periodic_conn(data);
543 uip_ipaddr_t *nexthop;
550 UIP_LOG(
"tcpip_ipv6_output: Packet to big");
556 UIP_LOG(
"tcpip_ipv6_output: Destination address unspecified");
568 if(uip_ds6_is_addr_onlink(&
UIP_IP_BUF->destipaddr)){
573 route = uip_ds6_route_lookup(&
UIP_IP_BUF->destipaddr);
577 PRINTF(
"tcpip_ipv6_output: no route found, using default route\n");
578 nexthop = uip_ds6_defrt_choose();
579 if(nexthop ==
NULL) {
580 #ifdef UIP_FALLBACK_INTERFACE
581 PRINTF(
"FALLBACK: removing ext hdrs & setting proto %d %d\n",
584 extern void remove_ext_hdr(
void);
585 uint8_t proto = *((uint8_t *)
UIP_IP_BUF + 40);
590 UIP_FALLBACK_INTERFACE.output();
592 PRINTF(
"tcpip_ipv6_output: Destination off-link but no route\n");
601 nexthop = uip_ds6_route_nexthop(route);
605 if(nexthop ==
NULL) {
606 #if UIP_CONF_IPV6_RPL
611 rpl_instance_t *instance;
613 dag = (rpl_dag_t *)route->state.dag;
615 instance = dag->instance;
617 rpl_repair_root(instance->instance_id);
620 uip_ds6_route_rm(route);
627 #if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
628 if(nexthop !=
NULL) {
629 static uint8_t annotate_last;
630 static uint8_t annotate_has_last = 0;
632 if(annotate_has_last) {
633 printf(
"#L %u 0; red\n", annotate_last);
635 printf(
"#L %u 1; red\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
636 annotate_last = nexthop->u8[
sizeof(uip_ipaddr_t) - 1];
637 annotate_has_last = 1;
644 #if UIP_CONF_IPV6_RPL
645 if(rpl_update_header_final(nexthop)) {
650 nbr = uip_ds6_nbr_lookup(nexthop);
657 #if UIP_CONF_IPV6_QUEUE_PKT
659 if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) !=
NULL) {
661 uip_packetqueue_set_buflen(&nbr->packethandle,
uip_len);
670 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->srcipaddr)){
676 stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
683 PRINTF(
"tcpip_ipv6_output: nbr cache entry incomplete\n");
684 #if UIP_CONF_IPV6_QUEUE_PKT
687 if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) !=
NULL) {
689 uip_packetqueue_set_buflen(&nbr->packethandle,
uip_len);
697 if(nbr->state == NBR_STALE) {
698 nbr->state = NBR_DELAY;
699 stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
701 PRINTF(
"tcpip_ipv6_output: nbr cache entry stale moving to delay\n");
707 #if UIP_CONF_IPV6_QUEUE_PKT
714 if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
715 uip_len = uip_packetqueue_buflen(&nbr->packethandle);
717 uip_packetqueue_free(&nbr->packethandle);
767 static unsigned char i;
768 struct listenport *l;
773 l = &s.listenports[0];
776 l->p != PROCESS_NONE) {
785 start_periodic_tcp_timer();
801 static unsigned char i;
804 s.listenports[i].port = 0;
817 #ifdef UIP_FALLBACK_INTERFACE
818 UIP_FALLBACK_INTERFACE.init();
821 #if UIP_CONF_IPV6 && UIP_CONF_IPV6_RPL
827 eventhandler(ev, data);
#define UIP_CONNS
The maximum number of simultaneously open TCP connections.
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
#define UIP_LINK_MTU
The maximum transmission unit at the IP Layer.
uip_len
The length of the packet in the uip_buf buffer.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
void tcpip_ipv6_output(void)
This function does address resolution and then calls tcpip_output.
An entry in the routing table.
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 3513 a is of type uip_ipaddr_t*
Neighbor discovery (RFC 4861)
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 PROCESS_BEGIN()
Define the beginning of a process.
Representation of a uIP TCP connection.
CCIF struct uip_conn * tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Open a TCP connection to the specified IP address and port.
CCIF void tcp_attach(struct uip_conn *conn, void *appstate)
Attach a TCP connection to the current process.
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
Post a synchronous event to a process.
CCIF struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
Network interface and stateless autoconfiguration (RFC 4862)
struct etimer uip_ds6_timer_rs
Timer for maintenance of data structures.
void uip_ds6_periodic(void)
Periodic processing of data structures.
uint16_t lport
The local TCP port, in network byte order.
#define NULL
The null pointer.
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
void uip_log(char *msg)
Print out a uIP log message.
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_split_output(void)
Handle outgoing packets.
process_event_t process_alloc_event(void)
Allocate a global event number.
void uip_listen(uint16_t port)
Start listening to the specified port.
uint16_t lport
The local port number in network byte order.
struct uip_conn * uip_connect(uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
uip_tcp_appstate_t appstate
The application state.
void uip_reass_over(void)
Periodic processing for a connection identified by its number.
void stimer_set(struct stimer *t, unsigned long interval)
Set a timer.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
CCIF void tcp_unlisten(uint16_t port)
Close a listening TCP port.
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn)
Cause a specified UDP connection to be polled.
uint8_t uip_fw_forward(void)
Forward an IP packet in the uip_buf buffer.
#define uip_connected()
Has the connection just been connected?
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define UIP_IP_BUF
Pointer to IP header.
#define PROCESS_END()
Define the end of a process.
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
struct uip_udp_conn * udp_broadcast_new(uint16_t port, void *appstate)
Create a new UDP broadcast connection.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
#define UIP_LISTENPORTS
The maximum number of simultaneously listening TCP ports.
uint8_t uip_ext_len
The length of the extension headers.
void uip_init(void)
uIP initialization function.
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_create_linklocal_allnodes_mcast(a)
set IP address a to the link local all-nodes multicast address
uint8_t tcpstateflags
TCP state and flags.
#define PROCESS(name, strname)
Declare a process.
Module for splitting outbound TCP segments in two to avoid the delayed ACK throughput degradation...
#define uip_input()
Process an incoming packet.
process_event_t tcpip_event
The uIP event.
void uip_ds6_send_rs(void)
Send periodic RS to find router.
void uip_fw_periodic(void)
Perform periodic processing.
#define PROCESS_YIELD()
Yield the currently running process.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
CCIF void tcp_listen(uint16_t port)
Open a TCP port.
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
void tcpip_poll_tcp(struct uip_conn *conn)
Cause a specified TCP connection to be polled.
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
Set up a new UDP connection.
#define UIP_FW_LOCAL
A non-error message that indicates that a packet should be processed locally.
A set of debugging macros.
void etimer_restart(struct etimer *et)
Restart an event timer from the current point in time.
uip_ipaddr_t ripaddr
The IP address of the remote host.
Representation of a uIP UDP connection.
#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
Construct an IP address from four bytes.
void udp_attach(struct uip_udp_conn *conn, void *appstate)
Attach the current process to a UDP connection.
uip_ds6_nbr_t * uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, uint8_t isrouter, uint8_t state)
Neighbor Cache basic routines.
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.
uip_udp_appstate_t appstate
The application state.
#define CLOCK_SECOND
A second, measured in system clock time.
An entry in the nbr cache.