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

📄 serial_tun.c

📁 tinyos-2.x.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * "Copyright (c) 2008 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */
/*
 * Copyright (c) 2007 Matus Harvan
 * All rights reserved
 *
 * Copyright (c) 2008 Stephen Dawson-Haggerty
 * Extensivly modified to use lib6lowpan / b6lowpan.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * The name of the author may not be used to endorse or promote
 *       products derived from this software without specific prior
 *       written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include <termios.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <lib6lowpan/TrackFlows.h>
#include <lib6lowpan/6lowpan.h>
#include <lib6lowpan/ip.h>
#include <lib6lowpan/lib6lowpan.h>
#include <lib6lowpan/devconf.h>
#include <lib6lowpan/IEEE154Packet.h>

#include "serialsource.h"
#include "serialpacket.h"
#include "serialprotocol.h"
#include "sfsource.h"

#include "tun_dev.h"
#include "routing.h"
#include "logging.h"
#include "config.h"
#include "nwstate.h"
#include "vty/vty.h"

#define min(a,b) ( (a>b) ? b : a )
#define max(a,b) ( (a>b) ? a : b )

int tun_fd, radvd_fd = -1, fifo_fd = -1, keepalive_needed = 1;
int opt_listenonly = 0, opt_trackflows = 0;

int radvd_init(char *ifname, struct config *c);
void radvd_process();
void radvd_reset_adverts(void);

#ifndef SF_SRC
serial_source ser_src;
#define write_pan_packet(DATA, LEN) write_serial_packet(ser_src, DATA, LEN)
#define read_pan_packet(LENP) read_serial_packet(ser_src, LENP)
#define close_pan()   close_serial_source(ser_src);
#else
int sf_fd;
#define write_pan_packet(DATA, LEN) write_sf_packet(sf_fd, DATA, LEN)
#define read_pan_packet(LENP) read_sf_packet(sf_fd, LENP)
#define close_pan()           close(sf_fd)
#endif

sig_atomic_t do_shutdown = 0;

void driver_shutdown() {
  do_shutdown = 1;
}


enum {
  N_RECONSTRUCTIONS = 10,
};

/*
 */ 
#ifdef __TARGET_mips__
const char *def_configfile = "/etc/lowpan/serial_tun.conf";
#else
const char *def_configfile = "serial_tun.conf";
#endif



extern struct in6_addr __my_address;
uint16_t local_seqno = 0;

volatile sig_atomic_t config_success = 0;
struct config driver_config;
char dev[IFNAMSIZ];
struct {
  time_t boot_time;
  unsigned long tx_pkts;
  unsigned long tx_frags;
  unsigned long tx_bytes;
  unsigned long rx_pkts;
  unsigned long rx_frags;
  unsigned long rx_bytes;
  unsigned long fw_pkts;
} stats = {0, 0, 0, 0, 0, 0, 0, 0};

#ifdef CENTRALIZED_ROUTING
void install_route(struct split_ip_msg *amsg, uint8_t flags);
void uninstall_route(uint16_t n1, uint16_t n2);
#endif


/* ------------------------------------------------------------------------- */

void stderr_msg(serial_source_msg problem)
{
  // fprintf(stderr, "Note: %s\n", msgs[problem]);
}


void print_ip_packet(struct split_ip_msg *msg) {
  int i;
  struct generic_header *g_hdr;
  if (log_getlevel() > LOGLVL_DEBUG) return;

  printf("  nxthdr: 0x%x hlim: 0x%x plen: %i\n", msg->hdr.nxt_hdr, msg->hdr.hlim, ntohs(msg->hdr.plen));
  printf("  src: ");
  for (i = 0; i < 16; i++) printf("0x%x ", msg->hdr.ip6_src.s6_addr[i]);
  printf("\n");
  printf("  dst: ");
  for (i = 0; i < 16; i++) printf("0x%x ", msg->hdr.ip6_dst.s6_addr[i]);
  printf("\n");

  g_hdr = msg->headers;
  while (g_hdr != NULL) {
    printf("header [%i]: ", g_hdr->len);
    for (i = 0; i < g_hdr->len; i++)
      printf("0x%x ", g_hdr->hdr.data[i]);
    printf("\n");
    g_hdr = g_hdr->next;
  }

  printf("data [%i]:\n\t", msg->data_len);
  for (i = 0; i < msg->data_len; i++) {
    if (i == 0x40) {
      printf (" ...\n");
      break;
    }
    printf("0x%x ", msg->data[i]);
    if (i % 16 == 15) printf("\n\t");
    if (i % 16 == 7) printf ("  ");
  }
  printf("\n");
}


const char *fifo_name = "/var/run/ip-driver/flows";
void fifo_open() {
  struct stat stat_buf;

  if (opt_trackflows) {
    if (stat(fifo_name, &stat_buf) < 0) {
      error("fifo does not exist -- track flows will be diabled\n");
      return;
    }
    fifo_fd = open(fifo_name, O_WRONLY | O_NONBLOCK );
    if (fifo_fd < 0) {
      error("unable to open fifo %i %s: is a reader connected?\n", fifo_fd, fifo_name);
      fifo_fd = -1;
      return;
    }
  }
}
void fifo_close() {
  if (fifo_fd >= 0) {
    close(fifo_fd);
  }
}

enum { N_OUTGOING_CACHE = 10, }; int outgoing_cache_idx = 0;
struct flow_id_msg outgoing_cache[N_OUTGOING_CACHE];

void fifo_report(struct split_ip_msg *msg, uint16_t dest, int nxt_hdr) {
  if (fifo_fd >= 0) {
    outgoing_cache_idx = (outgoing_cache_idx + 1) % N_OUTGOING_CACHE;
    outgoing_cache[outgoing_cache_idx].flow = msg->flow_id;
    outgoing_cache[outgoing_cache_idx].src  = ntohs(msg->hdr.ip6_src.s6_addr16[7]);
    outgoing_cache[outgoing_cache_idx].dst  = ntohs(msg->hdr.ip6_dst.s6_addr16[7]);
    outgoing_cache[outgoing_cache_idx].local_address = ntohs(__my_address.s6_addr16[7]);
    outgoing_cache[outgoing_cache_idx].nxt_hdr = nxt_hdr;
    outgoing_cache[outgoing_cache_idx].n_attempts = 1;
    outgoing_cache[outgoing_cache_idx].attempts[0].next_hop = (dest);
    debug("adding cache entry: %i %i\n",  outgoing_cache[outgoing_cache_idx].src,
          outgoing_cache[outgoing_cache_idx].flow);
  }
}

void flow_insert_label(struct split_ip_msg *msg) {
  uint8_t *buf;
  struct generic_header *g_hdr;


  if (opt_trackflows) {
    buf = malloc(sizeof(struct ip6_ext) + sizeof(struct tlv_hdr) + sizeof(struct flow_id));
    g_hdr = (struct generic_header *)malloc(sizeof(struct generic_header));
    struct ip6_ext *ext = (struct ip6_ext *)buf;
    struct tlv_hdr *tlv = (struct tlv_hdr *)(ext + 1);
    struct flow_id *id  = (struct flow_id *)(tlv + 1);

    ext->nxt_hdr = msg->hdr.nxt_hdr;
    msg->hdr.nxt_hdr = IPV6_HOP;
    ext->len = sizeof(struct ip6_ext) + sizeof(struct tlv_hdr) + sizeof(struct flow_id);
    tlv->type = TLV_TYPE_FLOW;
    tlv->len = ext->len - sizeof(struct ip6_ext);
    id->id = msg->flow_id;
  
    g_hdr->payload_malloced = 1;
    g_hdr->hdr.ext = ext;
    g_hdr->len = ext->len;
    g_hdr->next = msg->headers;
    msg->headers = g_hdr;
    
    msg->hdr.plen = htons(ntohs(msg->hdr.plen) + ext->len);
  }
}

/*
 * frees the linked list structs, and their payloads if we have
 * malloc'ed them at some other point.
 *
 * does not free the payload buffer or the actual split_ip_msg struct,
 * since those are malloc'ed seperatly in this implementation.
 */
void free_split_msg(struct split_ip_msg *msg) {
  struct generic_header *cur, *next;
  cur = msg->headers;
  while (cur != NULL) {
    next = cur->next;
    if (cur->payload_malloced)
      free(cur->hdr.data);
    free(cur);
    cur = next;
  }
}

void configure_timeout() {
  if (config_success == 0) {
    fatal("configuring interface failed!  aborting!\n");
    exit(2);
  } else {
    signal(SIGALRM, SIG_DFL);
  }
}

void configure_reboot() {
  uint8_t buf[sizeof(config_cmd_t) + 1];
  config_cmd_t *cmd = (config_cmd_t *)(&buf[1]);
  memset(buf, 0, sizeof(config_cmd_t) + 1);
  buf[0] = TOS_SERIAL_DEVCONF;
  cmd->cmd = CONFIG_REBOOT;

  signal(SIGALRM, configure_timeout);
  write_pan_packet(buf, CONFIGURE_MSG_SIZE + 1);
  alarm(5);
}

void configure_setparms(struct config *c, int cmdno) {
  uint8_t buf[sizeof(config_cmd_t) + 1];
  config_cmd_t *cmd = (config_cmd_t *)(&buf[1]);
  memset(buf, 0, sizeof(config_cmd_t) + 1);
  buf[0] = TOS_SERIAL_DEVCONF;
  cmd->cmd = cmdno;
  cmd->rf.addr = c->router_addr.s6_addr16[7]; // is network byte-order
  cmd->rf.channel = c->channel;
  cmd->retx.retries = htons(c->retries);
  cmd->retx.delay = htons(30);

  write_pan_packet(buf, CONFIGURE_MSG_SIZE + 1);
}


/* ------------------------------------------------------------------------- */
/*
 * the first byte the TOS serial stack sends is a dispatch byte.  One
 * dispatch value is for forwarded 802;.15.4 packets; we use a few
 * others to talk directly to the attached IPBaseStation.
 */
void handle_other_pkt(uint8_t *data, int len) {
  config_reply_t *rep;
  switch (data[0]) {
  case TOS_SERIAL_DEVCONF:
    rep = (config_reply_t *)(&data[1]);
    debug("interface configured (0x%x) addr: 0x%x\n", rep->error, ntohs(rep->addr));
    switch (rep->error) {
    case CONFIG_ERROR_BOOTED:
      configure_setparms(&driver_config, CONFIG_SET_PARM);
      break;
    default:
      info("interface device successfully initialized\n");
      config_success = 1;

      /* put this here because we already use SIGALRM for the
         configure timeout, and radvd needs it for its own timer. */
      if (radvd_fd < 0 && (radvd_fd = radvd_init(dev, &driver_config)) < 0) {
        fatal("radvd init failed!\n");
        exit(1);
      } 
    }
    break;
  default:
    warn("received serial packet with unknown dispatch 0x%x\n",data[0]);
    log_dump_serial_packet(data, len);
  }
}


/* ------------------------------------------------------------------------- */
/* handling of data arriving on the tun interface */
void write_radio_header(uint8_t *serial, ieee154_saddr_t dest, uint16_t payload_len) {
  IEEE154_header_t *radioPacket = (IEEE154_header_t *)(serial + 1);
  radioPacket->length = payload_len + MAC_HEADER_SIZE + MAC_FOOTER_SIZE;

  // don't include the length byte
  radioPacket->fcf = htons(0x4188);
  // dsn will get set on mote
  radioPacket->destpan = 0;
  radioPacket->dest = htole16(dest);
  // src will get set on mote 
  
  serial[0] = SERIAL_TOS_SERIAL_802_15_4_ID;
}

void send_fragments (struct split_ip_msg *msg, ieee154_saddr_t dest) {
  int result;
  uint16_t frag_len;

⌨️ 快捷键说明

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