Permalink
Browse files

Imported from http://code.google.com/p/tweag/ cause I <3 github

  • Loading branch information...
0 parents commit ee8b9c1521ebe967bbd5cd2481a2d54d5c6e892e @msantos committed Dec 29, 2009
Showing with 886 additions and 0 deletions.
  1. +18 −0 Makefile
  2. 0 README
  3. +142 −0 rst.c
  4. +122 −0 rst.h
  5. +292 −0 rst_icmp.c
  6. +49 −0 rst_net.c
  7. +118 −0 rst_pcap.c
  8. +67 −0 rst_priv.c
  9. +78 −0 rst_tcp.c
@@ -0,0 +1,18 @@
+LIBNET_CONFIG=/usr/pkg/bin/libnet11-config
+
+GCC=gcc
+RM=/bin/rm
+APP=rst
+LDFLAGS=-L/usr/pkg/lib $(LIBNET)
+CFLAGS=-I/usr/pkg/include
+LIBS=-lpcap -lnet
+
+rst:
+ $(GCC) $(CFLAGS) $(LDFLAGS) $(LIBS) \
+ `$(LIBNET_CONFIG) --libs` \
+ `$(LIBNET_CONFIG) --cflags` \
+ `$(LIBNET_CONFIG) --defines` \
+ -g -Wall -o $(APP) $(APP)_priv.c $(APP)_net.c $(APP)_pcap.c $(APP)_tcp.c $(APP)_icmp.c $(APP).c
+
+clean:
+ -@$(RM) $(APP)
0 README
No changes.
142 rst.c
@@ -0,0 +1,142 @@
+/*
+ * rst: TCP connect reset utility
+ *
+ * Aggressively resets TCP connections using TCP RST's or
+ * ICMP.
+ *
+ * Copyright (c) 2005-2007 Michael Santos <michael.santos@gmail.com>
+ *
+ */
+#include "rst.h"
+
+ int
+main(int argc, char *argv[])
+{
+ pkt_t *rst = NULL;
+
+ int ch = 0;
+ int exclude = 0;
+ char *host = NULL;
+ in_port_t port = 0;
+
+ char *user = strdup(RST_USER);
+ char *group = strdup(RST_GROUP);
+ char *path = strdup(RST_DIR);
+
+ ISNULL(rst = (pkt_t *)calloc(1, sizeof(pkt_t)));
+
+ rst->flags = RST_TCP_RST;
+ rst->icmp.type = ICMP_UNREACH; /* Default is ICMP unreachable (type 3) */
+ rst->icmp.code = ICMP_UNREACH_PORT; /* Default is ICMP port unreachable (code 3) */
+
+ while ( (ch = getopt(argc, argv, "c:d:g:hH:i:Ip:rR:t:u:xX:")) != EOF) {
+ switch (ch) {
+ case 'c': /* ICMP code */
+ rst->icmp.code = (u_int8_t)atoi(optarg);
+ rst->flags = RST_ICMP;
+ break;
+ case 'd': /* chroot path */
+ path = strdup(optarg);
+ break;
+ case 'g': /* unprivileged group */
+ group = strdup(optarg);
+ break;
+ case 'h': /* Help */
+ usage();
+ break;
+ case 'H':
+ if (strlen(optarg) > MAXHOSTNAMELEN)
+ errx(EXIT_FAILURE, "Hostname too long");
+ host = strdup(optarg);
+ break;
+ case 'i': /* Use interface */
+ rst->dev = strdup(optarg);
+ break;
+ case 'I':
+ rst->flags = RST_ICMP;
+ break;
+ case 'p': /* list of ports */
+ port = (in_port_t)atoi(optarg);
+ break;
+ case 'r':
+ rst->flags = RST_TCP_RST; /* TCP RST */
+ break;
+ case 'R':
+ rst->sleep_for = MICROSECONDS / (useconds_t)atoi(optarg); /* Maximum number of packets sent per second */
+ (void)fprintf(stderr, "[%s] Sleeping for %u usec between sending packets\n", __progname, rst->sleep_for);
+ break;
+ case 't': /* ICMP type */
+ rst->icmp.type = (u_int8_t)atoi(optarg);
+ break;
+ case 'u': /* unprivileged user */
+ user = strdup(optarg);
+ break;
+ case 'x': /* Exclude our IP address */
+ exclude = 1;
+ break;
+ case 'X': /* Exclude by specifying our IP address */
+ exclude = 1;
+ rst->myip = strdup(optarg);
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ rst_net_check(rst);
+
+ ISNULL(rst->l = rst_net_open(rst->dev));
+ ISNULL(rst->p = rst_pcap_open(rst->dev));
+
+ /* Drop privileges */
+ if (rst_priv_drop(user, group, path) != 0)
+ exit (EXIT_FAILURE);
+
+ ISLTZERO(rst_pcap_init(rst, host, port, exclude));
+ ISLTZERO(rst_pcap_run(rst));
+
+ ISLTZERO(rst_net_close(rst->l));
+ ISLTZERO(rst_pcap_close(rst->p));
+ if (rst->dev)
+ free(rst->dev);
+ if (rst->myip)
+ free(rst->myip);
+ if (host)
+ free(host);
+
+ free(user);
+ free(group);
+ free(path);
+
+ exit (EXIT_FAILURE);
+}
+
+ void
+usage(void)
+{
+ (void)fprintf(stdout, "[%s v%s: Reset TCP connections]\n",
+ __progname, RST_BUILD);
+ (void)fprintf(stdout, "Usage: %s [-h|-H <host>|-i <interface>|-I <icmp type>|-p <port>|-R <number>|-x|-X <ip>]\n", __progname);
+ (void)fprintf(stdout, "-h\t\tusage\n");
+ (void)fprintf(stdout, "\n");
+ (void)fprintf(stdout, "-x\t\texclude our IP address\n");
+ (void)fprintf(stdout, "-X <IP Address>\tspecify an IP address to exclude\n");
+ (void)fprintf(stdout, "\n");
+ (void)fprintf(stdout, "-H <host>\thostname\n");
+ (void)fprintf(stdout, "-p <port>\tport to reset\n");
+ (void)fprintf(stdout, "-i <interface>\tinterface\n");
+ (void)fprintf(stdout, "-R <number>\trate limit, number of packets per second\n");
+ (void)fprintf(stdout, "\n");
+ (void)fprintf(stdout, "-d <path>\tchroot path (default = %s)\n", RST_DIR);
+ (void)fprintf(stdout, "-u <user>\tunprivliged user (default = %s)\n", RST_USER);
+ (void)fprintf(stdout, "-g <group>\tunprivilged group (default = %s)\n", RST_GROUP);
+ (void)fprintf(stdout, "\n");
+ (void)fprintf(stdout, "-c <ICMP code>\tcode to use for ICMP resets\n");
+ (void)fprintf(stdout, "-I\t\treset using ICMP\n");
+ (void)fprintf(stdout, "-t <ICMP type>\ttype to use for ICMP resets\n");
+ (void)fprintf(stdout, "\n");
+ (void)fprintf(stdout, "[Bug reports to michael.santos@gmail.com]\n");
+
+ exit (EXIT_FAILURE);
+}
122 rst.h
@@ -0,0 +1,122 @@
+/*
+ * rst: TCP connect reset utility
+ *
+ * Aggressively resets TCP connections using TCP RST's or
+ * ICMP.
+ *
+ * Copyright (c) 2005-2007 Michael Santos <michael.santos@gmail.com>
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+#include <sys/param.h>
+
+#include <pcap.h>
+
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/ip_icmp.h>
+#include <arpa/inet.h>
+
+#include <libnet.h>
+
+#define RST_BUILD "0.2"
+
+#define PCAP_ERRBUF(x) do { \
+ if ((x) == NULL) \
+ errx(EXIT_FAILURE, "%s: %s", #x, errbuf); \
+} while (0);
+
+#define ISNULL(x) do { \
+ if ((x) == NULL) \
+ errx(EXIT_FAILURE, "%s", #x); \
+} while (0);
+
+#define ISLTZERO(x) do { \
+ if ((x) < 0) \
+ errx(EXIT_FAILURE, "%s", #x); \
+} while (0);
+
+#define PCAP_ERR(x) do { \
+ if ((x) != 0) \
+ errx(EXIT_FAILURE, "%s: %s", #x, pcap_geterr(p)); \
+} while (0);
+
+#define LIBNET_ERR(x) do { \
+ if ((x) == -1) { \
+ libnet_destroy(rst->l); \
+ errx(EXIT_FAILURE, "%s: %s", #x, libnet_geterror(rst->l)); \
+ } \
+} while (0);
+
+#define PAIR(x,y,z) ((x) == 0 ? (y) : (z))
+
+#define NLADD(x,y) (ntohl(htonl(x)+y))
+
+#define MAXWIDTH 60
+
+extern char *__progname;
+
+#define SNAPLEN 60
+#define PROMISC 1 /* true */
+#define TIMEOUT 500 /* ms */
+#define PCAP_FILT "tcp"
+#define MAXFILT 256
+#define ICMP_PKTLEN 8 /* 64 bits of original packet returned in ICMP packet */
+
+#define RST_USER "nobody"
+#define RST_GROUP "nobody"
+#define RST_DIR "/var/chroot/rst"
+
+#define MICROSECONDS 1000000
+
+enum {
+ RST_TCP_RST = 1, /* TCP RST */
+ RST_ICMP = 2, /* ICMP Unreachable */
+};
+
+enum {
+ ICMP_SRC_HOST, /* Use the host as the ICMP source address */
+ ICMP_SRC_GW, /* Use the gateway as the ICMP source address */
+};
+
+typedef struct {
+ char *dev;
+ u_char *pkt;
+ pcap_t *p;
+ libnet_t *l;
+ u_int8_t flags;
+ useconds_t sleep_for;
+ char *myip;
+ struct {
+ u_int8_t type;
+ u_int8_t code;
+ u_int8_t src;
+ } icmp;
+} pkt_t;
+
+libnet_t *rst_net_open(char *dev);
+int rst_net_init(libnet_t *l);
+int rst_net_send(libnet_t *l);
+void rst_net_check(pkt_t *rst);
+int rst_net_close(libnet_t *l);
+
+int rst_pcap_init(pkt_t *rst, char *host, in_port_t port, u_int8_t exclude);
+pcap_t *rst_pcap_open(char *dev);
+int rst_pcap_run(pkt_t *rst);
+int rst_pcap_close(pcap_t *p);
+
+void rst_tcp_send(pkt_t *rst);
+
+int rst_icmp_check(u_int8_t type, u_int8_t code);
+void rst_icmp_send(pkt_t *rst);
+void rst_icmp_type(pkt_t *rst);
+
+int rst_priv_drop(char *user, char *group, char *path);
+
+void usage(void);
+
Oops, something went wrong.

0 comments on commit ee8b9c1

Please sign in to comment.