nanog mailing list archives

Re: some of these are worse than others


From: Paul Vixie <paul () vix com>
Date: Mon, 18 Nov 2002 22:45:39 +0000


Which signature database you use to match these or just log the 404's ?

i wrote my own.  since it's only 247 lines long, i'll include it here.

/* httpk - killer of http requests
 * vixie 05aug01 [from netperf 14jan92 [original]]
 *
 * $Id: httpk.c,v 1.5 2002/11/18 21:33:33 vixie Exp $
 */

#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

#include <sys/errno.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>

#include "inetlib.h"
#include <arpa/inet.h>

extern int optind, opterr;
extern char *optarg;

static char *host = "localhost";
static char *serv = "http";
jmp_buf timedout;
static int timelim;
struct { char *base; size_t size; } content;
static int sndbuf = 16*1024;

static void setcontent(const char *);
static void httpk(const char *, const char *);
static void timeout(int);

#define outc(Ch) \
                if (isascii(Ch) && (isprint(Ch) || Ch == '\n')) \
                        putchar(Ch); \
                else \
                        printf("\\%03o", (u_char)Ch)

static void
usage(const char *msg) {
        fprintf(stderr, "usage error: %s\n", msg);
        fprintf(stderr,
        "usage:\thttpk\t[-h host] [-s serv] [-t timelim] [-f file] [-l]\n");
        exit(1);
}

main(int argc, char **argv) {
        int c;

        while (EOF != (c = getopt(argc, argv, "h:s:t:f:l"))) {
                switch (c) {
                case 'h':
                        host = optarg;
                        break;
                case 's':
                        serv = optarg;
                        break;
                case 't':
                        timelim = atoi(optarg);
                        break;
                case 'f':
                        setcontent(optarg);
                        break;
                case 'l':
                        setlinebuf(stdout);
                        break;
                default:
                        usage("unknown option");
                }
        }
        httpk(host, serv);
}

static void
setcontent(const char *filename) {
        struct stat sb;
        int fd;
        char *cp;

        if ((fd = open(filename, O_RDONLY)) < 0) {
                perror(filename);
                exit(1);
        }
        if (fstat(fd, &sb) < 0) {
                perror("fstat");
                exit(1);
        }
        content.size = sb.st_size;
        content.base = mmap(NULL, content.size, PROT_READ, 0, fd, 0);
        if (content.base == NULL) {
                perror("mmap");
                exit(1);
        }
}

static void
httpk(const char *host, const char *serv) {
        void *sockaddr;
        int server, client, i, tsize, rsize;
        long rtt;
        struct sockaddr_in sa;
        socklen_t sa_len;
        struct timeval whenrcvd;
        struct pkt *rbuf, *tbuf;

        sockaddr = InetSockAddr(host, serv, "tcp");
        if (!sockaddr) {
                perror("InetSockAddr");
                exit(1);
        }

        server = TcpServer(sockaddr, 0);
        if (server < 0) {
                perror("TcpServer");
                exit(1);
        }

        signal(SIGALRM, timeout);
 loop:
        sa_len = sizeof sa;
        client = accept(server, (struct sockaddr *)&sa, &sa_len);
        if (client < 0) {
                if (errno == ECONNABORTED)
                        goto loop;
        } else {
                struct sockaddr_in me;
                socklen_t me_len;
                char ch, lch;
                time_t now;
                FILE *fp;
                int n, l;

                me_len = sizeof me;
                if (getsockname(client, (struct sockaddr *)&me, &me_len) < 0) {
                        perror("getsockname");
                        exit(1);
                }
                now = time(0);
                printf("src [%s].%u; ",
                       inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
                printf("dst [%s].%u; ",
                       inet_ntoa(me.sin_addr), ntohs(me.sin_port));
                printf("%s", ctime(&now));
                fp = fdopen(client, "r+");
                if (!fp) {
                        perror("fdopen");
                        close(client);
                        exit(1);
                }

                if (setjmp(timedout) != 0) {
                        printf("*TIMEOUT*\n\n");
                } else {
                        enum { out, in, num } state;
                        int conlen_p = 0;
                        u_long conlen;

                        if (timelim != 0)
                                alarm(timelim);
                        while (ch = getc(fp), !feof(fp)) {
                                n = 0;
                                state = in;
                                do {
                                        if (isascii(ch) && isupper(ch))
                                                lch = tolower(ch);
                                        else
                                                lch = ch;
                                        if (state == in)
                                                if (lch=="content-length:"[n]){
                                                        if (lch == ':') {
                                                                state = num;
                                                                conlen = 0;
                                                                conlen_p = 0;
                                                        }
                                                } else
                                                        state = out;
                                        else if (state == num) {
                                                if (!isascii(ch))
                                                        ;
                                                else if (!conlen_p &&
                                                      isspace(ch))
                                                        ;
                                                else if (isdigit(ch)) {
                                                        conlen *= 10;
                                                        conlen += (ch - '0');
                                                        conlen_p = 1;
                                                } else
                                                        state = out;
                                        }
                                        if (ch == '\n')
                                                break;
                                        if (ch != '\r') {
                                                outc(ch);
                                                n++;
                                        }
                                } while (ch = getc(fp), !feof(fp));
                                if (n == 0)
                                        break;
                                putchar('\n');
                        }
                        if (conlen_p) {
                                putchar('+');
                                putchar('\n');
                                n = 0;
                                while (n < conlen &&
                                       (ch = getc(fp), !feof(fp))) {
                                        outc(ch);
                                        n++;
                                }
                                if (n > 0 && ch != '\n')
                                        putchar('\n');
                        }
                        putchar('\n');
                        if (timelim != 0)
                                alarm(0);
                }
                shutdown(client, SHUT_RD);
                setsockopt(client, 6, SO_SNDBUF, &sndbuf, sizeof sndbuf);
                fcntl(client, F_SETFL, fcntl(client, F_GETFL) | O_NONBLOCK);
                if (content.base != NULL && content.size != 0) {
                        fprintf(fp, "HTTP/1.1 404 %s\r\n",
                                "You are digging in the wrong place");
                        fprintf(fp, "Connection: close\r\n");
                        fprintf(fp, "Content-Length: %d\r\n", content.size);
                        fprintf(fp, "Content-Type: text/html\r\n");
                        fputs("\r\n", fp);
                        fflush(fp);
                        writev(client, &content, 1);
                } else {
                        fputs("HTTP/1.1 204 Zilch\r\n", fp);
                        fputs("Connection: close\r\n", fp);
                        fputs("Content-Length: 0\r\n", fp);
                        fputs("\r\n", fp);
                }
                fclose(fp);
                goto loop;
        }
        perror("accept");
        signal(SIGALRM, SIG_DFL);
}

static void
timeout(int foo) {
        longjmp(timedout, 1);
}


Current thread: