⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial_tun.c

📁 tinyos-2.x.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
  fragment_t progress;
  uint8_t serial[LOWPAN_LINK_MTU + 1];
  IEEE154_header_t *radioPacket = (IEEE154_header_t *)(serial + 1);
#define PKTLEN(X) ((X)->length + 2)

  uint8_t *lowpan = (uint8_t *)(radioPacket + 1);

#define LOWPAN_PAYLOAD_LENGTH (LOWPAN_LINK_MTU - MAC_HEADER_SIZE \
                              - MAC_FOOTER_SIZE)

  progress.offset = 0;

  // and IEEE 802.15.4 header
  // write_radio_header(serial, dest, frag_len);

  while ((frag_len = getNextFrag(msg, &progress, lowpan, 
                                 LOWPAN_PAYLOAD_LENGTH)) > 0) {

    //debug("frag len: 0x%x offset: 0x%x plen: 0x%x\n", frag_len, progress.offset * 8, ntohs(ip_header->plen));

    write_radio_header(serial, dest, frag_len);

    // if this is sent too fast, the base station can't keep up.  The effect of this is
    // we send incomplete fragment.  25ms seems to work pretty well.
    //   6-9-08 : SDH : this is a bad fix that does not address the
    //   problem.  
    //   at the very least, the serial ack's seem to be
    //   working, so we should be retrying if the ack is failing
    //   because the hardware cannot keep up.
    //   9-17-09 : SDH : it seems we've tracked this down to packets
    //   arriving too fast to enqueue, especially at higher baud rates
    //   (115200).  reenabled to prevent retries, which are very slow.
#ifdef __TARGET_mips__
    usleep(50000);
#else
    usleep(25000);
#endif
    log_dump_serial_packet(serial, PKTLEN(radioPacket));
    result = write_pan_packet(serial, PKTLEN(radioPacket));
    if (result != 0) 
      result = write_pan_packet(serial, PKTLEN(radioPacket));

    debug("send_fragments: result: 0x%x len: 0x%x\n", result, frag_len);
    log_dump_serial_packet(serial, PKTLEN(radioPacket));
    stats.tx_frags++;
    stats.tx_bytes += PKTLEN(radioPacket);
  }
  keepalive_needed = 0;
  stats.tx_pkts++;
}

void icmp_unreachable(struct split_ip_msg *msg) {
  
}

/*
 * this function takes a complete IP packet, and sends it out to a
 * destination in the PAN.  It will insert source routing headers and
 * recompute L4 checksums as necessary.
 *
 */ 
uint8_t ip_to_pan(struct split_ip_msg *msg) {
  int nxt_hdr = msg->hdr.nxt_hdr;
  uint16_t dest;

  debug("ip_to_pan\n");
  print_ip_packet(msg);
  // if this packet has a source route (rinstall header, or prexisting
  // source header, we don't want to mess with it
  switch (routing_is_onehop(msg)) {
  case ROUTE_MHOP:
    debug("Multihop packet\n");
    if (routing_insert_route(msg)) goto fail;
    break;
    
  case ROUTE_WORMHOLE:
    debug("Wormhole packet\n");

    // fall through
  case ROUTE_NO_ROUTE:
    tun_write(tun_fd, msg);
    // info("destination unreachable: 0x%x: dropping\n", ntohs(msg->hdr.ip6_dst.s6_addr16[7]));
    return 0;
  }

  dest = routing_get_nexthop(msg);
  debug("next hop: 0x%x\n", dest);
  flow_insert_label(msg);
  print_ip_packet(msg);

  fifo_report(msg, dest, nxt_hdr);

  send_fragments(msg, dest);
  return 0;
 fail:
  error("ip_to_pan: no route to host\n");
  return 1;
}

void upd_source_route(struct ip6_route *sh, ieee154_saddr_t addr) {
  if (sh->segs_remain > 0) {
    sh->hops[ROUTE_NENTRIES(sh) - sh->segs_remain] = leton16(addr);
    sh->segs_remain--;
  }
}

int process_dest_tlv(struct ip6_hdr *iph, struct ip6_ext *hdr, int len) {
  struct tlv_hdr *tlv = (struct tlv_hdr *)(hdr + 1);
  node_id_t reporter = ntohs(iph->ip6_src.s6_addr16[7]);

  if (len != hdr-> len) return 1;
  len -= sizeof(struct ip6_ext);

  while (tlv != NULL && len > 0) {
    if (tlv->len == 0) return 1;

    switch(tlv->type) {
    case TLV_TYPE_TOPOLOGY:
      routing_add_report(reporter, tlv);
      break;
    }
    
    len -= tlv->len;
    tlv = (struct tlv_hdr *)(((uint8_t *)tlv) + tlv->len);
  }
  return 0;
}

int process_hop_tlv(struct split_ip_msg *msg, struct ip6_ext *hdr, int len) {
  struct tlv_hdr *tlv = (struct tlv_hdr *)(hdr + 1);
  uint16_t *fl;

  if (len != hdr-> len) return 1;
  len -= sizeof(struct ip6_ext);

  while (tlv != NULL && len > 0) {
    if (tlv->len == 0) return 1;

    switch(tlv->type) {
    case TLV_TYPE_FLOW:
      fl = (uint16_t *)(tlv + 1);
      msg->flow_id = *fl;
      debug("process_hop_tlv: flow 0x%x\n", msg->flow_id);
      break;
    }

    len -= tlv->len;
    tlv = (struct tlv_hdr *)(((uint8_t *)tlv) + tlv->len);
  }
  return 0;
}

int process_extensions(struct split_ip_msg *msg) {
  struct generic_header *prev = NULL, *cur = msg->headers;
  struct ip6_route *route;
  uint8_t nxt_hdr = msg->hdr.nxt_hdr;
  int lendelta = 0;

  while (cur != NULL && EXTENSION_HEADER(nxt_hdr)) {
    debug("dropping header type 0x%x, len %i\n", nxt_hdr, cur->len);
    msg->headers = cur->next;
    msg->hdr.nxt_hdr = cur->hdr.ext->nxt_hdr;
    lendelta += cur->len;

    switch (nxt_hdr) {
    case IPV6_DEST:
      if (process_dest_tlv(&msg->hdr, cur->hdr.ext, cur->len)) 
        return 1;
      break;
    case IPV6_HOP:
      if (process_hop_tlv(msg, cur->hdr.ext, cur->len)) {
        warn("dropping packet due to hop tlv\n");
        return 1;
      }
      break;
    case IPV6_ROUTING:

      route = cur->hdr.sh;

      if ((route->type & ~IP6ROUTE_FLAG_MASK) == IP6ROUTE_TYPE_INVAL || route->segs_remain == 0) {
/*         if (route->type == IP6ROUTE_TYPE_INVAL) { */
/*           if (route->hops[0] == __my_address.s6_addr16[7]) { */
/*             warn("dropping packet since it has an invalid source route and I sent it\n"); */
/*             return 1; */
/*           } */
/*         } */
      } else {
        uint16_t target_hop = ntohs(route->hops[ROUTE_NENTRIES(route) - route->segs_remain]);
        // if this is actually a valid source route, maybe update it
        // (even though we're going to delete it shortly)
        if (target_hop != __my_address.s6_addr16[7]) {
          if (ROUTE_NENTRIES(route) >= 2) {
            route->hops[0] = htons(msg->prev_hop);
            route->hops[1] = htons(target_hop);
          }
          route->type = (route->type & IP6ROUTE_FLAG_MASK) | IP6ROUTE_TYPE_INVAL;
        } else {
          route->hops[ROUTE_NENTRIES(route) - route->segs_remain] = htons(msg->prev_hop);
          route->segs_remain--;
        }
      }
      
      if ((route->type & ~IP6ROUTE_FLAG_MASK) == IP6ROUTE_TYPE_INVAL && ROUTE_NENTRIES(route) >= 2) {
        node_id_t n1 = ntohs(route->hops[0]);
        node_id_t n2 = ntohs(route->hops[1]);
        warn ("broken link was %i -> %i\n", n1, n2);
        nw_remove_link(n1, n2);
        if (route->type & IP6ROUTE_FLAG_CONTROLLER) {
          warn("dropping packet since it has an invalid source route and I sent it\n");
          return 1;
        } else {
          warn("received broken source route based on installed route-- uninstalling\n");
/*           uninstall_route(ntohs(msg->hdr.ip6_src.s6_addr16[7]), */
/*                           ntohs(msg->hdr.ip6_dst.s6_addr16[7])); */
        }
      }
    }

    nxt_hdr = cur->hdr.ext->nxt_hdr;
    prev = cur;
    cur = cur->next;
    free(prev);
  }

  msg->hdr.plen = htons(ntohs(msg->hdr.plen) - lendelta);
  return 0;
}

#if 0
int remove_sourceroute(struct split_ip_msg *msg) {
  struct source_header *s;
  struct rinstall_header *rih;
  struct generic_header *g_hdr;
  uint8_t removeSource = 1;
  if (msg->hdr.nxt_hdr == NXTHDR_SOURCE) {
    sh = msg->headers->hdr.sh;
    upd_source_route(sh, msg->metadata.sender);

    // Our thinking here is that if something is source_routed
    //  from inside the network and it is not destined to us
    //  then its either a rinstall being forwarded, or a path
    //  that's been set up, so we shouldn't strip it away
    if (cmpPfx(msg->hdr.ip6_dst.s6_addr, __my_address.s6_addr) &&
        msg->hdr.ip6_dst.s6_addr16[7] != __my_address.s6_addr16[7]) {
/*         ((msg->hdr.ip6_dst.s6_addr[14] != __my_address[14] || */
/*           msg->hdr.ip6_dst.s6_addr[15] != __my_address[15]))) { */
      info("Packet with source header not destined for me\n");
  
      if ((sh->dispatch & IP_EXT_SOURCE_INVAL) != IP_EXT_SOURCE_INVAL) {
        debug("Removing invalid source header\n");
        removeSource = 0;
      }
      
      if ((sh->dispatch & IP_EXT_SOURCE_CONTROLLER) == IP_EXT_SOURCE_CONTROLLER) {
        debug("WE sent this packet! dropping...\n");
        return 1;
      }
    

      // If this is an rinstall header moving through, we need to
      //  updated the current position of the path, similar to
      //  what we do for source headers.
      if (sh->nxt_hdr == NXTHDR_INSTALL) {
        rih = msg->headers->next->hdr.rih;
        rih->current++;
        info("Incrementing current of rih to 0x%x\n", rih->current);
      }
    }
    if (removeSource) {
      msg->hdr.nxt_hdr = sh->nxt_hdr;
      msg->hdr.plen = htons(ntohs(msg->hdr.plen) - sh->len);
      g_hdr = msg->headers;
      msg->headers = msg->headers->next;
      free(g_hdr);
    }
  }
  return 0;
}
#endif

void handle_serial_packet(struct split_ip_msg *msg) {
  path_t* tPath;
  path_t* i;
#ifdef CENTRALIZED_ROUTING
  uint8_t flags = 0x00;
#endif
  if (ntohs(msg->hdr.plen) > INET_MTU - sizeof(struct ip6_hdr)) {
    warn("handle_ip_packet: too long: 0x%x\n", ntohs(msg->hdr.plen));
    return;
  }

  // print_ip_packet(msg);
  print_ip_packet(msg);
  if (process_extensions(msg))
    return;

  if (cmpPfx(msg->hdr.ip6_dst.s6_addr, __my_address.s6_addr) && 
      msg->hdr.ip6_dst.s6_addr16[7] != __my_address.s6_addr16[7]) {
      debug("Received packet destined to 0x%x\n", msg->hdr.ip6_dst.s6_addr[15]); 
      stats.fw_pkts++;
    
     // If this packet is not source routed, check to see if we're on the best path before
     //  issuing a route install
       tPath = nw_get_route(ntohs(msg->hdr.ip6_src.s6_addr16[7]), ntohs(msg->hdr.ip6_dst.s6_addr16[7]));
        for (i = tPath; i != NULL; i = i->next) {
          if (i->node == ntohs(__my_address.s6_addr16[7])) {
            debug("Not installing route for packet from 0x%x to 0x%x (on best path)\n", 
                  ntohs(msg->hdr.ip6_src.s6_addr16[7]), ntohs(msg->hdr.ip6_dst.s6_addr16[7]));
            nw_free_path(tPath);
            ip_to_pan(msg);
            return;
          }
        }
        nw_free_path(tPath);
        // }
      
      // We send the route installation packet before forwarding the actual
      //  packet, with the thinking being that the route can be set up, in
      //  case acks are issued by the destination on the packet
      //
      // We have to first select the flags that we want:
     
      //  At this point, if it's not source routed, then this packet
      //  shouldn't be coming through us so we install a route
        // if (msg->hdr.nxt_hdr != NXTHDR_SOURCE) {
        debug("installing route for packet from 0x%x to 0x%x\n", 
              ntohs(msg->hdr.ip6_src.s6_addr16[7]), ntohs(msg->hdr.ip6_dst.s6_addr16[7]));
#ifdef CENTRALIZED_ROUTING
#ifndef FULL_PATH_INSTALL
        flags = HYDRO_METHOD_SOURCE | HYDRO_INSTALL_REVERSE;
#else
        flags = HYDRO_METHOD_HOP | HYDRO_INSTALL_REVERSE;
#endif
        //        install_route(msg, flags);
#endif
        // } else {
        // info("Packet had a source header so no route install\n"); 
        // }
      ip_to_pan(msg);
      // do routing
  } else {
    // give it to linux
    // need to remove route info here.
    stats.rx_pkts++;
    tun_write(tun_fd, msg);
    debug("tun_write: wrote 0x%x bytes\n", sizeof(struct ip6_hdr) + ntohs(msg->hdr.plen));
  }
}

void add_header_list(struct split_ip_msg *msg) {
  uint8_t nxt_hdr;
  struct generic_header *g_hdr, **g_list;
  struct ip6_ext *ext = (struct ip6_ext *)msg->next;
  uint16_t hdr_len = 0;
  // debug("add_header_list for message destined to 0x%x\n", ntohs(msg->hdr.ip6_dst.s6_addr16[7]));
  nxt_hdr = msg->hdr.nxt_hdr;
  msg->headers = NULL;
  g_list = &(msg->headers);
  while (EXTENSION_HEADER(nxt_hdr)) {
    g_hdr = (struct generic_header *)malloc(sizeof(struct generic_header));
    g_hdr->payload_malloced = 0;
    g_hdr->hdr.ext = ext;
    g_hdr->next = NULL;
    *g_list = g_hdr;
    g_list = &g_hdr->next;

    g_hdr->len = ext->len;
    
    nxt_hdr = ext->nxt_hdr;
    ext = (struct ip6_ext *)(((uint8_t *)ext) + ext->len);
    
    hdr_len += g_hdr->len;
  }
  if (COMPRESSIBLE_TRANSPORT(nxt_hdr)) {
      int transport_len;
      switch (nxt_hdr) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -