📄 serial_tun.c
字号:
VTY_printf("Up since %s", ctime(&stats.boot_time));
VTY_printf(" receive packets: %lu fragments: %lu bytes: %lu\r\n",
stats.rx_pkts, stats.rx_frags, stats.rx_bytes);
VTY_printf(" transmit packets: %lu fragments: %lu bytes: %lu\r\n",
stats.tx_pkts, stats.tx_frags, stats.tx_bytes);
VTY_printf(" forward packets: %lu\r\n", stats.fw_pkts);
VTY_printf(" dag seqno: %hi\r\n", routing_get_seqno());
VTY_flush();
}
void print_help(int fd, int argc, char **argv) {
VTY_HEAD;
VTY_printf("ip-driver console\r\n");
VTY_printf(" conf : print configuration info\r\n");
VTY_printf(" stats : print statistics\r\n");
VTY_printf(" shutdown : shutdown the driver\r\n");
VTY_printf(" chan <c> : switch to channel 'c'\r\n");
VTY_printf(" dot <dotfile>: print dot-file of topology\r\n");
VTY_printf(" log {DEBUG INFO WARN ERROR FATAL}: set loglevel\r\n");
VTY_printf("\r\n Routing commands:\r\n");
VTY_printf(" inval <nodeid> : invalidate a router\r\n");
VTY_printf(" add <n1> <n2> : add a persistent link between n1 and n2\r\n");
VTY_printf(" links : print link detail\r\n");
VTY_printf(" routes : print routes\r\n");
VTY_printf(" newroutes : recalculate routes\r\n");
VTY_printf(" rebuild : initiate a DAG recomputation\r\n");
VTY_printf(" controller <n> : add a new controller\r\n");
#ifdef CENTRALIZED_ROUTING
VTY_printf(" install <HOP | SRC> <n1> <n2> [reverse]: install a route between n1 and n2\r\n");
VTY_printf(" uninstall <n1> <n2>: uninstall a route between n1 and n2\r\n");
#endif
VTY_printf("\r\n");
VTY_printf(" help: print this help\r\n");
VTY_flush();
}
void sh_loglevel(int fd, int argc, char **argv) {
VTY_HEAD;
int i;
if (argc != 2) return;
for (i = 0; i < 5; i++) {
if (strcmp(log_names[i], argv[1]) == 0) {
VTY_printf("setting verbosity to %s\r\n", log_names[i]);
log_setlevel(i);
}
}
VTY_flush();
}
void sh_dotfile(int fd, int argc, char **argv) {
VTY_HEAD;
if (argc == 2) {
VTY_printf("writing topology to %s\r\n", argv[1]);
nw_print_dotfile(argv[1]);
} else {
VTY_printf("error: include a filename!\r\n");
}
VTY_flush();
}
void sh_chan(int fd, int argc, char **argv) {
VTY_HEAD;
if (argc != 2) {
VTY_printf("%s <channel>\r\n", argv[0]);
} else {
int channel = atoi(argv[1]);
if (channel < 11 || channel > 26) {
VTY_printf("channel must be in [11:26]\r\n");
} else {
driver_config.channel = channel;
VTY_printf("setting channel to %i\r\n", channel);
configure_setparms(&driver_config, CONFIG_SET_PARM);
}
}
VTY_flush();
}
#ifdef CENTRALIZED_ROUTING
void sh_install(int fd, int argc, char **argv) {
VTY_HEAD;
int flags = 0;
struct split_ip_msg msg;
if (argc < 4) {
goto usage;
}
if (strcmp("HOP", argv[1]) == 0)
flags |= HYDRO_METHOD_HOP;
else if (strcmp("SRC", argv[1]) == 0) {
flags |= HYDRO_METHOD_SOURCE;
} else goto usage;
argc -= 4;
while (argc > 0) {
if (argv[argc+3][0] == 'R') {
flags |= HYDRO_INSTALL_REVERSE;
} else goto usage;
argc--;
}
memset(&msg, 0, sizeof(struct split_ip_msg));
memcpy(msg.hdr.ip6_src.s6_addr, __my_address.s6_addr, 8);
memcpy(msg.hdr.ip6_dst.s6_addr, __my_address.s6_addr, 8);
msg.hdr.ip6_src.s6_addr16[7] = htons(atoi(argv[2]));
msg.hdr.ip6_dst.s6_addr16[7] = htons(atoi(argv[3]));
VTY_printf("installing route between 0x%x and 0x%x\r\n", atoi(argv[2]), atoi(argv[3]));
install_route(&msg, flags);
VTY_flush();
return;
usage:
VTY_printf("%s <HOP | SRC> <n1> <n2> [REV]\r\n", argv[0]);
VTY_flush();
}
void sh_uninstall(int fd, int argc, char **argv) {
VTY_HEAD;
if (argc != 3) {
VTY_printf("%s <n1> <n2>\r\n", argv[0]);
VTY_flush();
return;
}
int n1 = atoi(argv[1]);
int n2 = atoi(argv[2]);
VTY_printf("uninstalling route from 0x%x to 0x%x\r\n", n1, n2);
uninstall_route(n1, n2);
VTY_flush();
}
#endif
void sh_controller(int fd, int argc, char **argv) {
VTY_HEAD;
if (argc != 2) {
VTY_printf("%s <cid>\r\n", argv[0]);
} else {
int n = atoi(argv[1]);
get_insert_router(n);
nw_add_controller(n);
}
VTY_flush();
}
void sh_incr_seqno(int fd, int argc, char **argv) {
VTY_HEAD;
VTY_printf("DAG seqno now %i\r\n", routing_incr_seqno());
radvd_reset_adverts();
VTY_flush();
}
struct vty_cmd vty_cmd_list[] = {{"help", print_help},
{"stats", print_stats},
{"links", nw_print_links},
{"routes", nw_print_routes},
{"newroutes", nw_test_routes},
{"add", nw_add_sticky_edge},
{"inval", nw_inval_node_sh},
{"conf", config_print},
{"log", sh_loglevel},
{"dot", sh_dotfile},
{"chan", sh_chan},
{"rebuild", sh_incr_seqno},
#ifdef CENTRALIZED_ROUTING
{"install", sh_install},
{"uninstall", sh_uninstall},
#endif
{"controller", sh_controller},
{"shutdown", (void(*)(int,int,char**))driver_shutdown}};
/* shifts data between the serial port and the tun interface */
int serial_tunnel(int tun_fd) {
fd_set fs;
int maxfd = -1;
int usecs_remain = KEEPALIVE_INTERVAL;
time_t last_aging, current_time;
time(&last_aging);
#ifndef SF_SRC
int pan_fd = opt_listenonly ? -1 : serial_source_fd(ser_src);
#else
int pan_fd = opt_listenonly ? -1 : sf_fd;
#endif
while (1) {
int n_fds;
struct timeval tv;
if (do_shutdown) return 0;
FD_ZERO(&fs);
if (opt_listenonly) {
maxfd = -1;
} else {
FD_SET(tun_fd, &fs);
FD_SET(pan_fd, &fs);
maxfd = max(tun_fd, pan_fd);
}
if (radvd_fd >= 0) {
FD_SET(radvd_fd, &fs);
maxfd = max(radvd_fd, maxfd);
}
maxfd = max(vty_add_fds(&fs), maxfd);
maxfd = max(routing_add_fds(&fs), maxfd);
// having a timeout also means that we poll for new packets every
// so often, which is apparently A Good Thing
tv.tv_sec = 0;
tv.tv_usec = KEEPALIVE_TIMEOUT;
if ((n_fds = select(maxfd + 1, &fs, NULL, NULL, &tv)) < 0) {
continue;
}
usecs_remain -= (KEEPALIVE_TIMEOUT - tv.tv_usec);
if (usecs_remain <= 0) {
if (keepalive_needed && !opt_listenonly) {
configure_setparms(&driver_config, CONFIG_KEEPALIVE);
} else keepalive_needed = 1;
usecs_remain = KEEPALIVE_INTERVAL;
}
if (!opt_listenonly) {
int more_data;
/* check for data */
do {
more_data = tun_input();
more_data = serial_input() || more_data ;
} while (more_data);
}
vty_process(&fs);
routing_process(&fs);
if (radvd_fd >= 0 && FD_ISSET(radvd_fd, &fs)) {
radvd_process();
}
/* end of data available */
time(¤t_time);
if (current_time > last_aging + (FRAG_EXPIRE_TIME / 1024)) {
last_aging = current_time;
age_reconstructions();
}
}
}
int main(int argc, char **argv) {
int i, c;
time(&stats.boot_time);
log_init();
while ((c = getopt(argc, argv, "c:lt")) != -1) {
switch (c) {
case 'c':
def_configfile = optarg;
break;
case 'l':
opt_listenonly = 1;
info("Listen Only: will not attach to interface device\n");
break;
case 't':
info("TrackFlows: will insert flow id on outgoing packets\n");
opt_trackflows = 1;
break;
default:
fatal("Invalid command line argument.\n");
exit(1);
}
}
if (argc - optind != 2 && !opt_listenonly) {
#ifndef SF_SRC
fatal("usage: %s [-c config] [-l] <device> <rate>\n", argv[0]);
#else
fatal("usage: %s [-c config] <host> <port>\n", argv[0]);
#endif
exit(2);
}
fifo_open();
signal(SIGINT, driver_shutdown);
if (config_parse(def_configfile, &driver_config) != 0) {
fatal ("config parse of %s failed!\n", def_configfile);
exit(1);
}
globalPrefix = 1;
memcpy(&__my_address, &driver_config.router_addr, sizeof(struct in6_addr));
struct vty_cmd_table t;
short vty_port = 6106;
t.n = sizeof(vty_cmd_list) / sizeof(struct vty_cmd);
t.table = vty_cmd_list;
if (vty_init(&t, vty_port) < 0) {
error("could not start debug console server\n");
error("the console will be available only on stdin\n");
} else {
info("telnet console server running on port %i\n", vty_port);
}
dev[0] = 0;
if (opt_listenonly) {
tun_fd = -1;
#ifndef SF_SRC
ser_src = NULL;
#endif
} else {
/* create the tunnel device */
tun_fd = tun_open(dev);
if (tun_fd < 1) {
fatal("Could not create tunnel device. Fatal.\n");
return 1;
} else {
info("created tun device: %s\n", dev);
}
if (tun_setup(dev, &__my_address) < 0) {
fatal("configuring the tun failed; aborting\n");
perror("tun_setup");
return 1;
}
for (i = 0; i < N_RECONSTRUCTIONS; i++) {
reconstructions[i].timeout = T_UNUSED;
}
/* open the serial port */
#ifndef SF_SRC
ser_src = open_serial_source(argv[optind], platform_baud_rate(argv[optind + 1]),
1, stderr_msg);
if (!ser_src) {
fatal("Couldn't open serial port at %s:%s\n", argv[optind], argv[optind + 1]);
exit(1);
}
#else
sf_fd = open_sf_source(argv[optind], atoi(argv[optind + 1]));
if (sf_fd < 0) {
fatal("Couldn't connect to serial forwarder sf@%s:%s\n", argv[optind], argv[optind + 1]);
exit(1);
}
#endif
#ifndef SIM
configure_reboot();
#endif
}
if (routing_init(&driver_config, dev) < 0) {
fatal("could not start routing engine!\n");
exit(1);
}
/* start tunneling */
serial_tunnel(tun_fd);
/* clean up */
info("driver shutting down\n");
vty_shutdown();
if (!opt_listenonly) {
tun_close(tun_fd, dev);
close_pan();
}
fifo_close();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -