diff options
Diffstat (limited to 'tools/testing/selftests/net/psock_lib.h')
-rw-r--r-- | tools/testing/selftests/net/psock_lib.h | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/tools/testing/selftests/net/psock_lib.h b/tools/testing/selftests/net/psock_lib.h new file mode 100644 index 000000000000..37da54ac85a9 --- /dev/null +++ b/tools/testing/selftests/net/psock_lib.h | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Google Inc. | ||
3 | * Author: Willem de Bruijn <willemb@google.com> | ||
4 | * Daniel Borkmann <dborkman@redhat.com> | ||
5 | * | ||
6 | * License (GPLv2): | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef PSOCK_LIB_H | ||
23 | #define PSOCK_LIB_H | ||
24 | |||
25 | #include <sys/types.h> | ||
26 | #include <sys/socket.h> | ||
27 | #include <string.h> | ||
28 | #include <arpa/inet.h> | ||
29 | #include <unistd.h> | ||
30 | |||
31 | #define DATA_LEN 100 | ||
32 | #define DATA_CHAR 'a' | ||
33 | |||
34 | #define PORT_BASE 8000 | ||
35 | |||
36 | #ifndef __maybe_unused | ||
37 | # define __maybe_unused __attribute__ ((__unused__)) | ||
38 | #endif | ||
39 | |||
40 | static __maybe_unused void pair_udp_setfilter(int fd) | ||
41 | { | ||
42 | struct sock_filter bpf_filter[] = { | ||
43 | { 0x80, 0, 0, 0x00000000 }, /* LD pktlen */ | ||
44 | { 0x35, 0, 5, DATA_LEN }, /* JGE DATA_LEN [f goto nomatch]*/ | ||
45 | { 0x30, 0, 0, 0x00000050 }, /* LD ip[80] */ | ||
46 | { 0x15, 0, 3, DATA_CHAR }, /* JEQ DATA_CHAR [f goto nomatch]*/ | ||
47 | { 0x30, 0, 0, 0x00000051 }, /* LD ip[81] */ | ||
48 | { 0x15, 0, 1, DATA_CHAR }, /* JEQ DATA_CHAR [f goto nomatch]*/ | ||
49 | { 0x06, 0, 0, 0x00000060 }, /* RET match */ | ||
50 | { 0x06, 0, 0, 0x00000000 }, /* RET no match */ | ||
51 | }; | ||
52 | struct sock_fprog bpf_prog; | ||
53 | |||
54 | bpf_prog.filter = bpf_filter; | ||
55 | bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_filter); | ||
56 | if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf_prog, | ||
57 | sizeof(bpf_prog))) { | ||
58 | perror("setsockopt SO_ATTACH_FILTER"); | ||
59 | exit(1); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | static __maybe_unused void pair_udp_open(int fds[], uint16_t port) | ||
64 | { | ||
65 | struct sockaddr_in saddr, daddr; | ||
66 | |||
67 | fds[0] = socket(PF_INET, SOCK_DGRAM, 0); | ||
68 | fds[1] = socket(PF_INET, SOCK_DGRAM, 0); | ||
69 | if (fds[0] == -1 || fds[1] == -1) { | ||
70 | fprintf(stderr, "ERROR: socket dgram\n"); | ||
71 | exit(1); | ||
72 | } | ||
73 | |||
74 | memset(&saddr, 0, sizeof(saddr)); | ||
75 | saddr.sin_family = AF_INET; | ||
76 | saddr.sin_port = htons(port); | ||
77 | saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | ||
78 | |||
79 | memset(&daddr, 0, sizeof(daddr)); | ||
80 | daddr.sin_family = AF_INET; | ||
81 | daddr.sin_port = htons(port + 1); | ||
82 | daddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | ||
83 | |||
84 | /* must bind both to get consistent hash result */ | ||
85 | if (bind(fds[1], (void *) &daddr, sizeof(daddr))) { | ||
86 | perror("bind"); | ||
87 | exit(1); | ||
88 | } | ||
89 | if (bind(fds[0], (void *) &saddr, sizeof(saddr))) { | ||
90 | perror("bind"); | ||
91 | exit(1); | ||
92 | } | ||
93 | if (connect(fds[0], (void *) &daddr, sizeof(daddr))) { | ||
94 | perror("connect"); | ||
95 | exit(1); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | static __maybe_unused void pair_udp_send(int fds[], int num) | ||
100 | { | ||
101 | char buf[DATA_LEN], rbuf[DATA_LEN]; | ||
102 | |||
103 | memset(buf, DATA_CHAR, sizeof(buf)); | ||
104 | while (num--) { | ||
105 | /* Should really handle EINTR and EAGAIN */ | ||
106 | if (write(fds[0], buf, sizeof(buf)) != sizeof(buf)) { | ||
107 | fprintf(stderr, "ERROR: send failed left=%d\n", num); | ||
108 | exit(1); | ||
109 | } | ||
110 | if (read(fds[1], rbuf, sizeof(rbuf)) != sizeof(rbuf)) { | ||
111 | fprintf(stderr, "ERROR: recv failed left=%d\n", num); | ||
112 | exit(1); | ||
113 | } | ||
114 | if (memcmp(buf, rbuf, sizeof(buf))) { | ||
115 | fprintf(stderr, "ERROR: data failed left=%d\n", num); | ||
116 | exit(1); | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static __maybe_unused void pair_udp_close(int fds[]) | ||
122 | { | ||
123 | close(fds[0]); | ||
124 | close(fds[1]); | ||
125 | } | ||
126 | |||
127 | #endif /* PSOCK_LIB_H */ | ||