Beispiel #1
0
/* Sends a ping packet out the radio */
static void
raven_ping6(void)
{
   
  /* ping ipv6.google.com*/
  uip_ip6addr(&ping_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB);
  //uip_ip6addr(&ping_addr, 0x2001, 0x4860, 0, 0x2001, 0, 0, 0, 0x68);
  //uip_ip6addr(&ping_addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
  
  UIP_IP_BUF->vtc = 0x60;
  UIP_IP_BUF->tcflow = 1;
  UIP_IP_BUF->flow = 0;
  UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
  UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit;
  uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &ping_addr);
  uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
 
  UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST;
  UIP_ICMP_BUF->icode = 0;
  /* set identifier and sequence number to 0 */
  memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
    
  uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN;
  UIP_IP_BUF->len[0] = (u8_t)((uip_len - 40) >> 8);
  UIP_IP_BUF->len[1] = (u8_t)((uip_len - 40) & 0x00FF);
    
  UIP_ICMP_BUF->icmpchksum = 0;
  UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
    
  tcpip_ipv6_output();
}
Beispiel #2
0
/*------------------------------------------------------------------*/
void
uip_nd6_io_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt)
{
  /* IP header fields */
  uip_ext_len = 0;
  UIP_IP_BUF->vtc = 0x60;
  UIP_IP_BUF->tcflow = 0;
  UIP_IP_BUF->flow = 0;
  UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
  UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT;

  /*
   * The caller must put a valid tgt address. 
   * For dest, if the caller is doing DAD or Address resolution, he sets
   * dest to NULL and we forge dest as the sollicited node mcast address
   * for tgt.
   * If the caller is sending the NS for NUD, dest is unicast and the caller
   * specifies it in the arguments
   */
  if(dest == NULL) {
    uip_create_solicited_node(tgt, &UIP_IP_BUF->destipaddr);
  } else {
    uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest);
  }
  UIP_ICMP_BUF->type = ICMP6_NS;
  UIP_ICMP_BUF->icode = 0;
  UIP_ND6_NS_BUF->reserved = 0;

  /* Copy the tgt address */
  uip_ipaddr_copy((uip_ipaddr_t *)&UIP_ND6_NS_BUF->tgtipaddr, tgt);
  
  UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */
  /*
   * check if we add a SLLAO option: for DAD, MUST NOT, for NUD, MAY
   * (here yes), for Address resolution , MUST 
   * i.e. if and only if tgt is our address (in this case it is DAD), we do
   * not add it
   */ 
  if(!(uip_netif_is_addr_my_unicast(tgt))) {
    if(src != NULL) {
      uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, src);
    } else {
      uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
    }
    UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN;
   
    uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN;
    nd6_opt_llao = (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NS_LEN];
    nd6_opt_llao->type = UIP_ND6_OPT_SLLAO; /* type of the option */
    /* 
     * length of the option: 2 bytes for type, length, plus the length of
     * the L2 address. It must be in units of 8 bytes 
     */
    nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3;
    memcpy(&nd6_opt_llao->addr, &uip_lladdr, UIP_LLADDR_LEN);
    /* padding if needed */
    memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN);
  }
  else {
Beispiel #3
0
/* Sends a ping packet out the radio */
static void
raven_ping6(void)
{
    /* ping the router */
    // Setup destination address.
    struct uip_nd6_defrouter *defrouter;
    uint8_t i,tmp;

    defrouter = uip_nd6_choose_defrouter();
    /* Get address from defrouter struct */
    memcpy(addr, defrouter->nb->ipaddr.u8, 16);
    /* Swap the bytes in the address array */
    for (i=0;i<8;i++)
    {
        tmp = addr[i] & 0xff;
        addr[i] >>= 8;
        addr[i] |= tmp << 8;
    }
    uip_ip6addr(&dest_addr, addr[0], addr[1],addr[2],
                addr[3],addr[4],addr[5],addr[6],addr[7]);
  
    UIP_IP_BUF->vtc = 0x60;
    UIP_IP_BUF->tcflow = 1;
    UIP_IP_BUF->flow = 0;
    UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
    UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit;
    uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &dest_addr);
    uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
 
    UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST;
    UIP_ICMP_BUF->icode = 0;
    /* set identifier and sequence number to 0 */
    memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
    /* put one byte of data */
    memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN,
           count, PING6_DATALEN);
     
    
    uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN + PING6_DATALEN;
    UIP_IP_BUF->len[0] = (u8_t)((uip_len - 40) >> 8);
    UIP_IP_BUF->len[1] = (u8_t)((uip_len - 40) & 0x00FF);
    
    UIP_ICMP_BUF->icmpchksum = 0;
    UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
   
    
    tcpip_ipv6_output();
}
Beispiel #4
0
void
uip_icmp6_echo_request_input(void)
{
  /*
   * we send an echo reply. It is trivial if there was no extension
   * headers in the request otherwise we need to remove the extension
   * headers and change a few fields
   */
  PRINTF("Received Echo Request from");
  PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
  PRINTF("to");
  PRINT6ADDR(&UIP_IP_BUF->destipaddr);
  PRINTF("\n");

  /* IP header */
  UIP_IP_BUF->ttl = uip_netif_physical_if[interface_number].cur_hop_limit;

  if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)){
    uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr);
    uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
  } else {
    uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF->srcipaddr);
    uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
    uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &tmp_ipaddr);
  }

  if(uip_ext_len > 0) {
    /* If there were extension headers*/
    UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
    uip_len -= uip_ext_len;
    UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
    /* move the echo request payload (starting after the icmp header)
     * to the new location in the reply.
     * The shift is equal to the length of the extension headers present
     * Note: UIP_ICMP_BUF still points to the echo request at this stage
     */
#ifdef RB
    memmove(((void *)UIP_ICMP_BUF + (void *)( UIP_ICMPH_LEN - uip_ext_len)),
            (((void *)UIP_ICMP_BUF) +( (void *)UIP_ICMPH_LEN)),
            ((uip_len - UIP_IPH_LEN) - UIP_ICMPH_LEN));
#endif 
	   memmove(((void *) (UIP_ICMP_BUF + (( UIP_ICMPH_LEN - uip_ext_len)))),
               ((void *) (UIP_ICMP_BUF + (UIP_ICMPH_LEN))),
               ((uip_len - UIP_IPH_LEN) - UIP_ICMPH_LEN));

  }
Beispiel #5
0
/*------------------------------------------------------------------*/
void 
uip_nd6_io_ns_input(void)
{
  PRINTF("Received NS from");
  PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
  PRINTF("to");
  PRINT6ADDR(&UIP_IP_BUF->destipaddr);
  PRINTF("with target address");
  PRINT6ADDR((uip_ipaddr_t *)(&UIP_ND6_NS_BUF->tgtipaddr));
  PRINTF("\n");
  UIP_STAT(++uip_stat.nd6.recv);
 
  u8_t flags;
 
#if UIP_CONF_IPV6_CHECKS
  if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) ||
     (uip_is_addr_mcast(&UIP_ND6_NS_BUF->tgtipaddr)) ||
     (UIP_ICMP_BUF->icode != 0))
  {
    goto badpkt;
  }
#endif /* UIP_CONF_IPV6_CHECKS */ 
  
  /* Options reading: we handle only SLLAO for now */
  nd6_opt_llao = NULL;
  nd6_opt_offset = UIP_ND6_NS_LEN;
  while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
#if UIP_CONF_IPV6_CHECKS
    if(UIP_ND6_OPT_HDR_BUF->len == 0) {
      goto badpkt;
    }
#endif /* UIP_CONF_IPV6_CHECKS */ 
    switch(UIP_ND6_OPT_HDR_BUF->type) {
      case UIP_ND6_OPT_SLLAO:
        nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF;
        break;
      default:
        UIP_LOG("ND option not supported in NS");
        break;
    }
    nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
  }

  /* Options processing: only SLLAO */
  if(nd6_opt_llao != NULL) {
#if UIP_CONF_IPV6_CHECKS
    /* There must be NO option in a DAD NS */
    if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
      goto badpkt;
    } else {
#endif /*UIP_CONF_IPV6_CHECKS*/
      neighbor = uip_nd6_nbrcache_lookup(&UIP_IP_BUF->srcipaddr);
      if(neighbor == NULL) {
        /* we need to add the neighbor*/
        uip_nd6_nbrcache_add(&UIP_IP_BUF->srcipaddr,
                             &nd6_opt_llao->addr, 0, STALE);
      } else {
        /* If LL address changed, set neighbor state to stale */
        if(memcmp(&nd6_opt_llao->addr, &neighbor->lladdr, UIP_LLADDR_LEN) != 0) {
          memcpy(&neighbor->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN);
          neighbor->state = STALE;
        } else {
          /* If neighbor state is INCOMPLETE, set to STALE */
          if(neighbor->state == INCOMPLETE) {
            neighbor->state = STALE;
          }
        }
      }
#if UIP_CONF_IPV6_CHECKS
    }   
#endif /*UIP_CONF_IPV6_CHECKS*/
  }

  /* 
   * Rest of NS processing: Depends on the purpose of the NS: NUD or DAD or
   * Address Resolution 
   */
  /** \note we use ifaddr to remember the target address */
  ifaddr = uip_netif_addr_lookup(&UIP_ND6_NS_BUF->tgtipaddr, 128, 0);
  if(ifaddr != NULL) {
    if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){
      /* DAD CASE */
#if UIP_CONF_IPV6_CHECKS 
      /* Dst address must be solicited node mcast address */
      if(!uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr)){
        goto badpkt;
      }
#endif /* UIP_CONF_IPV6_CHECKS */ 
      /*
       * If my address is not tentative, then send a NA to all nodes with
       * TLLAO flags are: override = yes.
       */
        if(ifaddr->state!=TENTATIVE) {  
        /* 
         * we need to send a NA, we set the src, dest, flags. tgt remains the
         * same and the rest is done at "create_na" 
         */
        uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr);
        uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
        flags = UIP_ND6_NA_FLAG_OVERRIDE;
        goto create_na;
      } else {
        /** \todo if I sent a NS before him, I win */
        uip_netif_dad_failed(&UIP_ND6_NS_BUF->tgtipaddr);
        goto discard;
      }
    }
  

#if UIP_CONF_IPV6_CHECKS
    /* Duplicate check */
    if(uip_netif_is_addr_my_unicast(&UIP_IP_BUF->srcipaddr)) {
      /**
       * \NOTE do we do something here? we both are using the same address.
       * If we are doing dad, we could cancel it, though we should receive a
       * NA in response of DAD NS we sent, hence DAD will fail anyway. If we
       * were not doing DAD, it means there is a duplicate in the network!
       */
      goto badpkt;
    }
#endif /*UIP_CONF_IPV6_CHECKS*/

    /* Address resolution case */  
    if(uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr)){
      /*   
       * we need to send a NA, we set the src, dest, flags. The rest is
       * set at the "create_na" label.
       */
      uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr);
      uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr);
      flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE;
      goto create_na;
    } 

    /* 
     * NUD CASE. at this point the packet must be for us! we check this, 
     * and at the same time if target == dest
     */
    if(uip_netif_addr_lookup(&UIP_IP_BUF->destipaddr, 128, 0) == ifaddr){
      /*   
       * we need to send a NA, we set the src, dest, flags. The rest is set
       * at the "create_na" label.
       */
      uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr);
      uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr);
      flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE;
      goto create_na;
    } else {
#if UIP_CONF_IPV6_CHECKS
      goto badpkt;
#endif /* UIP_CONF_IPV6_CHECKS */ 
    }    
  } else {
    goto discard;
  }
  

 create_na:
  /* 
   * Fill the part of the NA which is common to all NAs. If the NS contained
   * extension headers, we must set the target address properly
   */
  uip_ext_len = 0; 
  
  /* IP header */
  UIP_IP_BUF->vtc = 0x60;
  UIP_IP_BUF->tcflow = 0;
  UIP_IP_BUF->flow = 0;
  UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */
  UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN;
  UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
  UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT;

  /* ICMP header */
  UIP_ICMP_BUF->type = ICMP6_NA;
  UIP_ICMP_BUF->icode = 0;

  /* NA static part */
  UIP_ND6_NA_BUF->flagsreserved = flags;
  memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &ifaddr->ipaddr, sizeof(uip_ipaddr_t));

  /* NA option: TLLAO. note that length field is in unit of 8 bytes */
  uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN;
  nd6_opt_llao = (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NA_LEN];
  nd6_opt_llao->type = UIP_ND6_OPT_TLLAO;
  nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3;
  memcpy(&(nd6_opt_llao->addr), &uip_lladdr, UIP_LLADDR_LEN);
  /* padding if needed */
  memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN);

  /*ICMP checksum*/
  UIP_ICMP_BUF->icmpchksum = 0;
  UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); 


  UIP_STAT(++uip_stat.nd6.sent);
  PRINTF("Sending NA to");
  PRINT6ADDR(&UIP_IP_BUF->destipaddr);
  PRINTF("from");
  PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
  PRINTF("with target address");
  PRINT6ADDR(&UIP_ND6_NA_BUF->tgtipaddr);
  PRINTF("\n");
  return;

#if UIP_CONF_IPV6_CHECKS
 badpkt:
  UIP_STAT(++uip_stat.nd6.drop);
  UIP_LOG("NS received is bad"); 
#endif /* UIP_CONF_IPV6_CHECKS */
  
 discard:
  uip_len = 0;
  return;
}
Beispiel #6
0
/*---------------------------------------------------------------------------*/
static u8_t
ping6handler(process_event_t ev, process_data_t data)
{
  if(count == 0){
#if MACDEBUG
    // Setup destination address.
    addr[0] = 0xFE80;
    addr[4] = 0x6466;
    addr[5] = 0x6666;
    addr[6] = 0x6666;
    addr[7] = 0x6666;
    uip_ip6addr(&dest_addr, addr[0], addr[1],addr[2],
                addr[3],addr[4],addr[5],addr[6],addr[7]);

    // Set the command to fool the 'if' below.
    memcpy(command, (void *)"ping6", 5);
    
#else
/* prompt */
    printf("> ");
    /** \note the scanf here is blocking (the all stack is blocked waiting
     *  for user input). This is far from ideal and could be improved
     */
    scanf("%s", command);
    
    if(strcmp(command,"ping6") != 0){
      PRINTF("> invalid command\n");
      return 0;
    }

    if(scanf(" %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
             &addr[0],&addr[1],&addr[2],&addr[3],
             &addr[4],&addr[5],&addr[6],&addr[7]) == 8){

      uip_ip6addr(&dest_addr, addr[0], addr[1],addr[2],
                  addr[3],addr[4],addr[5],addr[6],addr[7]);
    } else {
      PRINTF("> invalid ipv6 address format\n");
      return 0;
    }
#endif

  } 
  
  if((strcmp(command,"ping6") == 0) && (count < PING6_NB)){
   
    UIP_IP_BUF->vtc = 0x60;
    UIP_IP_BUF->tcflow = 1;
    UIP_IP_BUF->flow = 0;
    UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
    UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit;
    uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &dest_addr);
    uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
 
    UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST;
    UIP_ICMP_BUF->icode = 0;
    /* set identifier and sequence number to 0 */
    memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
    /* put one byte of data */
    memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN,
           count, PING6_DATALEN);
     
    
    uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN + PING6_DATALEN;
    UIP_IP_BUF->len[0] = (u8_t)((uip_len - 40) >> 8);
    UIP_IP_BUF->len[1] = (u8_t)((uip_len - 40) & 0x00FF);
    
    UIP_ICMP_BUF->icmpchksum = 0;
    UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
   
    
    PRINTF("Sending Echo Request to");
    PRINT6ADDR(&UIP_IP_BUF->destipaddr);
    PRINTF("from");
    PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
    PRINTF("\n");
    UIP_STAT(++uip_stat.icmp.sent);

    tcpip_ipv6_output();

    count++;
    etimer_set(&ping6_periodic_timer, 3 * CLOCK_SECOND);
    return 1;
  }