/* ax25ipd.c main entrypoint * * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc. * This software may be freely used, distributed, or modified, providing * this header is not removed. * */ /* * cleaned up and prototyped for inclusion into the standard linux ax25 * toolset in january 1997 by rob mayfield, vk5xxx/vk5zeu */ #include #include #include #include #include #include #include #include #include #include #include #include "../pathnames.h" #include "ax25ipd.h" int udp_mode; /* true if we need a UDP socket */ int ip_mode; /* true if we need the raw IP socket */ unsigned short my_udp; /* the UDP port to use (network byte order) */ char ttydevice[PATH_MAX]; /* the tty device for serial comms */ int ttyspeed; /* The baud rate on the tty device */ unsigned char mycallsign[7]; /* My callsign, shifted ASCII with SSID */ unsigned char mycallsign2[7]; /* My seconds port callsign, shifted ASCII with SSID */ unsigned char myalias[7]; /* An alias to use */ unsigned char myalias2[7]; /* An alias for second port */ char bc_text[128]; /* The text for beacon messages */ int bc_interval; /* The interval, in seconds, between beacons */ int bc_every; /* true=every, false=after */ int digi; /* True if we are connected to a TNC */ int loglevel; /* Verbosity level */ struct ax25ipd_stats stats; /* Usage statistics */ int dual_port; /* addition for dual port flag */ static jmp_buf restart_env; static int opt_version; static int opt_loglevel; static int opt_nofork; static int opt_help; static char opt_configfile[PATH_MAX]; static char opt_ttydevice[PATH_MAX]; static struct option options[] = { {"version", 0, NULL, 'v'}, {"loglevel", 1, NULL, 'l'}, {"help", 0, NULL, 'h'}, {"configfile", 1, NULL, 'c'}, {"ttydevice", 1, NULL, 'd'}, {"nofork", 0, NULL, 'f'}, {NULL, 0, NULL, 0} }; static void greet_world(void) { printf("\nax25ipd %s\n", VERSION); printf ("Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.\n"); printf ("This software may be freely used, distributed, or modified, providing\nthis header is not removed\n\n"); fflush(stdout); } static void do_stats(void) { int save_loglevel; /* save the old loglevel, and force at least loglevel 1 */ save_loglevel = loglevel; loglevel = 1; printf("\nSIGUSR1 signal: statistics and configuration report\n"); greet_world(); dump_config(); dump_routes(); dump_params(); printf("\nInput stats:\n"); printf("KISS input packets: %d\n", stats.kiss_in); printf(" too big: %d\n", stats.kiss_toobig); printf(" bad type: %d\n", stats.kiss_badtype); printf(" too short: %d\n", stats.kiss_tooshort); printf(" not for me: %d\n", stats.kiss_not_for_me); printf(" I am destination: %d\n", stats.kiss_i_am_dest); printf(" no route found: %d\n", stats.kiss_no_ip_addr); printf("UDP input packets: %d\n", stats.udp_in); printf("IP input packets: %d\n", stats.ip_in); printf(" failed CRC test: %d\n", stats.ip_failed_crc); printf(" too short: %d\n", stats.ip_tooshort); printf(" not for me: %d\n", stats.ip_not_for_me); printf(" I am destination: %d\n", stats.ip_i_am_dest); printf("\nOutput stats:\n"); printf("KISS output packets: %d\n", stats.kiss_out); printf(" beacons: %d\n", stats.kiss_beacon_outs); printf("UDP output packets: %d\n", stats.udp_out); printf("IP output packets: %d\n", stats.ip_out); printf("\n"); fflush(stdout); /* restore the old loglevel */ loglevel = save_loglevel; } static void hupper(int i) { printf("\nSIGHUP!\n"); longjmp(restart_env, 1); } static void usr1_handler(int i) { printf("\nSIGUSR1!\n"); do_stats(); } static void int_handler(int i) { printf("\nSIGINT!\n"); do_stats(); exit(1); } static void term_handler(int i) { printf("\nSIGTERM!\n"); do_stats(); exit(1); } int main(int argc, char **argv) { if (setjmp(restart_env) == 0) { signal(SIGHUP, hupper); } *opt_configfile = 0; *opt_ttydevice = 0; /* set up the handler for statistics reporting */ signal(SIGUSR1, usr1_handler); signal(SIGINT, int_handler); signal(SIGTERM, term_handler); while (1) { int c; c = getopt_long(argc, argv, "c:d:fhl:v", options, NULL); if (c == -1) break; switch (c) { case 'c': strncpy(opt_configfile, optarg, sizeof(opt_configfile)-1); opt_configfile[sizeof(opt_configfile)-1] = 0; break; case 'd': strncpy(opt_ttydevice, optarg, sizeof(opt_ttydevice)-1); opt_ttydevice[sizeof(opt_ttydevice)-1] = 0; break; case 'f': opt_nofork = 1; break; case 'h': opt_help = 1; break; case 'v': opt_version = 1; break; case 'l': opt_loglevel = atoi(optarg); break; default: opt_help = 1; break; } } if (optind < argc) { printf("Unknown argument '%s' ...\n\n", argv[optind++]); opt_help = 1; } if (opt_version == 1) { greet_world(); exit(0); } if (opt_help == 1) { greet_world(); printf("Usage:\n"); printf("%s [flags]\n", argv[0]); printf("\nFlags:\n"); printf (" --version, -v Print version of program\n"); printf(" --help, -h This help screen\n"); printf (" --loglevel NUM, -l NUM Set logging level to NUM\n"); printf (" --configfile FILE, -c FILE Set configuration file to FILE\n"); printf (" --ttydevice TTYDEV, -d TTYDEV Set device parameter to TTYDEV\n"); printf (" --nofork, -f Do not put daemon in background\n"); exit(0); } /* Initialize all routines */ config_init(); kiss_init(); route_init(); process_init(); io_init(); /* read config file */ config_read(opt_configfile); if (opt_ttydevice[0] != '\0') { strncpy(ttydevice, opt_ttydevice, sizeof(ttydevice)-1); ttydevice[sizeof(ttydevice)-1] = '\0'; } /* print the current config and route info */ dump_config(); dump_routes(); dump_params(); /* Open the IO stuff */ io_open(); /* if we get this far without error, let's fork off ! :-) */ if (opt_nofork == 0) { if (!daemon_start(TRUE)) { syslog(LOG_DAEMON | LOG_CRIT, "ax25ipd: cannot become a daemon\n"); return 1; } } /* we need to close stdin, stdout, stderr: because otherwise * scripting like ttyname=$(ax25ipd | tail -1) does not work */ if (!isatty(1)) { fflush(stdout); fflush(stderr); close(0); close(1); close(2); } /* and let the games begin */ io_start(); return 0; }