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 {
111#if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS
112 if(uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) !=
114 LOG_INFO(
"Tagging TC with retrans: %d\n", uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
118 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) << 4;
122 if(netstack_process_ip_callback(NETSTACK_IP_OUTPUT, (
const linkaddr_t *)a) ==
123 NETSTACK_IP_PROCESS) {
124 ret = NETSTACK_NETWORK.output((
const linkaddr_t *) a);
133PROCESS(tcpip_process,
"TCP/IP stack");
138start_periodic_tcp_timer(
void)
147check_for_tcp_syn(
void)
157 (UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
158 start_periodic_tcp_timer();
167 LOG_INFO(
"input: received %u bytes\n",
uip_len);
171#if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS
176 uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_transmissions);
177 LOG_INFO(
"Received packet tagged with TC retrans: %d (%x)",
178 max_mac_transmissions, traffic_class);
202 init_appstate(&c->appstate, appstate);
214 struct listenport *l;
218 if(l->port == port &&
232 struct listenport *l;
249 init_appstate(&conn->appstate, appstate);
257 init_appstate(&conn->appstate, appstate);
313eventhandler(process_event_t ev, process_data_t data)
317 register struct listenport *l;
322 case PROCESS_EVENT_EXITED:
328 p = (
struct process *)data;
343 for(cptr = &uip_conns[0]; cptr < &uip_conns[
UIP_TCP_CONNS]; ++cptr) {
344 if(cptr->appstate.p == p) {
345 cptr->appstate.p = PROCESS_NONE;
355 for(cptr = &uip_udp_conns[0];
365 case PROCESS_EVENT_TIMER:
370 if(data == &periodic &&
385#if UIP_CONF_IPV6_REASSEMBLY
425 start_periodic_tcp_timer();
447 if(netstack_process_ip_callback(NETSTACK_IP_INPUT, NULL) ==
448 NETSTACK_IP_PROCESS) {
457#ifdef UIP_FALLBACK_INTERFACE
459 LOG_INFO(
"fallback: removing ext hdrs & setting proto %d %d\n",
465 if(UIP_FALLBACK_INTERFACE.output() < 0) {
466 LOG_ERR(
"fallback: output error. Reporting DST UNREACH\n");
473 LOG_ERR(
"output: destination off-link and no default route\n");
478annotate_transmission(
const uip_ipaddr_t *nexthop)
480#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
481 static uint8_t annotate_last;
482 static uint8_t annotate_has_last = 0;
484 if(annotate_has_last) {
485 printf(
"#L %u 0; red\n", annotate_last);
487 printf(
"#L %u 1; red\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
488 annotate_last = nexthop->u8[
sizeof(uip_ipaddr_t) - 1];
489 annotate_has_last = 1;
493static const uip_ipaddr_t*
494get_nexthop(uip_ipaddr_t *
addr)
496 const uip_ipaddr_t *nexthop;
499 LOG_INFO(
"output: processing %u bytes packet from ",
uip_len);
506 LOG_INFO(
"output: selected next hop from SRH: ");
507 LOG_INFO_6ADDR(
addr);
515 if(uip_ds6_is_addr_onlink(&
UIP_IP_BUF->destipaddr)) {
516 LOG_INFO(
"output: destination is on link\n");
521 route = uip_ds6_route_lookup(&
UIP_IP_BUF->destipaddr);
525 nexthop = uip_ds6_defrt_choose();
526 if(nexthop == NULL) {
529 LOG_INFO(
"output: no route found, using default route: ");
530 LOG_INFO_6ADDR(nexthop);
537 nexthop = uip_ds6_route_nexthop(route);
541 if(nexthop == NULL) {
542 LOG_ERR(
"output: found dead route\n");
546 uip_ds6_route_rm(route);
549 LOG_INFO(
"output: found next hop from routing table: ");
550 LOG_INFO_6ADDR(nexthop);
563#if UIP_CONF_IPV6_QUEUE_PKT
564 if(uip_packetqueue_alloc(&
nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
566 uip_packetqueue_set_buflen(&
nbr->packethandle,
uip_len);
578#if UIP_CONF_IPV6_QUEUE_PKT
585 if(uip_packetqueue_buflen(&
nbr->packethandle) != 0) {
586 uip_len = uip_packetqueue_buflen(&
nbr->packethandle);
588 uip_packetqueue_free(&
nbr->packethandle);
595send_nd6_ns(
const uip_ipaddr_t *nexthop)
611 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->srcipaddr)){
622 LOG_ERR(
"output: neighbor not in cache: ");
623 LOG_ERR_6ADDR(nexthop);
635 const uip_lladdr_t *linkaddr;
636 const uip_ipaddr_t *nexthop;
643 LOG_ERR(
"output: Packet too big");
648 LOG_ERR(
"output: Destination address unspecified");
655 LOG_ERR(
"output: routing protocol extension header update error\n");
667 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr)) {
668 LOG_INFO(
"output: sending to ourself\n");
674 if((nexthop = get_nexthop(&
ipaddr)) == NULL) {
675 LOG_WARN(
"output: No next-hop found, dropping packet\n");
678 annotate_transmission(nexthop);
682#if UIP_ND6_AUTOFILL_NBR_CACHE
691 0, NBR_REACHABLE, NBR_TABLE_REASON_IPV6_ND_AUTOFILL, NULL)) == NULL) {
692 LOG_ERR(
"output: failed to autofill neighbor cache for host ");
693 LOG_ERR_6ADDR(nexthop);
694 LOG_ERR_(
", link-layer addr ");
695 LOG_ERR_LLADDR((linkaddr_t*)&lladdr);
703 if(send_nd6_ns(nexthop)) {
704 LOG_ERR(
"output: failed to add neighbor to cache\n");
714 LOG_ERR(
"output: nbr cache entry incomplete\n");
720 if(
nbr->state == NBR_STALE) {
721 nbr->state = NBR_DELAY;
724 LOG_INFO(
"output: nbr cache entry stale moving to delay\n");
735 LOG_INFO(
"output: sending to ");
736 LOG_INFO_LLADDR((linkaddr_t *)linkaddr);
783 struct listenport *l;
788 l = &s.listenports[0];
791 l->p != PROCESS_NONE) {
800 start_periodic_tcp_timer();
826#ifdef UIP_FALLBACK_INTERFACE
827 UIP_FALLBACK_INTERFACE.init();
830 NETSTACK_ROUTING.
init();
834 eventhandler(ev, data);
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
#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.
int 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_YIELD()
Yield the currently running process.
static void send_packet(void)
This function is called by the 6lowpan code to send out a packet.
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.
struct tcpip_uipstate uip_tcp_appstate_t
The type of the application state that is to be stored in the uip_conn structure.
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_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.
uint8_t tcpstateflags
TCP state and flags.
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.
uint16_t lport
The local port number in network byte order.
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)