42#include "contiki-net.h"
43#include "net/ipv6/uip-packetqueue.h"
55#define LOG_MODULE "TCP/IP"
56#define LOG_LEVEL LOG_LEVEL_TCPIP
58#ifdef UIP_FALLBACK_INTERFACE
59extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
68static struct etimer periodic;
70#if UIP_CONF_IPV6_REASSEMBLY
84static struct internal_state {
99init_appstate(uip_tcp_appstate_t *as,
void *state)
113#if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS
114 if(uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) !=
116 LOG_INFO(
"Tagging TC with retrans: %d\n", uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
120 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) << 4;
124 if(netstack_process_ip_callback(NETSTACK_IP_OUTPUT, (
const linkaddr_t *)a) ==
125 NETSTACK_IP_PROCESS) {
126 ret = NETSTACK_NETWORK.output((
const linkaddr_t *) a);
135PROCESS(tcpip_process,
"TCP/IP stack");
140start_periodic_tcp_timer(
void)
149check_for_tcp_syn(
void)
160 (UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
161 start_periodic_tcp_timer();
170 LOG_INFO(
"input: received %u bytes\n",
uip_len);
174#if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS
179 uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_transmissions);
180 LOG_INFO(
"Received packet tagged with TC retrans: %d (%x)",
181 max_mac_transmissions, traffic_class);
205 init_appstate(&c->appstate, appstate);
217 struct listenport *l;
221 if(l->port == port &&
235 struct listenport *l;
252 init_appstate(&conn->appstate, appstate);
260 init_appstate(&conn->appstate, appstate);
316eventhandler(process_event_t ev, process_data_t data)
319#if UIP_TCP || UIP_UDP
320 case PROCESS_EVENT_EXITED:
326 struct process *p = (
struct process *)data;
328 struct listenport *l = s.listenports;
338 for(
struct uip_conn *cptr = &uip_conns[0];
340 if(cptr->appstate.p == p) {
341 cptr->appstate.p = PROCESS_NONE;
342 cptr->tcpstateflags = UIP_CLOSED;
349 if(cptr->appstate.p == p) {
358 case PROCESS_EVENT_TIMER:
363 if(data == &periodic &&
378#if UIP_CONF_IPV6_REASSEMBLY
413 start_periodic_tcp_timer();
435 if(netstack_process_ip_callback(NETSTACK_IP_INPUT, NULL) ==
436 NETSTACK_IP_PROCESS) {
445#ifdef UIP_FALLBACK_INTERFACE
447 LOG_INFO(
"fallback: removing ext hdrs & setting proto %d %d\n",
453 if(UIP_FALLBACK_INTERFACE.output() < 0) {
454 LOG_ERR(
"fallback: output error. Reporting DST UNREACH\n");
461 LOG_ERR(
"output: destination off-link and no default route\n");
466annotate_transmission(
const uip_ipaddr_t *nexthop)
468#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
469 static uint8_t annotate_last;
470 static uint8_t annotate_has_last = 0;
472 if(annotate_has_last) {
473 printf(
"#L %u 0; red\n", annotate_last);
475 printf(
"#L %u 1; red\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
476 annotate_last = nexthop->u8[
sizeof(uip_ipaddr_t) - 1];
477 annotate_has_last = 1;
481static const uip_ipaddr_t*
482get_nexthop(uip_ipaddr_t *
addr)
484 const uip_ipaddr_t *nexthop;
487 LOG_INFO(
"output: processing %u bytes packet from ",
uip_len);
494 LOG_INFO(
"output: selected next hop from SRH: ");
495 LOG_INFO_6ADDR(
addr);
503 if(uip_ds6_is_addr_onlink(&
UIP_IP_BUF->destipaddr)) {
504 LOG_INFO(
"output: destination is on link\n");
509 route = uip_ds6_route_lookup(&
UIP_IP_BUF->destipaddr);
513 nexthop = uip_ds6_defrt_choose();
514 if(nexthop == NULL) {
517 LOG_INFO(
"output: no route found, using default route: ");
518 LOG_INFO_6ADDR(nexthop);
525 nexthop = uip_ds6_route_nexthop(route);
529 if(nexthop == NULL) {
530 LOG_ERR(
"output: found dead route\n");
534 uip_ds6_route_rm(route);
537 LOG_INFO(
"output: found next hop from routing table: ");
538 LOG_INFO_6ADDR(nexthop);
551#if UIP_CONF_IPV6_QUEUE_PKT
552 if(uip_packetqueue_alloc(&
nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
554 uip_packetqueue_set_buflen(&
nbr->packethandle,
uip_len);
566#if UIP_CONF_IPV6_QUEUE_PKT
573 if(uip_packetqueue_buflen(&
nbr->packethandle) != 0) {
574 uip_len = uip_packetqueue_buflen(&
nbr->packethandle);
576 uip_packetqueue_free(&
nbr->packethandle);
583send_nd6_ns(
const uip_ipaddr_t *nexthop)
599 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->srcipaddr)){
610 LOG_ERR(
"output: neighbor not in cache: ");
611 LOG_ERR_6ADDR(nexthop);
623 const uip_lladdr_t *linkaddr;
624 const uip_ipaddr_t *nexthop;
631 LOG_ERR(
"output: Packet too big");
636 LOG_ERR(
"output: Destination address unspecified");
643 LOG_ERR(
"output: routing protocol extension header update error\n");
655 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr)) {
656 LOG_INFO(
"output: sending to ourself\n");
662 if((nexthop = get_nexthop(&
ipaddr)) == NULL) {
663 LOG_WARN(
"output: No next-hop found, dropping packet\n");
666 annotate_transmission(nexthop);
670#if UIP_ND6_AUTOFILL_NBR_CACHE
679 0, NBR_REACHABLE, NBR_TABLE_REASON_IPV6_ND_AUTOFILL, NULL)) == NULL) {
680 LOG_ERR(
"output: failed to autofill neighbor cache for host ");
681 LOG_ERR_6ADDR(nexthop);
682 LOG_ERR_(
", link-layer addr ");
683 LOG_ERR_LLADDR((linkaddr_t*)&lladdr);
691 if(send_nd6_ns(nexthop)) {
692 LOG_ERR(
"output: failed to add neighbor to cache\n");
702 LOG_ERR(
"output: nbr cache entry incomplete\n");
708 if(
nbr->state == NBR_STALE) {
709 nbr->state = NBR_DELAY;
712 LOG_INFO(
"output: nbr cache entry stale moving to delay\n");
723 LOG_INFO(
"output: sending to ");
724 LOG_INFO_LLADDR((linkaddr_t *)linkaddr);
756 uip_udp_appstate_t *ts;
771 struct listenport *l;
776 l = &s.listenports[0];
779 l->p != PROCESS_NONE) {
788 start_periodic_tcp_timer();
814#ifdef UIP_FALLBACK_INTERFACE
815 UIP_FALLBACK_INTERFACE.init();
818 NETSTACK_ROUTING.
init();
822 eventhandler(ev, data);
#define CLOCK_SECOND
A second, measured in system clock time.
void etimer_restart(struct etimer *et)
Restart an event timer from the current point in time.
static bool etimer_expired(struct etimer *et)
Check if an event timer has expired.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define PROCESS(name, strname)
Declare a process.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
Post a synchronous event to a process.
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
process_event_t process_alloc_event(void)
Allocate a global event number.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_END()
Define the end of a process.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_YIELD()
Yield the currently running process.
static void send_packet(void)
This function is called by the 6lowpan code to send out a packet.
static void stimer_set(struct stimer *t, unsigned long interval)
Set a timer.
void tcp_unlisten(uint16_t port)
Close a listening TCP port.
void udp_attach(struct uip_udp_conn *conn, void *appstate)
Attach the current process to a UDP connection.
process_event_t tcpip_event
The uIP event.
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.
struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
void tcp_attach(struct uip_conn *conn, void *appstate)
Attach a TCP connection to the current process.
uint8_t tcpip_output(const uip_lladdr_t *a)
Output packet to layer 2 The eventual parameter is the MAC address of the destination.
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
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...
void tcpip_poll_tcp(struct uip_conn *conn)
Cause a specified TCP connection to be polled.
struct uip_udp_conn * udp_broadcast_new(uint16_t port, void *appstate)
Create a new UDP broadcast connection.
uint8_t icmp6_new(void *appstate)
register an ICMPv6 callback
void tcpip_poll_udp(struct uip_udp_conn *conn)
Cause a specified UDP connection to be polled.
void tcpip_ipv6_output(void)
This function does address resolution and then calls tcpip_output.
process_event_t tcpip_icmp6_event
The ICMP6 event.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
void tcp_listen(uint16_t port)
Open a TCP port.
void uip_nd6_ns_output(const uip_ipaddr_t *src, const uip_ipaddr_t *dest, uip_ipaddr_t *tgt)
Send a neighbor solicitation, send a Neighbor Advertisement.
const uip_lladdr_t * uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr)
Get the link-layer address associated with a specified nbr cache.
void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param)
Send an icmpv6 error message.
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)
Add a neighbor cache for a specified IPv6 address, which is associated with a specified link-layer ad...
#define ICMP6_DST_UNREACH
dest unreachable
void uip_ds6_periodic(void)
Periodic processing of data structures.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
void uip_ds6_send_rs(void)
Send periodic RS to find router.
struct etimer uip_reass_timer
Timer for reassembly.
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
struct uip_icmp6_conn uip_icmp6_conns
single possible icmpv6 "connection"
#define ICMP6_DST_UNREACH_ADDR
address unreachable
struct etimer uip_ds6_timer_periodic
Timer for maintenance of data structures.
uip_ds6_nbr_t * uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
Get the neighbor cache associated with a specified IPv6 address.
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
bool uip_remove_ext_hdr(void)
Removes all IPv6 extension headers from uip_buf, updates length fields (uip_len and uip_ext_len)
struct etimer uip_ds6_timer_rs
RS timer, to schedule RS sending.
void uip_ds6_set_lladdr_from_iid(uip_lladdr_t *lladdr, const uip_ipaddr_t *ipaddr)
Build a link-layer address from an IPv6 address based on its UUID64.
uip_ds6_netif_t uip_ds6_if
The single interface.
#define uip_create_linklocal_allnodes_mcast(a)
set IP address a to the link local all-nodes multicast address
#define UIP_IP_BUF
Direct access to IPv6 header.
struct uip_conn * uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
void uip_listen(uint16_t port)
Start listening to the specified port.
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
Set up a new UDP connection.
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
#define uip_connected()
Has the connection just been connected?
#define uip_periodic(conn)
Periodic processing for a connection identified by its number.
#define uip_input()
Process an incoming packet.
#define uip_poll_conn(conn)
Request that a particular connection should be polled.
#define uip_udp_periodic_conn(conn)
Periodic processing for a UDP connection identified by a pointer to its structure.
void uip_reass_over(void)
Abandon the reassembly of the current packet.
#define uip_conn_active(conn)
Macro to determine whether a specific uIP connection is active.
uint16_t uip_ext_len
The length of the extension headers.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
uint8_t uip_last_proto
The final protocol after IPv6 extension headers: UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6.
void uip_init(void)
uIP initialization function.
#define UIP_LINK_MTU
The maximum transmission unit at the IP Layer.
#define UIP_TC_MAC_TRANSMISSION_COUNTER_BIT
The MAC-layer transmissons limit is encapslated in "Traffic Class" field.
#define UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED
This is the default value of MAC-layer transmissons for uIPv6.
#define UIP_TC_MAC_TRANSMISSION_COUNTER_MASK
The bits in the "Traffic Class" field that describe the MAC transmission limit.
#define UIP_LISTENPORTS
The maximum number of simultaneously listening TCP ports.
#define UIP_TCP_CONNS
The maximum number of simultaneously open TCP connections.
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
Header file for the link-layer address representation.
Header file for the logging system.
Routing driver header file.
int(* ext_header_srh_get_next_hop)(uip_ipaddr_t *ipaddr)
Look for next hop from SRH of current uIP packet.
void(* init)(void)
Initialize the routing protocol.
int(* ext_header_update)(void)
Adds/updates routing protocol extension headers to current uIP packet.
void(* drop_route)(uip_ds6_route_t *route)
Called by uIP if it has decided to drop a route because.
Representation of a uIP TCP connection.
uint16_t lport
The local TCP port, in network byte order.
uip_ipaddr_t ripaddr
The IP address of the remote host.
The default nbr_table entry (when UIP_DS6_NBR_MULTI_IPV6_ADDRS is disabled), that implements nbr cach...
An entry in the routing table.
Representation of a uIP UDP connection.
uip_ipaddr_t ripaddr
The IP address of the remote peer.
uip_udp_appstate_t appstate
The application state.
IPv6 Neighbor cache (link-layer/IPv6 address mapping)
Header file for IPv6-related data structures.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Header file for IPv6 Neighbor discovery (RFC 4861)