1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
/*
Simple discard service
This program can be used as an inetd replacement for performance testing.
License
'discard', Simple Discard Service
Copyright (C) 1999 Menno Pieters, M&I/STELVIO bv, the Netherlands
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Instructions:
To make the executable, simply make do:
gcc -o dicard discard.c
To use it, just run it as root. Telnet to port 9 to test it. I should
connect and NOT respond to anything typed.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
void discard(int sock) {
int max_fd;
unsigned long bytes;
unsigned long bytes_in;
char buf[4096];
for(;;) {
if ((bytes = read(sock, buf, sizeof(buf))) <= 0)
break;
}
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 1, sizeof(SO_REUSEADDR));
setsockopt(sock, SOL_SOCKET, SO_LINGER, 0, sizeof(SO_LINGER));
shutdown(sock, 2);
close(sock);
return;
}
void main() {
int sock = 0, newsock = 0;
struct sockaddr_in sin;
struct in_addr listenaddr;
int on = 1, aux;
if (fork()) exit(0); /* Deamon mode */
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
fprintf(stderr, "ERR: cannot create socket\n");
exit(1);
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(inet_addr("0.0.0.0"));
sin.sin_port = htons(9);
if (bind(sock, (struct sockaddr*) &sin, sizeof(sin)) < 0) {
/* helaas */
fprintf(stderr, "ERR: could not bind to socket\n");
shutdown(sock, 2);
close(sock);
exit(0);
}
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 1, sizeof(SO_REUSEADDR));
setsockopt(sock, SOL_SOCKET, SO_LINGER, 0, sizeof(SO_LINGER));
if (listen(sock, 1) < 0)
exit(2);
for(;;) {
aux = sizeof(sin);
newsock = accept(sock, (struct sockaddr*)&sin, &aux);
if (newsock < 0) {
continue;
}
if (!fork()) {
close(stdin);
close(stdout);
discard(newsock);
shutdown(sock, 2);
exit(0);
}
else {
int status;
(void) wait(&status);
close(newsock);
}
}
}
|