/*********************************************************************
* DBS: Distributed Benchmark System
* Copyright (c) 1995, 1996, 1997 Yukio Murayama
* Copyright (c) 1995, 1996, 1997 Nara Institute of Science and Technology
* All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided only with the following
* conditions are satisfied:
*
* 1. Both the copyright notice and this permission notice appear in
* all copies of the software, derivative works or modified versions,
* and any portions thereof, and that both notices appear in
* supporting documentation.
* 2. All advertising materials mentioning features or use of this
* software must display the following acknowledgement:
* This product includes software developed by Nara Institute of
* Science and Technology and its contributors.
* 3. Neither the name of Nara Institute of Science and Technology nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND NARA
* INSTITUTE OF SCIENCE AND TECHNOLOGY DISCLAIMS ANY LIABILITY OF
* ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
* THIS SOFTWARE. ALSO, THERE IS NO WARRANTY IMPLIED OR OTHERWISE,
* NOR IS SUPPORT PROVIDED.
*
* Feedback of the results generated from any improvements or
* extensions made to this software would be much appreciated.
* Any such feedback should be sent to:
*
* Yukio Murayama
* E-mail: <yukio-m@is.aist-nara.ac.jp>
* URL: <http://shika.aist-nara.ac.jp/member/yukio-m/index.html>
* Address: Graduate School of Information Science,
* Nara Institute of Science and Technology,
* Takayama 8916-5, Ikoma, Nara, Japan
*
* Nara Institute of Science and Technology has the rights to
* redistribute these changes.
*********************************************************************/
/*****************************************************************
* Distributed Benchmark System
* DBS Daemon
* $Revision: 1.25 $
* $Date: 1997/07/11 00:54:04 $
* $Author: yukio-m $
*****************************************************************/
#define DBSD
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
#include <netinet/in.h>
#include <sys/resource.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
#include <math.h>
#include <sys/param.h>
#ifdef SIGTSTP
#include <sys/file.h>
#include <sys/ioctl.h>
#endif
#if defined(__svr4__)
#include <sys/fcntl.h>
#endif
#if (!defined(BSD) || (BSD < 199306))
#include <malloc.h>
#endif
#include "dbs.h"
#include "dbs_net.h"
#include "dbsd.h"
#include "record.h"
#define CLOSE(FD) if((FD)!=-1 && close(FD)!=0){shutdown(FD, 1+1);}
#define SHUTDOWN(FD) if((FD)!=-1) shutdown(FD, 1+1)
void dbsd __P((int argc, char *argv[]));
void reset_time __P((struct dbsd_param *cmd, struct timeval origin_time));
void pre_proc __P((struct dbsd_param *cmd, struct record *rd, struct record *rd2, struct tcp_trace *rt, char **data));
void pre_proc2 __P((struct dbsd_param *cmd, struct record *rd, struct record *rd2, struct tcp_trace *rt, char **data));
void post_proc __P((struct dbsd_param *cmd, struct record *rd, struct record *rd2, struct tcp_trace *rt, char **data));
void receive_origin_time __P((int fd, struct timeval *origin_time));
void recv_command __P((int fd, struct dbsd_param *dbsd_cmd));
void recv_traffic __P((int fd, struct dbsd_traffic *traffic, int n));
int exec_cmd __P((struct dbsd_param *cmd, struct record *rd, struct record *rd2, struct tcp_trace *rt, char **data));
void send_status __P((int fd, int n, char *msg));
void send_result __P((int fd, struct record rd, struct timeval origin_time, char *debug_msg));
void send_tcp_trace __P((int fd, struct tcp_trace rt, struct timeval origin_time));
void getaddr __P((struct assosiation *a, struct sockaddr_in *d_address, struct sockaddr_in *b_address));
void setaddr __P((int fd, struct assosiation *a));
int recv_command2 __P((int fd));
void safe_exit_int __P((int signo));
void safe_exit_pip __P((int signo));
void safe_exit_alm __P((int signo));
void safe_exit_urg __P((int signo));
void safe_exit_bug __P((int signo));
void reaper __P((void));
void help __P((char *prog));
int no_daemon=0;
int yes_daemon=0;
int fd=-1, sockfd=-1;
struct dbsd_param cmd;
/*****************************************************************
* MAIN
*****************************************************************/
void main(argc, argv)
int argc;
char *argv[];
{
char *myname;
if ((myname = strrchr(*argv, '/')) == NULL)
myname = *argv;
else
++myname;
if (strcmp(myname, "dbsd") == 0) {
dbsd(argc, argv);
} else {
fprintf(stderr, "What is '%s'?\n", myname);
exit(1);
}
exit(0);
}
/*****************************************************************
* Distribute Benchimark Daemon Main Routine
*****************************************************************/
void dbsd(argc, argv)
int argc;
char *argv[];
{
struct assosiation a;
struct sockaddr_in serv_addr, cmd_addr, tmp_addr;
struct record rd;
struct record rd2;
struct tcp_trace rt;
struct timeval origin_time;
struct timeval current_time;
struct timezone tzp;
struct servent *sp;
int port, addrlen;
int pid = -1;
int one = 1;
int ch;
char localhost[MAXHOSTNAME];
char cmdhost[256];
char msg[CHAR_ARRAY];
char *data;
extern char *optarg;
extern int optind, opterr;
cmd.fd = -1;
strcpy(cmdhost, "");
if ((sp = getservbyname("dbs", "tcp")) != NULL)
port = (int)ntohs((u_short)sp->s_port);
else
port = DEFAULT_PORT;
while ((ch = getopt(argc, argv, "dDh:sp:v")) != EOF) {
switch(ch) {
case 'p': /* -p: Port Number */
port = atoi(optarg);
break;
case 'h': /* -h: Acceptable Control Host */
strcpy(cmdhost, optarg);
break;
case 'd': /* -d: DEBUG MODE */
debug++; /* Grobal Variable over dbsd modules */
break;
case 's': /* -s: running single process for DEBUGGER */
no_daemon++; /* Grobal Variable */
break;
case 'D': /* -D: DBSD are booted by inetd */
yes_daemon++; /* Grobal Variable */
break;
case 'v': /* -v: show version */
default:
help(argv[0]);
exit(1);
}
}
if (yes_daemon>=1)
debug = 0;
DEBUGMSG2(1, fprintf(stderr, "debug level = %d\n", debug));
signal(SIGINT, safe_exit_int);
signal(SIGPIPE, safe_exit_pip);
signal(SIGSEGV, safe_exit_bug);
signal(SIGBUS, safe_exit_bug);
signal(SIGSYS, safe_exit_bug);
/*
if (gethostname(localhost, MAXHOSTNAME-1) == -1) {
DEBUGMSG2(1, perror("gethostname"));
safe_exit(ABNORMAL, "DBSD.gethostname", strerror(errno));
}
*/
strcpy(localhost,"");
strcpy(a.dsthostname, cmdhost);
strcpy(a.srchostname, localhost);
a.source_port = (u_short)port;
a.dest_port = (u_short)0;
getaddr(&a, &tmp_addr, &serv_addr);
if (yes_daemon == 0) {
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if ((sockfd=socket(serv_addr.sin_family, SOCK_STREAM, 0)) < 0) {
DEBUGMSG2(1, perror("socket"));
safe_exit(SOCKET, "DBSD.soket", strerror(errno));
}
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
DEBUGMSG2(1, perror("bind"));
safe_exit(BIND, "DBSD.bind", strerror(errno));
}
listen(sockfd, LISTEN_NUM);
addrlen = sizeof(cmd_addr);
DEBUGMSG2(1, fprintf(stderr, "DBS Daemon Version %s is Starting.\n", DBS_VERSION));
signal(SIGCHLD, (void *)reaper);
while (1) {
fd=-1;
if ((fd = accept(sockfd, (struct sockaddr *)&cmd_addr, &addrlen)) < 0) {
if (errno == EINTR) {
continue;
} else {
DEBUGMSG2(1, perror("accept"));
safe_exit(ACCEPT, "DBSD.accept", strerror(errno));
}
}
DEBUGMSG(1, "Connection is established.\n");
if (no_daemon == 0) {
if ((pid = fork()) < 0) {
DEBUGMSG2(1, perror("fork"));
safe_exit(FORK, "DBSD.fork", strerror(errno));
}
if (pid == 0) {
close(sockfd);
break;
} else {
close(fd);
}
} else {
close(sockfd);
break;
}
}
} else {
fd = 0;
}
if(fcntl(fd, F_SETOWN, getpid()) < 0) {
DEBUGMSG2(1, perror("fcntl(F_SETOWN)"));
safe_exit(ABNORMAL, "DBSD.fctl(F_SETOWN)", strerror(errno));
}
signal(SIGURG, safe_exit_urg);
signal(SIGALRM, safe_exit_alm);
DEBUGMSG(1, "DBSD Accept\n");
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) < 0)
/* NULL */;
/***** *****
***** DBSD Main routine *****
***** *****/
/*
* Check Command Host.
*/
setaddr(fd, &a);
if (strcmp(cmdhost,"") != 0 && a.dest_address != tmp_addr.sin_addr.s_addr) {
DEBUGMSG(1, "DBSD: Command Host access denyed");
safe_exit(ACCESSDENY, "DBSD", "Command Host Access denyed");
}
/*
* Receive Command.
*/
alarm(60);
recv_command(fd, &cmd);
if ((cmd.traffic = (struct dbsd_traffic *)malloc(sizeof(struct dbsd_traffic) * cmd.traffic_n)) == NULL) {
DEBUGMSG2(1, perror("malloc"));
safe_exit(MALLOC, "DBSD.malloc(traffic)", strerror(errno));
}
alarm(60);
recv_traffic(fd, cmd.traffic, cmd.traffic_n);
DEBUGMSG(1, "RECV COMMAND: Normal END.\n");
/*
* Pre-Process1.
*
* Memory Allocation
* Socket Bind
* Socket Option
*/
alarm(60);
pre_proc(&cmd, &rd, &rd2, &rt, &data);
DEBUGMSG(1, "PRE PROC: Normal END.\n");
/*
* Send Status (Ready).
*/
gettimeofday(¤t_time, &tzp);
sprintf(msg, "%d.%06d", current_time.tv_sec, current_time.tv_usec % 1000000);
send_status(fd, NORMAL, msg);
DEBUGMSG(1, "SEND STATUS: Normal END.\n");
/*
* Pre-Process2.
* Server Accept
*/
alarm(60);
pre_proc2(&cmd, &rd, &rd2, &rt, &data);
/*
* Receive Origin Time.
* Set Start Time
*/
alarm(60);
receive_origin_time(fd, &origin_time);
DEBUGMSG(5, "RECV START TIME: Normal END.\n");
reset_time(&cmd, origin_time);
/*
* DBS Measurement start.
* Execute Command
* Data Transfer and Measurement
*/
{
int status;
alarm(0);
status = exec_cmd(&cmd, &rd, &rd2, &rt, &data);
DEBUGMSG(5, "EXEC CMD: Normal END.\n");
/*
* Receive Command1.
*/
signal(SIGALRM, safe_exit_alm);
alarm(360);
if (recv_command2(fd) == ABNORMAL) {
DEBUGMSG(1, "KILLED by DBSC.\n");
exit (1);
}
/*
* Send Status (Result).
*/
if (status == ON) {
send_status(fd, NORMAL, "*Time Out*");
} else {
send_status(fd, NORMAL, "");
}
DEBUGMSG(1, "SEND STATUS: Normal END.\n");
}
/*
* Receive Command2.
*/
alarm(360);
if (recv_command2(fd) == ABNORMAL) {
DEBUGMSG(1, "KILLED by DBSC.\n");
exit (1);
}
/*
* Send Results
* Send TCP_Trace
*/
alarm(360);
DEBUGMSG(1, "Sending Results...\n");
if (cmd.connection_mode == AFTER)
send_result(fd, rd2, origin_time, "SEND CONNECTION.");
alarm(360);
send_result(fd, rd, origin_time, "SEND RESULT.....");
if(cmd.tcp_trace == ON)
send_tcp_trace(fd, rt, origin_time);
DEBUGMSG(1, "SEND RESULT: Normal END\n");
close(fd);
/*
* Post Process
* Memory Free
*/
alarm(360);
post_proc(&cmd, &rd, &rd2, &rt, &data);
DEBUGMSG(1, "POST PROC: Normal END.\n");
/*
* DBS Normal End
*/
alarm(0);
DEBUGMSG(1, "DBSD Child process is end.\n");
exit(0);
}
/*****************************************************************
* Sub Routine
*****************************************************************/
/*
* Reset wait_at time
*/
void reset_time(cmd, origin_time)
struct dbsd_param *cmd;
struct timeval origin_time;
{
/*scan_cmd[i].total_size = total_size(send_traffic, &scan_cmd);*/
timeval_add(&(cmd->start_time), &origin_time);
DEBUGMSG2(4, fprintf(stderr, "start time (%12d %12d)\n", cmd->start_time.tv_sec, cmd->start_time.tv_usec));
timeval_add(&(cmd->end_time), &origin_time);
DEBUGMSG2(4, fprintf(stderr, "end time (%12d %12d)\n", cmd->end_time.tv_sec, cmd->end_time.tv_usec));
}
/*
* Pre-Process1.
*
* Memory Allocation
* Socket Bind
* Socket Option
*/
void pre_proc(cmd, rd, rd2, rt, data)
struct dbsd_param *cmd;
struct record *rd;
struct record *rd2;
struct tcp_trace *rt;
char **data;
{
int packet_stream, max_message, pattern_number, pattern_size;
int record_buff;
int m, i;
/*
* Socket Inisialize
*/
if (cmd->assosiation.transport == TCP) {
if (cmd->serverflg == CLIENT) {
tcp_init_client(&cmd->assosiation, cmd);
if (cmd->connection_mode == BEFORE && cmd->tcp_trace == ON) {
init_so_debug(rt, &cmd->assosiation, TA_OUTPUT, cmd->connection_mode);
}
} else if(cmd->serverflg == SERVER) {
tcp_init_server(&cmd->assosiation, cmd);
} else {
DEBUGMSG2(1, fprintf(stderr,"cmd->serverflg=%d Error\n", cmd->serverflg));
safe_exit(INTERNALERROR, "DBSD.Serverflg", "");
}
} else if (cmd->assosiation.transport == UDP) {
if (cmd->sendflg == SEND) {
udp_init(&cmd->assosiation, cmd);
} else if(cmd->sendflg == RECEIVE) {
udp_init(&cmd->assosiation, cmd);
} else {
DEBUGMSG2(1, fprintf(stderr, "cmd->sendflg=%d Error\n", cmd->sendflg));
safe_exit(INTERNALERROR, "DBSD.Sendflg", "");
}
} else {
DEBUGMSG2(1, fprintf(stderr, "cmd->sendflg=%d Error\n", cmd->sendflg));
safe_exit(INTERNALERROR, "DBSD.transport", "");
}
/*
* Record Buffer Initialize
*/
/* Caluculation of Buffer Size */
packet_stream = PACKET;
max_message = cmd->traffic[0].size;
pattern_number = 0;
pattern_size = 0;
for (i = 0; i < cmd->traffic_n; i++) {
if (cmd->traffic[i].packet <= 0) {
packet_stream = STREAM;
} else {
pattern_number += ((int)ceil((double)cmd->traffic[i].size/(double)cmd->traffic[i].packet));
pattern_size += cmd->traffic[i].size;
}
if (cmd->traffic[i].size > max_message)
max_message = cmd->traffic[i].size;
}
cmd->buf_size = max_message;
cmd->recv_mode = packet_stream;
if (cmd->sendflg == SEND) {
record_buff = pattern_number*cmd->send_times;
if (record_buff != cmd->total_message) {
DEBUGMSG(1, "DBSD: Traffic Pattern Error");
safe_exit(ABNORMAL, "DBSD", "Traffic Pattern Error");
}
} else {
if ((packet_stream == STREAM || cmd->assosiation.transport == UDP) && cmd->record_buff > 0)
record_buff = cmd->record_buff;
else if (cmd->assosiation.transport == UDP)
record_buff = cmd->total_message;
else if (cmd->assosiation.transport == TCP && packet_stream != STREAM)
if (pattern_size >= 0)
record_buff = (cmd->total_size/pattern_size + 1)*pattern_number;
else {
DEBUGMSG(1, "DBSD: DBSC's Command Error");
safe_exit(ABNORMAL, "pattern_size <= 0", "");
}
else if (cmd->assosiation.transport == TCP && packet_stream == STREAM)
if (cmd->sock_opt.mss > 0)
record_buff = (cmd->total_size/cmd->sock_opt.mss)+ cmd->total_message;
else
record_buff = (cmd->total_size/ 512 )+ cmd->total_message;
else {
DEBUGMSG(1, "DBSD: pre-process error");
safe_exit(INTERNALERROR, "DBSD.Pre-Process", "");
}
}
m = record_buff * sizeof(struct record_d); /* (XXX don't remove + 1.) (XXX But REMOVED) */
rd->d = (struct record_d *)malloc(m);
rd->size = record_buff;
rd->n = 0;
DEBUGMSG2(2, fprintf(stderr,"Malloc [%3d * %4d] = [%6d]byte for RECORD.\n",(int)sizeof(struct record_d),record_buff,m));
if (rd->d == NULL) {
DEBUGMSG2(1, perror("malloc"));
safe_exit(MALLOC, "DBSD.malloc(record_buff)", strerror(errno));
}
if (cmd->connection_mode == AFTER) {
record_buff = 5;
m = record_buff * sizeof(struct record_d); /* (XXXdon't remove +1XXXREMOVED) */
rd2->d = (struct record_d *)malloc(5);
rd2->size = record_buff;
rd2->n = 0;
if (rd->d == NULL) {
DEBUGMSG2(1, perror("malloc"));
safe_exit(MALLOC, "DBSD.malloc(connection)", strerror(errno));
}
DEBUGMSG2(2, fprintf(stderr,"Malloc [%3d * %4d] = [%6d]byte for RECORD2.\n",(int)sizeof(struct record_d),record_buff,m));
} else {
rd2->d = NULL;
rd2->size = 0;
rd2->n = 0;
}
/*
* TCP Trace Initialize
*/
if (cmd->tcp_trace == ON) {
#ifdef TCP_NDEBUG
if (cmd->trace_buff > 1)
record_buff = cmd->trace_buff;
else if( cmd->sock_opt.mss > 0)
record_buff = (cmd->total_size/cmd->sock_opt.mss)*2 + cmd->total_message; /* XXX */
else
record_buff = (cmd->total_size/512)*2 + cmd->total_message; /* XXX */
m = record_buff * sizeof(struct tcp_debug);
rt->d = (struct tcp_debug *)malloc(m);
rt->size = record_buff;
rt->n = 0;
/* rt->p = 0;*/
if (rt->d == NULL) {
DEBUGMSG2(1, perror("malloc"));
safe_exit(MALLOC, "DBSD.malloc(tcp_trace)", strerror(errno));
}
DEBUGMSG2(2, fprintf(stderr,"Malloc [%3d * %4d] = [%6d]byte for TCP TRACE.\n",(int)sizeof(struct tcp_debug),record_buff,m));
#endif
} else {
rt->d = NULL;
rt->size = 0;
rt->n = 0;
/* rt->p = 0;*/
}
/*
* Memory Alignment
*/
DEBUGMSG(2, "MALLOC OF BUFFER : Normal END.\n");
if ((*data=(char *)malloc(cmd->buf_size + cmd->mem_align + cmd->align_pad)) == NULL) {
DEBUGMSG2(1, perror("malloc"));
safe_exit(MALLOC, "DBSD.malloc(Data Buffer)", strerror(errno));
}
if (cmd->mem_align > 0)
*data = (char *)(((long)*data + (long)cmd->mem_align - 1L) & ~((long)cmd->mem_align - 1L));
if (cmd->align_offset != 0)
*data = (char *)(((long)*data + (long)cmd->align_offset));
DEBUGMSG2(2, fprintf(stderr,"Malloc size = %d\n", cmd->buf_size));
}
/*
* Pre-Process2.
* Server Accept
*/
void pre_proc2(cmd, rd, rd2, rt, data)
struct dbsd_param *cmd;
struct record *rd;
struct record *rd2;
struct tcp_trace *rt;
char **data;
{
/*
* Socket Inisialize
*/
if (cmd->assosiation.transport == TCP && cmd->serverflg == SERVER) {
tcp_init_server2(&cmd->assosiation, cmd);
if (cmd->connection_mode == BEFORE && cmd->tcp_trace == ON) {
init_so_debug(rt, &cmd->assosiation, TA_INPUT, cmd->connection_mode);
}
}
}
/*
* Main Process
* Data Transfer and Measurement
*/
int exec_cmd(cmd, rd, rd2, rt, data)
struct dbsd_param *cmd;
struct record *rd;
struct record *rd2;
struct tcp_trace *rt;
char **data;
{
int status = 0;
if (cmd->assosiation.transport == TCP) {
if (cmd->sendflg == SEND) {
status = tcp_send(cmd, *data, rd, rd2, rt);
} else if(cmd->sendflg == RECEIVE) {
status = tcp_recv(cmd, *data, rd, rd2, rt);
} else {
DEBUGMSG2(2, fprintf(stderr, "cmd->sendflg=%d Error\n", cmd->sendflg));
safe_exit(ABNORMAL, "DBSD.sendflg", "");
}
} else {
if (cmd->sendflg == SEND) {
status = udp_send(cmd, *data, rd);
} else if(cmd->sendflg == RECEIVE) {
status = udp_recv(cmd, *data, rd);
} else {
DEBUGMSG2(2, fprintf(stderr, "cmd->sendflg=%d Error\n", cmd->sendflg));
safe_exit(ABNORMAL, "DBSD.sendflg", "");
}
}
return status;
}
/*
* Post-Process
* Memory Free
*/
void post_proc(cmd, rd, rd2, rt, data)
struct dbsd_param *cmd;
struct record *rd;
struct record *rd2;
struct tcp_trace *rt;
char **data;
{
#define FREE(A) if((A) != (NULL)) free(A)
free(*data);
FREE(rd->d);
FREE(rd2->d);
FREE(rt->d);
#undef FREE
}
/*****************************************************************
* Recv Subroutine
*****************************************************************/
/*
* DBSC -> DBSD
*
* Get Origin Time
*
* Origin Time = DBS time 0.0s
*/
void receive_origin_time(fd, origin_time)
int fd;
struct timeval *origin_time;
{
struct timeval net_tv;
RECV(fd, &net_tv, sizeof(struct timeval));
origin_time->tv_sec = ntohl((u_int)net_tv.tv_sec);
origin_time->tv_usec = ntohl((u_int)net_tv.tv_usec);
DEBUGMSG2(4, fprintf(stderr,"Origin Time (%12d %12d)\n", origin_time->tv_sec, origin_time->tv_usec));
if (origin_time->tv_sec + origin_time->tv_usec <= 0) {
DEBUGMSG(1, "DBSD: Time is abnormal.");
safe_exit(TIME, "DBSD.origin_time", "Time is abnormal");
}
}
/*
* DBSC -> DBSD
*
* Get Small Command
*
* Get Value:
* NORMAL: continue
* ABNORMAL: abort
*/
int recv_command2(fd)
int fd;
{
int i;
RECV(fd, &i, sizeof(i));
return ntohl((u_int)i);
}
/*
* DBSC -> DBSD
*
* Get Main Command
*
*/
void recv_command(fd, dbsd_cmd)
int fd;
struct dbsd_param *dbsd_cmd;
{
struct net_cmd net_cmd;
DEBUGMSG2(4, fprintf(stderr,"sizeof(struct net_cmd)=%d\n",(int)sizeof(struct net_cmd)));
RECV(fd, &net_cmd, sizeof(struct net_cmd));
dbsd_cmd->assosiation.transport = (u_int)ntohl((u_int)net_cmd.transport);
dbsd_cmd->sendflg = (u_int)ntohl((u_int)net_cmd.sendflg);
dbsd_cmd->serverflg = (u_int)ntohl((u_int)net_cmd.serverflg);
strcpy(dbsd_cmd->assosiation.dsthostname, net_cmd.dsthostname);
strcpy(dbsd_cmd->assosiation.srchostname, net_cmd.srchostname);
dbsd_cmd->assosiation.source_port = (u_short)ntohl((u_int)net_cmd.source_port);
dbsd_cmd->assosiation.dest_port = (u_short)ntohl((u_int)net_cmd.dest_port);
dbsd_cmd->start_time.tv_sec = (u_int)ntohl((u_int)net_cmd.start_time.tv_sec);
dbsd_cmd->start_time.tv_usec = (u_int)ntohl((u_int)net_cmd.start_time.tv_usec);
dbsd_cmd->end_time.tv_sec = (u_int)ntohl((u_int)net_cmd.end_time.tv_sec);
dbsd_cmd->end_time.tv_usec = (u_int)ntohl((u_int)net_cmd.end_time.tv_usec);
dbsd_cmd->send_times = (u_int)ntohl((u_int)net_cmd.send_times);
dbsd_cmd->record_buff = (u_int)ntohl((u_int)net_cmd.record_buff);
dbsd_cmd->sock_opt.send_buff = (u_int)ntohl((u_int)net_cmd.send_buff);
dbsd_cmd->sock_opt.recv_buff = (u_int)ntohl((u_int)net_cmd.recv_buff);
dbsd_cmd->sock_opt.no_delay = (u_int)ntohl((u_int)net_cmd.no_delay);
dbsd_cmd->sock_opt.mss = (u_int)ntohl((u_int)net_cmd.mss);
dbsd_cmd->sock_opt.so_debug = (u_int)ntohl((u_int)net_cmd.so_debug);
dbsd_cmd->tcp_trace = (u_int)ntohl((u_int)net_cmd.tcp_trace);
dbsd_cmd->trace_buff = (u_int)ntohl((u_int)net_cmd.trace_buff);
dbsd_cmd->traffic_n = (u_int)ntohl((u_int)net_cmd.traffic_n);
dbsd_cmd->mem_align = (u_int)ntohl((u_int)net_cmd.mem_align);
dbsd_cmd->align_offset = (u_int)ntohl((u_int)net_cmd.align_offset);
dbsd_cmd->align_pad = (u_int)ntohl((u_int)net_cmd.align_pad);
dbsd_cmd->total_size = (u_int)ntohl((u_int)net_cmd.total_size);
dbsd_cmd->total_message = (u_int)ntohl((u_int)net_cmd.total_message);
dbsd_cmd->connection_mode = (u_int)ntohl((u_int)net_cmd.connection_mode);
DEBUGMSG2(3, {
fprintf(stderr, "Command Data -------------------------------------------\n");
fprintf(stderr, "Destination = %-12s %-12s\n", net_cmd.dsthostname, dbsd_cmd->assosiation.dsthostname);
fprintf(stderr, "Source = %-12s %-12s\n", net_cmd.srchostname, dbsd_cmd->assosiation.srchostname);
fprintf(stderr, "Protocol = %-12d %-12d\n", net_cmd.transport, dbsd_cmd->assosiation.transport);
fprintf(stderr, "Server flag = %-12d %-12d\n", net_cmd.serverflg, dbsd_cmd->serverflg);
fprintf(stderr, "Send flag = %-12d %-12d\n", net_cmd.sendflg, dbsd_cmd->sendflg);
fprintf(stderr, "Source Port = %-12d %-12d\n", net_cmd.source_port, dbsd_cmd->assosiation.source_port);
fprintf(stderr, "Receive Port = %-12d %-12d\n", net_cmd.dest_port, dbsd_cmd->assosiation.dest_port);
fprintf(stderr, "Send times = %-12d %-12d\n", net_cmd.send_times, dbsd_cmd->send_times);
fprintf(stderr, "Send Buff = %-12d %-12d\n", net_cmd.send_buff, dbsd_cmd->sock_opt.send_buff);
fprintf(stderr, "Receive Buff = %-12d %-12d\n", net_cmd.recv_buff, dbsd_cmd->sock_opt.recv_buff);
fprintf(stderr, "Total Size = %-12d %-12d\n", net_cmd.total_size, dbsd_cmd->total_size);
fprintf(stderr, "Total Message = %-12d %-12d\n", net_cmd.total_message, dbsd_cmd->total_message);
fprintf(stderr, "So Debug = %-12d %-12d\n", net_cmd.so_debug, dbsd_cmd->sock_opt.so_debug);
fprintf(stderr, "No Delay = %-12d %-12d\n", net_cmd.no_delay, dbsd_cmd->sock_opt.no_delay);
fprintf(stderr, "MSS = %-12d %-12d\n", net_cmd.mss, dbsd_cmd->sock_opt.mss);
fprintf(stderr, "TCP Trace = %-12d %-12d\n", net_cmd.tcp_trace, dbsd_cmd->tcp_trace);
fprintf(stderr, "Traffic_N = %-12d %-12d\n", net_cmd.traffic_n, dbsd_cmd->traffic_n);
fprintf(stderr, "Trace Buffer = %-12d %-12d\n", net_cmd.trace_buff, dbsd_cmd->trace_buff);
fprintf(stderr, "Record Buffer = %-12d %-12d\n", net_cmd.record_buff, dbsd_cmd->record_buff);
fprintf(stderr, "Memory Align = %-12d %-12d\n", net_cmd.mem_align, dbsd_cmd->mem_align);
fprintf(stderr, "Align Offset = %-12d %-12d\n", net_cmd.align_offset, dbsd_cmd->align_offset);
fprintf(stderr, "Align Pad = %-12d %-12d\n", net_cmd.align_pad, dbsd_cmd->align_pad);
fprintf(stderr, "Connection Mode= %-12d %-12d\n", net_cmd.connection_mode,dbsd_cmd->connection_mode);
fprintf(stderr, "Start Time = (%-12d, %-12d) (%-12d, %-12d)\n",
net_cmd.start_time.tv_sec, net_cmd.start_time.tv_usec,
dbsd_cmd->start_time.tv_sec, dbsd_cmd->start_time.tv_usec);
fprintf(stderr, "End time = (%-12d, %-12d) (%-12d, %-12d)\n",
net_cmd.end_time.tv_sec, net_cmd.end_time.tv_usec,
dbsd_cmd->end_time.tv_sec, dbsd_cmd->end_time.tv_usec);
fprintf(stderr, "--------------------------------------------------------\n");
}
); /* <--------------------------------------------------- XXX Don't Erase!!! */
}
/*
* DBSC -> DBSD
*
* Get Traffic Pattern
* {size, packet, esleep, isleep;
* size, packet, esleep, isleep;
* . . . .
* . . . .
* . . . . }
*/
void recv_traffic(fd, traffic, n)
int fd;
struct dbsd_traffic *traffic;
int n;
{
int i;
struct net_traffic net_traffic;
for (i=0; i<n; i++) {
RECV(fd, &net_traffic, sizeof(struct net_traffic));
traffic[i].size = ntohl(net_traffic.size);
traffic[i].packet = ntohl(net_traffic.packet);
traffic[i].isleep.tv_sec = ntohl(net_traffic.isleep) / 1000000;
traffic[i].isleep.tv_usec = ntohl(net_traffic.isleep) % 1000000;
traffic[i].esleep.tv_sec = ntohl(net_traffic.esleep) / 1000000;
traffic[i].esleep.tv_usec = ntohl(net_traffic.esleep) % 1000000;
traffic[i].isleep_flag = (traffic[i].isleep.tv_sec > 0) || (traffic[i].isleep.tv_usec > 0);
traffic[i].esleep_flag = (traffic[i].esleep.tv_sec > 0) || (traffic[i].esleep.tv_usec > 0);
if (debug >= 2) {
fprintf(stderr, "Traffic Pattern ----------------------------------------\n");
fprintf(stderr, "SIZE = %-12d %-12d\n", net_traffic.size, traffic[i].size);
fprintf(stderr, "PAKET = %-12d %-12d\n", net_traffic.packet, traffic[i].packet);
fprintf(stderr, "ESLEEP = %-12d(%-12d,%-12d)\n", net_traffic.esleep, traffic[i].esleep.tv_sec, traffic[i].esleep.tv_usec);
fprintf(stderr, "ISLEEP = %-12d(%-12d,%-12d)\n", net_traffic.isleep, traffic[i].isleep.tv_sec, traffic[i].isleep.tv_usec);
fprintf(stderr, "--------------------------------------------------------\n");
}
}
}
/*****************************************************************
* Send Subroutine
*****************************************************************/
/*
* DBSD -> DBSC
*
* Send Result
*
* {(int) Number of Record, (struct record_d_net) A Record * Number of Record}
*/
void send_result(fd, rd, origin_time, debug_msg)
int fd;
struct record rd;
struct timeval origin_time;
char *debug_msg;
{
int i, net, r;
struct record_d_net *d = NULL;
DEBUGMSG(2, debug_msg);
net = htonl(rd.n);
send(fd, (void *)&net, sizeof(net) , 0);
r = sizeof(struct record_d_net) * rd.n;
DEBUGMSG2(2, fprintf(stderr,"[%3d * %4d] = [%6d]byte", (int)sizeof(struct record_d_net), rd.n, r));
if (rd.n >= 1) {
if ((d=(struct record_d_net *)malloc(r)) == NULL) {
DEBUGMSG2(1, perror("malloc"));
safe_exit(MALLOC, "DBSD.malloc(send results)", strerror(errno));
}
for (i=0; i < rd.n; i++) {
d[i].packet_no = htonl(rd.d[i].packet_no);
d[i].packet_size = htonl(rd.d[i].packet_size);
timeval_sub(&rd.d[i].tv, &origin_time);
d[i].tv_sec = htonl(rd.d[i].tv.tv_sec);
d[i].tv_usec = htonl(rd.d[i].tv.tv_usec);
}
send(fd, (void *)d, r, 0);
free(d);
}
DEBUGMSG(2, "SENT.\n");
}
/*
* DBSD -> DBSC
*
* Send TCP Trace
*
* {(int) Number of Record, (struct tcp_trace_d_net) A Record * Number of Record}
*/
void send_tcp_trace(fd, rt, origin_time)
int fd;
struct tcp_trace rt;
struct timeval origin_time;
{
int i, net, s, origin;
struct tcp_trace_d_net *d;
DEBUGMSG(2, "SEND TCP Trace..");
#ifdef TCP_NDEBUG
net = htonl(rt.n);
send(fd, (void *)&net, sizeof(net) , 0);
s = sizeof(struct tcp_trace_d_net) * rt.n;
DEBUGMSG2(1, fprintf(stderr,"[%3d * %4d] = [%6d]byte", (int)sizeof(struct tcp_trace_d_net), rt.n, s));
if (rt.n >= 1) {
if ((d=(struct tcp_trace_d_net *)malloc(s)) == NULL) {
DEBUGMSG(1, "DBSD:malloc(send tcp_trace) Error.");
safe_exit(MALLOC, "DBSD.malloc(send tcp_trace)", strerror(errno));
}
origin = (int)(((double)(origin_time.tv_sec%(24*60*60))+(double)origin_time.tv_usec/(1000.0*1000.0))*1000);
for (i=0; i < rt.n; i++) {
d[i].td_time = (int)htonl((u_int)((int)ntohl((u_int)rt.d[i].td_time) - (int)origin));
d[i].td_act = htonl((int)rt.d[i].td_act);
if (d[i].td_act == TA_INPUT) {
d[i].th_seq = (int)htonl(rt.d[i].td_ti.ti_t.th_seq);
d[i].th_ack = (int)htonl(rt.d[i].td_ti.ti_t.th_ack);
} else {
d[i].th_seq = (int)rt.d[i].td_ti.ti_t.th_seq;
d[i].th_ack = (int)rt.d[i].td_ti.ti_t.th_ack;
}
d[i].th_flags = htonl((int)rt.d[i].td_ti.ti_t.th_flags);
if (d[i].td_act == TA_INPUT) {
d[i].len = htonl((int)(rt.d[i].td_ti.ti_i.ih_len));
} else {
d[i].len = htonl((int)ntohs(rt.d[i].td_ti.ti_i.ih_len) - ((int)rt.d[i].td_ti.ti_t.th_off<<2));
}
d[i].t_state = htonl((int)rt.d[i].td_cb.t_state);
d[i].t_rxtshift = htonl((int)rt.d[i].td_cb.t_rxtshift);
d[i].t_rxtcur = htonl((int)rt.d[i].td_cb.t_rxtcur);
d[i].t_dupacks = htonl((int)rt.d[i].td_cb.t_dupacks);
d[i].t_maxseg = htonl((int)rt.d[i].td_cb.t_maxseg);
/*
d[i].t_force = htonl((int)rt.d[i].td_cb.t_force);
*/
d[i].t_flags = htonl((int)rt.d[i].td_cb.t_flags);
d[i].snd_una = htonl((int)rt.d[i].td_cb.snd_una);
d[i].snd_nxt = htonl((int)rt.d[i].td_cb.snd_nxt);
d[i].snd_wl1 = htonl((int)rt.d[i].td_cb.snd_wl1);
d[i].snd_wl2 = htonl((int)rt.d[i].td_cb.snd_wl2);
d[i].iss = htonl((int)rt.d[i].td_cb.iss);
d[i].snd_wnd = htonl((int)rt.d[i].td_cb.snd_wnd);
d[i].rcv_wnd = htonl((int)rt.d[i].td_cb.rcv_wnd);
d[i].rcv_nxt = htonl((int)rt.d[i].td_cb.rcv_nxt);
d[i].irs = htonl((int)rt.d[i].td_cb.irs);
d[i].rcv_adv = htonl((int)rt.d[i].td_cb.rcv_adv);
d[i].snd_max = htonl((int)rt.d[i].td_cb.snd_max);
d[i].snd_cwnd = htonl((int)rt.d[i].td_cb.snd_cwnd);
d[i].snd_ssthresh = htonl((int)rt.d[i].td_cb.snd_ssthresh);
#if !defined(__FreeBSD_version) || (__FreeBSD_version < 400009)
d[i].t_idle = htonl((int)rt.d[i].td_cb.t_idle);
d[i].t_rtt = htonl((int)rt.d[i].td_cb.t_rtt);
#else
d[i].t_idle = htonl((int)rt.d[i].td_cb.t_rcvtime);
d[i].t_rtt = htonl((int)rt.d[i].td_cb.t_rtttime);
#endif
d[i].t_rtseq = htonl((int)rt.d[i].td_cb.t_rtseq);
d[i].t_srtt = htonl((int)rt.d[i].td_cb.t_srtt);
d[i].t_rttvar = htonl((int)rt.d[i].td_cb.t_rttvar);
/* d[i].t_rttmin = htonl((int)rt.d[i].td_cb.t_rttmin);*/ /* AAA */
d[i].max_sndwnd = htonl((int)rt.d[i].td_cb.max_sndwnd);
}
send(fd, (void *)d, s, 0);
free(d);
}
#endif
DEBUGMSG(2, "SENT.\n");
}
/*****************************************************************
* Signal Handlers
*****************************************************************/
/*
* Bye-bye Zombie!
*/
void reaper()
{
/*
#ifdef SYSTYPE_SVR4
union wait status;
#else
*/
int status;
/*
#endif
*/
while(wait3(&status, WNOHANG, (struct rusage *)0) > 0)
;
}
/*
* Safe Exit
*/
void safe_exit(i, msg, error)
int i;
char *msg, *error;
{
extern int fd, sockfd;
DEBUGMSG(1, "Safe Exitting....\n");
if (fd != -1) {
DEBUGMSG(1, "DBSD Child process is stoped.\n");
if (*error == '\0')
send_status(fd, i, msg);
else {
char tmp[CHAR_ARRAY+CHAR_ARRAY+3];
sprintf(tmp, "%s : %s", msg, error);
send_status(fd, i, tmp);
}
SHUTDOWN(cmd.fd);
CLOSE(fd);
} else {
DEBUGMSG(1, "DBSD Parent process is stoped.\n");
close(sockfd);
}
DEBUGMSG(1, "Program was killed.\n");
exit(1);
}
/*
* Signal Handler for SigINT
*/
void safe_exit_int(signo)
int signo;
{
extern int fd, sockfd;
DEBUGMSG(1, "Interrupting....\n");
if (fd != -1) {
DEBUGMSG(1, "DBSD Child process is stoped.\n");
send_status(fd, ABNORMAL, "Interrupted");
SHUTDOWN(cmd.fd);
CLOSE(fd);
} else {
DEBUGMSG(1, "DBSD Parent process is stoped.\n");
close(sockfd);
}
DEBUGMSG(1, "Program was killed.\n");
exit(2);
}
/*
* Signal Handler for SIGPIP
*/
void safe_exit_pip(signo)
int signo;
{
extern int fd, sockfd;
DEBUGMSG(1, "Pipe is Broken....\n");
if (fd != -1) {
DEBUGMSG(1, "DBSD Child process is stoped.\n");
send_status(fd, ABNORMAL, "Pipe is Broken");
SHUTDOWN(cmd.fd);
CLOSE(fd);
} else {
DEBUGMSG(1, "DBSD Parent process is stoped.\n");
close(sockfd);
}
DEBUGMSG(1, "Program was killed.\n");
exit(3);
}
/*
* Signal Handler for SIGPIP
*/
void safe_exit_alm(signo)
int signo;
{
extern int fd, sockfd;
DEBUGMSG(1, "TIME OUT\n");
if (fd != -1) {
DEBUGMSG(1, "DBSD Child process is stoped.\n");
send_status(fd, ABNORMAL, "ALARM");
SHUTDOWN(cmd.fd);
CLOSE(fd);
} else {
DEBUGMSG(1, "DBSD Parent process is stoped.\n");
close(sockfd);
}
DEBUGMSG(1, "Program was killed.\n");
exit(4);
}
/*
* Signal Handler for SIGURG (TCP urgent data was received.)
*/
void safe_exit_urg(signo)
int signo;
{
extern int fd, sockfd;
DEBUGMSG(1, "DBSC kill Message\n");
if (fd != -1) {
DEBUGMSG(1, "DBSD Child process is stoped.\n");
send_status(fd, ABNORMAL, "DBSC kill Message");
SHUTDOWN(cmd.fd);
CLOSE(fd);
} else {
DEBUGMSG(1, "DBSD Parent process is stoped.\n");
close(sockfd);
}
DEBUGMSG(1, "Program was killed.\n");
exit(5);
}
/****** run out from segmentation fault ******/
/*
* Signal Handler for Internal Bug!
*/
void safe_exit_bug(signo)
int signo;
{
extern int fd, sockfd;
int i;
signal(SIGSEGV, safe_exit_bug);
signal(SIGBUS, safe_exit_bug);
signal(SIGSYS, safe_exit_bug);
DEBUGMSG(1, "DBSD Internal Error !!\n");
if (fd != -1) {
DEBUGMSG(1, "DBSD Child process is stoped.\n");
switch (signo) {
case SIGSEGV:
send_status(fd, INTERNALERROR, "DBSD Internal Error!! Segmentation violation.\0");
break;
case SIGBUS:
send_status(fd, INTERNALERROR, "DBSD Internal Error!! Bus error.\0");
break;
case SIGSYS:
send_status(fd, INTERNALERROR, "DBSD Internal Error!! Bad argument to system call.\0");
break;
}
for (i=0; i < 15; i++) {
DEBUGMSG(1, ".");
sleep(1);
}
send_status(fd, INTERNALERROR, "DBSD Internal Error!!");
SHUTDOWN(cmd.fd);
CLOSE(fd);
} else {
DEBUGMSG(1, "DBSD Parent process is stoped.\n");
close(sockfd);
}
DEBUGMSG(1, "Program was killed.\n");
exit(6);
}
/*
* DBSD -> DBSC
*
* Send Status
*
* {(int)Status, (int)strlen(msg), (char *)msg}
*/
void send_status(fd, n, msg)
int fd;
int n;
char *msg;
{
int net, i;
/* Error Number */
net = htonl(n);
send(fd, (void *)&net, sizeof(net), 0);
/* Message Length */
i = strlen(msg);
net = htonl(i);
send(fd, (void *)&net, sizeof(net) , 0);
/* Message Strings */
if (i > 0)
send(fd, msg, i, 0);
DEBUGMSG2(2, fprintf(stderr, "%d, %i, %s\n", n, i, msg));
}
/*****************************************************************
* Help Message
*****************************************************************/
void help(prog)
char *prog;
{
fprintf(stderr, "DBS Version %d.%d%s by yukio-m@is.aist-nara.ac.jp\n", DBS_MAJOR_VERSION, DBS_MINOR_VERSION, DBS_PATCH_VERSION);
fprintf(stderr, "Usage: %s [-p port_number] [-d] [-D] [-v] [-h command_host] \n", prog);
}
syntax highlighted by Code2HTML, v. 0.9.1