00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <errno.h>
00037 #include <string.h>
00038 #include <ctype.h>
00039 #include <netdb.h>
00040 #include <unistd.h>
00041 #include <sys/types.h>
00042 #include <fcntl.h>
00043 #include <sys/socket.h>
00044 #include <netinet/in.h>
00045 #include <netinet/tcp.h>
00046 #ifdef USE_SCTP
00047 #include <netinet/sctp.h>
00048 #endif
00049 #include <arpa/inet.h>
00050 #include <signal.h>
00051
00052
00053 static char *id="$Id$";
00054 static char *version="protoflood 0.3";
00055 static char* help_msg="\
00056 Usage: udp_flood -f file -d address -p port -c count [-v]\n\
00057 Options:\n\
00058 -f file file with the content of the udp packet (max 65k)\n\
00059 -d address destination address\n\
00060 -p port destination port\n\
00061 -c count number of packets to be sent\n\
00062 -s usec microseconds to sleep before sending \"throttle\" packets\n\
00063 -t throttle number of packets to send before sleeping\n\
00064 -r sleep randomly up to -s usec packets (see -s) \n\
00065 -T use tcp instead of udp \n\
00066 -S use sctp instead of udp \n\
00067 -1 use sctp in one to one mode \n\
00068 -n no tcp connection number \n\
00069 -R close the tcp connections with RST (SO_LINGER) \n\
00070 -v increase verbosity level\n\
00071 -V version number\n\
00072 -h this help message\n\
00073 ";
00074
00075 #define BUF_SIZE 65535
00076
00077
00078 enum protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_SCTP };
00079
00080 int main (int argc, char** argv)
00081 {
00082 int fd;
00083 int sock;
00084 char c;
00085 int n,r;
00086 char* tmp;
00087 char buf[BUF_SIZE];
00088 struct hostent* he;
00089 struct sockaddr_in addr;
00090
00091 int count;
00092 int verbose;
00093 char *fname;
00094 char *dst;
00095 int port;
00096 unsigned long usec;
00097 int throttle;
00098 int random_sleep;
00099 enum protos proto;
00100 int sctp_o2o;
00101 int tcp_rst;
00102 int con_no;
00103 int t;
00104 struct linger t_linger;
00105 int k;
00106 int err;
00107
00108
00109 count=1;
00110 verbose=0;
00111 fname=0;
00112 dst="127.0.0.1";
00113 port=5060;
00114 usec=0;
00115 throttle=0;
00116 random_sleep=0;
00117 proto=PROTO_UDP;
00118 tcp_rst=0;
00119 con_no=1;
00120 sctp_o2o=0;
00121 err=0;
00122
00123 opterr=0;
00124 while ((c=getopt(argc,argv, "f:c:d:p:s:t:n:rTS1RvhV"))!=-1){
00125 switch(c){
00126 case 'f':
00127 fname=optarg;
00128 break;
00129 case 'v':
00130 verbose++;
00131 break;
00132 case 'd':
00133 dst=optarg;
00134 break;
00135 case 'p':
00136 port=strtol(optarg, &tmp, 10);
00137 if ((tmp==0)||(*tmp)){
00138 fprintf(stderr, "bad port number: -p %s\n", optarg);
00139 goto error;
00140 }
00141 break;
00142 case 'c':
00143 count=strtol(optarg, &tmp, 10);
00144 if ((tmp==0)||(*tmp)){
00145 fprintf(stderr, "bad count: -c %s\n", optarg);
00146 goto error;
00147 }
00148 break;
00149 case 's':
00150 usec=strtol(optarg, &tmp, 10);
00151 if ((tmp==0)||(*tmp)){
00152 fprintf(stderr, "bad count: -c %s\n", optarg);
00153 goto error;
00154 }
00155 break;
00156 case 't':
00157 throttle=strtol(optarg, &tmp, 10);
00158 if ((tmp==0)||(*tmp)){
00159 fprintf(stderr, "bad count: -c %s\n", optarg);
00160 goto error;
00161 }
00162 break;
00163 case 'n':
00164 con_no=strtol(optarg, &tmp, 10);
00165 if ((tmp==0)||(*tmp)||(con_no<1)){
00166 fprintf(stderr, "bad count: -c %s\n", optarg);
00167 goto error;
00168 }
00169 break;
00170 case 'r':
00171 random_sleep=1;
00172 break;
00173 case 'T':
00174 proto=PROTO_TCP;
00175 break;
00176 case 'S':
00177 #ifdef USE_SCTP
00178 proto=PROTO_SCTP;
00179 #else
00180 fprintf(stderr, "sctp not supported (recompile with "
00181 "-DUSE_SCTP)\n");
00182 goto error;
00183 #endif
00184 break;
00185 case '1':
00186 sctp_o2o=1;
00187 break;
00188 case 'R':
00189 tcp_rst=1;
00190 break;
00191 case 'V':
00192 printf("version: %s\n", version);
00193 printf("%s\n",id);
00194 exit(0);
00195 break;
00196 case 'h':
00197 printf("version: %s\n", version);
00198 printf("%s", help_msg);
00199 exit(0);
00200 break;
00201 case '?':
00202 if (isprint(optopt))
00203 fprintf(stderr, "Unknown option `-%c´\n", optopt);
00204 else
00205 fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
00206 goto error;
00207 case ':':
00208 fprintf(stderr, "Option `-%c´ requires an argument.\n",
00209 optopt);
00210 goto error;
00211 break;
00212 default:
00213 abort();
00214 }
00215 }
00216
00217
00218 if (fname==0){
00219 fprintf(stderr, "Missing -f file\n");
00220 exit(-1);
00221 }
00222 if (dst==0){
00223 fprintf(stderr, "Missing destination (-d ...)\n");
00224 exit(-1);
00225 }
00226 if(port==0){
00227 fprintf(stderr, "Missing port number (-p port)\n");
00228 exit(-1);
00229 }else if(port<0){
00230 fprintf(stderr, "Invalid port number (-p %d)\n", port);
00231 exit(-1);
00232 }
00233 if(count==0){
00234 fprintf(stderr, "Missing packet count (-c number)\n");
00235 exit(-1);
00236 }else if(count<0){
00237 fprintf(stderr, "Invalid packet count (-c %d)\n", count);
00238 exit(-1);
00239 }
00240 if (proto==PROTO_UDP || (proto==PROTO_SCTP && !sctp_o2o)) con_no=1;
00241
00242
00243 if (signal(SIGPIPE, SIG_IGN)==SIG_ERR){
00244 fprintf(stderr, "failed to ignore SIGPIPE: %s\n", strerror(errno));
00245 exit(-1);
00246 }
00247
00248
00249 fd=open(fname, O_RDONLY);
00250 if (fd<0){
00251 fprintf(stderr, "ERROR: loading packet-file(%s): %s\n", fname,
00252 strerror(errno));
00253 goto error;
00254 }
00255 n=read(fd, buf, BUF_SIZE);
00256 if (n<0){
00257 fprintf(stderr, "ERROR: reading file(%s): %s\n", fname,
00258 strerror(errno));
00259 goto error;
00260 }
00261 if (verbose) printf("read %d bytes from file %s\n", n, fname);
00262 close(fd);
00263
00264
00265 he=gethostbyname(dst);
00266 if (he==0){
00267 fprintf(stderr, "ERROR: could not resolve %s\n", dst);
00268 goto error;
00269 }
00270
00271 addr.sin_family=he->h_addrtype;
00272 addr.sin_port=htons(port);
00273 #ifdef HAVE_SOCKADDR_SA_LEN
00274 addr.sin_len=sizeof(struct sockaddr_in);
00275 #endif
00276 memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
00277
00278 for (k=0; k<con_no; k++){
00279 switch(proto){
00280 case PROTO_UDP:
00281 sock = socket(he->h_addrtype, SOCK_DGRAM, 0);
00282 break;
00283 case PROTO_TCP:
00284 sock = socket(he->h_addrtype, SOCK_STREAM, 0);
00285 break;
00286 #ifdef USE_SCTP
00287 case PROTO_SCTP:
00288 sock = socket(he->h_addrtype,
00289 sctp_o2o?SOCK_STREAM:SOCK_SEQPACKET,
00290 IPPROTO_SCTP);
00291 break;
00292 #endif
00293 default:
00294 fprintf(stderr, "BUG: unkown proto %d\n", proto);
00295 goto error;
00296 }
00297 if (sock==-1){
00298 fprintf(stderr, "ERROR: socket: %s\n", strerror(errno));
00299 goto error;
00300 }
00301 if (proto==PROTO_TCP){
00302 t=1;
00303 if (setsockopt(sock, IPPROTO_TCP , TCP_NODELAY, &t, sizeof(t))<0){
00304 fprintf(stderr, "ERROR: could not disable Nagle: %s\n",
00305 strerror(errno));
00306 }
00307 if (tcp_rst){
00308 t_linger.l_onoff=1;
00309 t_linger.l_linger=0;
00310 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &t_linger,
00311 sizeof(t_linger))<0){
00312 fprintf(stderr, "ERROR: could not set SO_LINGER: %s\n",
00313 strerror(errno));
00314 }
00315 }
00316 }
00317 #ifdef USE_SCTP
00318 else if (proto==PROTO_SCTP){
00319 t=1;
00320 if (setsockopt(sock, IPPROTO_SCTP, SCTP_NODELAY, &t, sizeof(t))<0){
00321 fprintf(stderr, "ERROR: could not disable Nagle: %s\n",
00322 strerror(errno));
00323 }
00324 }
00325 #endif
00326
00327 if (
00328 #ifdef USE_SCTP
00329 (proto!=PROTO_SCTP || sctp_o2o) &&
00330 #endif
00331 (connect(sock, (struct sockaddr*) &addr,
00332 sizeof(struct sockaddr))!=0)){
00333 fprintf(stderr, "ERROR: connect: %s\n", strerror(errno));
00334 goto error;
00335 }
00336
00337
00338
00339 t=throttle;
00340 for (r=0; r<count; r++){
00341 if ((verbose>1)&&((r%1000)==999)){ putchar('.'); fflush(stdout); }
00342 #ifdef USE_SCTP
00343 if (proto==PROTO_SCTP && !sctp_o2o){
00344 if (sctp_sendmsg(sock, buf, n, (struct sockaddr*) &addr,
00345 sizeof(struct sockaddr), 0, SCTP_UNORDERED,
00346 0, 0, 0)==-1){
00347 fprintf(stderr, "Error(%d): send: %s\n", err,
00348 strerror(errno));
00349 err++;;
00350 }
00351 }else
00352 #endif
00353 {
00354 if (send(sock, buf, n, 0)==-1) {
00355 fprintf(stderr, "Error(%d): send: %s\n", err,
00356 strerror(errno));
00357 err++;;
00358 }
00359 }
00360 if (usec){
00361 t--;
00362 if (t==0){
00363 usleep(random_sleep?
00364 (unsigned long)((double)usec*rand()/RAND_MAX):usec);
00365 t=throttle;
00366 }
00367 }
00368 }
00369
00370 close(sock);
00371 if ((verbose) && (k%1000==999)) { putchar('#'); fflush(stdout); }
00372 }
00373 if (proto==PROTO_TCP || proto==PROTO_SCTP){
00374 printf("\n%d packets sent on %d %s connections (%d on each of them),"
00375 " %d bytes each => total %d bytes\n",
00376 count*con_no-err, con_no, (proto==PROTO_TCP)?"tcp":"sctp",
00377 count, n,
00378 (con_no*count-err)*n);
00379 }else{
00380 printf("\n%d packets sent, %d bytes each => total %d bytes\n",
00381 count-err, n, n*(count-err));
00382 }
00383 if (err) printf("%d errors\n", err);
00384 exit(0);
00385
00386 error:
00387 fprintf(stderr, "exiting due to error (%s)\n", strerror(errno));
00388 exit(-1);
00389 }