2 * Copyright (c) 2010-2011 Juniper Networks, Inc.
5 * This software was developed by Robert N. M. Watson under contract
6 * to Juniper Networks, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * This is a test tool for IP divert sockets. For the time being, it just
34 * exercise creation and binding of sockets, rather than their divert
35 * behaviour. It would be highly desirable to broaden this test tool to
36 * include packet injection and diversion.
39 #include <sys/types.h>
40 #include <sys/socket.h>
42 #include <netinet/in.h>
55 fprintf(stderr, "%s: OK\n", test);
59 fail(const char *test, const char *note)
62 fprintf(stderr, "%s - %s: FAIL (%s)\n", test, note, strerror(errno));
67 failx(const char *test, const char *note)
70 fprintf(stderr, "%s - %s: FAIL\n", test, note);
75 ipdivert_create(const char *test)
79 s = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT);
86 ipdivert_close(const char *test, int s)
94 ipdivert_bind(const char *test, int s, u_short port, int expect)
96 struct sockaddr_in sin;
99 bzero(&sin, sizeof(sin));
100 sin.sin_family = AF_INET;
101 sin.sin_addr.s_addr = htonl(INADDR_ANY);
102 sin.sin_port = htons(port);
104 err = bind(s, (struct sockaddr *)&sin, sizeof(sin));
117 main(int argc, char *argv[])
123 * First test: create and close an IP divert socket.
125 test = "create_close";
126 s1 = ipdivert_create(test);
127 ipdivert_close(test, s1);
131 * Second test: create, bind, and close an IP divert socket.
133 test = "create_bind_close";
134 s1 = ipdivert_create(test);
135 ipdivert_bind(test, s1, 1000, 0);
136 ipdivert_close(test, s1);
140 * Third test: create two sockets, bind to different ports, and close.
141 * This should succeed due to non-conflict on the port numbers.
143 test = "create2_bind2_close2";
144 s1 = ipdivert_create(test);
145 s2 = ipdivert_create(test);
146 ipdivert_bind(test, s1, 1000, 0);
147 ipdivert_bind(test, s2, 1001, 0);
148 ipdivert_close(test, s1);
149 ipdivert_close(test, s2);
153 * Fourth test: create two sockets, bind to the *same* port, and
154 * close. This should fail due to conflicting port numbers.
156 test = "create2_bind2_conflict_close2";
157 s1 = ipdivert_create(test);
158 s2 = ipdivert_create(test);
159 ipdivert_bind(test, s1, 1000, 0);
160 ipdivert_bind(test, s2, 1000, EADDRINUSE);
161 ipdivert_close(test, s1);
162 ipdivert_close(test, s2);