Exemplo n.º 1
0
/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
 *  before calling ip6_output_if.
 *
 * @param p the packet to send (p->payload points to the data, e.g. next
            protocol header; if dest == IP_HDRINCL, p already includes an
            IPv6 header and p->payload points to that IPv6 header)
 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
 *         IP address of the netif is selected and used as source address.
 *         if src == NULL, IP6_ADDR_ANY is used as source)
 * @param dest the destination IPv6 address to send the packet to
 * @param hl the Hop Limit value to be set in the IPv6 header
 * @param tc the Traffic Class value to be set in the IPv6 header
 * @param nexth the Next Header to be set in the IPv6 header
 * @param addr_hint address hint pointer set to netif->addr_hint before
 *        calling ip_output_if()
 *
 * @return ERR_RTE if no route is found
 *         see ip_output_if() for more return values
 */
err_t
ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest,
                  u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint)
{
    struct netif *netif;
    err_t err;

    /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
       gets altered as the packet is passed down the stack */
    LWIP_ASSERT("p->ref == 1", p->ref == 1);

    if ((netif = ip6_route(src, dest)) == NULL) {
        LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
                                IP6_ADDR_BLOCK1(dest),
                                IP6_ADDR_BLOCK2(dest),
                                IP6_ADDR_BLOCK3(dest),
                                IP6_ADDR_BLOCK4(dest),
                                IP6_ADDR_BLOCK5(dest),
                                IP6_ADDR_BLOCK6(dest),
                                IP6_ADDR_BLOCK7(dest),
                                IP6_ADDR_BLOCK8(dest)));
        IP6_STATS_INC(ip6.rterr);
        return ERR_RTE;
    }

    NETIF_SET_HWADDRHINT(netif, addr_hint);
    err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
    NETIF_SET_HWADDRHINT(netif, NULL);

    return err;
}
Exemplo n.º 2
0
Arquivo: ip6.c Projeto: ORCOS/ORCOS
err_t ip6_output(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, u8_t ttl, u8_t proto) {
    struct netif *netif;
    if ((netif = ip6_route(dest)) == NULL) {
        LWIP_DEBUGF(IP_DEBUG, ("ip6_output: No route to dest\n"));IP_STATS_INC(ip.rterr);
        return ERR_RTE;
    }

    return ip6_output_if(p, src, dest, ttl, proto, netif);
}
Exemplo n.º 3
0
Arquivo: ip6.c Projeto: Akagi201/lwip
/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
 *  before calling ip6_output_if.
 *
 * @param p the packet to send (p->payload points to the data, e.g. next
            protocol header; if dest == IP_HDRINCL, p already includes an
            IPv6 header and p->payload points to that IPv6 header)
 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
 *         IP address of the netif is selected and used as source address.
 *         if src == NULL, IP6_ADDR_ANY is used as source)
 * @param dest the destination IPv6 address to send the packet to
 * @param hl the Hop Limit value to be set in the IPv6 header
 * @param tc the Traffic Class value to be set in the IPv6 header
 * @param nexth the Next Header to be set in the IPv6 header
 * @param addr_hint address hint pointer set to netif->addr_hint before
 *        calling ip_output_if()
 *
 * @return ERR_RTE if no route is found
 *         see ip_output_if() for more return values
 */
err_t
ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest,
          u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint)
{
  struct netif *netif;
  struct ip6_hdr *ip6hdr;
  ip6_addr_t src_addr, dest_addr;
  err_t err;

  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
     gets altered as the packet is passed down the stack */
  LWIP_ASSERT("p->ref == 1", p->ref == 1);

  if (dest != IP_HDRINCL) {
    netif = ip6_route(src, dest);
  } else {
    /* IP header included in p, read addresses. */
    ip6hdr = (struct ip6_hdr *)p->payload;
    ip6_addr_copy(src_addr, ip6hdr->src);
    ip6_addr_copy(dest_addr, ip6hdr->dest);
    netif = ip6_route(&src_addr, &dest_addr);
  }

  if (netif == NULL) {
    LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
        IP6_ADDR_BLOCK1(dest),
        IP6_ADDR_BLOCK2(dest),
        IP6_ADDR_BLOCK3(dest),
        IP6_ADDR_BLOCK4(dest),
        IP6_ADDR_BLOCK5(dest),
        IP6_ADDR_BLOCK6(dest),
        IP6_ADDR_BLOCK7(dest),
        IP6_ADDR_BLOCK8(dest)));
    IP6_STATS_INC(ip6.rterr);
    return ERR_RTE;
  }

  NETIF_SET_HWADDRHINT(netif, addr_hint);
  err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
  NETIF_SET_HWADDRHINT(netif, NULL);

  return err;
}
/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
 *  before calling ip6_output_if.
 *
 * @param p the packet to send (p->payload points to the data, e.g. next
            protocol header; if dest == IP_HDRINCL, p already includes an
            IPv6 header and p->payload points to that IPv6 header)
 * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an
 *         IP address of the netif is selected and used as source address.
 *         if src == NULL, IP6_ADDR_ANY is used as source)
 * @param dest the destination IPv6 address to send the packet to
 * @param hl the Hop Limit value to be set in the IPv6 header
 * @param tc the Traffic Class value to be set in the IPv6 header
 * @param nexth the Next Header to be set in the IPv6 header
 * @param addr_hint address hint pointer set to netif->addr_hint before
 *        calling ip_output_if()
 *
 * @return ERR_RTE if no route is found
 *         see ip_output_if() for more return values
 */
err_t
ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
          u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint)
{
  struct netif *netif;
  struct ip6_hdr *ip6hdr;
  ip6_addr_t src_addr, dest_addr;
  err_t err;

  LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);

  if (dest != IP_HDRINCL) {
    netif = ip6_route(src, dest);
  } else {
    /* IP header included in p, read addresses. */
    ip6hdr = (struct ip6_hdr *)p->payload;
    ip6_addr_copy(src_addr, ip6hdr->src);
    ip6_addr_copy(dest_addr, ip6hdr->dest);
    netif = ip6_route(&src_addr, &dest_addr);
  }

  if (netif == NULL) {
    LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
        IP6_ADDR_BLOCK1(dest),
        IP6_ADDR_BLOCK2(dest),
        IP6_ADDR_BLOCK3(dest),
        IP6_ADDR_BLOCK4(dest),
        IP6_ADDR_BLOCK5(dest),
        IP6_ADDR_BLOCK6(dest),
        IP6_ADDR_BLOCK7(dest),
        IP6_ADDR_BLOCK8(dest)));
    IP6_STATS_INC(ip6.rterr);
    return ERR_RTE;
  }

  NETIF_SET_HWADDRHINT(netif, addr_hint);
  err = ip6_output_if(p, src, dest, hl, tc, nexth, netif);
  NETIF_SET_HWADDRHINT(netif, NULL);

  return err;
}
Exemplo n.º 5
0
Arquivo: ip6.c Projeto: ORCOS/ORCOS
static void ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr) {
    struct netif *netif;

    PERF_START;

    if ((netif = ip6_route((struct ip6_addr *) &(iphdr->dest))) == NULL) {

        LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));
#if IP_DEBUG
        ip6_addr_debug_print(IP_DEBUG, ((struct ip6_addr *)&(iphdr->dest)));
#endif /* IP_DEBUG */
        LWIP_DEBUGF(IP_DEBUG, ("\n"));
        pbuf_free(p);
        return;
    }
    /* Decrement TTL and send ICMP if ttl == 0. */
    if (--iphdr->hoplim == 0) {
#if LWIP_ICMP
        /* Don't send ICMP messages in response to ICMP messages */
        if (iphdr->nexthdr != IP6_PROTO_ICMP) {
            icmp6_time_exceeded(p, ICMP_TE_TTL);
        }
#endif /* LWIP_ICMP */
        pbuf_free(p);
        return;
    }

    /* Incremental update of the IP checksum. */
    /*  if (iphdr->chksum >= htons(0xffff - 0x100)) {
     iphdr->chksum += htons(0x100) + 1;
     } else {
     iphdr->chksum += htons(0x100);
     }*/

    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));
#if IP_DEBUG
    ip6_addr_debug_print(IP_DEBUG, ((struct ip6_addr *)&(iphdr->dest)));
#endif /* IP_DEBUG */
    LWIP_DEBUGF(IP_DEBUG, ("\n"));

    IP_STATS_INC(ip.fw); IP_STATS_INC(ip.xmit);

    PERF_STOP("ip_forward");

    netif->ip6_output(netif, p, (struct ip6_addr *) &(iphdr->dest));
}
Exemplo n.º 6
0
static INT  __inetPing6FindSrc (struct netif    *netif, 
                                struct ip6_addr *pip6addrDest,
                                struct ip6_addr *pip6addrSrc)
{
    static struct ip6_addr  ip6addrAny = {{0, 0, 0, 0}};
           struct ip6_addr *pip6addr;

    if (netif == LW_NULL) {
        netif =  ip6_route(&ip6addrAny, pip6addrDest);
        if (netif == LW_NULL) {
            return  (-1);
        }
    }
    
    pip6addr = ip6_select_source_address(netif, pip6addrDest);
    if (pip6addr == NULL) {
        return  (-2);
    }
    
    *pip6addrSrc = *pip6addr;
    
    return  (ERROR_NONE);
}
/**
 * Forwards an IPv6 packet. It finds an appropriate route for the
 * packet, decrements the HL value of the packet, and outputs
 * the packet on the appropriate interface.
 *
 * @param p the packet to forward (p->payload points to IP header)
 * @param iphdr the IPv6 header of the input packet
 * @param inp the netif on which this packet was received
 */
static void
ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
{
  struct netif *netif;

  /* do not forward link-local addresses */
  if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
    LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
    IP6_STATS_INC(ip6.rterr);
    IP6_STATS_INC(ip6.drop);
    return;
  }

  /* Find network interface where to forward this IP packet to. */
  netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr());
  if (netif == NULL) {
    LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
        IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
        IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
        IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
        IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
        IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
        IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
        IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
        IP6_ADDR_BLOCK8(ip6_current_dest_addr())));
