Example #1
0
/**
 * \brief Take a packet received over the 802.15.4 link, and send it
 * out over ethernet, performing any translations needed.
 */
void mac_LowpanToEthernet(void)
{
#if !RF230BB
  parsed_frame = sicslowmac_get_frame();
#endif

  //Setup generic ethernet stuff
  ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6);

  //Check for broadcast message
  
#if RF230BB
  if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) {
//  if(linkaddr_cmp((const linkaddr_t *)destAddr, &linkaddr_null)) {
#else
  if(  ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) &&
       ( parsed_frame->dest_addr->addr16 == 0xffff) ) {
#endif
    ETHBUF(uip_buf)->dest.addr[0] = 0x33;
    ETHBUF(uip_buf)->dest.addr[1] = 0x33;

#if UIP_CONF_IPV6
    ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
    ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
    ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
    ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
#else
	//Not intended to be functional, but allows ip4 build without errors.
    ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[0];
    ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[1];
    ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[2];
    ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[3];
#endif
  } else {
	//Otherwise we have a real address
	mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]),
                        (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
  }

#if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
  //Source ethernet depends on node
  if(!mac_createEthernetAddr(
    (uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
    (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)
  ))
#endif

  {
    mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]));
  }

  //We only do address translation in network mode!
  if (usbstick_mode.translate) {
    //Some IP packets have link layer in them, need to change them around!
    mac_translateIPLinkLayer(ll_8023_type);
  }
 
#if UIP_CONF_IPV6_RPL
/* We won't play ping-pong with the host! */
    if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) {
        PRINTF("siclow_ethernet: Destination off-link but no route\n");
        uip_len=0;
        return;
    }
#endif

  PRINTF("Low2Eth: Sending packet to ethernet\n\r");

  uip_len += UIP_LLH_LEN;

  usb_eth_send(uip_buf, uip_len, 1);
#if !RF230BB
  usb_eth_stat.rxok++;
#endif
  uip_len = 0;
}

/**
 * \brief Translate IP packet's possible link-layer addresses, passing
 *        the message to the appropriate higher level function for this
 *        packet (aka: ICMP)
 * \param target The target we want to end up with - either ll_8023_type
 *        for ethernet, or ll_802154_type for 802.15.4
 * \return    Returns how successful the translation was
 * \retval 0  Addresses, if present, were translated.
 * \retval <0 Negative return values indicate various errors, as defined
 *            by the higher level function.
 */
int8_t mac_translateIPLinkLayer(lltype_t target)
{

#if UIP_LLADDR_LEN == 8
  if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
    PRINTF("eth2low: ICMP Message detected\n\r");
    return mac_translateIcmpLinkLayer(target);
  }
  return 0;
#else
  return 1;
#endif

}

#include "net/ipv6/uip-icmp6.h"
#include "net/ipv6/uip-nd6.h"

typedef struct {
  uint8_t type;
  uint8_t length;
  uint8_t data[16];
} icmp_opts_t;

#define UIP_ICMP_BUF     ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
#define UIP_ICMP_OPTS(x) ((icmp_opts_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + x])

void slide(uint8_t * data, uint8_t length, int16_t slide);

/**
 * \brief Translate the link-layer (L2) addresses in an ICMP packet.
 *        This will just be NA/NS/RA/RS packets currently.
 * \param target The target we want to end up with - either ll_8023_type
 *        for ethernet, or ll_802154_type for 802.15.4
 * \return       Returns how successful the translation was
 * \retval 0     Addresses, if present, were translated.
 * \retval -1    ICMP message was unknown type, nothing done.
 * \retval -2    ICMP Length does not make sense?
 * \retval -3    Unknown 'target' type
 */
int8_t mac_translateIcmpLinkLayer(lltype_t target)
{
  uint16_t icmp_opt_offset = 0;
  int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8);

  uint16_t iplen;

  uint8_t i;

  int16_t sizechange;

  uint8_t llbuf[16];

  //Figure out offset to start of options
  switch(UIP_ICMP_BUF->type) {
    case ICMP6_NS:
    case ICMP6_NA:
      icmp_opt_offset = 24;
      break;

    case ICMP6_RS:
      icmp_opt_offset = 8;
      break;

    case ICMP6_RA:
      icmp_opt_offset = 16;
      break;

    case ICMP6_REDIRECT:
      icmp_opt_offset = 40;
      break;

      /** Things without link-layer */
    case ICMP6_DST_UNREACH:
    case ICMP6_PACKET_TOO_BIG:
    case ICMP6_TIME_EXCEEDED:	
    case ICMP6_PARAM_PROB:
    case ICMP6_ECHO_REQUEST:  
    case ICMP6_ECHO_REPLY: 
      return 0;
      break;

    default:
      return -1;
  }

  //Figure out length of options
  len -= icmp_opt_offset;

  //Sanity check
  if (len < 8) return -2; 

  //While we have options to do...
  while (len >= 8){
    
    //If we have one of these, we have something useful!
    if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) || 
        ((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) {
      
      /* Shrinking the buffer may thrash things, so we store the old
         link-layer address */
      for(i = 0; i < (UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) {
        llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i];
      }

      //Shrink/grow buffer as needed
      if (target == ll_802154_type) {
        //Current is 802.3, Hence current link-layer option is 6 extra bytes
        sizechange = 8;
        slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange);
      } else if (target == ll_8023_type) {
        /* Current is 802.15.4, Hence current link-layer option is 14 extra
         * bytes.
         * (Actual LL is 8 bytes, but total option length is in multiples of
         * 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for
         * total optional length - 2 bytes for type + length leaves 14 )
         */
        sizechange = -8;
        slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange);
      } else {
        return -3; //Uh-oh!
      }
      
      //Translate addresses
      if (target == ll_802154_type) {
        mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
      } else {
#if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
        if(!mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf))
#endif
            mac_createDefaultEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data);
      }
      
      //Adjust the length
      if (target == ll_802154_type) {
        UIP_ICMP_OPTS(icmp_opt_offset)->length = 2;
      } else {
        UIP_ICMP_OPTS(icmp_opt_offset)->length = 1;
      }

      //Adjust the IP header length, as well as uIP length
      iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8);
      iplen += sizechange;
      len += sizechange;
      
      UIP_IP_BUF->len[1] = (uint8_t)iplen;
      UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8);

      uip_len += sizechange;

      //We broke ICMP checksum, be sure to fix that
      UIP_ICMP_BUF->icmpchksum = 0;
#if UIP_CONF_IPV6   //allow non ipv6 builds
      UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
#endif

      //Finally set up next run in while loop
      len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
      icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
    } else {
	  
      //Not an option we care about, ignore it
      len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
	      
      //This shouldn't happen!
      if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) {
        PRINTF("Option in ND packet has length zero, error?\n\r");
        len = 0;
      }

      icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
      
    } //If ICMP_OPT is one we care about
   
  } //while(len >= 8)
