GPLization banner introduced to *.[hc] files
[sip-router] / test / udp_flood_disc.c
1 /* $Id$ */
2 /*
3  *
4  * Copyright (C) 2001-2003 Fhg Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <netdb.h>
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <fcntl.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #ifdef __linux__
43 #include <linux/types.h>
44 #include <linux/errqueue.h>
45 #endif
46
47
48 static char *id="$Id$";
49 static char *version="udp_flood_disc 0.1";
50 static char* help_msg="\
51 Usage: udp_flood -f file -d address -p port -c count [-v]\n\
52 Options:\n\
53     -f file       file with the content of the udp packet (max 65k)\n\
54     -d address    destination address\n\
55     -p port       destination port\n\
56     -c count      number of packets to be sent\n\
57     -v            increase verbosity level\n\
58     -V            version number\n\
59     -h            this help message\n\
60 ";
61
62 #define BUF_SIZE 65535
63
64
65 int main (int argc, char** argv)
66 {
67         int fd;
68         int sock;
69         char c;
70         int n,r;
71         char* tmp;
72         char* buf[BUF_SIZE];
73         struct hostent* he;
74         struct sockaddr_in addr;
75         
76         int count;
77         int verbose;
78         char *fname;
79         char *dst;
80         int port;
81 #ifdef __linux__
82         int optval;
83 #endif
84         
85         /* init */
86         count=0;
87         verbose=0;
88         fname=0;
89         dst=0;
90         port=0;
91
92         opterr=0;
93         while ((c=getopt(argc,argv, "f:c:d:p:vhV"))!=-1){
94                 switch(c){
95                         case 'f':
96                                 fname=optarg;
97                                 break;
98                         case 'v':
99                                 verbose++;
100                                 break;
101                         case 'd':
102                                 dst=optarg;
103                                 break;
104                         case 'p':
105                                 port=strtol(optarg, &tmp, 10);
106                                 if ((tmp==0)||(*tmp)){
107                                         fprintf(stderr, "bad port number: -p %s\n", optarg);
108                                         goto error;
109                                 }
110                                 break;
111                         case 'c':
112                                 count=strtol(optarg, &tmp, 10);
113                                 if ((tmp==0)||(*tmp)){
114                                         fprintf(stderr, "bad count: -c %s\n", optarg);
115                                         goto error;
116                                 }
117                                 break;
118                         case 'V':
119                                 printf("version: %s\n", version);
120                                 printf("%s\n",id);
121                                 exit(0);
122                                 break;
123                         case 'h':
124                                 printf("version: %s\n", version);
125                                 printf("%s", help_msg);
126                                 exit(0);
127                                 break;
128                         case '?':
129                                 if (isprint(optopt))
130                                         fprintf(stderr, "Unknown option `-%c´\n", optopt);
131                                 else
132                                         fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
133                                 goto error;
134                         case ':':
135                                 fprintf(stderr, "Option `-%c´ requires an argument.\n",
136                                                 optopt);
137                                 goto error;
138                                 break;
139                         default:
140                                         abort();
141                 }
142         }
143         
144         /* check if all the required params are present */
145         if (fname==0){
146                 fprintf(stderr, "Missing -f file\n");
147                 exit(-1);
148         }
149         if (dst==0){
150                 fprintf(stderr, "Missing destination (-d ...)\n");
151                 exit(-1);
152         }
153         if(port==0){
154                 fprintf(stderr, "Missing port number (-p port)\n");
155                 exit(-1);
156         }else if(port<0){
157                 fprintf(stderr, "Invalid port number (-p %d)\n", port);
158                 exit(-1);
159         }
160         if(count==0){
161                 fprintf(stderr, "Missing packet count (-c number)\n");
162                 exit(-1);
163         }else if(count<0){
164                 fprintf(stderr, "Invalid packet count (-c %d)\n", count);
165                 exit(-1);
166         }
167         
168         /* open packet file */
169         fd=open(fname, O_RDONLY);
170         if (fd<0){
171                 fprintf(stderr, "ERROR: loading packet-file(%s): %s\n", fname,
172                                 strerror(errno));
173                 goto error;
174         }
175         n=read(fd, buf, BUF_SIZE);
176         if (n<0){
177                 fprintf(stderr, "ERROR: reading file(%s): %s\n", fname,
178                                 strerror(errno));
179                 goto error;
180         }
181         if (verbose) printf("read %d bytes from file %s\n", n, fname);
182         close(fd);
183
184         /* resolve destination */
185         he=gethostbyname(dst);
186         if (he==0){
187                 fprintf(stderr, "ERROR: could not resolve %s\n", dst);
188                 goto error;
189         }
190         /* open socket*/
191         addr.sin_family=he->h_addrtype;
192         addr.sin_port=htons(port);
193         memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
194         
195         sock = socket(he->h_addrtype, SOCK_DGRAM, 0);
196         if (sock==-1){
197                 fprintf(stderr, "ERROR: socket: %s\n", strerror(errno));
198                 goto error;
199         }
200 #ifdef __linux__
201         /* enable error receiving on unconnected sockets*/
202         optval=1;
203         if(setsockopt(sock,SOL_IP,IP_RECVERR,(void*)&optval,sizeof(optval))==-1){
204                 fprintf(stderr, "Error: setsockopt: %s\n", strerror(errno));
205                 exit(1);
206         }
207 #endif
208
209
210         /* flood loop */
211         for (r=0; r<count; r++){
212                 if ((verbose>1)&&(r%1000))  putchar('.');
213                 if (sendto(sock,buf, n, 0, (struct sockaddr*) &addr, sizeof(addr))==-1)
214                 {
215                         fprintf(stderr, "Error: send: %s\n",  strerror(errno));
216                         exit(1);
217                 }
218         }
219         printf("\n%d packets sent, %d bytes each => total %d bytes\n",
220                         count, n, n*count);
221
222         close(sock);
223         exit(0);
224
225 error:
226         exit(-1);
227 }