#if LWIP_ICMP6
    /* Don't send ICMP messages in response to ICMP messages */
    if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
      icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE);
    }
#endif /* LWIP_ICMP6 */
    IP6_STATS_INC(ip6.rterr);
    IP6_STATS_INC(ip6.drop);
    return;
  }
  /* Do not forward packets onto the same network interface on which
   * they arrived. */
  if (netif == inp) {
    LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n"));
    IP6_STATS_INC(ip6.rterr);
    IP6_STATS_INC(ip6.drop);
    return;
  }

  /* decrement HL */
  IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1);
  /* send ICMP6 if HL == 0 */
  if (IP6H_HOPLIM(iphdr) == 0) {
#if LWIP_ICMP6
    /* Don't send ICMP messages in response to ICMP messages */
    if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
      icmp6_time_exceeded(p, ICMP6_TE_HL);
    }
#endif /* LWIP_ICMP6 */
    IP6_STATS_INC(ip6.drop);
    return;
  }

  if (netif->mtu && (p->tot_len > netif->mtu)) {
#if LWIP_ICMP6
    /* Don't send ICMP messages in response to ICMP messages */
    if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) {
      icmp6_packet_too_big(p, netif->mtu);
    }
#endif /* LWIP_ICMP6 */
    IP6_STATS_INC(ip6.drop);
    return;
  }

  LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: forwarding packet to %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n",
      IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
      IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
      IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
      IP6_ADDR_BLOCK4(ip6_current_dest_addr()),
      IP6_ADDR_BLOCK5(ip6_current_dest_addr()),
      IP6_ADDR_BLOCK6(ip6_current_dest_addr()),
      IP6_ADDR_BLOCK7(ip6_current_dest_addr()),
      IP6_ADDR_BLOCK8(ip6_current_dest_addr())));

  /* transmit pbuf on chosen interface */
  netif->output_ip6(netif, p, ip6_current_dest_addr());
  IP6_STATS_INC(ip6.fw);
  IP6_STATS_INC(ip6.xmit);
  return;
}
Exemplo n.º 8
0
/**
 * Send an ICMPv6 packet in response to an incoming packet.
 *
 * @param p the input packet for which the response should be sent,
 *          p->payload pointing to the IPv6 header
 * @param code Code of the ICMPv6 header
 * @param data Additional 32-bit parameter in the ICMPv6 header
 * @param type Type of the ICMPv6 header
 */
static void
icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
{
  struct pbuf *q;
  struct icmp6_hdr *icmp6hdr;
  ip6_addr_t *reply_src, *reply_dest;
  ip6_addr_t reply_src_local, reply_dest_local;
  struct ip6_hdr *ip6hdr;
  struct interface *netif;

  /* ICMPv6 header + IPv6 header + data */
  q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE,
                 PBUF_RAM);
  if (q == NULL) {
    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n"));
    ICMP6_STATS_INC(icmp6.memerr);
    return;
  }
  LWIP_ASSERT("check that first pbuf can hold icmp 6message",
             (q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));

  icmp6hdr = (struct icmp6_hdr *)q->payload;
  icmp6hdr->type = type;
  icmp6hdr->code = code;
  icmp6hdr->data = data;

  /* copy fields from original packet */
  SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload,
          IP6_HLEN + LWIP_ICMP6_DATASIZE);

  /* Get the destination address and netif for this ICMP message. */
  if ((ip_current_netif() == NULL) ||
      ((code == ICMP6_TE_FRAG) && (type == ICMP6_TYPE_TE))) {
    /* Special case, as ip6_current_xxx is either NULL, or points
     * to a different packet than the one that expired.
     * We must use the addresses that are stored in the expired packet. */
    ip6hdr = (struct ip6_hdr *)p->payload;
    /* copy from packed address to aligned address */
    ip6_addr_copy(reply_dest_local, ip6hdr->src);
    ip6_addr_copy(reply_src_local, ip6hdr->dest);
    reply_dest = &reply_dest_local;
    reply_src = &reply_src_local;
    netif = ip6_route(reply_src, reply_dest);
    if (netif == NULL) {
      /* drop */
      pbuf_free(q);
      ICMP6_STATS_INC(icmp6.rterr);
      return;
    }
  }
  else {
    netif = ip_current_netif();
    reply_dest = ip6_current_src_addr();

    /* Select an address to use as source. */
    reply_src = ip6_select_source_address(netif, reply_dest);
    if (reply_src == NULL) {
      /* drop */
      pbuf_free(q);
      ICMP6_STATS_INC(icmp6.rterr);
      return;
    }
  }

  /* calculate checksum */
  icmp6hdr->chksum = 0;
  icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len,
    reply_src, reply_dest);

  ICMP6_STATS_INC(icmp6.xmit);
  ip6_output_if(q, reply_src, reply_dest, LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif);
  pbuf_free(q);
}