udp_flood_disc.c

00001 /* $Id$ */
00002 /*
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of ser, a free SIP server.
00007  *
00008  * ser is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * For a license to use the ser software under conditions
00014  * other than those described here, or to purchase support for this
00015  * software, please contact iptel.org by e-mail at the following addresses:
00016  *    info@iptel.org
00017  *
00018  * ser is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License 
00024  * along with this program; if not, write to the Free Software 
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  */
00027 
00028 
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <errno.h>
00033 #include <string.h>
00034 #include <ctype.h>
00035 #include <netdb.h>
00036 #include <unistd.h>
00037 #include <sys/types.h>
00038 #include <fcntl.h>
00039 #include <sys/socket.h>
00040 #include <netinet/in.h>
00041 #include <arpa/inet.h>
00042 #ifdef __linux__
00043 #include <linux/types.h>
00044 #include <linux/errqueue.h>
00045 #endif
00046 
00047 
00048 static char *id="$Id$";
00049 static char *version="udp_flood_disc 0.1";
00050 static char* help_msg="\
00051 Usage: udp_flood -f file -d address -p port -c count [-v]\n\
00052 Options:\n\
00053     -f file       file with the content of the udp packet (max 65k)\n\
00054     -d address    destination address\n\
00055     -p port       destination port\n\
00056     -c count      number of packets to be sent\n\
00057     -v            increase verbosity level\n\
00058     -V            version number\n\
00059     -h            this help message\n\
00060 ";
00061 
00062 #define BUF_SIZE 65535
00063 
00064 
00065 int main (int argc, char** argv)
00066 {
00067         int fd;
00068         int sock;
00069         char c;
00070         int n,r;
00071         char* tmp;
00072         char* buf[BUF_SIZE];
00073         struct hostent* he;
00074         struct sockaddr_in addr;
00075         
00076         int count;
00077         int verbose;
00078         char *fname;
00079         char *dst;
00080         int port;
00081 #ifdef __linux__
00082         int optval;
00083 #endif
00084         
00085         /* init */
00086         count=0;
00087         verbose=0;
00088         fname=0;
00089         dst=0;
00090         port=0;
00091 
00092         opterr=0;
00093         while ((c=getopt(argc,argv, "f:c:d:p:vhV"))!=-1){
00094                 switch(c){
00095                         case 'f':
00096                                 fname=optarg;
00097                                 break;
00098                         case 'v':
00099                                 verbose++;
00100                                 break;
00101                         case 'd':
00102                                 dst=optarg;
00103                                 break;
00104                         case 'p':
00105                                 port=strtol(optarg, &tmp, 10);
00106                                 if ((tmp==0)||(*tmp)){
00107                                         fprintf(stderr, "bad port number: -p %s\n", optarg);
00108                                         goto error;
00109                                 }
00110                                 break;
00111                         case 'c':
00112                                 count=strtol(optarg, &tmp, 10);
00113                                 if ((tmp==0)||(*tmp)){
00114                                         fprintf(stderr, "bad count: -c %s\n", optarg);
00115                                         goto error;
00116                                 }
00117                                 break;
00118                         case 'V':
00119                                 printf("version: %s\n", version);
00120                                 printf("%s\n",id);
00121                                 exit(0);
00122                                 break;
00123                         case 'h':
00124                                 printf("version: %s\n", version);
00125                                 printf("%s", help_msg);
00126                                 exit(0);
00127                                 break;
00128                         case '?':
00129                                 if (isprint(optopt))
00130                                         fprintf(stderr, "Unknown option `-%c´\n", optopt);
00131                                 else
00132                                         fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
00133                                 goto error;
00134                         case ':':
00135                                 fprintf(stderr, "Option `-%c´ requires an argument.\n",
00136                                                 optopt);
00137                                 goto error;
00138                                 break;
00139                         default:
00140                                         abort();
00141                 }
00142         }
00143         
00144         /* check if all the required params are present */
00145         if (fname==0){
00146                 fprintf(stderr, "Missing -f file\n");
00147                 exit(-1);
00148         }
00149         if (dst==0){
00150                 fprintf(stderr, "Missing destination (-d ...)\n");
00151                 exit(-1);
00152         }
00153         if(port==0){
00154                 fprintf(stderr, "Missing port number (-p port)\n");
00155                 exit(-1);
00156         }else if(port<0){
00157                 fprintf(stderr, "Invalid port number (-p %d)\n", port);
00158                 exit(-1);
00159         }
00160         if(count==0){
00161                 fprintf(stderr, "Missing packet count (-c number)\n");
00162                 exit(-1);
00163         }else if(count<0){
00164                 fprintf(stderr, "Invalid packet count (-c %d)\n", count);
00165                 exit(-1);
00166         }
00167         
00168         /* open packet file */
00169         fd=open(fname, O_RDONLY);
00170         if (fd<0){
00171                 fprintf(stderr, "ERROR: loading packet-file(%s): %s\n", fname,
00172                                 strerror(errno));
00173                 goto error;
00174         }
00175         n=read(fd, buf, BUF_SIZE);
00176         if (n<0){
00177                 fprintf(stderr, "ERROR: reading file(%s): %s\n", fname,
00178                                 strerror(errno));
00179                 goto error;
00180         }
00181         if (verbose) printf("read %d bytes from file %s\n", n, fname);
00182         close(fd);
00183 
00184         /* resolve destination */
00185         he=gethostbyname(dst);
00186         if (he==0){
00187                 fprintf(stderr, "ERROR: could not resolve %s\n", dst);
00188                 goto error;
00189         }
00190         /* open socket*/
00191         addr.sin_family=he->h_addrtype;
00192         addr.sin_port=htons(port);
00193         memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
00194         
00195         sock = socket(he->h_addrtype, SOCK_DGRAM, 0);
00196         if (sock==-1){
00197                 fprintf(stderr, "ERROR: socket: %s\n", strerror(errno));
00198                 goto error;
00199         }
00200 #ifdef __linux__
00201         /* enable error receiving on unconnected sockets*/
00202         optval=1;
00203         if(setsockopt(sock,SOL_IP,IP_RECVERR,(void*)&optval,sizeof(optval))==-1){
00204                 fprintf(stderr, "Error: setsockopt: %s\n", strerror(errno));
00205                 exit(1);
00206         }
00207 #endif
00208 
00209 
00210         /* flood loop */
00211         for (r=0; r<count; r++){
00212                 if ((verbose>1)&&(r%1000))  putchar('.');
00213                 if (sendto(sock,buf, n, 0, (struct sockaddr*) &addr, sizeof(addr))==-1)
00214                 {
00215                         fprintf(stderr, "Error: send: %s\n",  strerror(errno));
00216                         exit(1);
00217                 }
00218         }
00219         printf("\n%d packets sent, %d bytes each => total %d bytes\n",
00220                         count, n, n*count);
00221 
00222         close(sock);
00223         exit(0);
00224 
00225 error:
00226         exit(-1);
00227 }