Example #2
0
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
		  uip_ipaddr_t *nexthop)
{
  uip_ds6_route_t *r;
  struct uip_ds6_route_neighbor_route *nbrr;

#if DEBUG != DEBUG_NONE
  assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */

  /* Get link-layer address of next hop, make sure it is in neighbor table */
  const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
  if(nexthop_lladdr == NULL) {
    PRINTF("uip_ds6_route_add: neighbor link-local address unknown for ");
    PRINT6ADDR(nexthop);
    PRINTF("\n");
    return NULL;
  }

  /* First make sure that we don't add a route twice. If we find an
     existing route for our destination, we'll delete the old
     one first. */
  r = uip_ds6_route_lookup(ipaddr);
  if(r != NULL) {
    uip_ipaddr_t *current_nexthop;
    current_nexthop = uip_ds6_route_nexthop(r);
    if(current_nexthop != NULL && uip_ipaddr_cmp(nexthop, current_nexthop)) {
      /* no need to update route - already correct! */
      return r;
    }
    PRINTF("uip_ds6_route_add: old route for ");
    PRINT6ADDR(ipaddr);
    PRINTF(" found, deleting it\n");

    uip_ds6_route_rm(r);
  }
  {
    struct uip_ds6_route_neighbor_routes *routes;
    /* If there is no routing entry, create one. We first need to
       check if we have room for this route. If not, we remove the
       least recently used one we have. */

    if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) {
      uip_ds6_route_t *oldest;
      oldest = NULL;
#if UIP_DS6_ROUTE_REMOVE_LEAST_RECENTLY_USED
      /* Removing the oldest route entry from the route table. The
         least recently used route is the first route on the list. */
      oldest = list_tail(routelist);
#endif
      if(oldest == NULL) {
        return NULL;
      }
      PRINTF("uip_ds6_route_add: dropping route to ");
      PRINT6ADDR(&oldest->ipaddr);
      PRINTF("\n");
      uip_ds6_route_rm(oldest);
    }


    /* Every neighbor on our neighbor table holds a struct
       uip_ds6_route_neighbor_routes which holds a list of routes that
       go through the neighbor. We add our route entry to this list.

       We first check to see if we already have this neighbor in our
       nbr_route table. If so, the neighbor already has a route entry
       list.
    */
    routes = nbr_table_get_from_lladdr(nbr_routes,
                                       (linkaddr_t *)nexthop_lladdr);

    if(routes == NULL) {
      /* If the neighbor did not have an entry in our neighbor table,
         we create one. The nbr_table_add_lladdr() function returns a
         pointer to a pointer that we may use for our own purposes. We
         initialize this pointer with the list of routing entries that
         are attached to this neighbor. */
      routes = nbr_table_add_lladdr(nbr_routes,
                                    (linkaddr_t *)nexthop_lladdr,
                                    NBR_TABLE_REASON_ROUTE, NULL);
      if(routes == NULL) {
        /* This should not happen, as we explicitly deallocated one
           route table entry above. */
        PRINTF("uip_ds6_route_add: could not allocate neighbor table entry\n");
        return NULL;
      }
      LIST_STRUCT_INIT(routes, route_list);
#ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK
      NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK((const linkaddr_t *)nexthop_lladdr);
#endif
    }

    /* Allocate a routing entry and populate it. */
    r = memb_alloc(&routememb);

    if(r == NULL) {
      /* This should not happen, as we explicitly deallocated one
         route table entry above. */
      PRINTF("uip_ds6_route_add: could not allocate route\n");
      return NULL;
    }

    /* add new routes first - assuming that there is a reason to add this
       and that there is a packet coming soon. */
    list_push(routelist, r);

    nbrr = memb_alloc(&neighborroutememb);
    if(nbrr == NULL) {
      /* This should not happen, as we explicitly deallocated one
         route table entry above. */
      PRINTF("uip_ds6_route_add: could not allocate neighbor route list entry\n");
      memb_free(&routememb, r);
      return NULL;
    }

    nbrr->route = r;
    /* Add the route to this neighbor */
    list_add(routes->route_list, nbrr);
    r->neighbor_routes = routes;
    num_routes++;

    PRINTF("uip_ds6_route_add num %d\n", num_routes);

    /* lock this entry so that nexthop is not removed */
    nbr_table_lock(nbr_routes, routes);
  }

  uip_ipaddr_copy(&(r->ipaddr), ipaddr);
  r->length = length;

#ifdef UIP_DS6_ROUTE_STATE_TYPE
  memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE));
#endif

  PRINTF("uip_ds6_route_add: adding route: ");
  PRINT6ADDR(ipaddr);
  PRINTF(" via ");
  PRINT6ADDR(nexthop);
  PRINTF("\n");
  ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);

#if UIP_DS6_NOTIFICATIONS
  call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop);
#endif

#if DEBUG != DEBUG_NONE
  assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */

#ifdef NETSTACK_CONF_ROUTE_ADDED_CALLBACK
NETSTACK_CONF_ROUTE_ADDED_CALLBACK(ipaddr);
#endif /* NETSTACK_CONF_ROUTE_ADDED_CALLBACK*/

  return r;
}
Example #3
0
node_info_t *
node_info_update(uip_ipaddr_t * ipaddr, char * info)
{
  node_info_t *node = NULL;
  char *  sep;
  uip_ipaddr_t ip_parent;

  node = node_info_lookup(ipaddr);
  if (node == NULL) {
    node = node_info_add(ipaddr);
  }
  if ( node != NULL ) {
    node->last_seen = clock_time();
    node->last_message = clock_time();
    uint16_t up_sequence = 0;
    uint16_t down_sequence = 0;

    sep = index(info, '|');
    if (sep != NULL) {
      node->messages_received++;
      up_sequence = atoi(info);
      *sep = 0;
      info = sep + 1;
      if (*info == ' ') {
        info++;
      }
      sep = index(info, '|');
      if (sep != NULL) {
        *sep = 0;
      }
      if (uiplib_ipaddrconv(info, &ip_parent) == 0) {
        uip_create_unspecified(&ip_parent);
      }
      if(!uip_ipaddr_cmp(&node->ip_parent, &ip_parent)) {
        uip_ipaddr_copy(&(node->ip_parent), &ip_parent);
        if (node->messages_received > 1) {
          node->parent_switch++;
        }
      }
      if (sep != NULL) {
        info = sep + 1;
        down_sequence = atoi(info);
      }
      if (node->messages_received > 1) {
        uint16_t up_delta = up_sequence - node->last_up_sequence;
        if (up_delta < 100) {
          node->messages_sent += up_delta;
          node->up_messages_lost += up_delta - 1;
          if(down_sequence != node->last_down_sequence + 1) {
            node->down_messages_lost += 1;
          }
        } else {
          //Reset statistics
          node->messages_sent = 1;
          node->replies_sent = 0;
          node->up_messages_lost = 0;
          node->down_messages_lost = 0;
        }
      } else {
        node->messages_sent = 1;
        node->replies_sent = 0;
        node->up_messages_lost = 0;
        node->down_messages_lost = 0;
      }
      node->last_up_sequence = up_sequence;
      node->last_down_sequence = down_sequence;
    } else {
      node->last_up_sequence = 0;
      node->last_down_sequence = 0;
      uip_create_unspecified(&node->ip_parent);
    }
  }
  return node;
}
Example #4
0
/*----------------------------------------------------------------------------*/
void
uip_arp_arpin(void)
{
    //spark_print("\n****************************uip_arp_arpin\n");
    //spark_printLong(uip_len);
    if(uip_len < sizeof(struct arp_hdr)) {
        //spark_print("\nuip len is not updated\n");
        //spark_printLong(uip_len);
        uip_len = 0;
        return;
    }
    uip_len = 0;

    //spark_print("\n\n\nBUF->opcode\n");
    //spark_printLong(BUF->opcode);
    //spark_print("\n\n\nBUF->hwlen\n");
    //spark_printLong(BUF->hwlen);
    //spark_printLong( ((u16_t *)(BUF->dipaddr))[0] );
    //spark_printLong( ((u16_t *)(BUF->dipaddr))[1] );
    //spark_printLong( ((u16_t *)(uip_hostaddr))[0] );
    //spark_printLong( ((u16_t *)(uip_hostaddr))[1] );

    switch(BUF->opcode) {
    case HTONS(ARP_REQUEST):
        /* ARP request. If it asked for our address, we send out a
           reply. */
        if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
            //spark_print("\n\n\n\n-----------------------ARP_REQUESTFOR Me\n");
            //spark_print("--------------------------------FOR ME\n");

            /* First, we register the one who made the request in our ARP
            table, since it is likely that we will do more communication
             with this host in the future. */
            uip_arp_update(BUF->sipaddr, &BUF->shwaddr);

            /* The reply opcode is 2. */
            BUF->opcode = HTONS(2);

            memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
            memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
            memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
            memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);

            BUF->dipaddr[0] = BUF->sipaddr[0];
            BUF->dipaddr[1] = BUF->sipaddr[1];
            BUF->sipaddr[0] = uip_hostaddr[0];
            BUF->sipaddr[1] = uip_hostaddr[1];

            BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
            uip_len = sizeof(struct arp_hdr);
        }
        break;
    case HTONS(ARP_REPLY):
        //spark_print("\n--------------------------------ARP_REPLY\n");

        /* ARP reply. We insert or update the ARP table if it was meant
           for us. */
        if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
            //spark_print("\n\n\n\nuip_arp_updating the ARP table \n");
            uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
        }
        break;
    }

    return;
}
Example #5
0
/*-----------------------------------------------------------------------------------*/
void
uip_arp_out(void)
{
  struct arp_entry *tabptr;

  /* Find the destination IP address in the ARP table and construct
     the Ethernet header. If the destination IP addres isn't on the
     local network, we use the default router's IP address instead.

     If not ARP table entry is found, we overwrite the original IP
     packet with an ARP request for the IP address. */

  /* First check if destination is a local broadcast. */
  if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
    memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
  } else {
    /* Check if the destination address is on the local network. */
    if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
      /* Destination address was not on the local network, so we need to
	 use the default router's IP address instead of the destination
	 address when determining the MAC address. */
      uip_ipaddr_copy(ipaddr, uip_draddr);
    } else {
      /* Else, we use the destination IP address. */
      uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
    }

    for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
      tabptr = &arp_table[i];
      if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
	break;
      }
    }

    if(i == UIP_ARPTAB_SIZE) {
      /* The destination address was not in our ARP table, so we
	 overwrite the IP packet with an ARP request. */

      memset(BUF->ethhdr.dest.addr, 0xff, 6);
      memset(BUF->dhwaddr.addr, 0x00, 6);
      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);

      uip_ipaddr_copy(BUF->dipaddr, ipaddr);
      uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
      BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
      BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
      BUF->protocol = HTONS(UIP_ETHTYPE_IP);
      BUF->hwlen = 6;
      BUF->protolen = 4;
      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);

      uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];

      uip_len = sizeof(struct arp_hdr);
      return;
    }

    /* Build an ethernet header. */
    memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
  }
  memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);

  IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);

  uip_len += sizeof(struct uip_eth_hdr);
}
Example #6
0
/*-----------------------------------------------------------------------------------*/
void
uip_arp_arpin(void)
{
  
  if(uip_len < sizeof(struct arp_hdr)) {
    uip_len = 0;
    return;
  }
  uip_len = 0;
  
  switch(BUF->opcode) {
  case HTONS(ARP_REQUEST):
    /* ARP request. If it asked for our address, we send out a
       reply. */
    if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)
#ifdef RFM12_ARP_PROXY
       /* If RFM12 ARP-proxy is enabled, check that one's IP address
	  as well and possibly answer it. */
       || uip_ipaddr_maskcmp(BUF->dipaddr, rfm12_stack_hostaddr,
			     rfm12_stack_netmask)
#endif
#ifdef ZBUS_ARP_PROXY
       /* If ZBUS ARP-proxy is enabled, check that one's IP address
	  as well and possibly answer it. */
       || uip_ipaddr_maskcmp(BUF->dipaddr, zbus_stack_hostaddr,
			     zbus_stack_netmask)
#endif
#ifdef USB_ARP_PROXY
       /* If USB ARP-proxy is enabled, check that one's IP address
	  as well and possibly answer it. */
       || uip_ipaddr_maskcmp(BUF->dipaddr, usb_stack_hostaddr,
			     usb_stack_netmask)
#endif
       ) {
      /* First, we register the one who made the request in our ARP
	 table, since it is likely that we will do more communication
	 with this host in the future. */
      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
      
      /* The reply opcode is 2. */
      BUF->opcode = HTONS(2);

      memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
      memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);

      for (uint8_t i = 0; i < 4; i ++)
	flip (uint8_t, ((uint8_t *) BUF->dipaddr)[i],
	      ((uint8_t *) BUF->sipaddr)[i]);

      /* BUF->dipaddr[0] = BUF->sipaddr[0];
	 BUF->dipaddr[1] = BUF->sipaddr[1];
	 BUF->sipaddr[0] = uip_hostaddr[0];
	 BUF->sipaddr[1] = uip_hostaddr[1]; */

      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
      uip_len = sizeof(struct arp_hdr);
    }
    break;
  case HTONS(ARP_REPLY):
    /* ARP reply. We insert or update the ARP table if it was meant
       for us. */
    if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
    }
    break;
  }

  return;
}
Example #7
0
void
udpio_net_main(void)
{
	uint8_t* answer = uip_appdata;
	uint8_t i;
	uip_ipaddr_t nullip;
	uip_ipaddr(&nullip, 0,0,0,0);


	if (uip_newdata ()) {
		// No new data: We will compare pins instead
		for (i=0;i<ALLOWED_CLIENTS;++i) {
			if(uip_ipaddr_cmp(&(clients[i].address), &nullip))
				continue;
			// found address of calling client in clients: compare pins now
			if (vport[clients[i].pinport].read_port(clients[i].pinport) ^ clients[i].last_pin_state) {
				// update last pin state
				clients[i].last_pin_state = vport[clients[i].pinport].read_port(clients[i].pinport) & clients[i].pinmask;
				// send changes
				answer[0] = 'p';
				answer[1] = 'i';
				answer[2] = 'n';
				answer[3] = 'c';
				answer[4] = clients[i].pinport;
				answer[5] = clients[i].last_pin_state;
				uip_slen += 6;
				answer += 6;

				uip_udp_conn_t echo_conn;
				uip_ipaddr_copy(echo_conn.ripaddr, BUF->srcipaddr);
				echo_conn.rport = HTONS(UDP_IO_PORT); // send packages to clients at the udp io module port
				echo_conn.lport = HTONS(UDP_IO_PORT);

				uip_udp_conn = &echo_conn;
				uip_process(UIP_UDP_SEND_CONN);
				router_output();

				uip_slen = 0;
			}
		}
		// No new data, return now
		return;
	}

	uip_slen = 0;
	uint16_t len = uip_len;
	uint8_t buffer[uip_len];
	memcpy(buffer, uip_appdata, uip_len);
	struct udpio_packet* packet = (struct udpio_packet*)buffer;

	while (len>=sizeof(struct udpio_packet))
	{
		switch(packet->mode) {
			case udpIOOnlyDisable:
				if (packet->port > IO_HARD_PORTS) break;
				vport[packet->port].write_port(packet->port, vport[packet->port].read_port(packet->port) & ~(uint8_t)packet->pinmask);
				break;
			case udpIOOnlyEnable:
				if (packet->port > IO_HARD_PORTS) break;
				vport[packet->port].write_port(packet->port, vport[packet->port].read_port(packet->port) | packet->pinmask);
				break;
			case udpIOEnableAndDisable:
				if (packet->port > IO_HARD_PORTS) break;
				vport[packet->port].write_port(packet->port, packet->pinmask);
				break;
			case udpIOGetAllPortPins:
				answer[0] = 'p';
				answer[1] = 'i';
				answer[2] = 'n';
				answer[3] = 's';
				answer[4] = PORTA;
				answer[5] = PORTB;
				answer[6] = PORTC;
				answer[7] = PORTD;
				uip_slen += 8;
				answer += 8;
				break;
			case udpIORegisterClientForPortChanges:
				// look for a not used entry in the array
				for (;i<ALLOWED_CLIENTS;++i) {
					if(uip_ipaddr_cmp(&(clients[i].address), nullip)) // found empty entry
						break;
				}
				// override last array entry if no free entry available
				if (i==ALLOWED_CLIENTS) i = ALLOWED_CLIENTS-1;
				// create entry with ip adress of the calling client, the ioport to observe, the pinmask and the current port state
				uip_ipaddr_copy(&(clients[i].address), BUF->srcipaddr);
				clients[i].pinport = packet->port;
				clients[i].pinmask = packet->pinmask;
				clients[i].last_pin_state = vport[packet->port].read_port(packet->port) & clients[i].pinmask;
				break;
			case udpIOUnRegisterClientForPortChanges:
				for (i=0;i<ALLOWED_CLIENTS;++i) {
					if(uip_ipaddr_cmp(&(clients[i].address), &(BUF->srcipaddr))) // found address of calling client in clients: remove it now
						uip_ipaddr(&(clients[i].address), 0,0,0,0);
				}
				break;
			default:
			break;
		};
		packet++;
		len-=sizeof(struct udpio_packet);
	}

	if (uip_slen == 0) return;
	/* Sent data out */

	uip_udp_conn_t echo_conn;
	uip_ipaddr_copy(echo_conn.ripaddr, BUF->srcipaddr);
	echo_conn.rport = BUF->srcport;
	echo_conn.lport = HTONS(UDP_IO_PORT);

	uip_udp_conn = &echo_conn;
	uip_process(UIP_UDP_SEND_CONN);
	router_output();

	uip_slen = 0;

}
Example #8
0
/*---------------------------------------------------------------------------*/
static void
handle_incoming_rrep(void)
{
  struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
  struct uaodv_rt_entry *rt;

  /* Useless HELLO message? */
  if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
#ifdef AODV_RESPOND_TO_HELLOS
    uint32_t net_seqno;
#ifdef CC2420_RADIO
    int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);

    if(ret == REMOTE_YES) {
      print_debug("HELLO drop is remote\n");
      return;
    } else if (ret == REMOTE_NO) {
      /* Is neigbour, accept it. */
    } else if(cc2420_last_rssi < RSSI_THRESHOLD) {
      print_debug("HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation);
      return;
    }
#endif
    /* Sometimes it helps to send a non-requested RREP in response! */
    net_seqno = uip_htonl(my_hseqno);
    send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0);
#endif
    return;
  }

  print_debug("RREP %d.%d.%d.%d -> %d.%d.%d.%d"
	      " dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n",
	      uip_ipaddr_to_quad(&BUF->srcipaddr),
	      uip_ipaddr_to_quad(&BUF->destipaddr),
	      uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno),
	      rm->hop_count,
	      uip_ipaddr_to_quad(&rm->orig_addr));

  rt = uaodv_rt_lookup(&rm->dest_addr);

  /* New forward route? */
  if(rt == NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) {
    print_debug("Inserting3\n");
    rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(),
		      rm->hop_count, &rm->dest_seqno);
#ifdef CC2420_RADIO
    /* This link is ok since he is unicasting back to us! */
    cc2420_recv_ok(uip_udp_sender());
    print_debug("RREP recv ok %d %d\n",
		cc2420_last_rssi, cc2420_last_correlation);
#endif
  } else {
    print_debug("Not inserting\n");
  }

  /* Forward RREP towards originator? */
  if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
    print_debug("ROUTE FOUND\n");
    if(rm->flags & UAODV_RREP_ACK) {
      struct uaodv_msg_rrep_ack *ack = (void *)uip_appdata;
      ack->type = UAODV_RREP_ACK_TYPE;
      ack->reserved = 0;
      sendto(uip_udp_sender(), ack, sizeof(*ack));
    }
  } else {
    rt = uaodv_rt_lookup(&rm->orig_addr);

    if(rt == NULL) {
      print_debug("RREP received, but no route back to originator... :-( \n");
      return;
    }

    if(rm->flags & UAODV_RREP_ACK) {
      print_debug("RREP with ACK request (ignored)!\n");
      /* Don't want any RREP-ACKs in return! */
      rm->flags &= ~UAODV_RREP_ACK;
    }

    rm->hop_count++;

    print_debug("Fwd RREP to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&rt->nexthop));

    sendto(&rt->nexthop, rm, sizeof(struct uaodv_msg_rrep));
  }
}
Example #9
0
void uip_icmpinput(struct uip_driver_s *dev)
{
  struct uip_icmpip_hdr *picmp = ICMPBUF;

#ifdef CONFIG_NET_STATISTICS
  uip_stat.icmp.recv++;
#endif

#ifndef CONFIG_NET_IPv6
  /* ICMPv4 processing code follows. */

  /* ICMP echo (i.e., ping) processing. This is simple, we only change the
   * ICMP type from ECHO to ECHO_REPLY and adjust the ICMP checksum before
   * we return the packet.
   */

  if (picmp->type == ICMP_ECHO_REQUEST)
    {
      /* If we are configured to use ping IP address assignment, we use
       * the destination IP address of this ping packet and assign it to
       * ourself.
       */

#ifdef CONFIG_NET_PINGADDRCONF
      if (dev->d_ipaddr == 0)
        {
          dev->d_ipaddr = picmp->destipaddr;
        }
#endif

      /* Change the ICMP type */

      picmp->type = ICMP_ECHO_REPLY;

      /* Swap IP addresses. */

      uiphdr_ipaddr_copy(picmp->destipaddr, picmp->srcipaddr);
      uiphdr_ipaddr_copy(picmp->srcipaddr, &dev->d_ipaddr);

      /* Recalculate the ICMP checksum */

#if 0
      /* The slow way... sum over the ICMP message */

      picmp->icmpchksum = 0;
      picmp->icmpchksum = ~uip_icmpchksum(dev, (((uint16_t)picmp->len[0] << 8) | (uint16_t)picmp->len[1]) - UIP_IPH_LEN);
      if (picmp->icmpchksum == 0)
        {
          picmp->icmpchksum = 0xffff;
        }
#else
      /* The quick way -- Since only the type has changed, just adjust the
       * checksum for the change of type
       */

      if (picmp->icmpchksum >= HTONS(0xffff - (ICMP_ECHO_REQUEST << 8)))
        {
          picmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8) + 1;
        }
      else
        {
          picmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8);
        }
#endif

      nllvdbg("Outgoing ICMP packet length: %d (%d)\n",
              dev->d_len, (picmp->len[0] << 8) | picmp->len[1]);

#ifdef CONFIG_NET_STATISTICS
      uip_stat.icmp.sent++;
      uip_stat.ip.sent++;
#endif
    }

  /* If an ICMP echo reply is received then there should also be
   * a thread waiting to received the echo response.
   */

#ifdef CONFIG_NET_ICMP_PING
  else if (picmp->type == ICMP_ECHO_REPLY && g_echocallback)
    {
      (void)uip_callbackexecute(dev, picmp, UIP_ECHOREPLY, g_echocallback);
    }
#endif

  /* Otherwise the ICMP input was not processed */

  else
    {
      nlldbg("Unknown ICMP cmd: %d\n", picmp->type);
      goto typeerr;
    }

  return;

typeerr:
#ifdef CONFIG_NET_STATISTICS
  uip_stat.icmp.typeerr++;
  uip_stat.icmp.drop++;
#endif
  dev->d_len = 0;

#else /* !CONFIG_NET_IPv6 */

  /* If we get a neighbor solicitation for our address we should send
   * a neighbor advertisement message back.
   */

  if (picmp->type == ICMP6_NEIGHBOR_SOLICITATION)
    {
      if (uip_ipaddr_cmp(picmp->icmp6data, dev->d_ipaddr))
        {
          if (picmp->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS)
            {
              /* Save the sender's address in our neighbor list. */

              uiphdr_neighbor_add(picmp->srcipaddr, &(picmp->options[2]));
            }

          /* We should now send a neighbor advertisement back to where the
           * neighbor solicitation came from.
           */

          picmp->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
          picmp->flags = ICMP6_FLAG_S; /* Solicited flag. */

          picmp->reserved1 = picmp->reserved2 = picmp->reserved3 = 0;

          uiphdr_ipaddr_copy(picmp->destipaddr, picmp->srcipaddr);
          uiphdr_ipaddr_copy(picmp->srcipaddr, &dev->d_ipaddr);
          picmp->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
          picmp->options[1] = 1;  /* Options length, 1 = 8 bytes. */
          memcpy(&(picmp->options[2]), &dev->d_mac, IFHWADDRLEN);
          picmp->icmpchksum = 0;
          picmp->icmpchksum = ~uip_icmp6chksum(dev);
        }
      else
        {
          goto drop;
        }
    }
  else if (picmp->type == ICMP6_ECHO_REQUEST)
    {
      /* ICMP echo (i.e., ping) processing. This is simple, we only
       * change the ICMP type from ECHO to ECHO_REPLY and update the
       * ICMP checksum before we return the packet.
       */

      picmp->type = ICMP6_ECHO_REPLY;

      uiphdr_ipaddr_copy(picmp->destipaddr, picmp->srcipaddr);
      uiphdr_ipaddr_copy(picmp->srcipaddr, &dev->d_ipaddr);
      picmp->icmpchksum = 0;
      picmp->icmpchksum = ~uip_icmp6chksum(dev);
    }

  /* If an ICMP echo reply is received then there should also be
   * a thread waiting to received the echo response.
   */

#ifdef CONFIG_NET_ICMP_PING
  else if (picmp->type == ICMP6_ECHO_REPLY && g_echocallback)
    {
      uint16_t flags = UIP_ECHOREPLY;

      if (g_echocallback)
        {
          /* Dispatch the ECHO reply to the waiting thread */

          flags = uip_callbackexecute(dev, picmp, flags, g_echocallback);
        }

      /* If the ECHO reply was not handled, then drop the packet */

      if (flags == UIP_ECHOREPLY)
        {
          /* The ECHO reply was not handled */

          goto drop;
        }
    }
#endif

  else
    {
      nlldbg("Unknown ICMP6 cmd: %d\n", picmp->type);
      goto typeerr;
    }

  nllvdbg("Outgoing ICMP6 packet length: %d (%d)\n",
          dev->d_len, (picmp->len[0] << 8) | picmp->len[1]);

#ifdef CONFIG_NET_STATISTICS
  uip_stat.icmp.sent++;
  uip_stat.ip.sent++;
#endif
  return;

typeerr:
#ifdef CONFIG_NET_STATISTICS
  uip_stat.icmp.typeerr++;
#endif

drop:
#ifdef CONFIG_NET_STATISTICS
  uip_stat.icmp.drop++;
#endif
  dev->d_len = 0;

#endif /* !CONFIG_NET_IPv6 */
}
Example #10
0
static int
eth_output(const uip_lladdr_t * src, const uip_lladdr_t * dest)
{
  if(IS_BROADCAST_ADDR(dest)) {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: broadcast\n");
  } else {
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_OUT, dest, "eth_output: ");
  }

  //Packet filtering
  //----------------
  if(uip_len == 0) {
    LOG6LBR_ERROR("eth_output: uip_len = 0\n");
    return 0;
  }

  if(dest && linkaddr_cmp((linkaddr_t *) & dest,
      (linkaddr_t *) & eth_mac64_addr)) {
    LOG6LBR_ERROR("ethernet_output: sending to self\n");
    return 0;
  }

#if CETIC_6LBR_ETH_FILTER_RPL
  //Filter out RPL (broadcast) traffic
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
     UIP_ICMP_BUF->type == ICMP6_RPL) {
    //LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Filtering out RPL traffic\n");
    return 0;
  }
#endif

  //IP packet alteration
  //--------------------
#if CETIC_6LBR_ROUTER
  //Modify source address
  if((nvm_data.mode & CETIC_MODE_REWRITE_ADDR_MASK) != 0
     && uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)
     && uip_ipaddr_cmp(&UIP_IP_BUF->srcipaddr, &wsn_ip_local_addr)) {
    LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Update src address\n");
    uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &eth_ip_local_addr);
    if(UIP_IP_BUF->proto == UIP_PROTO_UDP) {
#if UIP_UDP_CHECKSUMS
      /* Calculate UDP checksum. */
      UIP_UDP_BUF->udpchksum = 0;
      UIP_UDP_BUF->udpchksum = ~(uip_udpchksum());
      if(UIP_UDP_BUF->udpchksum == 0) {
        UIP_UDP_BUF->udpchksum = 0xffff;
      }
#endif /* UIP_UDP_CHECKSUMS */
    } else if(UIP_IP_BUF->proto == UIP_PROTO_TCP) {
      /* Calculate TCP checksum. */
      UIP_TCP_BUF->tcpchksum = 0;
      UIP_TCP_BUF->tcpchksum = ~(uip_tcpchksum());
    } else if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
      /* Calculate ICMP checksum. */
      UIP_ICMP_BUF->icmpchksum = 0;
      UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
    }
  }
#endif
#if CETIC_6LBR_SMARTBRIDGE
  //Reset Hop Limit when in smart-bridge for NDP packets
  //TODO: Is this still needed after #4467 ?
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 &&
     (UIP_ICMP_BUF->type == ICMP6_NS || UIP_ICMP_BUF->type == ICMP6_NA
      || UIP_ICMP_BUF->type == ICMP6_RS || UIP_ICMP_BUF->type == ICMP6_RA)) {
    UIP_IP_BUF->ttl = 255;
  }
#endif
#if CETIC_6LBR_SMARTBRIDGE || CETIC_6LBR_TRANSPARENTBRIDGE
  //Remove ROUTER flag when in bridge mode
  if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type == ICMP6_NA) {
    //LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Updating NA\n");
    UIP_ND6_NA_BUF->flagsreserved &= ~UIP_ND6_NA_FLAG_ROUTER;
  }
#endif
  //Some IP packets have link layer in them, need to change them around!
  mac_translateIPLinkLayer(ll_8023_type);

  //IP header alteration
  //--------------------
#if UIP_CONF_IPV6_RPL
  rpl_remove_header();
