Tizen 2.0 Release
[framework/connectivity/bluez.git] / test / rctest.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
6  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <getopt.h>
36 #include <syslog.h>
37 #include <signal.h>
38 #include <sys/time.h>
39 #include <sys/ioctl.h>
40 #include <sys/socket.h>
41
42 #include <bluetooth/bluetooth.h>
43 #include <bluetooth/hci.h>
44 #include <bluetooth/hci_lib.h>
45 #include <bluetooth/rfcomm.h>
46 #include <bluetooth/sdp.h>
47 #include <bluetooth/sdp_lib.h>
48
49 /* Test modes */
50 enum {
51         SEND,
52         RECV,
53         RECONNECT,
54         MULTY,
55         DUMP,
56         CONNECT,
57         CRECV,
58         LSEND
59 };
60
61 static unsigned char *buf;
62
63 /* Default data size */
64 static long data_size = 127;
65 static long num_frames = -1;
66
67 /* Default number of consecutive frames before the delay */
68 static int count = 1;
69
70 /* Default delay after sending count number of frames */
71 static unsigned long delay = 0;
72
73 /* Default addr and channel */
74 static bdaddr_t bdaddr;
75 static uint16_t uuid = 0x0000;
76 static uint8_t channel = 10;
77
78 static char *filename = NULL;
79
80 static int master = 0;
81 static int auth = 0;
82 static int encrypt = 0;
83 static int secure = 0;
84 static int socktype = SOCK_STREAM;
85 static int linger = 0;
86 static int timestamp = 0;
87 static int defer_setup = 0;
88 static int priority = -1;
89
90 static float tv2fl(struct timeval tv)
91 {
92         return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0);
93 }
94
95 static uint8_t get_channel(const char *svr, uint16_t uuid)
96 {
97         sdp_session_t *sdp;
98         sdp_list_t *srch, *attrs, *rsp;
99         uuid_t svclass;
100         uint16_t attr;
101         bdaddr_t dst;
102         uint8_t channel = 0;
103         int err;
104
105         str2ba(svr, &dst);
106
107         sdp = sdp_connect(&bdaddr, &dst, SDP_RETRY_IF_BUSY);
108         if (!sdp)
109                 return 0;
110
111         sdp_uuid16_create(&svclass, uuid);
112         srch = sdp_list_append(NULL, &svclass);
113
114         attr = SDP_ATTR_PROTO_DESC_LIST;
115         attrs = sdp_list_append(NULL, &attr);
116
117         err = sdp_service_search_attr_req(sdp, srch,
118                                         SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
119         if (err)
120                 goto done;
121
122         for (; rsp; rsp = rsp->next) {
123                 sdp_record_t *rec = (sdp_record_t *) rsp->data;
124                 sdp_list_t *protos;
125
126                 if (!sdp_get_access_protos(rec, &protos)) {
127                         channel = sdp_get_proto_port(protos, RFCOMM_UUID);
128                         if (channel > 0)
129                                 break;
130                 }
131         }
132
133 done:
134         sdp_close(sdp);
135
136         return channel;
137 }
138
139 static int do_connect(const char *svr)
140 {
141         struct sockaddr_rc addr;
142         struct rfcomm_conninfo conn;
143         socklen_t optlen;
144         int sk, opt;
145
146         if (uuid != 0x0000)
147                 channel = get_channel(svr, uuid);
148
149         if (channel == 0) {
150                 syslog(LOG_ERR, "Can't get channel number");
151                 return -1;
152         }
153
154         /* Create socket */
155         sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM);
156         if (sk < 0) {
157                 syslog(LOG_ERR, "Can't create socket: %s (%d)",
158                                                         strerror(errno), errno);
159                 return -1;
160         }
161
162         /* Bind to local address */
163         memset(&addr, 0, sizeof(addr));
164         addr.rc_family = AF_BLUETOOTH;
165         bacpy(&addr.rc_bdaddr, &bdaddr);
166
167         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
168                 syslog(LOG_ERR, "Can't bind socket: %s (%d)",
169                                                         strerror(errno), errno);
170                 goto error;
171         }
172
173 #if 0
174         /* Enable SO_TIMESTAMP */
175         if (timestamp) {
176                 int t = 1;
177
178                 if (setsockopt(sk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) {
179                         syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)",
180                                                         strerror(errno), errno);
181                         goto error;
182                 }
183         }
184 #endif
185
186         /* Enable SO_LINGER */
187         if (linger) {
188                 struct linger l = { .l_onoff = 1, .l_linger = linger };
189
190                 if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) {
191                         syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)",
192                                                         strerror(errno), errno);
193                         goto error;
194                 }
195         }
196
197         /* Set link mode */
198         opt = 0;
199         if (master)
200                 opt |= RFCOMM_LM_MASTER;
201         if (auth)
202                 opt |= RFCOMM_LM_AUTH;
203         if (encrypt)
204                 opt |= RFCOMM_LM_ENCRYPT;
205         if (secure)
206                 opt |= RFCOMM_LM_SECURE;
207
208         if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) {
209                 syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)",
210                                                         strerror(errno), errno);
211                 goto error;
212         }
213
214         /* Connect to remote device */
215         memset(&addr, 0, sizeof(addr));
216         addr.rc_family = AF_BLUETOOTH;
217         str2ba(svr, &addr.rc_bdaddr);
218         addr.rc_channel = channel;
219
220         if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
221                 syslog(LOG_ERR, "Can't connect: %s (%d)",
222                                                         strerror(errno), errno);
223                 goto error;
224         }
225
226         /* Get connection information */
227         memset(&conn, 0, sizeof(conn));
228         optlen = sizeof(conn);
229
230         if (getsockopt(sk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) {
231                 syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)",
232                                                         strerror(errno), errno);
233                 //goto error;
234         }
235
236         if (priority > 0 && setsockopt(sk, SOL_SOCKET, SO_PRIORITY, &priority,
237                                                 sizeof(priority)) < 0) {
238                 syslog(LOG_ERR, "Can't set socket priority: %s (%d)",
239                                                         strerror(errno), errno);
240                 goto error;
241         }
242
243         if (getsockopt(sk, SOL_SOCKET, SO_PRIORITY, &opt, &optlen) < 0) {
244                 syslog(LOG_ERR, "Can't get socket priority: %s (%d)",
245                                                         strerror(errno), errno);
246                 goto error;
247         }
248
249         syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x, "
250                         "priority %d]", conn.hci_handle, conn.dev_class[2],
251                         conn.dev_class[1], conn.dev_class[0], opt);
252
253         return sk;
254
255 error:
256         close(sk);
257         return -1;
258 }
259
260 static void do_listen(void (*handler)(int sk))
261 {
262         struct sockaddr_rc addr;
263         struct rfcomm_conninfo conn;
264         socklen_t optlen;
265         int sk, nsk, opt;
266         char ba[18];
267
268         /* Create socket */
269         sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM);
270         if (sk < 0) {
271                 syslog(LOG_ERR, "Can't create socket: %s (%d)",
272                                                         strerror(errno), errno);
273                 exit(1);
274         }
275
276         /* Bind to local address */
277         memset(&addr, 0, sizeof(addr));
278         addr.rc_family = AF_BLUETOOTH;
279         bacpy(&addr.rc_bdaddr, &bdaddr);
280         addr.rc_channel = channel;
281
282         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
283                 syslog(LOG_ERR, "Can't bind socket: %s (%d)",
284                                                         strerror(errno), errno);
285                 goto error;
286         }
287
288         /* Set link mode */
289         opt = 0;
290         if (master)
291                 opt |= RFCOMM_LM_MASTER;
292         if (auth)
293                 opt |= RFCOMM_LM_AUTH;
294         if (encrypt)
295                 opt |= RFCOMM_LM_ENCRYPT;
296         if (secure)
297                 opt |= RFCOMM_LM_SECURE;
298
299         if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) {
300                 syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)",
301                                                         strerror(errno), errno);
302                 goto error;
303         }
304
305         /* Enable deferred setup */
306         opt = defer_setup;
307
308         if (opt && setsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP,
309                                                 &opt, sizeof(opt)) < 0) {
310                 syslog(LOG_ERR, "Can't enable deferred setup : %s (%d)",
311                                                         strerror(errno), errno);
312                 goto error;
313         }
314
315         /* Listen for connections */
316         if (listen(sk, 10)) {
317                 syslog(LOG_ERR,"Can not listen on the socket: %s (%d)",
318                                                         strerror(errno), errno);
319                 goto error;
320         }
321
322         /* Check for socket address */
323         memset(&addr, 0, sizeof(addr));
324         optlen = sizeof(addr);
325
326         if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) {
327                 syslog(LOG_ERR, "Can't get socket name: %s (%d)",
328                                                         strerror(errno), errno);
329                 goto error;
330         }
331
332         channel = addr.rc_channel;
333
334         syslog(LOG_INFO, "Waiting for connection on channel %d ...", channel);
335
336         while (1) {
337                 memset(&addr, 0, sizeof(addr));
338                 optlen = sizeof(addr);
339
340                 nsk = accept(sk, (struct sockaddr *) &addr, &optlen);
341                 if (nsk < 0) {
342                         syslog(LOG_ERR,"Accept failed: %s (%d)",
343                                                         strerror(errno), errno);
344                         goto error;
345                 }
346                 if (fork()) {
347                         /* Parent */
348                         close(nsk);
349                         continue;
350                 }
351                 /* Child */
352                 close(sk);
353
354                 /* Get connection information */
355                 memset(&conn, 0, sizeof(conn));
356                 optlen = sizeof(conn);
357
358                 if (getsockopt(nsk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) {
359                         syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)",
360                                                         strerror(errno), errno);
361                         //close(nsk);
362                         //goto error;
363                 }
364
365                 if (priority > 0 && setsockopt(sk, SOL_SOCKET, SO_PRIORITY,
366                                         &priority, sizeof(priority)) < 0) {
367                         syslog(LOG_ERR, "Can't set socket priority: %s (%d)",
368                                                 strerror(errno), errno);
369                         close(nsk);
370                         goto error;
371                 }
372
373                 optlen = sizeof(priority);
374                 if (getsockopt(nsk, SOL_SOCKET, SO_PRIORITY, &opt, &optlen) < 0) {
375                         syslog(LOG_ERR, "Can't get socket priority: %s (%d)",
376                                                         strerror(errno), errno);
377                         goto error;
378                 }
379
380                 ba2str(&addr.rc_bdaddr, ba);
381                 syslog(LOG_INFO, "Connect from %s [handle %d, "
382                                 "class 0x%02x%02x%02x, priority %d]",
383                                 ba, conn.hci_handle, conn.dev_class[2],
384                                 conn.dev_class[1], conn.dev_class[0], opt);
385
386 #if 0
387                 /* Enable SO_TIMESTAMP */
388                 if (timestamp) {
389                         int t = 1;
390
391                         if (setsockopt(nsk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) {
392                                 syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)",
393                                                         strerror(errno), errno);
394                                 goto error;
395                         }
396                 }
397 #endif
398
399                 /* Enable SO_LINGER */
400                 if (linger) {
401                         struct linger l = { .l_onoff = 1, .l_linger = linger };
402
403                         if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) {
404                                 syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)",
405                                                         strerror(errno), errno);
406                                 close(nsk);
407                                 goto error;
408                         }
409                 }
410
411                 /* Handle deferred setup */
412                 if (defer_setup) {
413                         syslog(LOG_INFO, "Waiting for %d seconds",
414                                                         abs(defer_setup) - 1);
415                         sleep(abs(defer_setup) - 1);
416
417                         if (defer_setup < 0) {
418                                 close(nsk);
419                                 goto error;
420                         }
421                 }
422
423                 handler(nsk);
424
425                 syslog(LOG_INFO, "Disconnect: %m");
426                 exit(0);
427         }
428
429         return;
430
431 error:
432         close(sk);
433         exit(1);
434 }
435
436 static void dump_mode(int sk)
437 {
438         int len;
439
440         syslog(LOG_INFO, "Receiving ...");
441         while ((len = read(sk, buf, data_size)) > 0)
442                 syslog(LOG_INFO, "Recevied %d bytes", len);
443 }
444
445 static void recv_mode(int sk)
446 {
447         struct timeval tv_beg, tv_end, tv_diff;
448         char ts[30];
449         long total;
450
451         syslog(LOG_INFO, "Receiving ...");
452
453         memset(ts, 0, sizeof(ts));
454
455         while (1) {
456                 gettimeofday(&tv_beg,NULL);
457                 total = 0;
458                 while (total < data_size) {
459                         //uint32_t sq;
460                         //uint16_t l;
461                         int r;
462
463                         if ((r = recv(sk, buf, data_size, 0)) < 0) {
464                                 if (r < 0)
465                                         syslog(LOG_ERR, "Read failed: %s (%d)",
466                                                         strerror(errno), errno);
467                                 return;
468                         }
469
470                         if (timestamp) {
471                                 struct timeval tv;
472
473                                 if (ioctl(sk, SIOCGSTAMP, &tv) < 0) {
474                                         timestamp = 0;
475                                         memset(ts, 0, sizeof(ts));
476                                 } else {
477                                         sprintf(ts, "[%ld.%ld] ",
478                                                         tv.tv_sec, tv.tv_usec);
479                                 }
480                         }
481
482 #if 0
483                         /* Check sequence */
484                         sq = btohl(*(uint32_t *) buf);
485                         if (seq != sq) {
486                                 syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq);
487                                 seq = sq;
488                         }
489                         seq++;
490
491                         /* Check length */
492                         l = btohs(*(uint16_t *) (buf + 4));
493                         if (r != l) {
494                                 syslog(LOG_INFO, "size missmatch: %d -> %d", r, l);
495                                 continue;
496                         }
497
498                         /* Verify data */
499                         for (i = 6; i < r; i++) {
500                                 if (buf[i] != 0x7f)
501                                         syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]);
502                         }
503 #endif
504                         total += r;
505                 }
506                 gettimeofday(&tv_end,NULL);
507
508                 timersub(&tv_end,&tv_beg,&tv_diff);
509
510                 syslog(LOG_INFO,"%s%ld bytes in %.2f sec, %.2f kB/s", ts, total,
511                         tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0);
512         }
513 }
514
515 static void do_send(int sk)
516 {
517         uint32_t seq;
518         int i, fd, len;
519
520         syslog(LOG_INFO,"Sending ...");
521
522         if (filename) {
523                 fd = open(filename, O_RDONLY);
524                 if (fd < 0) {
525                         syslog(LOG_ERR, "Open failed: %s (%d)",
526                                                         strerror(errno), errno);
527                         exit(1);
528                 }
529                 len = read(fd, buf, data_size);
530                 send(sk, buf, len, 0);
531                 return;
532         } else {
533                 for (i = 6; i < data_size; i++)
534                         buf[i] = 0x7f;
535         }
536
537         seq = 0;
538         while ((num_frames == -1) || (num_frames-- > 0)) {
539                 *(uint32_t *) buf = htobl(seq);
540                 *(uint16_t *) (buf + 4) = htobs(data_size);
541                 seq++;
542
543                 if (send(sk, buf, data_size, 0) <= 0) {
544                         syslog(LOG_ERR, "Send failed: %s (%d)",
545                                                         strerror(errno), errno);
546                         exit(1);
547                 }
548
549                 if (num_frames && delay && count && !(seq % count))
550                         usleep(delay);
551         }
552 }
553
554 static void send_mode(int sk)
555 {
556         do_send(sk);
557
558         syslog(LOG_INFO, "Closing channel ...");
559         if (shutdown(sk, SHUT_RDWR) < 0)
560                 syslog(LOG_INFO, "Close failed: %m");
561         else
562                 syslog(LOG_INFO, "Done");
563 }
564
565 static void reconnect_mode(char *svr)
566 {
567         while(1) {
568                 int sk = do_connect(svr);
569                 close(sk);
570         }
571 }
572
573 static void multi_connect_mode(int argc, char *argv[])
574 {
575         int i, n, sk;
576
577         while (1) {
578                 for (n = 0; n < argc; n++) {
579                         for (i = 0; i < count; i++) {
580                                 if (fork())
581                                         continue;
582
583                                 /* Child */
584                                 sk = do_connect(argv[n]);
585                                 usleep(500);
586                                 close(sk);
587                                 exit(0);
588                         }
589                 }
590                 sleep(4);
591         }
592 }
593
594 static void usage(void)
595 {
596         printf("rctest - RFCOMM testing\n"
597                 "Usage:\n");
598         printf("\trctest <mode> [options] [bdaddr]\n");
599         printf("Modes:\n"
600                 "\t-r listen and receive\n"
601                 "\t-w listen and send\n"
602                 "\t-d listen and dump incoming data\n"
603                 "\t-s connect and send\n"
604                 "\t-u connect and receive\n"
605                 "\t-n connect and be silent\n"
606                 "\t-c connect, disconnect, connect, ...\n"
607                 "\t-m multiple connects\n");
608
609         printf("Options:\n"
610                 "\t[-b bytes] [-i device] [-P channel] [-U uuid]\n"
611                 "\t[-L seconds] enabled SO_LINGER option\n"
612                 "\t[-W seconds] enable deferred setup\n"
613                 "\t[-B filename] use data packets from file\n"
614                 "\t[-N num] number of frames to send\n"
615                 "\t[-C num] send num frames before delay (default = 1)\n"
616                 "\t[-D milliseconds] delay after sending num frames (default = 0)\n"
617                 "\t[-Y priority] socket priority\n"
618                 "\t[-A] request authentication\n"
619                 "\t[-E] request encryption\n"
620                 "\t[-S] secure connection\n"
621                 "\t[-M] become master\n"
622                 "\t[-T] enable timestamps\n");
623 }
624
625 int main(int argc, char *argv[])
626 {
627         struct sigaction sa;
628         int opt, sk, mode = RECV, need_addr = 0;
629
630         bacpy(&bdaddr, BDADDR_ANY);
631
632         while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:U:B:N:MAESL:W:C:D:Y:T")) != EOF) {
633                 switch (opt) {
634                 case 'r':
635                         mode = RECV;
636                         break;
637
638                 case 's':
639                         mode = SEND;
640                         need_addr = 1;
641                         break;
642
643                 case 'w':
644                         mode = LSEND;
645                         break;
646
647                 case 'u':
648                         mode = CRECV;
649                         need_addr = 1;
650                         break;
651
652                 case 'd':
653                         mode = DUMP;
654                         break;
655
656                 case 'c':
657                         mode = RECONNECT;
658                         need_addr = 1;
659                         break;
660
661                 case 'n':
662                         mode = CONNECT;
663                         need_addr = 1;
664                         break;
665
666                 case 'm':
667                         mode = MULTY;
668                         need_addr = 1;
669                         break;
670
671                 case 'b':
672                         data_size = atoi(optarg);
673                         break;
674
675                 case 'i':
676                         if (!strncasecmp(optarg, "hci", 3))
677                                 hci_devba(atoi(optarg + 3), &bdaddr);
678                         else
679                                 str2ba(optarg, &bdaddr);
680                         break;
681
682                 case 'P':
683                         channel = atoi(optarg);
684                         break;
685
686                 case 'U':
687                         if (!strcasecmp(optarg, "spp"))
688                                 uuid = SERIAL_PORT_SVCLASS_ID;
689                         else if (!strncasecmp(optarg, "0x", 2))
690                                 uuid = strtoul(optarg + 2, NULL, 16);
691                         else
692                                 uuid = atoi(optarg);
693                         break;
694
695                 case 'M':
696                         master = 1;
697                         break;
698
699                 case 'A':
700                         auth = 1;
701                         break;
702
703                 case 'E':
704                         encrypt = 1;
705                         break;
706
707                 case 'S':
708                         secure = 1;
709                         break;
710
711                 case 'L':
712                         linger = atoi(optarg);
713                         break;
714
715                 case 'W':
716                         defer_setup = atoi(optarg);
717                         break;
718
719                 case 'B':
720                         filename = strdup(optarg);
721                         break;
722
723                 case 'N':
724                         num_frames = atoi(optarg);
725                         break;
726
727                 case 'C':
728                         count = atoi(optarg);
729                         break;
730
731                 case 'D':
732                         delay = atoi(optarg) * 1000;
733                         break;
734
735                 case 'Y':
736                         priority = atoi(optarg);
737                         break;
738
739                 case 'T':
740                         timestamp = 1;
741                         break;
742
743                 default:
744                         usage();
745                         exit(1);
746                 }
747         }
748
749         if (need_addr && !(argc - optind)) {
750                 usage();
751                 exit(1);
752         }
753
754         if (!(buf = malloc(data_size))) {
755                 perror("Can't allocate data buffer");
756                 exit(1);
757         }
758
759         memset(&sa, 0, sizeof(sa));
760         sa.sa_handler = SIG_IGN;
761         sa.sa_flags   = SA_NOCLDSTOP;
762         sigaction(SIGCHLD, &sa, NULL);
763
764         openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0);
765
766         switch (mode) {
767                 case RECV:
768                         do_listen(recv_mode);
769                         break;
770
771                 case CRECV:
772                         sk = do_connect(argv[optind]);
773                         if (sk < 0)
774                                 exit(1);
775                         recv_mode(sk);
776                         break;
777
778                 case DUMP:
779                         do_listen(dump_mode);
780                         break;
781
782                 case SEND:
783                         sk = do_connect(argv[optind]);
784                         if (sk < 0)
785                                 exit(1);
786                         send_mode(sk);
787                         break;
788
789                 case LSEND:
790                         do_listen(send_mode);
791                         break;
792
793                 case RECONNECT:
794                         reconnect_mode(argv[optind]);
795                         break;
796
797                 case MULTY:
798                         multi_connect_mode(argc - optind, argv + optind);
799                         break;
800
801                 case CONNECT:
802                         sk = do_connect(argv[optind]);
803                         if (sk < 0)
804                                 exit(1);
805                         dump_mode(sk);
806                         break;
807         }
808
809         syslog(LOG_INFO, "Exit");
810
811         closelog();
812
813         return 0;
814 }