Exemplo n.º 1
0
static void uip_tcpsendcomplete(struct uip_driver_s *dev)
{
  struct uip_tcpip_hdr *pbuf = BUF;

  pbuf->ttl         = UIP_TTL;

#ifdef CONFIG_NET_IPv6

  /* For IPv6, the IP length field does not include the IPv6 IP header
   * length.
   */

  pbuf->len[0]      = ((dev->d_len - UIP_IPH_LEN) >> 8);
  pbuf->len[1]      = ((dev->d_len - UIP_IPH_LEN) & 0xff);

#else /* CONFIG_NET_IPv6 */

  pbuf->len[0]      = (dev->d_len >> 8);
  pbuf->len[1]      = (dev->d_len & 0xff);

#endif /* CONFIG_NET_IPv6 */

  pbuf->urgp[0]     = pbuf->urgp[1] = 0;

  /* Calculate TCP checksum. */

  pbuf->tcpchksum   = 0;
  pbuf->tcpchksum   = ~(uip_tcpchksum(dev));

#ifdef CONFIG_NET_IPv6

  pbuf->vtc         = 0x60;
  pbuf->tcf         = 0x00;
  pbuf->flow        = 0x00;

#else /* CONFIG_NET_IPv6 */

  pbuf->vhl         = 0x45;
  pbuf->tos         = 0;
  pbuf->ipoffset[0] = 0;
  pbuf->ipoffset[1] = 0;
  ++g_ipid;
  pbuf->ipid[0]     = g_ipid >> 8;
  pbuf->ipid[1]     = g_ipid & 0xff;

  /* Calculate IP checksum. */

  pbuf->ipchksum    = 0;
  pbuf->ipchksum    = ~(uip_ipchksum(dev));

#endif /* CONFIG_NET_IPv6 */

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

#ifdef CONFIG_NET_STATISTICS
  uip_stat.tcp.sent++;
  uip_stat.ip.sent++;
#endif
}
static void
uip_split_output_send(chanend mac_tx)
{
	/* Recalculate the TCP checksum. */
	BUF->tcpchksum = 0;
	BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
	/* Recalculate the IP checksum. */
	BUF->ipchksum = 0;
	BUF->ipchksum = ~(uip_ipchksum());
#endif
	uip_len += UIP_LLH_LEN;

	/* Transmit the first packet. */
	xcoredev_send(mac_tx);
}
Exemplo n.º 3
0
/*-----------------------------------------------------------------------------*/
void
uip_split_output(void)
{
#if UIP_TCP
  u16_t tcplen, len1, len2;

  /* We only try to split maximum sized TCP segments. */
  if(BUF->proto == UIP_PROTO_TCP  && uip_len == UIP_BUFSIZE) {

    tcplen = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
    /* Split the segment in two. If the original packet length was
       odd, we make the second packet one byte larger. */
    len1 = len2 = tcplen / 2;
    if(len1 + len2 < tcplen) {
      ++len2;
    }

    /* Create the first packet. This is done by altering the length
       field of the IP header and updating the checksums. */
    uip_len = len1 + UIP_TCPIP_HLEN + UIP_LLH_LEN;
#if UIP_CONF_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
    BUF->len[0] = (uip_len - UIP_LLH_LEN) >> 8;
    BUF->len[1] = (uip_len - UIP_LLH_LEN) & 0xff;
#endif /* UIP_CONF_IPV6 */

    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */

    /* Transmit the first packet. */
#if UIP_CONF_IPV6
    tcpip_ipv6_output();
#else
	RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
#endif /* UIP_CONF_IPV6 */

    /* Now, create the second packet. To do this, it is not enough to
       just alter the length field, but we must also update the TCP
       sequence number and point the uip_appdata to a new place in
       memory. This place is determined by the length of the first
       packet (len1). */
    uip_len = len2 + UIP_TCPIP_HLEN + UIP_LLH_LEN;
#if UIP_CONF_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
    BUF->len[0] = (uip_len  - UIP_LLH_LEN) >> 8;
    BUF->len[1] = (uip_len - UIP_LLH_LEN) & 0xff;
#endif /* UIP_CONF_IPV6 */

    memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);

    uip_add32(BUF->seqno, len1);
    BUF->seqno[0] = uip_acc32[0];
    BUF->seqno[1] = uip_acc32[1];
    BUF->seqno[2] = uip_acc32[2];
    BUF->seqno[3] = uip_acc32[3];

    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */

    /* Transmit the second packet. */
#if UIP_CONF_IPV6
    tcpip_ipv6_output();
#else
	RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
#endif /* UIP_CONF_IPV6 */
    return;
  }
Exemplo n.º 4
0
/*-----------------------------------------------------------------------------*/
void
uip_split_output(chanend mac_tx)
{
  u16_t tcplen, len1, len2;

  /* We only try to split maximum sized TCP segments. */
  if(BUF->proto == UIP_PROTO_TCP &&
     uip_len + UIP_TCPIP_HLEN > UIP_BUFSIZE/2) {
//    printstr("split");
    tcplen = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
    /* Split the segment in two. If the original packet length was
       odd, we make the second packet one byte larger. */
    len1 = len2 = tcplen / 2;
    if(len1 + len2 < tcplen) {
      ++len2;
    }

    /* Create the first packet. This is done by altering the length
       field of the IP header and updating the checksums. */
    uip_len = len1 + UIP_TCPIP_HLEN;
#if UIP_CONF_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
    BUF->len[0] = uip_len >> 8;
    BUF->len[1] = uip_len & 0xff;
#endif /* UIP_CONF_IPV6 */
    
    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */
    
    uip_len += UIP_LLH_LEN;
    /* Transmit the first packet. */
    /*    uip_fw_output();*/
    /*    tcpip_output(); */
    xcoredev_send(mac_tx);

    /* Now, create the second packet. To do this, it is not enough to
       just alter the length field, but we must also update the TCP
       sequence number and point the uip_appdata to a new place in
       memory. This place is detemined by the length of the first
       packet (len1). */    
    uip_len = len2 + UIP_TCPIP_HLEN;
#if UIP_CONF_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
    BUF->len[0] = uip_len >> 8;
    BUF->len[1] = uip_len & 0xff;
#endif /* UIP_CONF_IPV6 */
    
    /*    uip_appdata += len1;*/
    memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);

    uip_add32(BUF->seqno, len1);
    BUF->seqno[0] = uip_acc32[0];
    BUF->seqno[1] = uip_acc32[1];
    BUF->seqno[2] = uip_acc32[2];
    BUF->seqno[3] = uip_acc32[3];
    
    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */

    /* Transmit the second packet. */
    /*    uip_fw_output();*/
    /*tcpip_output();*/
    uip_len += UIP_LLH_LEN;
    xcoredev_send(mac_tx);
  } else {
Exemplo n.º 5
0
/*-----------------------------------------------------------------------------*/
void
uip_split_output(void)
{
#if UIP_TCP
  uint16_t tcplen, len1, len2;

  /* We only split TCP segments that are larger than or equal to
     UIP_SPLIT_SIZE, which is configurable through
     UIP_SPLIT_CONF_SIZE. */
  if(BUF->proto == UIP_PROTO_TCP &&
     uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) {

    tcplen = uip_len - UIP_TCPIP_HLEN;
    /* Split the segment in two. If the original packet length was
       odd, we make the second packet one byte larger. */
    len1 = len2 = tcplen / 2;
    if(len1 + len2 < tcplen) {
      ++len2;
    }

    /* Create the first packet. This is done by altering the length
       field of the IP header and updating the checksums. */
    uip_len = len1 + UIP_TCPIP_HLEN;
#if NETSTACK_CONF_WITH_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* NETSTACK_CONF_WITH_IPV6 */
    BUF->len[0] = uip_len >> 8;
    BUF->len[1] = uip_len & 0xff;
#endif /* NETSTACK_CONF_WITH_IPV6 */
    
    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !NETSTACK_CONF_WITH_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* NETSTACK_CONF_WITH_IPV6 */
    
    /* Transmit the first packet. */
    /*    uip_fw_output();*/
#if NETSTACK_CONF_WITH_IPV6
    tcpip_ipv6_output();
#else
    tcpip_output();
#endif /* NETSTACK_CONF_WITH_IPV6 */
   
    /* Now, create the second packet. To do this, it is not enough to
       just alter the length field, but we must also update the TCP
       sequence number and point the uip_appdata to a new place in
       memory. This place is detemined by the length of the first
       packet (len1). */
    uip_len = len2 + UIP_TCPIP_HLEN;
#if NETSTACK_CONF_WITH_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* NETSTACK_CONF_WITH_IPV6 */
    BUF->len[0] = uip_len >> 8;
    BUF->len[1] = uip_len & 0xff;
#endif /* NETSTACK_CONF_WITH_IPV6 */
    
    /*    uip_appdata += len1;*/
    memcpy(uip_appdata, (uint8_t *)uip_appdata + len1, len2);

    uip_add32(BUF->seqno, len1);
    BUF->seqno[0] = uip_acc32[0];
    BUF->seqno[1] = uip_acc32[1];
    BUF->seqno[2] = uip_acc32[2];
    BUF->seqno[3] = uip_acc32[3];
    
    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !NETSTACK_CONF_WITH_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* NETSTACK_CONF_WITH_IPV6 */

    /* Transmit the second packet. */
    /*    uip_fw_output();*/
#if NETSTACK_CONF_WITH_IPV6
    tcpip_ipv6_output();
#else
    tcpip_output();
#endif /* NETSTACK_CONF_WITH_IPV6 */
    return;
  }
Exemplo n.º 6
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;
}