1 /*********************************************************************
2  * DBS: Distributed Benchmark System
3  * Copyright (c) 1995, 1996, 1997 Yukio Murayama
4  * Copyright (c) 1995, 1996, 1997 Nara Institute of Science and Technology
5  * All rights reserved.
6  *
7  * Permission to use, copy, modify and distribute this software and its
8  * documentation is hereby granted, provided only with the following
9  * conditions are satisfied:
10  *
11  * 1. Both the copyright notice and this permission notice appear in
12  *    all copies of the software, derivative works or modified versions,
13  *    and any portions thereof, and that both notices appear in
14  *    supporting documentation.
15  * 2. All advertising materials mentioning features or use of this
16  *    software must display the following acknowledgement:
17  *      This product includes software developed by Nara Institute of
18  *      Science and Technology and its contributors.
19  * 3. Neither the name of Nara Institute of Science and Technology nor
20  *    the names of its contributors may be used to endorse or promote
21  *    products derived from this software without specific prior written
22  *    permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND NARA
25  * INSTITUTE OF SCIENCE AND TECHNOLOGY DISCLAIMS ANY LIABILITY OF
26  * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
27  * THIS SOFTWARE. ALSO, THERE IS NO WARRANTY IMPLIED OR OTHERWISE,
28  * NOR IS SUPPORT PROVIDED.
29  *
30  * Feedback of the results generated from any improvements or
31  * extensions made to this software would be much appreciated.
32  * Any such feedback should be sent to:
33  *
34  *  Yukio Murayama
35  *  E-mail:  <yukio-m@is.aist-nara.ac.jp>
36  *  URL:     <http://shika.aist-nara.ac.jp/member/yukio-m/index.html>
37  *  Address: Graduate School of Information Science,
38  *           Nara Institute of Science and Technology,
39  *           Takayama 8916-5, Ikoma, Nara, Japan
40  *
41  * Nara Institute of Science and Technology has the rights to
42  * redistribute these changes.
43  *********************************************************************/
44 /*****************************************************************
45  * Distributed Benchmark System
46  * DBS Daemon
47  * $Revision: 1.25 $
48  * $Date: 1997/07/11 00:54:04 $
49  * $Author: yukio-m $
50  *****************************************************************/
51 
52 #define DBSD
53 
54 #ifdef HAVE_SYS_PARAM_H
55 #include <sys/param.h>
56 #endif
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <sys/types.h>
61 #include <sys/wait.h>
62 #include <sys/stat.h>
63 #include <sys/socket.h>
64 #include <sys/time.h>
65 #include <time.h>
66 #include <signal.h>
67 #include <netinet/in.h>
68 #include <sys/resource.h>
69 #include <netdb.h>
70 #include <unistd.h>
71 #include <arpa/inet.h>
72 #include <errno.h>
73 #include <math.h>
74 
75 #include <sys/param.h>
76 
77 #ifdef SIGTSTP
78 #include <sys/file.h>
79 #include <sys/ioctl.h>
80 #endif
81 
82 #if defined(__svr4__)
83 #include <sys/fcntl.h>
84 #endif
85 
86 #if (!defined(BSD) || (BSD < 199306))
87 #include <malloc.h>
88 #endif
89 
90 #include "dbs.h"
91 #include "dbs_net.h"
92 #include "dbsd.h"
93 #include "record.h"
94 
95 #define CLOSE(FD) if((FD)!=-1 && close(FD)!=0){shutdown(FD, 1+1);}
96 #define SHUTDOWN(FD) if((FD)!=-1) shutdown(FD, 1+1)
97 
98 void dbsd                __P((int argc, char *argv[]));
99 
100 void reset_time          __P((struct dbsd_param *cmd, struct timeval origin_time));
101 void pre_proc            __P((struct dbsd_param *cmd, struct record *rd, struct record *rd2, struct tcp_trace *rt, char **data));
102 void pre_proc2           __P((struct dbsd_param *cmd, struct record *rd, struct record *rd2, struct tcp_trace *rt, char **data));
103 void post_proc           __P((struct dbsd_param *cmd, struct record *rd, struct record *rd2, struct tcp_trace *rt, char **data));
104 void receive_origin_time __P((int fd, struct timeval *origin_time));
105 void recv_command        __P((int fd, struct dbsd_param *dbsd_cmd));
106 void recv_traffic        __P((int fd, struct dbsd_traffic *traffic, int n));
107 
108 int exec_cmd            __P((struct dbsd_param *cmd, struct record *rd, struct record *rd2, struct tcp_trace *rt, char **data));
109 
110 void send_status         __P((int fd, int n, char *msg));
111 void send_result         __P((int fd, struct record rd, struct timeval origin_time, char *debug_msg));
112 void send_tcp_trace      __P((int fd, struct tcp_trace rt, struct timeval origin_time));
113 
114 void getaddr             __P((struct assosiation *a, struct sockaddr_in *d_address, struct sockaddr_in *b_address));
115 void setaddr             __P((int fd, struct assosiation *a));
116 int recv_command2        __P((int fd));
117 
118 void safe_exit_int       __P((int signo));
119 void safe_exit_pip       __P((int signo));
120 void safe_exit_alm       __P((int signo));
121 void safe_exit_urg       __P((int signo));
122 void safe_exit_bug       __P((int signo));
123 void reaper              __P((void));
124 void help                __P((char *prog));
125 
126 int no_daemon=0;
127 int yes_daemon=0;
128 int fd=-1, sockfd=-1;
129 struct dbsd_param cmd;
130 
131 /*****************************************************************
132  * MAIN
133  *****************************************************************/
main(argc,argv)134 void main(argc, argv)
135 int argc;
136 char *argv[];
137 {
138     char *myname;
139 
140     if ((myname = strrchr(*argv, '/')) == NULL)
141 	myname = *argv;
142     else
143 	++myname;
144 
145     if (strcmp(myname, "dbsd") == 0) {
146 	dbsd(argc, argv);
147     } else {
148 	fprintf(stderr, "What is '%s'?\n", myname);
149 	exit(1);
150     }
151 
152     exit(0);
153 }
154 
155 /*****************************************************************
156  * Distribute Benchimark Daemon   Main Routine
157  *****************************************************************/
dbsd(argc,argv)158 void dbsd(argc, argv)
159 int argc;
160 char *argv[];
161 {
162     struct assosiation a;
163     struct sockaddr_in serv_addr, cmd_addr, tmp_addr;
164     struct record    rd;
165     struct record    rd2;
166     struct tcp_trace rt;
167     struct timeval origin_time;
168     struct timeval current_time;
169     struct timezone tzp;
170     struct servent *sp;
171     int port, addrlen;
172     int pid = -1;
173     int one = 1;
174     int ch;
175     char localhost[MAXHOSTNAME];
176     char cmdhost[256];
177     char msg[CHAR_ARRAY];
178     char *data;
179     extern char *optarg;
180     extern int optind, opterr;
181 
182     cmd.fd = -1;
183 
184     strcpy(cmdhost, "");
185 
186     if ((sp = getservbyname("dbs", "tcp")) != NULL)
187 	port = (int)ntohs((u_short)sp->s_port);
188     else
189 	port = DEFAULT_PORT;
190 
191     while ((ch = getopt(argc, argv, "dDh:sp:v")) != EOF) {
192 	switch(ch) {
193 	  case 'p':    /* -p: Port Number */
194 	    port = atoi(optarg);
195 	    break;
196 	  case 'h':    /* -h: Acceptable Control Host */
197 	    strcpy(cmdhost, optarg);
198 	    break;
199 	  case 'd':    /* -d: DEBUG MODE */
200 	    debug++;       /* Grobal Variable over dbsd modules */
201 	    break;
202 	  case 's':    /* -s: running single process for DEBUGGER */
203 	    no_daemon++;   /* Grobal Variable */
204 	    break;
205 	  case 'D':    /* -D: DBSD are booted by inetd */
206 	    yes_daemon++;      /* Grobal Variable */
207 	    break;
208 	  case 'v':    /* -v: show version */
209 	  default:
210 	    help(argv[0]);
211 	    exit(1);
212 	}
213     }
214 
215     if (yes_daemon>=1)
216 	debug = 0;
217 
218     DEBUGMSG2(1, fprintf(stderr, "debug level = %d\n", debug));
219 
220     signal(SIGINT,  safe_exit_int);
221     signal(SIGPIPE, safe_exit_pip);
222     signal(SIGSEGV, safe_exit_bug);
223     signal(SIGBUS,  safe_exit_bug);
224     signal(SIGSYS,  safe_exit_bug);
225 
226 /*
227     if (gethostname(localhost, MAXHOSTNAME-1) == -1) {
228         DEBUGMSG2(1, perror("gethostname"));
229         safe_exit(ABNORMAL, "DBSD.gethostname", strerror(errno));
230     }
231 */
232     strcpy(localhost,"");
233 
234     strcpy(a.dsthostname, cmdhost);
235     strcpy(a.srchostname, localhost);
236     a.source_port = (u_short)port;
237     a.dest_port   = (u_short)0;
238 
239     getaddr(&a, &tmp_addr, &serv_addr);
240 
241     if (yes_daemon == 0) {
242 	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
243 	if ((sockfd=socket(serv_addr.sin_family, SOCK_STREAM, 0)) < 0) {
244 	    DEBUGMSG2(1, perror("socket"));
245 	    safe_exit(SOCKET, "DBSD.soket", strerror(errno));
246 	}
247 
248 	if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
249 	    DEBUGMSG2(1, perror("bind"));
250 	    safe_exit(BIND, "DBSD.bind", strerror(errno));
251 	}
252 
253 	listen(sockfd, LISTEN_NUM);
254 	addrlen = sizeof(cmd_addr);
255 
256 	DEBUGMSG2(1, fprintf(stderr, "DBS Daemon Version %s is Starting.\n", DBS_VERSION));
257 
258 	signal(SIGCHLD, (void *)reaper);
259 
260 	while (1) {
261 	    fd=-1;
262 	    if ((fd = accept(sockfd, (struct sockaddr *)&cmd_addr, &addrlen)) < 0) {
263 		if (errno == EINTR) {
264 		    continue;
265 		} else {
266 		    DEBUGMSG2(1, perror("accept"));
267 		    safe_exit(ACCEPT, "DBSD.accept", strerror(errno));
268 		}
269 	    }
270 
271 	    DEBUGMSG(1, "Connection is established.\n");
272 
273 	    if (no_daemon == 0) {
274 		if ((pid = fork()) < 0) {
275 		    DEBUGMSG2(1, perror("fork"));
276 		    safe_exit(FORK, "DBSD.fork", strerror(errno));
277 		}
278 
279 		if (pid == 0) {
280 		    close(sockfd);
281 		    break;
282 		} else {
283 		    close(fd);
284 		}
285 	    } else {
286 		close(sockfd);
287 		break;
288 	    }
289 	}
290     } else {
291 	fd = 0;
292     }
293 
294     if(fcntl(fd, F_SETOWN, getpid()) < 0) {
295         DEBUGMSG2(1, perror("fcntl(F_SETOWN)"));
296 	safe_exit(ABNORMAL, "DBSD.fctl(F_SETOWN)", strerror(errno));
297     }
298 
299     signal(SIGURG, safe_exit_urg);
300     signal(SIGALRM, safe_exit_alm);
301 
302     DEBUGMSG(1, "DBSD Accept\n");
303 
304     if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) < 0)
305 	/* NULL */;
306 
307     /*****                     *****
308      *****  DBSD Main routine  *****
309      *****                     *****/
310 
311     /*
312      *   Check Command Host.
313      */
314     setaddr(fd, &a);
315     if (strcmp(cmdhost,"") != 0 && a.dest_address != tmp_addr.sin_addr.s_addr) {
316         DEBUGMSG(1, "DBSD: Command Host access denyed");
317 	safe_exit(ACCESSDENY, "DBSD", "Command Host Access denyed");
318     }
319     /*
320      *  Receive Command.
321      */
322     alarm(60);
323     recv_command(fd, &cmd);
324     if ((cmd.traffic = (struct dbsd_traffic *)malloc(sizeof(struct dbsd_traffic) * cmd.traffic_n)) == NULL) {
325         DEBUGMSG2(1, perror("malloc"));
326 	safe_exit(MALLOC, "DBSD.malloc(traffic)", strerror(errno));
327     }
328 
329     alarm(60);
330     recv_traffic(fd, cmd.traffic, cmd.traffic_n);
331 
332     DEBUGMSG(1, "RECV COMMAND: Normal END.\n");
333 
334     /*
335      *  Pre-Process1.
336      *
337      * Memory Allocation
338      * Socket Bind
339      * Socket Option
340      */
341 
342     alarm(60);
343     pre_proc(&cmd, &rd, &rd2, &rt, &data);
344     DEBUGMSG(1, "PRE PROC: Normal END.\n");
345     /*
346      * Send Status (Ready).
347      */
348     gettimeofday(&current_time, &tzp);
349     sprintf(msg, "%d.%06d", current_time.tv_sec, current_time.tv_usec % 1000000);
350 
351     send_status(fd, NORMAL, msg);
352     DEBUGMSG(1, "SEND STATUS: Normal END.\n");
353 
354     /*
355      *  Pre-Process2.
356      *  Server Accept
357      */
358     alarm(60);
359     pre_proc2(&cmd, &rd, &rd2, &rt, &data);
360 
361     /*
362      * Receive Origin Time.
363      * Set Start Time
364      */
365     alarm(60);
366     receive_origin_time(fd, &origin_time);
367     DEBUGMSG(5, "RECV START TIME: Normal END.\n");
368     reset_time(&cmd, origin_time);
369 
370     /*
371      *   DBS Measurement start.
372      *   Execute Command
373      *   Data Transfer and Measurement
374      */
375     {
376 	int status;
377 	alarm(0);
378 	status = exec_cmd(&cmd, &rd, &rd2, &rt, &data);
379 	DEBUGMSG(5, "EXEC CMD: Normal END.\n");
380 
381 	/*
382 	 *   Receive Command1.
383 	 */
384 	signal(SIGALRM, safe_exit_alm);
385 	alarm(360);
386 	if (recv_command2(fd) == ABNORMAL) {
387 	    DEBUGMSG(1, "KILLED by DBSC.\n");
388 	    exit (1);
389 	}
390 
391 	/*
392 	 *  Send Status (Result).
393 	 */
394 	if (status == ON) {
395 	    send_status(fd, NORMAL, "*Time Out*");
396 	} else {
397 	    send_status(fd, NORMAL, "");
398 	}
399 	DEBUGMSG(1, "SEND STATUS: Normal END.\n");
400     }
401 
402     /*
403      *   Receive Command2.
404      */
405     alarm(360);
406     if (recv_command2(fd) == ABNORMAL) {
407 	DEBUGMSG(1, "KILLED by DBSC.\n");
408 	exit (1);
409     }
410 
411     /*
412      *  Send Results
413      *  Send TCP_Trace
414      */
415     alarm(360);
416     DEBUGMSG(1, "Sending Results...\n");
417     if (cmd.connection_mode == AFTER)
418 	send_result(fd, rd2, origin_time, "SEND CONNECTION.");
419 
420     alarm(360);
421     send_result(fd, rd, origin_time, "SEND RESULT.....");
422     if(cmd.tcp_trace == ON)
423 	send_tcp_trace(fd, rt, origin_time);
424     DEBUGMSG(1, "SEND RESULT: Normal END\n");
425     close(fd);
426 
427     /*
428      * Post Process
429      * Memory Free
430      */
431     alarm(360);
432     post_proc(&cmd, &rd, &rd2, &rt, &data);
433     DEBUGMSG(1, "POST PROC: Normal END.\n");
434 
435     /*
436      *  DBS Normal End
437      */
438     alarm(0);
439     DEBUGMSG(1, "DBSD Child process is end.\n");
440     exit(0);
441 }
442 
443 /*****************************************************************
444  * Sub Routine
445  *****************************************************************/
446 /*
447  * Reset wait_at time
448  */
reset_time(cmd,origin_time)449 void reset_time(cmd, origin_time)
450 struct dbsd_param *cmd;
451 struct timeval origin_time;
452 {
453     /*scan_cmd[i].total_size = total_size(send_traffic, &scan_cmd);*/
454     timeval_add(&(cmd->start_time), &origin_time);
455     DEBUGMSG2(4, fprintf(stderr, "start time (%12d %12d)\n", cmd->start_time.tv_sec, cmd->start_time.tv_usec));
456     timeval_add(&(cmd->end_time),   &origin_time);
457     DEBUGMSG2(4, fprintf(stderr, "end time   (%12d %12d)\n", cmd->end_time.tv_sec, cmd->end_time.tv_usec));
458 }
459 
460 /*
461  *  Pre-Process1.
462  *
463  * Memory Allocation
464  * Socket Bind
465  * Socket Option
466  */
pre_proc(cmd,rd,rd2,rt,data)467 void pre_proc(cmd, rd, rd2, rt, data)
468 struct dbsd_param *cmd;
469 struct record *rd;
470 struct record *rd2;
471 struct tcp_trace *rt;
472 char **data;
473 {
474     int packet_stream, max_message, pattern_number, pattern_size;
475     int record_buff;
476     int m, i;
477 
478 
479     /*
480      * Socket Inisialize
481      */
482     if (cmd->assosiation.transport == TCP) {
483 	if (cmd->serverflg == CLIENT) {
484 	    tcp_init_client(&cmd->assosiation, cmd);
485 
486 	    if (cmd->connection_mode == BEFORE && cmd->tcp_trace == ON) {
487 		init_so_debug(rt, &cmd->assosiation, TA_OUTPUT, cmd->connection_mode);
488 	    }
489 	} else if(cmd->serverflg == SERVER) {
490 	    tcp_init_server(&cmd->assosiation, cmd);
491 	} else {
492 	    DEBUGMSG2(1, fprintf(stderr,"cmd->serverflg=%d Error\n", cmd->serverflg));
493 	    safe_exit(INTERNALERROR, "DBSD.Serverflg", "");
494 	}
495     } else if (cmd->assosiation.transport == UDP) {
496 	if (cmd->sendflg == SEND) {
497 	    udp_init(&cmd->assosiation, cmd);
498 	} else if(cmd->sendflg == RECEIVE) {
499 	    udp_init(&cmd->assosiation, cmd);
500 	} else {
501 	    DEBUGMSG2(1, fprintf(stderr, "cmd->sendflg=%d Error\n", cmd->sendflg));
502 	    safe_exit(INTERNALERROR, "DBSD.Sendflg", "");
503 	}
504     } else {
505 	DEBUGMSG2(1, fprintf(stderr, "cmd->sendflg=%d Error\n", cmd->sendflg));
506 	safe_exit(INTERNALERROR, "DBSD.transport", "");
507     }
508 
509     /*
510      * Record Buffer  Initialize
511      */
512     /* Caluculation of Buffer Size */
513     packet_stream = PACKET;
514     max_message = cmd->traffic[0].size;
515     pattern_number = 0;
516     pattern_size = 0;
517     for (i = 0; i < cmd->traffic_n; i++) {
518 	if (cmd->traffic[i].packet <= 0) {
519 	    packet_stream = STREAM;
520 	} else {
521 	    pattern_number += ((int)ceil((double)cmd->traffic[i].size/(double)cmd->traffic[i].packet));
522 	    pattern_size   += cmd->traffic[i].size;
523 	}
524 	if (cmd->traffic[i].size > max_message)
525 	    max_message = cmd->traffic[i].size;
526     }
527 
528     cmd->buf_size  = max_message;
529     cmd->recv_mode = packet_stream;
530 
531     if (cmd->sendflg == SEND) {
532 	record_buff = pattern_number*cmd->send_times;
533 	if (record_buff != cmd->total_message) {
534 	    DEBUGMSG(1, "DBSD: Traffic Pattern Error");
535 	    safe_exit(ABNORMAL, "DBSD", "Traffic Pattern Error");
536 	}
537     } else {
538 	if ((packet_stream == STREAM || cmd->assosiation.transport == UDP) && cmd->record_buff > 0)
539 	    record_buff = cmd->record_buff;
540 	else if (cmd->assosiation.transport == UDP)
541 	    record_buff = cmd->total_message;
542 	else if (cmd->assosiation.transport == TCP && packet_stream != STREAM)
543 	    if (pattern_size >= 0)
544 		record_buff = (cmd->total_size/pattern_size + 1)*pattern_number;
545 	    else {
546 		DEBUGMSG(1, "DBSD: DBSC's Command Error");
547 		safe_exit(ABNORMAL, "pattern_size <= 0", "");
548 	    }
549 	else if (cmd->assosiation.transport == TCP && packet_stream == STREAM)
550 	    if (cmd->sock_opt.mss > 0)
551 		record_buff = (cmd->total_size/cmd->sock_opt.mss)+ cmd->total_message;
552 	    else
553 		record_buff = (cmd->total_size/ 512 )+ cmd->total_message;
554 	else {
555 	    DEBUGMSG(1, "DBSD: pre-process error");
556 	    safe_exit(INTERNALERROR, "DBSD.Pre-Process", "");
557 	}
558     }
559 
560     m = record_buff * sizeof(struct record_d); /* (XXX don't remove + 1.) (XXX But REMOVED) */
561 
562     rd->d    = (struct record_d *)malloc(m);
563     rd->size = record_buff;
564     rd->n    = 0;
565 
566     DEBUGMSG2(2, fprintf(stderr,"Malloc [%3d * %4d] = [%6d]byte for RECORD.\n",(int)sizeof(struct record_d),record_buff,m));
567 
568     if (rd->d == NULL) {
569         DEBUGMSG2(1, perror("malloc"));
570 	safe_exit(MALLOC, "DBSD.malloc(record_buff)", strerror(errno));
571     }
572     if (cmd->connection_mode == AFTER) {
573 	record_buff = 5;
574 	m = record_buff * sizeof(struct record_d); /* (XXXdon't remove +1XXXREMOVED) */
575 	rd2->d    = (struct record_d *)malloc(5);
576 	rd2->size = record_buff;
577 	rd2->n    = 0;
578 
579 	if (rd->d == NULL) {
580 	    DEBUGMSG2(1, perror("malloc"));
581 	    safe_exit(MALLOC, "DBSD.malloc(connection)", strerror(errno));
582 	}
583 
584 	DEBUGMSG2(2, fprintf(stderr,"Malloc [%3d * %4d] = [%6d]byte for RECORD2.\n",(int)sizeof(struct record_d),record_buff,m));
585     } else {
586 	rd2->d    = NULL;
587 	rd2->size = 0;
588 	rd2->n    = 0;
589     }
590 
591     /*
592      * TCP Trace Initialize
593      */
594     if (cmd->tcp_trace == ON) {
595 #ifdef TCP_NDEBUG
596 	if (cmd->trace_buff > 1)
597 	    record_buff = cmd->trace_buff;
598 	else if( cmd->sock_opt.mss > 0)
599 	    record_buff = (cmd->total_size/cmd->sock_opt.mss)*2 + cmd->total_message; /* XXX */
600 	else
601 	    record_buff = (cmd->total_size/512)*2 + cmd->total_message; /* XXX */
602 
603 	m = record_buff * sizeof(struct tcp_debug);
604 
605 	rt->d    = (struct tcp_debug *)malloc(m);
606 	rt->size = record_buff;
607 	rt->n    = 0;
608 /*	rt->p    = 0;*/
609 
610 	if (rt->d == NULL) {
611 	    DEBUGMSG2(1, perror("malloc"));
612 	    safe_exit(MALLOC, "DBSD.malloc(tcp_trace)", strerror(errno));
613 	}
614 
615 	DEBUGMSG2(2, fprintf(stderr,"Malloc [%3d * %4d] = [%6d]byte for TCP TRACE.\n",(int)sizeof(struct tcp_debug),record_buff,m));
616 #endif
617     } else {
618 	rt->d    = NULL;
619 	rt->size = 0;
620 	rt->n    = 0;
621 /*	rt->p    = 0;*/
622     }
623 
624     /*
625      * Memory Alignment
626      */
627     DEBUGMSG(2, "MALLOC OF BUFFER : Normal END.\n");
628     if ((*data=(char *)malloc(cmd->buf_size + cmd->mem_align + cmd->align_pad)) == NULL) {
629         DEBUGMSG2(1, perror("malloc"));
630 	safe_exit(MALLOC, "DBSD.malloc(Data Buffer)", strerror(errno));
631     }
632     if (cmd->mem_align > 0)
633 	*data = (char *)(((long)*data + (long)cmd->mem_align - 1L) & ~((long)cmd->mem_align - 1L));
634 
635     if (cmd->align_offset != 0)
636 	*data = (char *)(((long)*data + (long)cmd->align_offset));
637 
638     DEBUGMSG2(2, fprintf(stderr,"Malloc size = %d\n", cmd->buf_size));
639 }
640 
641 /*
642  *  Pre-Process2.
643  *  Server Accept
644  */
pre_proc2(cmd,rd,rd2,rt,data)645 void pre_proc2(cmd, rd, rd2, rt, data)
646 struct dbsd_param *cmd;
647 struct record *rd;
648 struct record *rd2;
649 struct tcp_trace *rt;
650 char **data;
651 {
652     /*
653      * Socket Inisialize
654      */
655 
656     if (cmd->assosiation.transport == TCP && cmd->serverflg == SERVER) {
657 	tcp_init_server2(&cmd->assosiation, cmd);
658 	if (cmd->connection_mode == BEFORE && cmd->tcp_trace == ON) {
659 	    init_so_debug(rt, &cmd->assosiation, TA_INPUT, cmd->connection_mode);
660 	}
661     }
662 }
663 
664 /*
665  * Main Process
666  * Data Transfer and Measurement
667  */
exec_cmd(cmd,rd,rd2,rt,data)668 int exec_cmd(cmd, rd, rd2, rt, data)
669 struct dbsd_param *cmd;
670 struct record    *rd;
671 struct record    *rd2;
672 struct tcp_trace *rt;
673 char **data;
674 {
675     int status = 0;
676 
677     if (cmd->assosiation.transport == TCP) {
678 	if (cmd->sendflg == SEND) {
679 	    status = tcp_send(cmd, *data, rd, rd2, rt);
680 	} else if(cmd->sendflg == RECEIVE) {
681 	    status = tcp_recv(cmd, *data, rd, rd2, rt);
682 	} else {
683 	    DEBUGMSG2(2, fprintf(stderr, "cmd->sendflg=%d Error\n", cmd->sendflg));
684 	    safe_exit(ABNORMAL, "DBSD.sendflg", "");
685 	}
686     } else {
687 	if (cmd->sendflg == SEND) {
688 	    status = udp_send(cmd, *data, rd);
689 	} else if(cmd->sendflg == RECEIVE) {
690 	    status = udp_recv(cmd, *data, rd);
691 	} else {
692 	    DEBUGMSG2(2, fprintf(stderr, "cmd->sendflg=%d Error\n", cmd->sendflg));
693 	    safe_exit(ABNORMAL, "DBSD.sendflg", "");
694 	}
695     }
696     return status;
697 }
698 
699 /*
700  * Post-Process
701  * Memory Free
702  */
post_proc(cmd,rd,rd2,rt,data)703 void post_proc(cmd, rd, rd2, rt, data)
704 struct dbsd_param *cmd;
705 struct record *rd;
706 struct record *rd2;
707 struct tcp_trace *rt;
708 char **data;
709 {
710 #define FREE(A) if((A) != (NULL)) free(A)
711     free(*data);
712     FREE(rd->d);
713     FREE(rd2->d);
714     FREE(rt->d);
715 #undef FREE
716 }
717 
718 /*****************************************************************
719  * Recv Subroutine
720  *****************************************************************/
721 /*
722  * DBSC -> DBSD
723  *
724  * Get Origin Time
725  *
726  * Origin Time = DBS time 0.0s
727  */
receive_origin_time(fd,origin_time)728 void receive_origin_time(fd, origin_time)
729 int fd;
730 struct timeval *origin_time;
731 {
732     struct timeval net_tv;
733 
734     RECV(fd, &net_tv, sizeof(struct timeval));
735 
736     origin_time->tv_sec  = ntohl((u_int)net_tv.tv_sec);
737     origin_time->tv_usec = ntohl((u_int)net_tv.tv_usec);
738 
739     DEBUGMSG2(4, fprintf(stderr,"Origin Time (%12d %12d)\n", origin_time->tv_sec, origin_time->tv_usec));
740 
741     if (origin_time->tv_sec + origin_time->tv_usec <= 0) {
742         DEBUGMSG(1, "DBSD: Time is abnormal.");
743 	safe_exit(TIME, "DBSD.origin_time", "Time is abnormal");
744     }
745 }
746 
747 /*
748  * DBSC -> DBSD
749  *
750  * Get Small Command
751  *
752  * Get Value:
753  *   NORMAL:   continue
754  *   ABNORMAL: abort
755  */
recv_command2(fd)756 int recv_command2(fd)
757 int fd;
758 {
759     int i;
760     RECV(fd, &i, sizeof(i));
761 
762     return ntohl((u_int)i);
763 }
764 
765 /*
766  * DBSC -> DBSD
767  *
768  * Get Main Command
769  *
770  */
recv_command(fd,dbsd_cmd)771 void recv_command(fd, dbsd_cmd)
772 int fd;
773 struct dbsd_param *dbsd_cmd;
774 {
775     struct net_cmd net_cmd;
776 
777     DEBUGMSG2(4, fprintf(stderr,"sizeof(struct net_cmd)=%d\n",(int)sizeof(struct net_cmd)));
778 
779     RECV(fd, &net_cmd, sizeof(struct net_cmd));
780 
781     dbsd_cmd->assosiation.transport   = (u_int)ntohl((u_int)net_cmd.transport);
782     dbsd_cmd->sendflg                 = (u_int)ntohl((u_int)net_cmd.sendflg);
783     dbsd_cmd->serverflg               = (u_int)ntohl((u_int)net_cmd.serverflg);
784     strcpy(dbsd_cmd->assosiation.dsthostname, net_cmd.dsthostname);
785     strcpy(dbsd_cmd->assosiation.srchostname, net_cmd.srchostname);
786     dbsd_cmd->assosiation.source_port = (u_short)ntohl((u_int)net_cmd.source_port);
787     dbsd_cmd->assosiation.dest_port   = (u_short)ntohl((u_int)net_cmd.dest_port);
788     dbsd_cmd->start_time.tv_sec       = (u_int)ntohl((u_int)net_cmd.start_time.tv_sec);
789     dbsd_cmd->start_time.tv_usec      = (u_int)ntohl((u_int)net_cmd.start_time.tv_usec);
790     dbsd_cmd->end_time.tv_sec         = (u_int)ntohl((u_int)net_cmd.end_time.tv_sec);
791     dbsd_cmd->end_time.tv_usec        = (u_int)ntohl((u_int)net_cmd.end_time.tv_usec);
792     dbsd_cmd->send_times              = (u_int)ntohl((u_int)net_cmd.send_times);
793     dbsd_cmd->record_buff             = (u_int)ntohl((u_int)net_cmd.record_buff);
794     dbsd_cmd->sock_opt.send_buff      = (u_int)ntohl((u_int)net_cmd.send_buff);
795     dbsd_cmd->sock_opt.recv_buff      = (u_int)ntohl((u_int)net_cmd.recv_buff);
796     dbsd_cmd->sock_opt.no_delay       = (u_int)ntohl((u_int)net_cmd.no_delay);
797     dbsd_cmd->sock_opt.mss            = (u_int)ntohl((u_int)net_cmd.mss);
798     dbsd_cmd->sock_opt.so_debug       = (u_int)ntohl((u_int)net_cmd.so_debug);
799     dbsd_cmd->tcp_trace               = (u_int)ntohl((u_int)net_cmd.tcp_trace);
800     dbsd_cmd->trace_buff              = (u_int)ntohl((u_int)net_cmd.trace_buff);
801     dbsd_cmd->traffic_n               = (u_int)ntohl((u_int)net_cmd.traffic_n);
802     dbsd_cmd->mem_align               = (u_int)ntohl((u_int)net_cmd.mem_align);
803     dbsd_cmd->align_offset            = (u_int)ntohl((u_int)net_cmd.align_offset);
804     dbsd_cmd->align_pad               = (u_int)ntohl((u_int)net_cmd.align_pad);
805     dbsd_cmd->total_size              = (u_int)ntohl((u_int)net_cmd.total_size);
806     dbsd_cmd->total_message           = (u_int)ntohl((u_int)net_cmd.total_message);
807     dbsd_cmd->connection_mode         = (u_int)ntohl((u_int)net_cmd.connection_mode);
808 
809     DEBUGMSG2(3, {
810 	fprintf(stderr, "Command Data -------------------------------------------\n");
811 	fprintf(stderr, "Destination    = %-12s %-12s\n", net_cmd.dsthostname,    dbsd_cmd->assosiation.dsthostname);
812 	fprintf(stderr, "Source         = %-12s %-12s\n", net_cmd.srchostname,    dbsd_cmd->assosiation.srchostname);
813 	fprintf(stderr, "Protocol       = %-12d %-12d\n", net_cmd.transport,      dbsd_cmd->assosiation.transport);
814 	fprintf(stderr, "Server flag    = %-12d %-12d\n", net_cmd.serverflg,      dbsd_cmd->serverflg);
815 	fprintf(stderr, "Send flag      = %-12d %-12d\n", net_cmd.sendflg,        dbsd_cmd->sendflg);
816 	fprintf(stderr, "Source Port    = %-12d %-12d\n", net_cmd.source_port,    dbsd_cmd->assosiation.source_port);
817 	fprintf(stderr, "Receive Port   = %-12d %-12d\n", net_cmd.dest_port,      dbsd_cmd->assosiation.dest_port);
818 	fprintf(stderr, "Send times     = %-12d %-12d\n", net_cmd.send_times,     dbsd_cmd->send_times);
819 	fprintf(stderr, "Send Buff      = %-12d %-12d\n", net_cmd.send_buff,      dbsd_cmd->sock_opt.send_buff);
820 	fprintf(stderr, "Receive Buff   = %-12d %-12d\n", net_cmd.recv_buff,      dbsd_cmd->sock_opt.recv_buff);
821 	fprintf(stderr, "Total Size     = %-12d %-12d\n", net_cmd.total_size,     dbsd_cmd->total_size);
822 	fprintf(stderr, "Total Message  = %-12d %-12d\n", net_cmd.total_message,  dbsd_cmd->total_message);
823 	fprintf(stderr, "So Debug       = %-12d %-12d\n", net_cmd.so_debug,       dbsd_cmd->sock_opt.so_debug);
824 	fprintf(stderr, "No Delay       = %-12d %-12d\n", net_cmd.no_delay,       dbsd_cmd->sock_opt.no_delay);
825 	fprintf(stderr, "MSS            = %-12d %-12d\n", net_cmd.mss,            dbsd_cmd->sock_opt.mss);
826 	fprintf(stderr, "TCP Trace      = %-12d %-12d\n", net_cmd.tcp_trace,      dbsd_cmd->tcp_trace);
827 	fprintf(stderr, "Traffic_N      = %-12d %-12d\n", net_cmd.traffic_n,      dbsd_cmd->traffic_n);
828 	fprintf(stderr, "Trace Buffer   = %-12d %-12d\n", net_cmd.trace_buff,     dbsd_cmd->trace_buff);
829 	fprintf(stderr, "Record Buffer  = %-12d %-12d\n", net_cmd.record_buff,    dbsd_cmd->record_buff);
830 	fprintf(stderr, "Memory Align   = %-12d %-12d\n", net_cmd.mem_align,      dbsd_cmd->mem_align);
831 	fprintf(stderr, "Align Offset   = %-12d %-12d\n", net_cmd.align_offset,   dbsd_cmd->align_offset);
832 	fprintf(stderr, "Align Pad      = %-12d %-12d\n", net_cmd.align_pad,      dbsd_cmd->align_pad);
833 	fprintf(stderr, "Connection Mode= %-12d %-12d\n", net_cmd.connection_mode,dbsd_cmd->connection_mode);
834 
835 	fprintf(stderr, "Start Time     = (%-12d, %-12d) (%-12d, %-12d)\n",
836 		net_cmd.start_time.tv_sec, net_cmd.start_time.tv_usec,
837 		dbsd_cmd->start_time.tv_sec, dbsd_cmd->start_time.tv_usec);
838 	fprintf(stderr, "End time      = (%-12d, %-12d) (%-12d, %-12d)\n",
839 		net_cmd.end_time.tv_sec,  net_cmd.end_time.tv_usec,
840 		dbsd_cmd->end_time.tv_sec, dbsd_cmd->end_time.tv_usec);
841 	fprintf(stderr, "--------------------------------------------------------\n");
842     }
843 	      ); /* <--------------------------------------------------- XXX  Don't Erase!!! */
844 
845 }
846 
847 /*
848  * DBSC -> DBSD
849  *
850  * Get Traffic Pattern
851  * {size, packet, esleep, isleep;
852  *  size, packet, esleep, isleep;
853  *    .     .       .       .
854  *    .     .       .       .
855  *    .     .       .       .    }
856  */
recv_traffic(fd,traffic,n)857 void recv_traffic(fd, traffic, n)
858 int fd;
859 struct dbsd_traffic *traffic;
860 int n;
861 {
862     int i;
863     struct net_traffic net_traffic;
864 
865     for (i=0; i<n; i++) {
866 	RECV(fd, &net_traffic, sizeof(struct net_traffic));
867 
868 	traffic[i].size           = ntohl(net_traffic.size);
869 	traffic[i].packet         = ntohl(net_traffic.packet);
870 	traffic[i].isleep.tv_sec  = ntohl(net_traffic.isleep) / 1000000;
871 	traffic[i].isleep.tv_usec = ntohl(net_traffic.isleep) % 1000000;
872 	traffic[i].esleep.tv_sec  = ntohl(net_traffic.esleep) / 1000000;
873 	traffic[i].esleep.tv_usec = ntohl(net_traffic.esleep) % 1000000;
874 
875 	traffic[i].isleep_flag = (traffic[i].isleep.tv_sec > 0) || (traffic[i].isleep.tv_usec > 0);
876 	traffic[i].esleep_flag = (traffic[i].esleep.tv_sec > 0) || (traffic[i].esleep.tv_usec > 0);
877 
878 	if (debug >= 2) {
879 	    fprintf(stderr, "Traffic Pattern ----------------------------------------\n");
880 	    fprintf(stderr, "SIZE   = %-12d %-12d\n",        net_traffic.size,   traffic[i].size);
881 	    fprintf(stderr, "PAKET  = %-12d %-12d\n",        net_traffic.packet, traffic[i].packet);
882 	    fprintf(stderr, "ESLEEP = %-12d(%-12d,%-12d)\n", net_traffic.esleep, traffic[i].esleep.tv_sec, traffic[i].esleep.tv_usec);
883 	    fprintf(stderr, "ISLEEP = %-12d(%-12d,%-12d)\n", net_traffic.isleep, traffic[i].isleep.tv_sec, traffic[i].isleep.tv_usec);
884 	    fprintf(stderr, "--------------------------------------------------------\n");
885 	}
886     }
887 }
888 
889 /*****************************************************************
890  * Send Subroutine
891  *****************************************************************/
892 
893 /*
894  * DBSD -> DBSC
895  *
896  * Send Result
897  *
898  * {(int) Number of Record, (struct record_d_net) A Record * Number of Record}
899  */
send_result(fd,rd,origin_time,debug_msg)900 void send_result(fd, rd, origin_time, debug_msg)
901 int fd;
902 struct record rd;
903 struct timeval origin_time;
904 char *debug_msg;
905 {
906     int i, net, r;
907     struct record_d_net *d = NULL;
908 
909     DEBUGMSG(2, debug_msg);
910 
911     net = htonl(rd.n);
912     send(fd, (void *)&net, sizeof(net) , 0);
913 
914     r = sizeof(struct record_d_net) * rd.n;
915 
916     DEBUGMSG2(2, fprintf(stderr,"[%3d * %4d] = [%6d]byte", (int)sizeof(struct record_d_net), rd.n, r));
917 
918     if (rd.n >= 1) {
919 	if ((d=(struct record_d_net *)malloc(r)) == NULL) {
920 	    DEBUGMSG2(1, perror("malloc"));
921 	    safe_exit(MALLOC, "DBSD.malloc(send results)", strerror(errno));
922 	}
923 	for (i=0; i < rd.n; i++) {
924 	    d[i].packet_no   = htonl(rd.d[i].packet_no);
925 	    d[i].packet_size = htonl(rd.d[i].packet_size);
926 
927 	    timeval_sub(&rd.d[i].tv, &origin_time);
928 
929 	    d[i].tv_sec   = htonl(rd.d[i].tv.tv_sec);
930 	    d[i].tv_usec  = htonl(rd.d[i].tv.tv_usec);
931 	}
932 	send(fd, (void *)d, r, 0);
933 	free(d);
934     }
935     DEBUGMSG(2, "SENT.\n");
936 }
937 
938 /*
939  * DBSD -> DBSC
940  *
941  * Send TCP Trace
942  *
943  * {(int) Number of Record, (struct tcp_trace_d_net) A Record * Number of Record}
944  */
send_tcp_trace(fd,rt,origin_time)945 void send_tcp_trace(fd, rt, origin_time)
946 int fd;
947 struct tcp_trace rt;
948 struct timeval origin_time;
949 {
950     int i, net, s, origin;
951     struct tcp_trace_d_net *d;
952 
953     DEBUGMSG(2, "SEND TCP Trace..");
954 #ifdef TCP_NDEBUG
955     net = htonl(rt.n);
956     send(fd, (void *)&net, sizeof(net) , 0);
957 
958     s = sizeof(struct tcp_trace_d_net) * rt.n;
959     DEBUGMSG2(1, fprintf(stderr,"[%3d * %4d] = [%6d]byte", (int)sizeof(struct tcp_trace_d_net), rt.n, s));
960 
961     if (rt.n >= 1) {
962 	if ((d=(struct tcp_trace_d_net *)malloc(s)) == NULL) {
963 	    DEBUGMSG(1, "DBSD:malloc(send tcp_trace) Error.");
964 	    safe_exit(MALLOC, "DBSD.malloc(send tcp_trace)", strerror(errno));
965 	}
966 	origin = (int)(((double)(origin_time.tv_sec%(24*60*60))+(double)origin_time.tv_usec/(1000.0*1000.0))*1000);
967 
968 	for (i=0; i < rt.n; i++) {
969 	    d[i].td_time      = (int)htonl((u_int)((int)ntohl((u_int)rt.d[i].td_time) - (int)origin));
970 	    d[i].td_act       = htonl((int)rt.d[i].td_act);
971 	    if (d[i].td_act == TA_INPUT) {
972 		d[i].th_seq   =   (int)htonl(rt.d[i].td_ti.ti_t.th_seq);
973 		d[i].th_ack   =   (int)htonl(rt.d[i].td_ti.ti_t.th_ack);
974 	    } else {
975 		d[i].th_seq   =   (int)rt.d[i].td_ti.ti_t.th_seq;
976 		d[i].th_ack   =   (int)rt.d[i].td_ti.ti_t.th_ack;
977 	    }
978 	    d[i].th_flags     = htonl((int)rt.d[i].td_ti.ti_t.th_flags);
979 
980 	    if (d[i].td_act == TA_INPUT) {
981 		d[i].len          = htonl((int)(rt.d[i].td_ti.ti_i.ih_len));
982 	    } else {
983 		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));
984 	    }
985 
986 	    d[i].t_state      = htonl((int)rt.d[i].td_cb.t_state);
987 	    d[i].t_rxtshift   = htonl((int)rt.d[i].td_cb.t_rxtshift);
988 	    d[i].t_rxtcur     = htonl((int)rt.d[i].td_cb.t_rxtcur);
989 	    d[i].t_dupacks    = htonl((int)rt.d[i].td_cb.t_dupacks);
990 	    d[i].t_maxseg     = htonl((int)rt.d[i].td_cb.t_maxseg);
991 /*
992 	    d[i].t_force      = htonl((int)rt.d[i].td_cb.t_force);
993 */
994 	    d[i].t_flags      = htonl((int)rt.d[i].td_cb.t_flags);
995 	    d[i].snd_una      = htonl((int)rt.d[i].td_cb.snd_una);
996 	    d[i].snd_nxt      = htonl((int)rt.d[i].td_cb.snd_nxt);
997 	    d[i].snd_wl1      = htonl((int)rt.d[i].td_cb.snd_wl1);
998 	    d[i].snd_wl2      = htonl((int)rt.d[i].td_cb.snd_wl2);
999 	    d[i].iss          = htonl((int)rt.d[i].td_cb.iss);
1000 	    d[i].snd_wnd      = htonl((int)rt.d[i].td_cb.snd_wnd);
1001 	    d[i].rcv_wnd      = htonl((int)rt.d[i].td_cb.rcv_wnd);
1002 	    d[i].rcv_nxt      = htonl((int)rt.d[i].td_cb.rcv_nxt);
1003 	    d[i].irs          = htonl((int)rt.d[i].td_cb.irs);
1004 	    d[i].rcv_adv      = htonl((int)rt.d[i].td_cb.rcv_adv);
1005 	    d[i].snd_max      = htonl((int)rt.d[i].td_cb.snd_max);
1006 	    d[i].snd_cwnd     = htonl((int)rt.d[i].td_cb.snd_cwnd);
1007 	    d[i].snd_ssthresh = htonl((int)rt.d[i].td_cb.snd_ssthresh);
1008 #if !defined(__FreeBSD_version) && !defined(__DragonFly__)
1009 	    d[i].t_idle       = htonl((int)rt.d[i].td_cb.t_idle);
1010 	    d[i].t_rtt        = htonl((int)rt.d[i].td_cb.t_rtt);
1011 #else
1012 	    d[i].t_idle       = htonl((int)rt.d[i].td_cb.t_rcvtime);
1013 	    d[i].t_rtt        = htonl((int)rt.d[i].td_cb.t_rtttime);
1014 #endif
1015 	    d[i].t_rtseq      = htonl((int)rt.d[i].td_cb.t_rtseq);
1016 	    d[i].t_srtt       = htonl((int)rt.d[i].td_cb.t_srtt);
1017 	    d[i].t_rttvar     = htonl((int)rt.d[i].td_cb.t_rttvar);
1018 /*	    d[i].t_rttmin     = htonl((int)rt.d[i].td_cb.t_rttmin);*/      /* AAA */
1019 	    d[i].max_sndwnd   = htonl((int)rt.d[i].td_cb.max_sndwnd);
1020 	}
1021 	send(fd, (void *)d, s, 0);
1022 	free(d);
1023     }
1024 #endif
1025     DEBUGMSG(2, "SENT.\n");
1026 }
1027 
1028 /*****************************************************************
1029  * Signal Handlers
1030  *****************************************************************/
1031 /*
1032  * Bye-bye Zombie!
1033  */
reaper()1034 void reaper()
1035 {
1036 /*
1037 #ifdef SYSTYPE_SVR4
1038     union wait status;
1039 #else
1040 */
1041     int status;
1042 /*
1043 #endif
1044 */
1045 
1046     while(wait3(&status, WNOHANG, (struct rusage *)0) > 0)
1047 	;
1048 }
1049 
1050 /*
1051  * Safe Exit
1052  */
safe_exit(i,msg,error)1053 void safe_exit(i, msg, error)
1054 int i;
1055 char *msg, *error;
1056 {
1057     extern int fd, sockfd;
1058 
1059     DEBUGMSG(1, "Safe Exitting....\n");
1060 
1061     if (fd != -1) {
1062 	DEBUGMSG(1, "DBSD Child process is stoped.\n");
1063 	if (*error == '\0')
1064 	    send_status(fd, i, msg);
1065 	else {
1066 	    char tmp[CHAR_ARRAY+CHAR_ARRAY+3];
1067 	    sprintf(tmp, "%s : %s", msg, error);
1068 	    send_status(fd, i, tmp);
1069 	}
1070 	SHUTDOWN(cmd.fd);
1071 	CLOSE(fd);
1072     } else {
1073 	DEBUGMSG(1, "DBSD Parent process is stoped.\n");
1074 	close(sockfd);
1075     }
1076     DEBUGMSG(1, "Program was killed.\n");
1077     exit(1);
1078 }
1079 
1080 /*
1081  * Signal Handler for SigINT
1082  */
safe_exit_int(signo)1083 void safe_exit_int(signo)
1084 int signo;
1085 {
1086     extern int fd, sockfd;
1087 
1088     DEBUGMSG(1, "Interrupting....\n");
1089 
1090     if (fd != -1) {
1091 	DEBUGMSG(1, "DBSD Child process is stoped.\n");
1092 	send_status(fd, ABNORMAL, "Interrupted");
1093 	SHUTDOWN(cmd.fd);
1094 	CLOSE(fd);
1095     } else {
1096 	DEBUGMSG(1, "DBSD Parent process is stoped.\n");
1097 	close(sockfd);
1098     }
1099     DEBUGMSG(1, "Program was killed.\n");
1100     exit(2);
1101 }
1102 
1103 /*
1104  * Signal Handler for SIGPIP
1105  */
safe_exit_pip(signo)1106 void safe_exit_pip(signo)
1107 int signo;
1108 {
1109     extern int fd, sockfd;
1110 
1111     DEBUGMSG(1, "Pipe is Broken....\n");
1112 
1113     if (fd != -1) {
1114 	DEBUGMSG(1, "DBSD Child process is stoped.\n");
1115 	send_status(fd, ABNORMAL, "Pipe is Broken");
1116 	SHUTDOWN(cmd.fd);
1117 	CLOSE(fd);
1118     } else {
1119 	DEBUGMSG(1, "DBSD Parent process is stoped.\n");
1120 	close(sockfd);
1121     }
1122     DEBUGMSG(1, "Program was killed.\n");
1123     exit(3);
1124 }
1125 
1126 /*
1127  * Signal Handler for SIGPIP
1128  */
safe_exit_alm(signo)1129 void safe_exit_alm(signo)
1130 int signo;
1131 {
1132     extern int fd, sockfd;
1133 
1134     DEBUGMSG(1, "TIME OUT\n");
1135 
1136     if (fd != -1) {
1137 	DEBUGMSG(1, "DBSD Child process is stoped.\n");
1138 	send_status(fd, ABNORMAL, "ALARM");
1139 	SHUTDOWN(cmd.fd);
1140 	CLOSE(fd);
1141     } else {
1142 	DEBUGMSG(1, "DBSD Parent process is stoped.\n");
1143 	close(sockfd);
1144     }
1145     DEBUGMSG(1, "Program was killed.\n");
1146     exit(4);
1147 }
1148 
1149 /*
1150  * Signal Handler for SIGURG (TCP urgent data was received.)
1151  */
safe_exit_urg(signo)1152 void safe_exit_urg(signo)
1153 int signo;
1154 {
1155     extern int fd, sockfd;
1156 
1157     DEBUGMSG(1, "DBSC kill Message\n");
1158 
1159     if (fd != -1) {
1160 	DEBUGMSG(1, "DBSD Child process is stoped.\n");
1161 	send_status(fd, ABNORMAL, "DBSC kill Message");
1162 	SHUTDOWN(cmd.fd);
1163 	CLOSE(fd);
1164     } else {
1165 	DEBUGMSG(1, "DBSD Parent process is stoped.\n");
1166 	close(sockfd);
1167     }
1168     DEBUGMSG(1, "Program was killed.\n");
1169     exit(5);
1170 }
1171 
1172 /****** run out from segmentation fault ******/
1173 
1174 /*
1175  * Signal Handler for Internal Bug!
1176  */
safe_exit_bug(signo)1177 void safe_exit_bug(signo)
1178 int signo;
1179 {
1180     extern int fd, sockfd;
1181     int i;
1182 
1183     signal(SIGSEGV, safe_exit_bug);
1184     signal(SIGBUS,  safe_exit_bug);
1185     signal(SIGSYS,  safe_exit_bug);
1186 
1187     DEBUGMSG(1, "DBSD Internal Error !!\n");
1188 
1189     if (fd != -1) {
1190 	DEBUGMSG(1, "DBSD Child process is stoped.\n");
1191 
1192 	switch (signo) {
1193 	  case SIGSEGV:
1194 	    send_status(fd, INTERNALERROR, "DBSD Internal Error!! Segmentation violation.\0");
1195 	    break;
1196 	  case SIGBUS:
1197 	    send_status(fd, INTERNALERROR, "DBSD Internal Error!! Bus error.\0");
1198 	    break;
1199 	  case SIGSYS:
1200 	    send_status(fd, INTERNALERROR, "DBSD Internal Error!! Bad argument to system call.\0");
1201 	    break;
1202 	}
1203 
1204 	for (i=0; i < 15; i++) {
1205 	    DEBUGMSG(1, ".");
1206 	    sleep(1);
1207 	}
1208 	send_status(fd, INTERNALERROR, "DBSD Internal Error!!");
1209 	SHUTDOWN(cmd.fd);
1210 	CLOSE(fd);
1211     } else {
1212 	DEBUGMSG(1, "DBSD Parent process is stoped.\n");
1213 	close(sockfd);
1214     }
1215 
1216     DEBUGMSG(1, "Program was killed.\n");
1217     exit(6);
1218 }
1219 
1220 /*
1221  * DBSD -> DBSC
1222  *
1223  * Send Status
1224  *
1225  * {(int)Status, (int)strlen(msg), (char *)msg}
1226  */
send_status(fd,n,msg)1227 void send_status(fd, n, msg)
1228 int fd;
1229 int n;
1230 char *msg;
1231 {
1232     int net, i;
1233 
1234     /* Error Number */
1235     net = htonl(n);
1236     send(fd, (void *)&net, sizeof(net), 0);
1237 
1238     /* Message Length */
1239     i = strlen(msg);
1240     net = htonl(i);
1241     send(fd, (void *)&net, sizeof(net) , 0);
1242 
1243     /* Message Strings */
1244     if (i > 0)
1245 	send(fd, msg, i, 0);
1246 
1247     DEBUGMSG2(2, fprintf(stderr, "%d, %i, %s\n", n, i, msg));
1248 }
1249 
1250 /*****************************************************************
1251  * Help Message
1252  *****************************************************************/
help(prog)1253 void help(prog)
1254 char *prog;
1255 {
1256     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);
1257     fprintf(stderr, "Usage: %s [-p port_number] [-d] [-D] [-v] [-h command_host] \n", prog);
1258 }
1259