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 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN + uip_ext_len]) 59 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 60 #define UIP_TCP_BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) 62 #ifdef UIP_FALLBACK_INTERFACE 63 extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
72 static struct etimer periodic;
74 #if UIP_CONF_IPV6_REASSEMBLY 88 static struct internal_state {
115 #if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS 116 if(uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) !=
118 LOG_INFO(
"Tagging TC with retrans: %d\n", uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
122 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS) << 4;
126 if(netstack_process_ip_callback(NETSTACK_IP_OUTPUT, (
const linkaddr_t *)a) ==
127 NETSTACK_IP_PROCESS) {
128 ret = NETSTACK_NETWORK.output((
const linkaddr_t *) a);
137 PROCESS(tcpip_process,
"TCP/IP stack");
142 start_periodic_tcp_timer(
void)
151 check_for_tcp_syn(
void)
161 (UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
162 start_periodic_tcp_timer();
171 LOG_INFO(
"input: received %u bytes\n",
uip_len);
175 #if UIP_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS 180 uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_transmissions);
181 LOG_INFO(
"Received packet tagged with TC retrans: %d (%x)",
182 max_mac_transmissions, traffic_class);
206 init_appstate(&c->appstate, appstate);
218 struct listenport *l;
222 if(l->port == port &&
236 struct listenport *l;
253 init_appstate(&conn->appstate, appstate);
261 init_appstate(&conn->
appstate, appstate);
273 init_appstate(&c->
appstate, appstate);
286 conn =
udp_new(&addr, port, appstate);
317 eventhandler(process_event_t ev, process_data_t data)
321 register struct listenport *l;
326 case PROCESS_EVENT_EXITED:
332 p = (
struct process *)data;
347 for(cptr = &uip_conns[0]; cptr < &uip_conns[
UIP_TCP_CONNS]; ++cptr) {
348 if(cptr->appstate.p == p) {
349 cptr->appstate.p = PROCESS_NONE;
359 for(cptr = &uip_udp_conns[0];
369 case PROCESS_EVENT_TIMER:
374 if(data == &periodic &&
389 #if UIP_CONF_IPV6_REASSEMBLY 429 start_periodic_tcp_timer();
451 if(netstack_process_ip_callback(NETSTACK_IP_INPUT, NULL) ==
452 NETSTACK_IP_PROCESS) {
458 extern void remove_ext_hdr(
void);
461 output_fallback(
void)
463 #ifdef UIP_FALLBACK_INTERFACE 464 LOG_INFO(
"fallback: removing ext hdrs & setting proto %d %d\n",
470 if(UIP_FALLBACK_INTERFACE.output() < 0) {
471 LOG_ERR(
"fallback: output error. Reporting DST UNREACH\n");
478 LOG_ERR(
"output: destination off-link and no default route\n");
483 annotate_transmission(
const uip_ipaddr_t *nexthop)
485 #if TCPIP_CONF_ANNOTATE_TRANSMISSIONS 486 static uint8_t annotate_last;
487 static uint8_t annotate_has_last = 0;
489 if(annotate_has_last) {
490 printf(
"#L %u 0; red\n", annotate_last);
492 printf(
"#L %u 1; red\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
493 annotate_last = nexthop->u8[
sizeof(uip_ipaddr_t) - 1];
494 annotate_has_last = 1;
498 static const uip_ipaddr_t*
499 get_nexthop(uip_ipaddr_t *
addr)
501 const uip_ipaddr_t *nexthop;
504 LOG_INFO(
"output: processing %u bytes packet from ",
uip_len);
511 LOG_INFO(
"output: selected next hop from SRH: ");
512 LOG_INFO_6ADDR(addr);
520 if(uip_ds6_is_addr_onlink(&
UIP_IP_BUF->destipaddr)) {
521 LOG_INFO(
"output: destination is on link\n");
526 route = uip_ds6_route_lookup(&
UIP_IP_BUF->destipaddr);
530 nexthop = uip_ds6_defrt_choose();
531 if(nexthop == NULL) {
534 LOG_INFO(
"output: no route found, using default route: ");
535 LOG_INFO_6ADDR(nexthop);
542 nexthop = uip_ds6_route_nexthop(route);
546 if(nexthop == NULL) {
547 LOG_ERR(
"output: found dead route\n");
551 uip_ds6_route_rm(route);
554 LOG_INFO(
"output: found next hop from routing table: ");
555 LOG_INFO_6ADDR(nexthop);
568 #if UIP_CONF_IPV6_QUEUE_PKT 569 if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
571 uip_packetqueue_set_buflen(&nbr->packethandle,
uip_len);
583 #if UIP_CONF_IPV6_QUEUE_PKT 590 if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
591 uip_len = uip_packetqueue_buflen(&nbr->packethandle);
593 uip_packetqueue_free(&nbr->packethandle);
600 send_nd6_ns(
const uip_ipaddr_t *nexthop)
616 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->srcipaddr)){
627 LOG_ERR(
"output: neighbor not in cache: ");
628 LOG_ERR_6ADDR(nexthop);
640 const uip_lladdr_t *linkaddr;
641 const uip_ipaddr_t *nexthop;
648 LOG_ERR(
"output: Packet too big");
653 LOG_ERR(
"output: Destination address unspecified");
660 LOG_ERR(
"output: routing protocol extension header update error\n");
672 if(uip_ds6_is_my_addr(&
UIP_IP_BUF->destipaddr)) {
673 LOG_INFO(
"output: sending to ourself\n");
679 if((nexthop = get_nexthop(&ipaddr)) == NULL) {
682 annotate_transmission(nexthop);
684 nbr = uip_ds6_nbr_lookup(nexthop);
686 #if UIP_ND6_AUTOFILL_NBR_CACHE 695 0, NBR_REACHABLE, NBR_TABLE_REASON_IPV6_ND_AUTOFILL, NULL)) == NULL) {
696 LOG_ERR(
"output: failed to autofill neighbor cache for host ");
697 LOG_ERR_6ADDR(nexthop);
698 LOG_ERR_(
", link-layer addr ");
699 LOG_ERR_LLADDR((linkaddr_t*)&lladdr);
707 if(send_nd6_ns(nexthop)) {
708 LOG_ERR(
"output: failed to add neighbor to cache\n");
718 LOG_ERR(
"output: nbr cache entry incomplete\n");
724 if(nbr->state == NBR_STALE) {
725 nbr->state = NBR_DELAY;
726 stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
728 LOG_INFO(
"output: nbr cache entry stale moving to delay\n");
734 linkaddr = uip_ds6_nbr_get_ll(nbr);
739 LOG_INFO(
"output: sending to ");
740 LOG_INFO_LLADDR((linkaddr_t *)linkaddr);
787 struct listenport *l;
792 l = &s.listenports[0];
795 l->p != PROCESS_NONE) {
804 start_periodic_tcp_timer();
830 #ifdef UIP_FALLBACK_INTERFACE 831 UIP_FALLBACK_INTERFACE.init();
834 NETSTACK_ROUTING.
init();
838 eventhandler(ev, data);
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
#define UIP_IP_BUF
Pointer to IP header.
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
Post a synchronous event to a process.
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
Set up a new UDP connection.
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_reass_over(void)
Abandon the reassembly of the current packet.
#define PROCESS(name, strname)
Declare a process.
void udp_attach(struct uip_udp_conn *conn, void *appstate)
Attach the current process to a UDP connection.
void tcpip_poll_udp(struct uip_udp_conn *conn)
Cause a specified UDP connection to be polled.
Representation of a uIP TCP connection.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
void uip_ds6_send_rs(void)
Send periodic RS to find router.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
void tcpip_ipv6_output(void)
This function does address resolution and then calls tcpip_output.
void etimer_restart(struct etimer *et)
Restart an event timer from the current point in time.
#define uip_connected()
Has the connection just been connected?
#define PROCESS_BEGIN()
Define the beginning of a process.
#define UIP_TCP_CONNS
The maximum number of simultaneously open TCP connections.
Header file for the link-layer address representation
#define PROCESS_END()
Define the end of a process.
process_event_t tcpip_event
The uIP event.
void tcp_attach(struct uip_conn *conn, void *appstate)
Attach a TCP connection to the current process.
static void send_packet(linkaddr_t *dest)
This function is called by the 6lowpan code to send out a packet.
#define UIP_UDP_CONNS
The maximum amount of concurrent UDP connections.
IPv6 Neighbor cache (link-layer/IPv6 address mapping)
void(* drop_route)(uip_ds6_route_t *route)
Called by uIP if it has decided to drop a route because.
void tcpip_poll_tcp(struct uip_conn *conn)
Cause a specified TCP connection to be polled.
uip_ipaddr_t ripaddr
The IP address of the remote host.
struct uip_icmp6_conn uip_icmp6_conns
single possible icmpv6 "connection"
#define ICMP6_DST_UNREACH
dest unreachable
struct uip_udp_conn * udp_broadcast_new(uint16_t port, void *appstate)
Create a new UDP broadcast connection.
#define UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED
This is the default value of MAC-layer transmissons for uIPv6.
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.
void uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param)
Send an icmpv6 error message.
void uip_unlisten(uint16_t port)
Stop listening to the specified port.
#define uip_periodic(conn)
Periodic processing for a connection identified by its number.
#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.
Header file for IPv6-related data structures.
uint16_t lport
The local port number in network byte order.
#define ICMP6_DST_UNREACH_ADDR
address unreachable
void tcp_unlisten(uint16_t port)
Close a listening TCP port.
void(* init)(void)
Initialize the routing protocol.
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
process_event_t tcpip_icmp6_event
The ICMP6 event.
An entry in the routing table.
void uip_init(void)
uIP initialization function.
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.
#define uip_conn_active(conn)
Macro to determine whether a specific uIP connection is active.
#define CLOCK_SECOND
A second, measured in system clock time.
void stimer_set(struct stimer *t, unsigned long interval)
Set a timer.
struct etimer uip_ds6_timer_periodic
Timer for maintenance of data structures.
struct tcpip_uipstate uip_udp_appstate_t
The type of the application state that is to be stored in the uip_conn structure. ...
uint8_t tcpstateflags
TCP state and flags.
#define uip_poll_conn(conn)
Request that a particular connection should be polled.
struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
#define uip_create_linklocal_allnodes_mcast(a)
set IP address a to the link local all-nodes multicast address
uint16_t lport
The local TCP port, in network byte order.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
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 uip_listen(uint16_t port)
Start listening to the specified port.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
#define PROCESS_YIELD()
Yield the currently running process.
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
process_event_t process_alloc_event(void)
Allocate a global event number.
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
void uip_ds6_periodic(void)
Periodic processing of data structures.
struct etimer uip_reass_timer
Timer for reassembly.
struct etimer uip_ds6_timer_rs
RS timer, to schedule RS sending.
uint8_t uip_ext_len
The length of the extension headers.
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.
Header file for IPv6 Neighbor discovery (RFC 4861)
uip_ds6_netif_t uip_ds6_if
The single interface.
void tcp_listen(uint16_t port)
Open a TCP port.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
uip_ipaddr_t ripaddr
The IP address of the remote peer.
#define UIP_LISTENPORTS
The maximum number of simultaneously listening TCP ports.
uint8_t icmp6_new(void *appstate)
register an ICMPv6 callback
#define uip_udp_periodic_conn(conn)
Periodic processing for a UDP connection identified by a pointer to its structure.
int(* ext_header_update)(void)
Adds/updates routing protocol extension headers to current uIP packet.
struct uip_conn * uip_connect(const uip_ipaddr_t *ripaddr, uint16_t port)
Connect to a remote host using TCP.
#define UIP_TC_MAC_TRANSMISSION_COUNTER_MASK
The bits in the "Traffic Class" field that describe the MAC transmission limit.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Header file for the logging system
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
#define uip_input()
Process an incoming packet.
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 tcpip_uipstate uip_tcp_appstate_t
The type of the application state that is to be stored in the uip_conn structure. ...
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
Representation of a uIP UDP connection.
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...
An entry in the nbr cache.
uip_udp_appstate_t appstate
The application state.