📄 slmon.c
字号:
/***************************************************************************** @(#) slmon.c,v openss7-0_9_2_E(0.9.2.2) 2007/01/21 20:22:41 ----------------------------------------------------------------------------- Copyright (c) 2001-2007 OpenSS7 Corporation <http://www.openss7.com/> Copyright (c) 1997-2000 Brian F. G. Bidulock <bidulock@openss7.org> All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------------------------------------------------------------------------- U.S. GOVERNMENT RESTRICTED RIGHTS. If you are licensing this Software on behalf of the U.S. Government ("Government"), the following provisions apply to you. If the Software is supplied by the Department of Defense ("DoD"), it is classified as "Commercial Computer Software" under paragraph 252.227-7014 of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any successor regulations) and the Government is acquiring only the license rights granted herein (the license rights customarily provided to non-Government users). If the Software is supplied to any unit or agency of the Government other than DoD, it is classified as "Restricted Computer Software" and the Government's rights in the Software are defined in paragraph 52.227-19 of the Federal Acquisition Regulations ("FAR") (or any successor regulations) or, in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR (or any successor regulations). ----------------------------------------------------------------------------- Commercial licensing and support of this software is available from OpenSS7 Corporation at a fee. See http://www.openss7.com/ ----------------------------------------------------------------------------- Last Modified 2007/01/21 20:22:41 by brian ----------------------------------------------------------------------------- slmon.c,v Revision 0.9.2.2 2007/01/21 20:22:41 brian - working up drivers Revision 0.9.2.1 2007/01/15 11:33:57 brian - added new and old signalling link utilities *****************************************************************************/#ident "@(#) slmon.c,v openss7-0_9_2_E(0.9.2.2) 2007/01/21 20:22:41"static char const ident[] = "slmon.c,v openss7-0_9_2_E(0.9.2.2) 2007/01/21 20:22:41";/* * This is a signalling link monitoring utiltiy for the SL-MUX multiplexing driver. It purpose is * to open signalling link monitoring streams, /dev/sl-mon, on the SL-MUX driver, and attach them to * specific signalling links using the global PPA or CLEI for the signalling link. The utility then * outputs configuration and monitoring information obtained from the signalling link service * interface and formats the information and outputs it to either standard output of a file. When a * file is specified as an option, the utility closes standard input, output and error, and places * itself in the background as a daemon process. */#include <stropts.h>#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/poll.h>#include <sys/time.h>#include <sys/ioctl.h>#include <fcntl.h>#include <getopt.h>#include <time.h>#include <signal.h>#include <syslog.h>#include <sys/utsname.h>#include <ctype.h>#include <stdint.h>#include <ss7/lmi.h>#include <ss7/lmi_ioctl.h>#include <ss7/sdli.h>#include <ss7/sdli_ioctl.h>#include <ss7/sdti.h>#include <ss7/sdti_ioctl.h>#include <ss7/sli.h>#include <ss7/sli_ioctl.h>int output = 1;int nomead = 0;char clei[32] = "";int ppa = 0;int mon_fd = -1;int link_state = 0;char outfile[256] = "";char errfile[256] = "";char outpath[256] = "";char errpath[256] = "";char lnkname[256] = "";char cfgfile[256] = "";char outpdir[256] = "/var/log/slmon";char devname[256] = "/dev/sl-mon";int alm_signal = 0;int hup_signal = 0;int trm_signal = 0;int usr_signal = 0;#define BUFSIZE 512char cbuf[BUFSIZE];char dbuf[BUFSIZE];struct strbuf ctrl = { sizeof(cbuf), 0, cbuf };struct strbuf data = { sizeof(dbuf), 0, dbuf };struct strioctl ctl;struct monconfig { lmi_option_t opt; sl_config_t sl; sdt_config_t sdt; sdl_config_t sdl;} monconf;voidsig_handler(int signum){ switch (signum) { case SIGALRM: alm_signal = 1; break; case SIGUSR1: usr_signal = 1; break; case SIGHUP: hup_signal = 1; break; case SIGTERM: trm_signal = 1; break; } return;}intsig_register(int signum, void (*handler) (int)){ sigset_t mask; struct sigaction act; act.sa_handler = handler ? handler : SIG_DFL; act.sa_flags = handler ? SA_RESTART : 0; act.sa_restorer = NULL; sigemptyset(&act.sa_mask); if (sigaction(signum, &act, NULL)) return -1; sigemptyset(&mask); sigaddset(&mask, signum); sigprocmask(handler ? SIG_UNBLOCK : SIG_BLOCK, &mask, NULL); return 0;}inthup_catch(void){ return sig_register(SIGHUP, sig_handler);}intalm_catch(void){ return sig_register(SIGALRM, sig_handler);}inttrm_catch(void){ return sig_register(SIGTERM, sig_handler);}intusr_catch(void){ return sig_register(SIGUSR1, sig_handler);}voidsig_catch(void){ hup_catch(); alm_catch(); trm_catch(); usr_catch();}inthup_block(void){ return sig_register(SIGHUP, NULL);}intalm_block(void){ return sig_register(SIGALRM, NULL);}inttrm_block(void){ return sig_register(SIGTERM, NULL);}intusr_block(void){ return sig_register(SIGUSR1, NULL);}voidsig_block(void){ hup_block(); alm_block(); trm_block(); usr_block();}int mon_stop(void);intmon_exit(int retval){ syslog(LOG_NOTICE, "Exiting %d", retval); fflush(stdout); fflush(stderr); mon_stop(); sig_block(); closelog(); exit(retval);}static struct timeval tv;voidfprint_time(FILE * stream){ if (0 > tv.tv_usec || tv.tv_usec > 1000000) { tv.tv_sec += (tv.tv_usec / 1000000); tv.tv_usec %= 1000000; } fprintf(stream, "%012ld.%06ld", tv.tv_sec, tv.tv_usec);}intftimestamp(void){ while (gettimeofday(&tv, NULL) < 0) if (errno == EAGAIN || errno == EINTR || errno == ERESTART) { syslog(LOG_ERR, "%m"); syslog(LOG_ERR, "Could not read timestamp: winging it%s", outpath); break; } return (0);}/* generate output header */voidoutput_header(void){ char buf[128] = ""; struct utsname uts; ftimestamp(); fprint_time(stdout); fprintf(stdout, " # SS7MON slmon.c,v 0.9.2.2 2007/01/21 20:22:41 brian Exp Output File Header\n"); uname(&uts); fprint_time(stdout); fprintf(stdout, " # machine %s %s %s %s %s\n", uts.sysname, uts.nodename, uts.release, uts.version, uts.machine); fprint_time(stdout); fprintf(stdout, " # device: %08x %s\n", ppa, clei); fprint_time(stdout); if (outpath[0] != '\0') snprintf(buf, sizeof(buf), outpath); else snprintf(buf, sizeof(buf), "(stdout)"); fprintf(stdout, " # original file name; %s\n", buf); fprint_time(stdout); gethostname(buf, sizeof(buf)); fprintf(stdout, " # host: %s\n", buf); fprint_time(stdout); fprintf(stdout, " # date: %s\n", ctime(&tv.tv_sec));}voidtrm_action(void){ syslog(LOG_WARNING, "Caught SIGTERM, shutting down"); mon_exit(0);}int mon_config(void);void output_config(void);voidhup_action(void){ syslog(LOG_WARNING, "Caught SIGHUP, reopening files."); if (output > 1) syslog(LOG_NOTICE, "Reopening output file %s", outpath); if (outpath[0] != '\0') { fflush(stdout); fclose(stdout); if (freopen(outpath, "a", stdout) == NULL) { syslog(LOG_ERR, "%m"); syslog(LOG_ERR, "Could not reopen stdout file %s", outpath); } output_header(); mon_config(); output_config(); } if (output > 1) syslog(LOG_NOTICE, "Reopening error file %s", errpath); if (errpath[0] != '\0') { fflush(stderr); fclose(stderr); if (freopen(errpath, "a", stderr) == NULL) { syslog(LOG_ERR, "%m"); syslog(LOG_ERR, "Could not reopen stderr file %s", errpath); } } return;}voidalm_action(void){ return;}voidusr_action(void){ mon_config(); output_config();}intstart_timer(long duration){ struct itimerval setting = { {0, 0}, {duration / 1000, (duration % 1000) * 1000} }; if (alm_catch()) return (-1); if (setitimer(ITIMER_REAL, &setting, NULL)) return (-1); alm_signal = 0; return (0);}intstop_timer(void){ return alm_block();}voidprint_data(caddr_t ptr, size_t len){ static unsigned char hexchar[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; int i; for (i = 0; i < len; i++) { fputc(hexchar[(ptr[i] >> 4) & 0x0f], stdout); fputc(hexchar[(ptr[i] >> 0) & 0x0f], stdout); }}intdecode_data(void){ ftimestamp(); fprint_time(stdout); fputc(' ', stdout); print_data((caddr_t) dbuf, data.len); fputc('\n', stdout); return (0);}intdecode_ctrl(void){ union { union LMI_primitives lmi; union SL_primitives sl; } *p = (typeof(p)) cbuf; uint32_t prim = *(uint32_t *) cbuf; ftimestamp(); if (output > 2) fprintf(stderr, "Got control message! %d\n", prim); fprint_time(stdout); switch (prim) { case LMI_INFO_REQ: fprintf(stdout, "ctrl=LMI_INFO_REQ"); break; case LMI_ATTACH_REQ: fprintf(stdout, "ctrl=LMI_ATTACH_REQ"); fprintf(stdout, "{lmi_ppa="); print_data((caddr_t) p->lmi.attach_req.lmi_ppa, ctrl.len - sizeof(p->lmi.attach_req)); fputc('}', stdout); break; case LMI_DETACH_REQ: fprintf(stdout, "ctrl=LMI_DETACH_REQ"); break; case LMI_ENABLE_REQ: fprintf(stdout, "ctrl=LMI_ENABLE_REQ"); fprintf(stdout, "{lmi_rem"); print_data((caddr_t) p->lmi.enable_req.lmi_rem, ctrl.len - sizeof(p->lmi.enable_req)); fputc('}', stdout); break; case LMI_DISABLE_REQ: fprintf(stdout, "ctrl=LMI_DISABLE_REQ"); break; case LMI_OPTMGMT_REQ: fprintf(stdout, "ctrl=LMI_OPTMGMT_REQ"); break; case LMI_INFO_ACK: fprintf(stdout, "ctrl=LMI_INFO_ACK"); fprintf(stdout, "{lmi_version=%u", p->lmi.info_ack.lmi_version); fprintf(stdout, ",lmi_state="); switch (p->lmi.info_ack.lmi_state) { case LMI_UNATTACHED: fprintf(stdout, "LMI_UNATTACHED"); break; case LMI_ATTACH_PENDING: fprintf(stdout, "LMI_ATTACH_PENDING"); break; case LMI_UNUSABLE: fprintf(stdout, "LMI_UNUSABLE"); break; case LMI_DISABLED: fprintf(stdout, "LMI_DISABLED"); break; case LMI_ENABLE_PENDING: fprintf(stdout, "LMI_ENABLE_PENDING"); break; case LMI_ENABLED: fprintf(stdout, "LMI_ENABLED"); break; case LMI_DISABLE_PENDING: fprintf(stdout, "LMI_DISABLE_PENDING"); break; case LMI_DETACH_PENDING: fprintf(stdout, "LMI_DETACH_PENDING"); break; default: fprintf(stdout, "[%u]", p->lmi.info_ack.lmi_state); break; } fprintf(stdout, ",lmi_max_sdu=%u", p->lmi.info_ack.lmi_max_sdu); fprintf(stdout, ",lmi_min_sdu=%u", p->lmi.info_ack.lmi_min_sdu); fprintf(stdout, ",lmi_header_len=%u", p->lmi.info_ack.lmi_header_len); fprintf(stdout, ",lmi_ppa_style="); switch (p->lmi.info_ack.lmi_ppa_style) { case LMI_STYLE1: fprintf(stdout, "LMI_STYLE1"); break; case LMI_STYLE2: fprintf(stdout, "LMI_STYLE2"); break; default: fprintf(stdout, "%u", p->lmi.info_ack.lmi_ppa_style); break; } fprintf(stdout, ",lmi_ppa_addr="); print_data((caddr_t) p->lmi.info_ack.lmi_ppa_addr, ctrl.len - sizeof(p->lmi.info_ack)); fputc('}', stdout); break; case LMI_OK_ACK: fprintf(stdout, "ctrl=LMI_OK_ACK"); fprintf(stdout, "{lmi_correct_primitive="); switch (p->lmi.ok_ack.lmi_correct_primitive) { case LMI_INFO_REQ: fprintf(stdout, "LMI_INFO_REQ"); break; case LMI_ATTACH_REQ: fprintf(stdout, "LMI_ATTACH_REQ"); break; case LMI_DETACH_REQ: fprintf(stdout, "LMI_DETACH_REQ"); break; case LMI_ENABLE_REQ: fprintf(stdout, "LMI_ENABLE_REQ"); break; case LMI_DISABLE_REQ: fprintf(stdout, "LMI_DISABLE_REQ"); break; case LMI_OPTMGMT_REQ: fprintf(stdout, "LMI_OPTMGMT_REQ"); break; case LMI_INFO_ACK: fprintf(stdout, "LMI_INFO_ACK"); break; case LMI_OK_ACK: fprintf(stdout, "LMI_OK_ACK"); break; case LMI_ERROR_ACK: fprintf(stdout, "LMI_ERROR_ACK"); break; case LMI_ENABLE_CON: fprintf(stdout, "LMI_ENABLE_CON"); break; case LMI_DISABLE_CON: fprintf(stdout, "LMI_DISABLE_CON"); break; case LMI_OPTMGMT_ACK: fprintf(stdout, "LMI_OPTMGMT_ACK"); break; case LMI_ERROR_IND: fprintf(stdout, "LMI_ERROR_IND"); break; case LMI_STATS_IND: fprintf(stdout, "LMI_STATS_IND"); break; case LMI_EVENT_IND: fprintf(stdout, "LMI_EVENT_IND"); break; default: fprintf(stdout, "%u", p->lmi.ok_ack.lmi_correct_primitive); break; } fprintf(stdout, ",lmi_state="); switch (p->lmi.ok_ack.lmi_state) { case LMI_UNATTACHED: fprintf(stdout, "LMI_UNATTACHED"); break; case LMI_ATTACH_PENDING: fprintf(stdout, "LMI_ATTACH_PENDING"); break; case LMI_UNUSABLE: fprintf(stdout, "LMI_UNUSABLE"); break; case LMI_DISABLED: fprintf(stdout, "LMI_DISABLED"); break; case LMI_ENABLE_PENDING: fprintf(stdout, "LMI_ENABLE_PENDING"); break; case LMI_ENABLED: fprintf(stdout, "LMI_ENABLED"); break; case LMI_DISABLE_PENDING: fprintf(stdout, "LMI_DISABLE_PENDING"); break; case LMI_DETACH_PENDING: fprintf(stdout, "LMI_DETACH_PENDING"); break; default: fprintf(stdout, "[%u]", p->lmi.ok_ack.lmi_state); break; } fputc('}', stdout); break; case LMI_ERROR_ACK: fprintf(stdout, "ctrl=LMI_ERROR_ACK"); fprintf(stdout, "{lmi_errno=\"%s\"", strerror(p->lmi.error_ack.lmi_errno)); fprintf(stdout, ",lmi_reason=");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -