1
0
Files
irix-657m-src/irix/cmd/tokenring/mtr/mtrmonitor.c
2022-09-29 17:59:04 +03:00

258 lines
5.9 KiB
C

/*
* Copyright 1996 Silicon Graphics, Inc. All rights reserved.
*
* Snooping the MAC frames for if_mtr.o.
* As it uses drain(7p), it gives much less performance impact
* to the system. Also, that gives no concern regarding security.
*
*/
typedef struct {
short junk;
} SCB;
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <net/raw.h>
#include <sys/stream.h>
#include <sys/tr.h>
#include <sys/llc.h>
#include <sys/tr_user.h>
#include <sys/tcp-param.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/if_ether.h>
#include <sys/utsname.h>
#include <mtr.h>
#define MTR_MONITOR_MODE_ALL 0
#define MTR_MONITOR_MODE_EVENT_ONLY 1
int FunctionalAddressRequired = 0;
uint_t FunctionalAddressEnabled = 0;
int
main(int argc, char **argv)
{
int error = 0;
int socket_fd = -1;
int pkt_size;
int pkt_cnt, max_pkts;
int ifr_name_size;
int opt;
char *output_file = NULL;
struct sockaddr_raw sr;
struct ifreq ifr;
tr_drain_t tr_drain_pkt;
struct tm *tm;
struct utsname utsname;
char msg[MAX_MSG_SIZE];
if( Begin(argc, argv, REAL_ROOT_REQUIRED) != NO_ERROR ){
goto done;
}
if( uname(&utsname) < 0 ){
Perror("uname()");
} else {
if( !strcmp(utsname.machine, "IP32") &&
!strncmp(utsname.release, "6.3", 3) ){
FunctionalAddressRequired = 1;
}
}
DumpMode = 0;
while( (opt = getopt(argc, argv, "faDi:o:")) != -1 ){
switch(opt){
case 'f':
FunctionalAddressRequired = 1;
break;
case 'a':
DumpMode |= DUMP_TR_ALL_EVENTS;
break;
case 'D':
DebugMode = 1;
break;
case 'i':
Interface = optarg;
break;
case 'o':
output_file = optarg;
break;
default:
break;
} /* switch */
}
if( Interface == NULL || strncmp(Interface, "mtr", strlen("mtr")) ){
sprintf(msg, "interface \"%s\" not correct!",
Interface ? Interface : "");
Log(LOG_ERR, msg);
error = 10;
goto done;
}
ifr_name_size = min(sizeof(ifr.ifr_name), (strlen(Interface) + 1));
if( DebugMode ){
Log(LOG_DEBUG,"socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN).");
}
if( (socket_fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN)) == -1){
Perror("socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN)");
error = 1;
goto done;
}
bzero(&sr, sizeof(sr));
sr.sr_family = AF_RAW;
sr.sr_port = TR_PORT_MAC; /* MAC frames, excluding LLC */
strncpy(sr.sr_ifname, Interface, sizeof(sr.sr_ifname));
if( DebugMode ){
sprintf(msg, "bind(%d, %d.%d.%s, %d).",
socket_fd, sr.sr_family, sr.sr_port,
sr.sr_ifname, sizeof(sr));
Log(LOG_DEBUG, msg);
}
if( bind(socket_fd, &sr, sizeof(sr)) == -1 ){
Perror("bind()");
error = 2;
goto done;
}
signal(SIGHUP, sig_handler);
signal(SIGTERM, sig_handler);
signal(SIGALRM, sig_handler);
signal(SIGINT, sig_handler);
if( DebugMode ){
sprintf(msg, "signal_handler enabled for %d, %d, %d, %d.",
SIGHUP, SIGTERM, SIGALRM, SIGINT);
Log(LOG_DEBUG, msg);
}
if( FunctionalAddressRequired ){
FunctionalAddressEnabled =
(TR_FUNCTIONAL_ADDR_REM | TR_FUNCTIONAL_ADDR_CRS);
bzero((char *)&ifr, sizeof(ifr));
strncpy(ifr.ifr_name, Interface, ifr_name_size);
ifr.ifr_dstaddr.sa_family = AF_RAW;
*(uint_t *)ifr.ifr_dstaddr.sa_data =
(uint_t)(TR_FUNCTIONAL_ADDR_REM |
TR_FUNCTIONAL_ADDR_CRS);
if( DebugMode ){
sprintf(msg,
"ioctl(%d, SIOC_MTR_ADDFUNC, %s.%d.%d).",
socket_fd,
ifr.ifr_name,
ifr.ifr_dstaddr.sa_family,
*(uint_t *)ifr.ifr_dstaddr.sa_data);
Log(LOG_DEBUG, msg);
}
if( ioctl(socket_fd, SIOC_MTR_ADDFUNC, &ifr) == -1 ){
Perror("ioctl(SIOC_MTR_ADDFUNC)");
FunctionalAddressEnabled = 0;
error = 31;
goto done;
}
}
pkt_size = sizeof(tr_drain_t);
if( DebugMode ){
sprintf(msg, "setsockopt(%d, %d, %d, 0x%x(%d), %d).",
socket_fd, SOL_SOCKET, SO_RCVBUF,
(char *)&pkt_size, pkt_size, sizeof(pkt_size));
Log(LOG_DEBUG, msg);
}
if( setsockopt(socket_fd, SOL_SOCKET, SO_RCVBUF, (char *)&pkt_size,
sizeof(pkt_size)) == -1 ){
Perror("setsockopt(SOL_SOCKET, SO_RCVBUF)");
error = 3;
goto done;
}
if( output_file != NULL ){
if( DebugMode ){
sprintf(msg, "freopen(%s, %s, stdout).", output_file, "wb+");
Log(LOG_DEBUG, msg);
}
if( freopen(output_file, "wb+", stdout) == NULL ){
Perror("freopen(output_file)");
error = 33;
goto done;
}
setbuf(stdout, NULL);
}
for( pkt_cnt = 0;; pkt_cnt++){
bzero(&tr_drain_pkt, sizeof(tr_drain_pkt));
if( (pkt_size = read(socket_fd, (char *)&tr_drain_pkt,
sizeof(tr_drain_t))) == -1 ){
Perror("read()");
if( errno == EINTR && GotSignal )break;
error = 20;
goto done;
} else if(pkt_size == 0) {
sprintf(msg, "got EOF from %d -> exit.", socket_fd);
Log(LOG_INFO, msg);
goto done;
} else {
dump_snoop_hdr( pkt_cnt, pkt_size, "mtrmonitor",
Interface, &tr_drain_pkt.sh);
dump_mac_pkt( (TR_MAC *)&tr_drain_pkt,
(TR_MACMV *)tr_drain_pkt.data, pkt_size,
(sizeof(TR_MAC) + TR_MAC_HEADER_PAD_SIZE +
sizeof(struct snoopheader)),
Interface, pkt_cnt);
}
} /* while() */
done:
if( FunctionalAddressEnabled ){
bzero((char *)&ifr, sizeof(ifr));
strncpy(ifr.ifr_name, Interface, ifr_name_size);
ifr.ifr_dstaddr.sa_family = AF_RAW;
*(uint_t *)ifr.ifr_dstaddr.sa_data = FunctionalAddressEnabled;
if( DebugMode ){
sprintf(msg,
"mtrmonitor: debug: "
"ioctl(%d, SIOC_MTR_DELFUNC, "
"%s.%d.%d).",
socket_fd,
ifr.ifr_name,
ifr.ifr_dstaddr.sa_family,
*(uint_t *)ifr.ifr_dstaddr.sa_data);
Log(LOG_DEBUG, msg);
}
if( ioctl(socket_fd, SIOC_MTR_DELFUNC, &ifr) == -1 ){
Perror("ioctl(SIOC_MTR_DELFUNC)");
}
FunctionalAddressEnabled = 0;
}
if( socket_fd != -1 )close(socket_fd);
exit( error );
} /* main() */