/********************************************************************* * 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: * URL: * 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 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef SIGTSTP #include #include #endif #if defined(__svr4__) #include #endif #if (!defined(BSD) || (BSD < 199306)) #include #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 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); }