41 #include "contiki-net.h" 42 #if UIP_CONF_TCP_SPLIT 43 #include "net/uip-split.h" 45 #if UIP_CONF_IPV6_QUEUE_PKT 46 #include "net/uip-packetqueue.h" 50 #include "net/uip-nd6.h" 51 #include "net/uip-ds6.h" 57 #define DEBUG DEBUG_NONE 64 #define UIP_LOG(m) uip_log(m) 69 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN + uip_ext_len]) 70 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 71 #define UIP_TCP_BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) 73 #ifdef UIP_FALLBACK_INTERFACE 74 extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
83 process_event_t tcpip_icmp6_event;
87 static struct etimer periodic;
89 #if UIP_CONF_IPV6 && UIP_CONF_IPV6_REASSEMBLY 91 extern struct etimer uip_reass_timer;
103 static struct internal_state {
116 static bool (* quotefunc)(
const uip_ipaddr_t *destipaddr);
120 if(quotefunc != NULL) {
121 return quotefunc(destipaddr);
123 UIP_LOG(
"tcpip_quote: Use tcpip_set_quotefunc() to set an quote function");
128 tcpip_set_quotefunc(
bool (*f)(
const uip_ipaddr_t *destipaddr))
142 if(outputfunc != NULL) {
146 UIP_LOG(
"tcpip_output: Use tcpip_set_outputfunc() to set an output function");
151 tcpip_set_outputfunc(uint8_t (*f)(
const uip_lladdr_t *))
157 static uint8_t (* outputfunc)(void);
161 if(outputfunc != NULL) {
164 UIP_LOG(
"tcpip_output: Use tcpip_set_outputfunc() to set an output function");
169 tcpip_set_outputfunc(uint8_t (*f)(
void))
175 #if UIP_CONF_IP_FORWARD 176 unsigned char tcpip_is_forwarding;
179 PROCESS(tcpip_process,
"TCP/IP stack");
183 start_periodic_tcp_timer(
void)
191 check_for_tcp_syn(
void)
193 #if UIP_TCP || UIP_CONF_IP_FORWARD 200 if(UIP_IP_BUF->proto == UIP_PROTO_TCP &&
201 (UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
202 start_periodic_tcp_timer();
210 #if UIP_CONF_IP_FORWARD 212 tcpip_is_forwarding = 1;
214 tcpip_is_forwarding = 0;
218 #if UIP_CONF_TCP_SPLIT 224 PRINTF(
"tcpip packet_input forward output len %d\n",
uip_len);
230 tcpip_is_forwarding = 0;
237 #if UIP_CONF_TCP_SPLIT 243 PRINTF(
"tcpip packet_input output len %d\n",
uip_len);
276 static unsigned char i;
277 struct listenport *l;
281 if(l->port == port &&
294 static unsigned char i;
295 struct listenport *l;
359 uip_create_linklocal_allnodes_mcast(&addr);
363 conn =
udp_new(&addr, port, appstate);
373 icmp6_new(
void *appstate) {
374 if(uip_icmp6_conns.appstate.p == PROCESS_NONE) {
376 uip_icmp6_conns.appstate.state =
appstate;
383 tcpip_icmp6_call(uint8_t type)
385 if(uip_icmp6_conns.appstate.p != PROCESS_NONE) {
395 eventhandler(process_event_t ev, process_data_t
data)
398 static unsigned char i;
399 register struct listenport *l;
404 case PROCESS_EVENT_EXITED:
410 p = (
struct process *)data;
425 for(cptr = &uip_conns[0]; cptr < &uip_conns[
UIP_CONNS]; ++cptr) {
437 for(cptr = &uip_udp_conns[0];
447 case PROCESS_EVENT_TIMER:
452 if(data == &periodic &&
456 if(uip_conn_active(i)) {
465 PRINTF(
"tcpip_output from periodic len %d\n",
uip_len);
467 PRINTF(
"tcpip_output after periodic len %d\n",
uip_len);
473 #if UIP_CONF_IP_FORWARD 479 #if UIP_CONF_IPV6_REASSEMBLY 483 if(data == &uip_reass_timer &&
499 if(data == &uip_ds6_timer_rs &&
505 if(data == &uip_ds6_timer_periodic &&
522 PRINTF(
"tcpip_output from tcp poll len %d\n",
uip_len);
527 start_periodic_tcp_timer();
534 uip_udp_periodic_conn(data);
564 tcpip_ipv6_output(
void)
566 uip_ds6_nbr_t *nbr = NULL;
574 UIP_LOG(
"tcpip_ipv6_output: Packet to big");
579 if(uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr)){
580 UIP_LOG(
"tcpip_ipv6_output: Destination address unspecified");
585 if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
592 if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){
593 nexthop = &UIP_IP_BUF->destipaddr;
595 uip_ds6_route_t *route;
597 route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
601 PRINTF(
"tcpip_ipv6_output: no route found, using default route\n");
602 nexthop = uip_ds6_defrt_choose();
603 if(nexthop == NULL) {
604 #ifdef UIP_FALLBACK_INTERFACE 605 PRINTF(
"FALLBACK: removing ext hdrs & setting proto %d %d\n",
608 extern void remove_ext_hdr(
void);
609 uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40);
612 UIP_IP_BUF->proto = proto;
614 UIP_FALLBACK_INTERFACE.output();
616 PRINTF(
"tcpip_ipv6_output: Destination off-link but no route\n");
625 nexthop = uip_ds6_route_nexthop(route);
629 if(nexthop == NULL) {
630 #if UIP_CONF_IPV6_RPL 635 rpl_instance_t *instance;
637 dag = (rpl_dag_t *)route->state.dag;
639 instance = dag->instance;
641 rpl_repair_root(instance->instance_id);
644 uip_ds6_route_rm(route);
651 #if TCPIP_CONF_ANNOTATE_TRANSMISSIONS 652 if(nexthop != NULL) {
653 static uint8_t annotate_last;
654 static uint8_t annotate_has_last = 0;
656 if(annotate_has_last) {
657 printf(
"#L %u 0; red\n", annotate_last);
659 printf(
"#L %u 1; red\n", nexthop->u8[
sizeof(
uip_ipaddr_t) - 1]);
661 annotate_has_last = 1;
668 #if UIP_CONF_IPV6_RPL 669 if(rpl_update_header_final(nexthop)) {
674 nbr = uip_ds6_nbr_lookup(nexthop);
677 if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) {
681 #if UIP_CONF_IPV6_QUEUE_PKT 683 if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
684 memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF,
uip_len);
685 uip_packetqueue_set_buflen(&nbr->packethandle,
uip_len);
694 if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){
695 uip_nd6_ns_output(&UIP_IP_BUF->srcipaddr, NULL, &nbr->ipaddr);
697 uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr);
700 stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
706 if(nbr->state == NBR_INCOMPLETE) {
707 PRINTF(
"tcpip_ipv6_output: nbr cache entry incomplete\n");
708 #if UIP_CONF_IPV6_QUEUE_PKT 711 if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
712 memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF,
uip_len);
713 uip_packetqueue_set_buflen(&nbr->packethandle,
uip_len);
721 if(nbr->state == NBR_STALE) {
722 nbr->state = NBR_DELAY;
723 stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
725 PRINTF(
"tcpip_ipv6_output: nbr cache entry stale moving to delay\n");
731 #if UIP_CONF_IPV6_QUEUE_PKT 738 if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
739 uip_len = uip_packetqueue_buflen(&nbr->packethandle);
740 memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle),
uip_len);
741 uip_packetqueue_free(&nbr->packethandle);
780 register struct uip_conn *conn = &uip_conns[i];
781 if (uip_tx_stopped(conn)) {
782 uip_restart_tx(conn);
806 static unsigned char i;
807 struct listenport *l;
812 l = &s.listenports[0];
815 l->p != PROCESS_NONE) {
824 start_periodic_tcp_timer();
840 static unsigned char i;
843 s.listenports[i].port = 0;
856 #ifdef UIP_FALLBACK_INTERFACE 857 UIP_FALLBACK_INTERFACE.init();
860 #if UIP_CONF_IPV6 && UIP_CONF_IPV6_RPL 866 eventhandler(ev, data);
870 #ifdef ECLIPSE_STUB_CODE_ANALYSE
uint8_t uip_fw_forward(void)
struct uip_udp_conn * uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
void uip_reass_over(void)
Abandon the reassembly of the current packet.
#define PROCESS(name, strname)
void uip_listen(uint16_t port)
void udp_attach(struct uip_udp_conn *conn, void *appstate)
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
void etimer_restart(struct etimer *et)
Restart an event timer from the current point in time.
void tcpip_poll_tcp(struct uip_conn *conn)
struct uip_udp_conn * udp_broadcast_new(uint16_t port, void *appstate)
process_event_t process_alloc_event(void)
Allocate a global event number.
CCIF void tcp_attach(struct uip_conn *conn, void *appstate)
void uip_fw_periodic(void)
#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
CCIF struct uip_conn * tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
process_event_t tcpip_event
CCIF void tcp_listen(uint16_t port)
struct uip_conn * uip_connect(uip_ipaddr_t *ripaddr, uint16_t port)
#define PROCESS_CURRENT()
int process_post(struct process *p, process_event_t ev, process_data_t data)
void stimer_set(struct stimer *t, unsigned long interval)
struct tcpip_uipstate uip_udp_appstate_t
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
CCIF struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
uint8_t data[USBNET_RX_BUF_SIZE]
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define PROCESS_THREAD(name, ev, data)
CCIF void tcp_unlisten(uint16_t port)
uip_tcp_appstate_t appstate
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
void uip_unlisten(uint16_t port)
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn)
#define udp_bind(conn, port)
struct tcpip_uipstate uip_tcp_appstate_t
uint8_t tcpip_output(void)
Output packet to layer 2 The eventual parameter is the MAC address of the destination.
uip_udp_appstate_t appstate