GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdrop/tcpdrop.c Lines: 0 76 0.0 %
Date: 2017-11-07 Branches: 0 42 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: tcpdrop.c,v 1.17 2015/01/16 06:40:21 deraadt Exp $ */
2
3
/*
4
 * Copyright (c) 2004 Markus Friedl <markus@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/socket.h>
20
#include <sys/sysctl.h>
21
#include <sys/queue.h>
22
#include <sys/timeout.h>
23
24
#include <netinet/in.h>
25
#include <netinet/tcp.h>
26
#include <netinet/tcp_timer.h>
27
#include <netinet/tcp_var.h>
28
29
#include <err.h>
30
#include <stdio.h>
31
#include <string.h>
32
#include <stdlib.h>
33
#include <netdb.h>
34
35
__dead void	 usage(void);
36
37
__dead void
38
usage(void)
39
{
40
	extern char	*__progname;
41
42
	fprintf(stderr,
43
	    "usage: %s local-addr local-port remote-addr remote-port\n",
44
	    __progname);
45
	fprintf(stderr,
46
	    "       %s local-addr:local-port remote-addr:remote-port\n",
47
	    __progname);
48
	exit(1);
49
}
50
51
/*
52
 * Drop a tcp connection.
53
 */
54
int
55
main(int argc, char **argv)
56
{
57
	int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_DROP };
58
	struct addrinfo hints, *ail, *aif, *laddr, *faddr;
59
	char fhbuf[NI_MAXHOST], fsbuf[NI_MAXSERV];
60
	char lhbuf[NI_MAXHOST], lsbuf[NI_MAXSERV];
61
	char *laddr1, *addr1, *port1, *faddr2, *addr2, *port2;
62
	struct tcp_ident_mapping tir;
63
	int gaierr, rval = 0;
64
65
	memset(&hints, 0, sizeof(hints));
66
	hints.ai_family = AF_UNSPEC;
67
	hints.ai_socktype = SOCK_STREAM;
68
69
	if (argc == 3) {
70
		laddr1 = addr1 = strdup(argv[1]);
71
		if (!addr1)
72
			err(1, "strdup");
73
		port1 = strrchr(addr1, ':');
74
		if (port1)
75
			*port1++ = '\0';
76
		else
77
			usage();
78
79
		faddr2 = addr2 = strdup(argv[2]);
80
		if (!addr2)
81
			err(1, "strdup");
82
		port2 = strrchr(addr2, ':');
83
		if (port2)
84
			*port2++ = '\0';
85
		else
86
			usage();
87
	} else if (argc == 5) {
88
		laddr1 = addr1 = argv[1];
89
		port1 = argv[2];
90
		faddr2 = addr2 = argv[3];
91
		port2 = argv[4];
92
	} else
93
		usage();
94
95
	if (addr1[0] == '[' && addr1[strlen(addr1) - 1] == ']') {
96
		laddr1 = strdup(addr1);
97
		if (!laddr1)
98
			err(1, "strdup");
99
		laddr1[strlen(laddr1) - 1] = '\0';
100
		laddr1++;
101
	}
102
	if (addr2[0] == '[' && addr2[strlen(addr2) - 1] == ']') {
103
		faddr2 = strdup(addr2);
104
		if (!faddr2)
105
			err(1, "strdup");
106
		faddr2[strlen(faddr2) - 1] = '\0';
107
		faddr2++;
108
	}
109
110
	if ((gaierr = getaddrinfo(laddr1, port1, &hints, &laddr)) != 0)
111
		errx(1, "%s port %s: %s", addr1, port1,
112
		    gai_strerror(gaierr));
113
114
	if ((gaierr = getaddrinfo(faddr2, port2, &hints, &faddr)) != 0)
115
		errx(1, "%s port %s: %s", addr2, port2,
116
		    gai_strerror(gaierr));
117
118
	rval = 1;
119
	for (ail = laddr; ail; ail = ail->ai_next) {
120
		for (aif = faddr; aif; aif = aif->ai_next) {
121
			if (ail->ai_family != aif->ai_family)
122
				continue;
123
			rval = 0;
124
			memset(&tir, 0, sizeof(tir));
125
			memcpy(&tir.faddr, aif->ai_addr, aif->ai_addrlen);
126
			memcpy(&tir.laddr, ail->ai_addr, ail->ai_addrlen);
127
128
			if ((gaierr = getnameinfo(aif->ai_addr, aif->ai_addrlen,
129
			    fhbuf, sizeof(fhbuf), fsbuf, sizeof(fsbuf),
130
			    NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
131
				errx(1, "getnameinfo: %s", gai_strerror(gaierr));
132
			if ((gaierr = getnameinfo(ail->ai_addr, ail->ai_addrlen,
133
			    lhbuf, sizeof(lhbuf), lsbuf, sizeof(lsbuf),
134
			    NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
135
				errx(1, "getnameinfo: %s", gai_strerror(gaierr));
136
137
			if (sysctl(mib, sizeof (mib) / sizeof (int), NULL,
138
			    NULL, &tir, sizeof(tir)) == -1) {
139
				rval = 1;
140
				warn("%s %s %s %s", lhbuf, lsbuf, fhbuf, fsbuf);
141
			} else {
142
				if (aif->ai_family == PF_INET6)
143
					printf("[%s]:%s [%s]:%s dropped\n",
144
					    lhbuf, lsbuf, fhbuf, fsbuf);
145
				else
146
					printf("%s:%s %s:%s dropped\n",
147
					    lhbuf, lsbuf, fhbuf, fsbuf);
148
			}
149
		}
150
	}
151
	freeaddrinfo(laddr);
152
	freeaddrinfo(faddr);
153
	exit(rval);
154
}