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 59 extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
68 static struct etimer periodic;
70 #if UIP_CONF_IPV6_REASSEMBLY 84 static 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);
133 PROCESS(tcpip_process,
"TCP/IP stack");
138 start_periodic_tcp_timer(
void)
147 check_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);
269 init_appstate(&c->
appstate, appstate);
282 conn =
udp_new(&addr, port, appstate);
313 eventhandler(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) {
455 output_fallback(
void)
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");
478 annotate_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;
493 static const uip_ipaddr_t*
494 get_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);
595 send_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) {
677 annotate_transmission(nexthop);
681 #if UIP_ND6_AUTOFILL_NBR_CACHE 690 0, NBR_REACHABLE, NBR_TABLE_REASON_IPV6_ND_AUTOFILL, NULL)) == NULL) {
691 LOG_ERR(
"output: failed to autofill neighbor cache for host ");
692 LOG_ERR_6ADDR(nexthop);
693 LOG_ERR_(
", link-layer addr ");
694 LOG_ERR_LLADDR((linkaddr_t*)&lladdr);
702 if(send_nd6_ns(nexthop)) {
703 LOG_ERR(
"output: failed to add neighbor to cache\n");
713 LOG_ERR(
"output: nbr cache entry incomplete\n");
719 if(nbr->state == NBR_STALE) {
720 nbr->state = NBR_DELAY;
721 stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
723 LOG_INFO(
"output: nbr cache entry stale moving to delay\n");
734 LOG_INFO(
"output: sending to ");
735 LOG_INFO_LLADDR((linkaddr_t *)linkaddr);
782 struct listenport *l;
787 l = &s.listenports[0];
790 l->p != PROCESS_NONE) {
799 start_periodic_tcp_timer();
825 #ifdef UIP_FALLBACK_INTERFACE 826 UIP_FALLBACK_INTERFACE.init();
829 NETSTACK_ROUTING.
init();
833 eventhandler(ev, data);
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
#define UIP_IP_BUF
Direct access to IPv6 header.
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
Post a synchronous event to a process.
uint8_t uip_last_proto
The final protocol after IPv6 extension headers: UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6.
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.
uint16_t uip_ext_len
The length of the extension headers.
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
uip_ds6_nbr_t * uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
Get the neighbor cache associated with a specified IPv6 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.
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...
Header file for IPv6 Neighbor discovery (RFC 4861)
uip_ds6_netif_t uip_ds6_if
The single interface.
bool uip_remove_ext_hdr(void)
Removes all IPv6 extension headers from uip_buf, updates length fields (uip_len and uip_ext_len) ...
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.
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.
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...
The default nbr_table entry (when UIP_DS6_NBR_MULTI_IPV6_ADDRS is disabled), that implements nbr cach...
uip_udp_appstate_t appstate
The application state.