#endif

  //Create packet header
  //--------------------
  //Packet type
  BUF->type = uip_htons(UIP_ETHTYPE_IPV6);

  //Destination address
  if(IS_BROADCAST_ADDR(dest)) {
    BUF->dest.addr[0] = 0x33;
    BUF->dest.addr[1] = 0x33;
    BUF->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
    BUF->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
    BUF->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
    BUF->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
  } else {
    mac_createEthernetAddr(BUF->dest.addr, dest);
  }

  //Source address
  if ( src != NULL ) {
    mac_createEthernetAddr(BUF->src.addr, src);
  } else {
    memcpy(BUF->src.addr, eth_mac_addr, 6);
  }
  //Sending packet
  //--------------
  LOG6LBR_PRINTF(PACKET, PF_OUT, "eth_output: Sending packet to Ethernet\n");
  eth_drv_send(uip_buf, uip_len + UIP_LLH_LEN);

  return 1;
}
Example #11
0
/*-----------------------------------------------------------------------------------*/
void
uip_arp_arpin(void)
{
	if(uip_len < sizeof(struct arp_hdr)) {
		uip_len = 0;
		return;
	}
	uip_len = 0;

	switch(BUF->opcode) {
	case HTONS(ARP_HINT):
		/* Please note this is not a valid ARP type, this is just a 
		 * hint to implement prefetch/refresh of ARP mapping */

		/* This is a valid hint if we are the source of this request,
		 * the requested ipaddr is in dipaddress */
		if(uip_ipaddr_cmp(BUF->sipaddr, uip_hostaddr)) {
			/* We first try to check for the destination address 
			 * in our ARP table */
			if(uip_arp_update(BUF->dipaddr, &broadcast_ethaddr)) {
			/* If the destination address was not in our ARP table, 
			 * we send out an ARP request for the same */
				memset(BUF->ethhdr.dest.addr, 0xff, 6);
				BUF->opcode = HTONS(ARP_REQUEST);
				/* The other ARP fields of incoming hint are 
				 * supposed to be same as ARP broadcast except
				 * the opcode field */

				uip_len = sizeof(struct arp_hdr);
			}
		}
		break;

	case HTONS(ARP_REQUEST):
		/* ARP request. If it asked for our address, we send out a
		   reply. */
		if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
			/* First, we register the one who made the request in our ARP
			   table, since it is likely that we will do more communication
			   with this host in the future. */
			uip_arp_update(BUF->sipaddr, &BUF->shwaddr);

			BUF->opcode = HTONS(ARP_REPLY);

			memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
			memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
			memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
			memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);

			BUF->dipaddr[0] = BUF->sipaddr[0];
			BUF->dipaddr[1] = BUF->sipaddr[1];
			BUF->sipaddr[0] = uip_hostaddr[0];
			BUF->sipaddr[1] = uip_hostaddr[1];

			BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
			uip_len = sizeof(struct arp_hdr);
		}
		break;
	case HTONS(ARP_REPLY):
		/* ARP reply. We insert or update the ARP table if it was meant
		   for us. */
		if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
			uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
			vmm_completion_complete(&uip_arp_prefetch_done);
		}
		break;
	}

	return;
}
Example #12
0
PROCESS_THREAD(cc2420_process, ev, data)
{
  PROCESS_BEGIN();

  process_start(&cc2420_retransmit_process, NULL);

  while (1) {
    unsigned len;
    int s;

    PROCESS_YIELD();

    len = rx_fifo_remaining_bytes;
    if (len > 0) {
      /* Read payload and two bytes of footer */
      if ((len - 2) > (UIP_BUFSIZE - UIP_LLH_LEN) || len < 2) {
	PRINTF("cc2420_process too big len=%d\n", len);
	s = splhigh();
	FASTSPI_READ_FIFO_GARBAGE(len);
	rx_fifo_remaining_bytes = 0; /* RX FIFO emptied! */
	splx(s);
	len = 0;
      } else {
	u8_t footer[2];
	uip_len = 0;
	s = splhigh();
	if (len > 2)
	  FASTSPI_READ_FIFO_NO_WAIT(&uip_buf[UIP_LLH_LEN], len - 2);
	FASTSPI_READ_FIFO_NO_WAIT(footer, 2);
	rx_fifo_remaining_bytes = 0; /* RX FIFO emptied! */
	splx(s);
	if (footer[1] & FOOTER1_CRC_OK) {
	  cc2420_last_rssi = footer[0];
	  cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION;
	  if ((h.fc0 & FC0_TYPE_MASK) == FC0_TYPE_DATA)
	    uip_len = len - 2;
	}
      }
    }

    if (len == 2)
      PRINTF("recv data_ack\n");

    /* Clean up in case of FIFO overflow!  This happens for every full
     * length frame and is signaled by FIFOP = 1 and FIFO = 0.
     */
    if (FIFOP_IS_1 && !FIFO_IS_1) {
      cc2420_strobe(CC2420_SFLUSHRX);
      cc2420_strobe(CC2420_SFLUSHRX);
    }

    if (FIFOP_IS_1) {
      s = splhigh();
      __cc2420_intr();		/* Fake interrupt! */
      splx(s);
    }

    if (len == 2) {		/* A DATA ACK packet. */
      if (last_dst == h.src)
	cc2420_ack_received = 1;
      neigbour_update(h.src, 0);
    } else if (len > 2 && uip_len > 0
       && uip_len == (((u16_t)(BUF->len[0]) << 8) + BUF->len[1])) {
      /*
       * If we are the unique receiver send DATA ACK.
       */
      if (h.dst == 0xffff
	  && uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr))
	cc2420_send_data_ack(h.src);
      leds_toggle(LEDS_GREEN);
      cc2420_is_input = 1;
      tcpip_input();
      cc2420_is_input = 0;
      leds_toggle(LEDS_GREEN);
    }
  }

  PROCESS_END();
}
Example #13
0
/*-----------------------------------------------------------------------------------*/
uint8_t
uip_arp_out(void)
{
#ifdef MDNS_SD_SUPPORT
  uip_ipaddr_t mdns_address = {0x00e0, 0xfb00};
#endif
  
  /* Find the destination IP address in the ARP table and construct
     the Ethernet header. If the destination IP addres isn't on the
     local network, we use the default router's IP address instead.

     If not ARP table entry is found, we overwrite the original IP
     packet with an ARP request for the IP address. */

  /* First check if destination is a local broadcast. */
  if(((const uint8_t *)IPBUF->destipaddr)[0] >= 224
     && ((const uint8_t *)IPBUF->destipaddr)[0] <= 239) {
    /* packet is addressed to multicast ip range, generate
       the associated mac address for it. */
    IPBUF->ethhdr.dest.addr[0] = 0x01;
    IPBUF->ethhdr.dest.addr[1] = 0x00;
    IPBUF->ethhdr.dest.addr[2] = 0x5e;
    IPBUF->ethhdr.dest.addr[3] = ((const uint8_t *)IPBUF->destipaddr)[1] & 0x7f;
    IPBUF->ethhdr.dest.addr[4] = ((const uint8_t *)IPBUF->destipaddr)[2];
    IPBUF->ethhdr.dest.addr[5] = ((const uint8_t *)IPBUF->destipaddr)[3];
  }
  else if((IPBUF->destipaddr[0] == (uip_hostaddr[0] | ~uip_netmask[0])
           && IPBUF->destipaddr[1] == (uip_hostaddr[1] | ~uip_netmask[1]))
          || (uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr))) {
    memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
#ifdef MDNS_SD_SUPPORT
  /* If the ip is the mdns mulicast ip, we answer to the mac who asked */
  } else if (uip_ipaddr_cmp(IPBUF->destipaddr, mdns_address)) {
    memcpy(IPBUF->ethhdr.dest.addr, &((struct uip_eth_hdr *) uip_buf)->dest, 6); 
#endif
  } else {
    /* Check if the destination address is on the local network. */
    if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
      /* Destination address was not on the local network, so we need to
	 use the default router's IP address instead of the destination
	 address when determining the MAC address. */
      uip_ipaddr_copy(ipaddr, uip_draddr);
    } else {
      /* Else, we use the destination IP address. */
      uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
    }

    struct arp_entry *tabptr = uip_arp_lookup (ipaddr);

    if(!tabptr) {
      /* The destination address was not in our ARP table, so we
	 overwrite the IP packet with an ARP request. */

      memset(BUF->ethhdr.dest.addr, 0xff, 6);
      memset(BUF->dhwaddr.addr, 0x00, 6);
      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
    
      uip_ipaddr_copy(BUF->dipaddr, ipaddr);
      uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
      BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
      BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
      BUF->protocol = HTONS(UIP_ETHTYPE_IP);
      BUF->hwlen = 6;
      BUF->protolen = 4;
      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);

      /* FIXME uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN]; */
    
      uip_len = sizeof(struct arp_hdr);
      return 1;
    }

    /* Build an ethernet header. */
    memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
  }
  memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
  
  IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);

  uip_len += sizeof(struct uip_eth_hdr);

  return 0;
}
Example #14
0
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
{
  rpl_dag_t *dag;
  rpl_instance_t *instance;
  uint8_t version;
  int i;

#if CETIC_6LBR
  version = nvm_data.rpl_version_id;
  uint8_t new_version = version;
  RPL_LOLLIPOP_INCREMENT(new_version);
  nvm_data.rpl_version_id = new_version;
  store_nvm_config();
#else
  version = RPL_LOLLIPOP_INIT;
#endif
  instance = rpl_get_instance(instance_id);
  if(instance != NULL) {
    for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; ++i) {
      dag = &instance->dag_table[i];
      if(dag->used) {
        if(uip_ipaddr_cmp(&dag->dag_id, dag_id)) {
          version = dag->version;
          RPL_LOLLIPOP_INCREMENT(version);
#if CETIC_6LBR
          nvm_data.rpl_version_id = version;
          store_nvm_config();
#endif
        }
        if(dag == dag->instance->current_dag) {
          PRINTF("RPL: Dropping a joined DAG when setting this node as root");
          dag->instance->current_dag = NULL;
        } else {
          PRINTF("RPL: Dropping a DAG when setting this node as root");
        }
        rpl_free_dag(dag);
      }
    }
  }

  dag = rpl_alloc_dag(instance_id, dag_id);
  if(dag == NULL) {
    PRINTF("RPL: Failed to allocate a DAG\n");
    return NULL;
  }

  instance = dag->instance;

  dag->version = version;
  dag->joined = 1;
  dag->grounded = RPL_GROUNDED;
  dag->preference = RPL_PREFERENCE;
  instance->mop = RPL_MOP_DEFAULT;
  instance->of = &RPL_OF;
  rpl_set_preferred_parent(dag, NULL);

  memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id));

  instance->dio_intdoubl = RPL_DIO_INTERVAL_DOUBLINGS;
  instance->dio_intmin = RPL_DIO_INTERVAL_MIN;
  /* The current interval must differ from the minimum interval in order to
     trigger a DIO timer reset. */
  instance->dio_intcurrent = RPL_DIO_INTERVAL_MIN +
    RPL_DIO_INTERVAL_DOUBLINGS;
  instance->dio_redundancy = RPL_DIO_REDUNDANCY;
  instance->max_rankinc = RPL_MAX_RANKINC;
  instance->min_hoprankinc = RPL_MIN_HOPRANKINC;
  instance->default_lifetime = RPL_DEFAULT_LIFETIME;
  instance->lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT;

  dag->rank = ROOT_RANK(instance);

  if(instance->current_dag != dag && instance->current_dag != NULL) {
    /* Remove routes installed by DAOs. */
    rpl_remove_routes(instance->current_dag);

    instance->current_dag->joined = 0;
  }

  instance->current_dag = dag;
  instance->dtsn_out = RPL_LOLLIPOP_INIT;
  instance->of->update_metric_container(instance);
  default_instance = instance;

  PRINTF("RPL: Node set to be a DAG root with DAG ID ");
  PRINT6ADDR(&dag->dag_id);
  PRINTF("\n");

  ANNOTATE("#A root=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);

  rpl_reset_dio_timer(instance);

  return dag;
}
Example #15
0
/*------------------------------------------------------------------------------*/
u8_t
uip_fw_forward(void)
{
  struct fwcache_entry *fw;

  /* First check if the packet is destined for ourselves and return 0
     to indicate that the packet should be processed locally. */
  if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
    return UIP_FW_LOCAL;
  }

#ifdef AODV_COMPLIANCE
#define udp ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
  if(udp->proto == UIP_PROTO_UDP && udp->destport == UIP_HTONS(UAODV_UDPPORT)) {
    return UIP_FW_LOCAL;
  }
#endif

  /* If we use ping IP address configuration, and our IP address is
     not yet configured, we should intercept all ICMP echo packets. */
#if UIP_PINGADDRCONF
  if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) &&
     BUF->proto == UIP_PROTO_ICMP &&
     ICMPBUF->type == ICMP_ECHO) {
    return UIP_FW_LOCAL;
  }
#endif /* UIP_PINGADDRCONF */

  /* Check if the packet is in the forwarding cache already, and if so
     we drop it. */

  for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
    if(fw->timer != 0 &&
#if UIP_REASSEMBLY > 0
       fw->len == BUF->len &&
       fw->offset == BUF->ipoffset &&
#endif
       fw->ipid == BUF->ipid &&
       uip_ipaddr_cmp(&fw->srcipaddr, &BUF->srcipaddr) &&
       uip_ipaddr_cmp(&fw->destipaddr, &BUF->destipaddr) &&
#if notdef
       fw->payload[0] == BUF->srcport &&
       fw->payload[1] == BUF->destport &&
#endif
       fw->proto == BUF->proto) {
      /* Drop packet. */
      return UIP_FW_FORWARDED;
    }
  }

  /* If the TTL reaches zero we produce an ICMP time exceeded message
     in the uip_buf buffer and forward that packet back to the sender
     of the packet. */

  if(BUF->ttl <= 1) {
    /* No time exceeded for broadcasts and multicasts! */
    if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
      return UIP_FW_LOCAL;
    }
    time_exceeded();
  }

  /* Decrement the TTL (time-to-live) value in the IP header */
  BUF->ttl = BUF->ttl - 1;

  /* Update the IP checksum. */
  if(BUF->ipchksum >= UIP_HTONS(0xffff - 0x0100)) {
    BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100) + 1;
  } else {
    BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100);
  }

  if(uip_len > 0) {
    uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
    uip_fw_output();
  }

#if UIP_BROADCAST
  if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
    return UIP_FW_LOCAL;
  }
#endif /* UIP_BROADCAST */

  /* Return non-zero to indicate that the packet was forwarded and that no
     other processing should be made. */
  return UIP_FW_FORWARDED;
}
Example #16
0
/*---------------------------------------------------------------------------*/
static void
handle_incoming_rreq(void)
{
  struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
  uip_ipaddr_t dest_addr, orig_addr;
  struct uaodv_rt_entry *rt, *fw = NULL;
  
  print_debug("RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u"
	      " orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n",
	      uip_ipaddr_to_quad(&BUF->srcipaddr),
	      uip_ipaddr_to_quad(&BUF->destipaddr),
	      BUF->ttl,
	      uip_ipaddr_to_quad(&rm->orig_addr), uip_ntohl(rm->orig_seqno),
	      rm->hop_count,
	      uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno));

  if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
    return;			/* RREQ looped back! */
  }

#ifdef CC2420_RADIO
 {
   int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);

   if(ret == REMOTE_YES) {
     print_debug("RREQ drop is remote\n");
     return;
   } else if (ret == REMOTE_NO) {
     /* Is neigbour, accept it. */
   } else if(cc2420_last_rssi < RSSI_THRESHOLD) {
     print_debug("RREQ drop %d %d\n", cc2420_last_rssi,
		 cc2420_last_correlation);
     return;
   }
 }
#endif

#ifdef AODV_BAD_HOP_EXTENSION
  if(uip_len > (sizeof(*rm) + 2)) {
    struct uaodv_bad_hop_ext *ext = (void *)(uip_appdata + sizeof(*rm));
    uint8_t *end = uip_appdata + uip_len;
    for(;
	(uint8_t *)ext < end;
	ext = (void *)((uint8_t *)ext + ext->length + 2)) {
      uint8_t *eend = (uint8_t *)ext + ext->length;
      if(eend > end)
	eend = end;

      if(ext->type == RREQ_BAD_HOP_EXT) {
	uip_ipaddr_t *a;
	for(a = ext->addrs; (uint8_t *)a < eend; a++) {
	  if(uip_ipaddr_cmp(a, &uip_hostaddr)) {
	    print_debug("BAD_HOP drop\n");
	    return;
	  }
	}
      }
    }
  }
#endif /* AODV_BAD_HOP_EXTENSION */

  /* New reverse route? */
  rt = uaodv_rt_lookup(&rm->orig_addr);
  if(rt == NULL
     || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0) /* New route. */
     || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0
	 && rm->hop_count < rt->hop_count)) { /* Better route. */
    print_debug("Inserting1\n");
    rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(),
		      rm->hop_count, &rm->orig_seqno);
  }
    
  /* Check if it is for our address or a fresh route. */
  if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)
     || rm->flags & UAODV_RREQ_DESTONLY) {
    fw = NULL;
  } else {
    fw = uaodv_rt_lookup(&rm->dest_addr);
    if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
       && fw != NULL
       && SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) {
      fw = NULL;
    }
  }

  if (fw != NULL) {
    uint32_t net_seqno;

    print_debug("RREQ for known route\n");
    uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
    uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
    net_seqno = uip_htonl(fw->hseqno);
    send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno,
	      fw->hop_count + 1);
  } else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) {
    uint32_t net_seqno;

    print_debug("RREQ for our address\n");
    uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
    uip_ipaddr_copy(&orig_addr, &rm->orig_addr);

    my_hseqno++;
    if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
       && SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) {
      print_debug("New my_hseqno %lu\n", my_hseqno); /* We have rebooted. */
      my_hseqno = uip_ntohl(rm->dest_seqno) + 1;
    }
    net_seqno = uip_htonl(my_hseqno);
    send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0);
  } else if(BUF->ttl > 1) {
    int len;

    /* Have we seen this RREQ before? */
    if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) {
      print_debug("RREQ cached, not fwd\n");
      return;
    }
    fwc_add(&rm->orig_addr, &rm->rreq_id);

    print_debug("RREQ fwd\n");
    rm->hop_count++;
    bcastconn->ttl = BUF->ttl - 1;
    len = sizeof(struct uaodv_msg_rreq);
    len += add_rreq_extensions(rm + 1);
    uip_udp_packet_send(bcastconn, rm, len);
  }
}
Example #17
0
/**
 * @brief
 * @note
 * @param
 * @retval
 */
bool UIPDebug::uip_debug_printcon(struct uip_conn* lhs, struct uip_conn* rhs) {
    bool    changed = false;
    if(!uip_ipaddr_cmp(lhs->ripaddr, rhs->ripaddr)) {
        pc.printf(" ripaddr: ");
        uip_debug_printbytes((const uint8_t*)lhs->ripaddr, 4);
        pc.printf(" -> ");
        uip_debug_printbytes((const uint8_t*)rhs->ripaddr, 4);
        pc.printf("\n");
        uip_ipaddr_copy(lhs->ripaddr, rhs->ripaddr);
        changed = true;
    }

    if(lhs->lport != rhs->lport) {
        pc.printf(" lport: ");
        pc.printf("%d", htons(lhs->lport));
        pc.printf(" -> ");
        pc.printf("%d\n", htons(rhs->lport));
        lhs->lport = rhs->lport;
        changed = true;
    }

    if(lhs->rport != rhs->rport) {
        pc.printf(" rport: ");
        pc.printf("%d", htons(lhs->rport));
        pc.printf(" -> ");
        pc.printf("%d\n", htons(rhs->rport));
        lhs->rport = rhs->rport;
        changed = true;
    }

    if((uint32_t) lhs->rcv_nxt[0] != (uint32_t) rhs->rcv_nxt[0]) {
        pc.printf(" rcv_nxt: ");
        uip_debug_printbytes(lhs->rcv_nxt, 4);
        pc.printf(" -> ");
        uip_debug_printbytes(rhs->rcv_nxt, 4);
        *((uint32_t*) &lhs->rcv_nxt[0]) = (uint32_t) rhs->rcv_nxt[0];
        pc.printf("\n");
        changed = true;
    }

    if((uint32_t) lhs->snd_nxt[0] != (uint32_t) rhs->snd_nxt[0]) {
        pc.printf(" snd_nxt: ");
        uip_debug_printbytes(lhs->snd_nxt, 4);
        pc.printf(" -> ");
        uip_debug_printbytes(rhs->snd_nxt, 4);
        *((uint32_t*) &lhs->snd_nxt[0]) = (uint32_t) rhs->snd_nxt[0];
        pc.printf("\n");
        changed = true;
    }

    if(lhs->len != rhs->len) {
        pc.printf(" len: ");
        pc.printf("%d", lhs->len);
        pc.printf(" -> ");
        pc.printf("%d\n", rhs->len);
        lhs->len = rhs->len;
        changed = true;
    }

    if(lhs->mss != rhs->mss) {
        pc.printf(" mss: ");
        pc.printf("%d", lhs->mss);
        pc.printf(" -> ");
        pc.printf("%d\n", rhs->mss);
        lhs->mss = rhs->mss;
        changed = true;
    }

    if(lhs->initialmss != rhs->initialmss) {
        pc.printf(" initialmss: ");
        pc.printf("%d", lhs->initialmss);
        pc.printf(" -> ");
        pc.printf("%d\n", rhs->initialmss);
        lhs->initialmss = rhs->initialmss;
        changed = true;
    }

    if(lhs->sa != rhs->sa) {
        pc.printf(" sa: ");
        pc.printf("%d", lhs->sa);
        pc.printf(" -> ");
        pc.printf("%d", rhs->sa);
        lhs->sa = rhs->sa;
        changed = true;
    }

    if(lhs->sv != rhs->sv) {
        pc.printf(" sv: ");
        pc.printf("%d", lhs->sv);
        pc.printf(" -> ");
        pc.printf("%d\n", rhs->sv);
        lhs->sv = rhs->sv;
        changed = true;
    }

    if(lhs->rto != rhs->rto) {
        pc.printf(" rto: ");
        pc.printf("%d", lhs->rto);
        pc.printf(" -> ");
        pc.printf("%d\n", rhs->rto);
        lhs->rto = rhs->rto;
        changed = true;
    }

    if(lhs->tcpstateflags != rhs->tcpstateflags) {
        pc.printf(" tcpstateflags: ");
        pc.printf("%d", lhs->tcpstateflags);
        pc.printf(" -> ");
        pc.printf("%d\n", rhs->tcpstateflags);
        lhs->tcpstateflags = rhs->tcpstateflags;
        changed = true;
    }

    if(lhs->timer != rhs->timer) {
        pc.printf(" timer: ");
        pc.printf("%d", lhs->timer);
        pc.printf(" -> ");
        pc.printf("%d\n", rhs->timer);
        lhs->timer = rhs->timer;
        changed = true;
    }

    if(lhs->nrtx != rhs->nrtx) {
        pc.printf(" nrtx: ");
        pc.printf("%d", lhs->nrtx);
        pc.printf(" -> ");
        pc.printf("%d\n", rhs->nrtx);
        lhs->nrtx = rhs->nrtx;
        changed = true;
    }

    return changed;
}
Example #18
0
static CC_INLINE int
fwc_lookup(const uip_ipaddr_t *orig, const uint32_t *id)
{
  unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
  return fwcache[n].id == *id && uip_ipaddr_cmp(&fwcache[n].orig, orig);
}
Example #19
0
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm(uip_ds6_route_t *route)
{
    struct uip_ds6_route_neighbor_route *neighbor_route;
#if DEBUG != DEBUG_NONE
    assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
    if(route != NULL && route->neighbor_routes != NULL) {

        PRINTF("uip_ds6_route_rm: removing route: ");
        PRINT6ADDR(&route->ipaddr);
        PRINTF("\n");

        /* Remove the neighbor from the route list */
        list_remove(routelist, route);

        /* Find the corresponding neighbor_route and remove it. */
        for(neighbor_route = list_head(route->neighbor_routes->route_list);
                neighbor_route != NULL && neighbor_route->route != route;
                neighbor_route = list_item_next(neighbor_route));

        if(neighbor_route == NULL) {
            PRINTF("uip_ds6_route_rm: neighbor_route was NULL for ");
            uip_debug_ipaddr_print(&route->ipaddr);
            PRINTF("\n");
        }
        list_remove(route->neighbor_routes->route_list, neighbor_route);
        if(list_head(route->neighbor_routes->route_list) == NULL) {
            /* If this was the only route using this neighbor, remove the
               neibhor from the table */
            PRINTF("uip_ds6_route_rm: removing neighbor too\n");
            nbr_table_remove(nbr_routes, route->neighbor_routes->route_list);
        }
        memb_free(&routememb, route);
        memb_free(&neighborroutememb, neighbor_route);

        num_routes--;

        PRINTF("uip_ds6_route_rm num %d\n", num_routes);

#if UIP_DS6_NOTIFICATIONS
        call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
                            &route->ipaddr, uip_ds6_route_nexthop(route));
#endif
#if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
        /* we need to check if this was the last route towards "nexthop" */
        /* if so - remove that link (annotation) */
        uip_ds6_route_t *r;
        for(r = uip_ds6_route_head();
                r != NULL;
                r = uip_ds6_route_next(r)) {
            uip_ipaddr_t *nextr, *nextroute;
            nextr = uip_ds6_route_nexthop(r);
            nextroute = uip_ds6_route_nexthop(route);
            if(nextr != NULL &&
                    nextroute != NULL &&
                    uip_ipaddr_cmp(nextr, nextroute)) {
                /* we found another link using the specific nexthop, so keep the #L */
                return;
            }
        }
        ANNOTATE("#L %u 0\n", uip_ds6_route_nexthop(route)->u8[sizeof(uip_ipaddr_t) - 1]);
#endif
    }

#if DEBUG != DEBUG_NONE
    assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
    return;
}
Example #20
0
/*-----------------------------------------------------------------------------------*/
static void
uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr)
{
  register struct arp_entry *tabptr = arp_table;

  /* Walk through the ARP mapping table and try to find an entry to
     update. If none is found, the IP -> MAC address mapping is
     inserted in the ARP table. */
  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
    tabptr = &arp_table[i];

    /* Only check those entries that are actually in use. */
    if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {

      /* Check if the source IP address of the incoming packet matches
         the IP address in this ARP table entry. */
      if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) {
	 
	/* An old entry found, update this and return. */
	memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
	tabptr->time = arptime;

	return;
      }
    }
	tabptr++;
  }

  /* If we get here, no existing ARP table entry was found, so we
     create one. */

  /* First, we try to find an unused entry in the ARP table. */
  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
    tabptr = &arp_table[i];
    if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
      break;
    }
  }

  /* If no unused entry is found, we try to find the oldest entry and
     throw it away. */
  if(i == UIP_ARPTAB_SIZE) {
    tmpage = 0;
    c = 0;
    for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
      tabptr = &arp_table[i];
      if(arptime - tabptr->time > tmpage) {
	tmpage = arptime - tabptr->time;
	c = i;
      }
    }
    i = c;
    tabptr = &arp_table[i];
  }

  /* Now, i is the ARP table entry which we will fill with the new
     information. */
  uip_ipaddr_copy(&tabptr->ipaddr, ipaddr);
  memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
  tabptr->time = arptime;
}
Example #21
0
/*-----------------------------------------------------------------------------------*/
void
uip_arp_out(struct net_buf *buf)
{
  struct arp_entry *tabptr = arp_table;

  /* Find the destination IP address in the ARP table and construct
     the Ethernet header. If the destination IP addres isn't on the
     local network, we use the default router's IP address instead.

     If not ARP table entry is found, we overwrite the original IP
     packet with an ARP request for the IP address. */

  /* First check if destination is a local broadcast. */
  if(uip_ipaddr_cmp(&IPBUF(buf)->destipaddr, &uip_broadcast_addr)) {
    memcpy(IPBUF(buf)->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
  } else if(IPBUF(buf)->destipaddr.u8[0] == 224) {
    /* Multicast. */
    IPBUF(buf)->ethhdr.dest.addr[0] = 0x01;
    IPBUF(buf)->ethhdr.dest.addr[1] = 0x00;
    IPBUF(buf)->ethhdr.dest.addr[2] = 0x5e;
    IPBUF(buf)->ethhdr.dest.addr[3] = IPBUF(buf)->destipaddr.u8[1];
    IPBUF(buf)->ethhdr.dest.addr[4] = IPBUF(buf)->destipaddr.u8[2];
    IPBUF(buf)->ethhdr.dest.addr[5] = IPBUF(buf)->destipaddr.u8[3];
  } else {
    /* Check if the destination address is on the local network. */
    if(!uip_ipaddr_maskcmp(&IPBUF(buf)->destipaddr, &uip_hostaddr, &uip_netmask)) {
      /* Destination address was not on the local network, so we need to
	 use the default router's IP address instead of the destination
	 address when determining the MAC address. */
      uip_ipaddr_copy(&ipaddr, &uip_draddr);
    } else {
      /* Else, we use the destination IP address. */
      uip_ipaddr_copy(&ipaddr, &IPBUF(buf)->destipaddr);
    }
    for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
      if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) {
	break;
      }
	  tabptr++;
    }

    if(i == UIP_ARPTAB_SIZE) {
      /* The destination address was not in our ARP table, so we
	 overwrite the IP packet with an ARP request. */

      memset(BUF(buf)->ethhdr.dest.addr, 0xff, 6);
      memset(BUF(buf)->dhwaddr.addr, 0x00, 6);
      memcpy(BUF(buf)->ethhdr.src.addr, uip_lladdr.addr, 6);
      memcpy(BUF(buf)->shwaddr.addr, uip_lladdr.addr, 6);

      uip_ipaddr_copy(&BUF(buf)->dipaddr, &ipaddr);
      uip_ipaddr_copy(&BUF(buf)->sipaddr, &uip_hostaddr);
      BUF(buf)->opcode = UIP_HTONS(ARP_REQUEST); /* ARP request. */
      BUF(buf)->hwtype = UIP_HTONS(ARP_HWTYPE_ETH);
      BUF(buf)->protocol = UIP_HTONS(UIP_ETHTYPE_IP);
      BUF(buf)->hwlen = 6;
      BUF(buf)->protolen = 4;
      BUF(buf)->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);

      uip_appdata(buf) = &uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN];

      uip_len(buf) = sizeof(struct arp_hdr);
      return;
    }

    /* Build an ethernet header. */
    memcpy(IPBUF(buf)->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
  }
  memcpy(IPBUF(buf)->ethhdr.src.addr, uip_lladdr.addr, 6);

  IPBUF(buf)->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_IP);

  uip_len(buf) += sizeof(struct uip_eth_hdr);
}