| @@ -1,902 +1,901 @@ | | | @@ -1,902 +1,901 @@ |
1 | /* $NetBSD: setkey.c,v 1.11.6.1 2007/08/01 11:52:23 vanhu Exp $ */ | | 1 | /* $NetBSD: setkey.c,v 1.11.6.2 2009/08/06 04:45:16 tteras Exp $ */ |
2 | | | 2 | |
3 | /* $KAME: setkey.c,v 1.36 2003/09/24 23:52:51 itojun Exp $ */ | | 3 | /* $KAME: setkey.c,v 1.36 2003/09/24 23:52:51 itojun Exp $ */ |
4 | | | 4 | |
5 | /* | | 5 | /* |
6 | * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. | | 6 | * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in the | | 15 | * notice, this list of conditions and the following disclaimer in the |
16 | * documentation and/or other materials provided with the distribution. | | 16 | * documentation and/or other materials provided with the distribution. |
17 | * 3. Neither the name of the project nor the names of its contributors | | 17 | * 3. Neither the name of the project nor the names of its contributors |
18 | * may be used to endorse or promote products derived from this software | | 18 | * may be used to endorse or promote products derived from this software |
19 | * without specific prior written permission. | | 19 | * without specific prior written permission. |
20 | * | | 20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | | 21 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | | 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
31 | * SUCH DAMAGE. | | 31 | * SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #ifdef HAVE_CONFIG_H | | 34 | #ifdef HAVE_CONFIG_H |
35 | #include "config.h" | | 35 | #include "config.h" |
36 | #endif | | 36 | #endif |
37 | | | 37 | |
38 | #include <sys/types.h> | | 38 | #include <sys/types.h> |
39 | #include <sys/param.h> | | 39 | #include <sys/param.h> |
40 | #include <sys/socket.h> | | 40 | #include <sys/socket.h> |
41 | #include <sys/time.h> | | 41 | #include <sys/time.h> |
42 | #include <sys/stat.h> | | 42 | #include <sys/stat.h> |
43 | #include <sys/sysctl.h> | | 43 | #include <sys/sysctl.h> |
44 | #include <err.h> | | 44 | #include <err.h> |
45 | #include <netinet/in.h> | | 45 | #include <netinet/in.h> |
46 | #include <net/pfkeyv2.h> | | 46 | #include <net/pfkeyv2.h> |
47 | #include PATH_IPSEC_H | | 47 | #include PATH_IPSEC_H |
48 | | | 48 | |
49 | #include <stdio.h> | | 49 | #include <stdio.h> |
50 | #include <stdlib.h> | | 50 | #include <stdlib.h> |
51 | #include <limits.h> | | 51 | #include <limits.h> |
52 | #include <string.h> | | 52 | #include <string.h> |
53 | #include <ctype.h> | | 53 | #include <ctype.h> |
54 | #include <unistd.h> | | 54 | #include <unistd.h> |
55 | #include <errno.h> | | 55 | #include <errno.h> |
56 | #include <netdb.h> | | 56 | #include <netdb.h> |
57 | #include <fcntl.h> | | 57 | #include <fcntl.h> |
58 | #include <dirent.h> | | 58 | #include <dirent.h> |
59 | #include <time.h> | | 59 | #include <time.h> |
60 | | | 60 | |
61 | #ifdef HAVE_READLINE | | 61 | #ifdef HAVE_READLINE |
62 | #include <readline/readline.h> | | 62 | #include <readline/readline.h> |
63 | #include <readline/history.h> | | 63 | #include <readline/history.h> |
64 | #endif | | 64 | #endif |
65 | | | 65 | |
66 | #include "config.h" | | 66 | #include "config.h" |
67 | #include "libpfkey.h" | | 67 | #include "libpfkey.h" |
68 | #include "package_version.h" | | 68 | #include "package_version.h" |
69 | #define extern /* so that variables in extern.h are not extern... */ | | 69 | #define extern /* so that variables in extern.h are not extern... */ |
70 | #include "extern.h" | | 70 | #include "extern.h" |
71 | | | 71 | |
72 | #define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0') | | 72 | #define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0') |
73 | | | 73 | |
74 | void usage __P((int)); | | 74 | void usage __P((int)); |
75 | int main __P((int, char **)); | | 75 | int main __P((int, char **)); |
76 | int get_supported __P((void)); | | 76 | int get_supported __P((void)); |
77 | void sendkeyshort __P((u_int)); | | 77 | void sendkeyshort __P((u_int)); |
78 | void promisc __P((void)); | | 78 | void promisc __P((void)); |
79 | int postproc __P((struct sadb_msg *, int)); | | 79 | int postproc __P((struct sadb_msg *, int)); |
80 | int verifypriority __P((struct sadb_msg *m)); | | 80 | int verifypriority __P((struct sadb_msg *m)); |
81 | int fileproc __P((const char *)); | | 81 | int fileproc __P((const char *)); |
82 | const char *numstr __P((int)); | | 82 | const char *numstr __P((int)); |
83 | void shortdump_hdr __P((void)); | | 83 | void shortdump_hdr __P((void)); |
84 | void shortdump __P((struct sadb_msg *)); | | 84 | void shortdump __P((struct sadb_msg *)); |
85 | static void printdate __P((void)); | | 85 | static void printdate __P((void)); |
86 | static int32_t gmt2local __P((time_t)); | | 86 | static int32_t gmt2local __P((time_t)); |
87 | void stdin_loop __P((void)); | | 87 | void stdin_loop __P((void)); |
88 | | | 88 | |
89 | #define MODE_SCRIPT 1 | | 89 | #define MODE_SCRIPT 1 |
90 | #define MODE_CMDDUMP 2 | | 90 | #define MODE_CMDDUMP 2 |
91 | #define MODE_CMDFLUSH 3 | | 91 | #define MODE_CMDFLUSH 3 |
92 | #define MODE_PROMISC 4 | | 92 | #define MODE_PROMISC 4 |
93 | #define MODE_STDIN 5 | | 93 | #define MODE_STDIN 5 |
94 | | | 94 | |
95 | int so; | | 95 | int so; |
96 | | | 96 | |
97 | int f_forever = 0; | | 97 | int f_forever = 0; |
98 | int f_all = 0; | | 98 | int f_all = 0; |
99 | int f_verbose = 0; | | 99 | int f_verbose = 0; |
100 | int f_mode = 0; | | 100 | int f_mode = 0; |
101 | int f_cmddump = 0; | | 101 | int f_cmddump = 0; |
102 | int f_policy = 0; | | 102 | int f_policy = 0; |
103 | int f_hexdump = 0; | | 103 | int f_hexdump = 0; |
104 | int f_tflag = 0; | | 104 | int f_tflag = 0; |
105 | int f_notreally = 0; | | 105 | int f_notreally = 0; |
106 | int f_withports = 0; | | 106 | int f_withports = 0; |
107 | #ifdef HAVE_POLICY_FWD | | 107 | #ifdef HAVE_POLICY_FWD |
108 | int f_rfcmode = 1; | | 108 | int f_rfcmode = 1; |
109 | #define RK_OPTS "rk" | | 109 | #define RK_OPTS "rk" |
110 | #else | | 110 | #else |
111 | int f_rkwarn = 0; | | 111 | int f_rkwarn = 0; |
112 | #define RK_OPTS "" | | 112 | #define RK_OPTS "" |
113 | static void rkwarn(void); | | 113 | static void rkwarn(void); |
114 | static void | | 114 | static void |
115 | rkwarn(void) | | 115 | rkwarn(void) |
116 | { | | 116 | { |
117 | if (!f_rkwarn) { | | 117 | if (!f_rkwarn) { |
118 | f_rkwarn = 1; | | 118 | f_rkwarn = 1; |
119 | printf("warning: -r and -k options are not supported in this environment\n"); | | 119 | printf("warning: -r and -k options are not supported in this environment\n"); |
120 | } | | 120 | } |
121 | } | | 121 | } |
122 | | | 122 | |
123 | #endif | | 123 | #endif |
124 | static time_t thiszone; | | 124 | static time_t thiszone; |
125 | | | 125 | |
126 | void | | 126 | void |
127 | usage(int only_version) | | 127 | usage(int only_version) |
128 | { | | 128 | { |
129 | printf("setkey @(#) %s (%s)\n", TOP_PACKAGE_STRING, TOP_PACKAGE_URL); | | 129 | printf("setkey @(#) %s (%s)\n", TOP_PACKAGE_STRING, TOP_PACKAGE_URL); |
130 | if (! only_version) { | | 130 | if (! only_version) { |
131 | printf("usage: setkey [-v" RK_OPTS "] file ...\n"); | | 131 | printf("usage: setkey [-v" RK_OPTS "] file ...\n"); |
132 | printf(" setkey [-nv" RK_OPTS "] -c\n"); | | 132 | printf(" setkey [-nv" RK_OPTS "] -c\n"); |
133 | printf(" setkey [-nv" RK_OPTS "] -f filename\n"); | | 133 | printf(" setkey [-nv" RK_OPTS "] -f filename\n"); |
134 | printf(" setkey [-Palpv" RK_OPTS "] -D\n"); | | 134 | printf(" setkey [-Palpv" RK_OPTS "] -D\n"); |
135 | printf(" setkey [-Pv] -F\n"); | | 135 | printf(" setkey [-Pv] -F\n"); |
136 | printf(" setkey [-H] -x\n"); | | 136 | printf(" setkey [-H] -x\n"); |
137 | printf(" setkey [-V] [-h]\n"); | | 137 | printf(" setkey [-V] [-h]\n"); |
138 | } | | 138 | } |
139 | exit(1); | | 139 | exit(1); |
140 | } | | 140 | } |
141 | | | 141 | |
142 | int | | 142 | int |
143 | main(argc, argv) | | 143 | main(argc, argv) |
144 | int argc; | | 144 | int argc; |
145 | char **argv; | | 145 | char **argv; |
146 | { | | 146 | { |
147 | FILE *fp = stdin; | | 147 | FILE *fp = stdin; |
148 | int c; | | 148 | int c; |
149 | | | 149 | |
150 | if (argc == 1) { | | 150 | if (argc == 1) { |
151 | usage(0); | | 151 | usage(0); |
152 | /* NOTREACHED */ | | 152 | /* NOTREACHED */ |
153 | } | | 153 | } |
154 | | | 154 | |
155 | thiszone = gmt2local(0); | | 155 | thiszone = gmt2local(0); |
156 | | | 156 | |
157 | while ((c = getopt(argc, argv, "acdf:HlnvxDFPphVrk?")) != -1) { | | 157 | while ((c = getopt(argc, argv, "acdf:HlnvxDFPphVrk?")) != -1) { |
158 | switch (c) { | | 158 | switch (c) { |
159 | case 'c': | | 159 | case 'c': |
160 | f_mode = MODE_STDIN; | | 160 | f_mode = MODE_STDIN; |
161 | #ifdef HAVE_READLINE | | 161 | #ifdef HAVE_READLINE |
162 | /* disable filename completion */ | | 162 | /* disable filename completion */ |
163 | rl_bind_key('\t', rl_insert); | | 163 | rl_bind_key('\t', rl_insert); |
164 | #endif | | 164 | #endif |
165 | break; | | 165 | break; |
166 | case 'f': | | 166 | case 'f': |
167 | f_mode = MODE_SCRIPT; | | 167 | f_mode = MODE_SCRIPT; |
168 | if ((fp = fopen(optarg, "r")) == NULL) { | | 168 | if ((fp = fopen(optarg, "r")) == NULL) { |
169 | err(1, "fopen"); | | 169 | err(1, "fopen"); |
170 | /*NOTREACHED*/ | | 170 | /*NOTREACHED*/ |
171 | } | | 171 | } |
172 | break; | | 172 | break; |
173 | case 'D': | | 173 | case 'D': |
174 | f_mode = MODE_CMDDUMP; | | 174 | f_mode = MODE_CMDDUMP; |
175 | break; | | 175 | break; |
176 | case 'F': | | 176 | case 'F': |
177 | f_mode = MODE_CMDFLUSH; | | 177 | f_mode = MODE_CMDFLUSH; |
178 | break; | | 178 | break; |
179 | case 'a': | | 179 | case 'a': |
180 | f_all = 1; | | 180 | f_all = 1; |
181 | break; | | 181 | break; |
182 | case 'l': | | 182 | case 'l': |
183 | f_forever = 1; | | 183 | f_forever = 1; |
184 | break; | | 184 | break; |
185 | case 'n': | | 185 | case 'n': |
186 | f_notreally = 1; | | 186 | f_notreally = 1; |
187 | break; | | 187 | break; |
188 | #ifdef __NetBSD__ | | 188 | #ifdef __NetBSD__ |
189 | case 'h': | | 189 | case 'h': |
190 | #endif | | 190 | #endif |
191 | case 'H': | | 191 | case 'H': |
192 | f_hexdump = 1; | | 192 | f_hexdump = 1; |
193 | break; | | 193 | break; |
194 | case 'x': | | 194 | case 'x': |
195 | f_mode = MODE_PROMISC; | | 195 | f_mode = MODE_PROMISC; |
196 | f_tflag++; | | 196 | f_tflag++; |
197 | break; | | 197 | break; |
198 | case 'P': | | 198 | case 'P': |
199 | f_policy = 1; | | 199 | f_policy = 1; |
200 | break; | | 200 | break; |
201 | case 'p': | | 201 | case 'p': |
202 | f_withports = 1; | | 202 | f_withports = 1; |
203 | break; | | 203 | break; |
204 | case 'v': | | 204 | case 'v': |
205 | f_verbose = 1; | | 205 | f_verbose = 1; |
206 | break; | | 206 | break; |
207 | case 'r': | | 207 | case 'r': |
208 | #ifdef HAVE_POLICY_FWD | | 208 | #ifdef HAVE_POLICY_FWD |
209 | f_rfcmode = 1; | | 209 | f_rfcmode = 1; |
210 | #else | | 210 | #else |
211 | rkwarn(); | | 211 | rkwarn(); |
212 | #endif | | 212 | #endif |
213 | break; | | 213 | break; |
214 | case 'k': | | 214 | case 'k': |
215 | #ifdef HAVE_POLICY_FWD | | 215 | #ifdef HAVE_POLICY_FWD |
216 | f_rfcmode = 0; | | 216 | f_rfcmode = 0; |
217 | #else | | 217 | #else |
218 | rkwarn(); | | 218 | rkwarn(); |
219 | #endif | | 219 | #endif |
220 | break; | | 220 | break; |
221 | case 'V': | | 221 | case 'V': |
222 | usage(1); | | 222 | usage(1); |
223 | break; | | 223 | break; |
224 | /*NOTREACHED*/ | | 224 | /*NOTREACHED*/ |
225 | #ifndef __NetBSD__ | | 225 | #ifndef __NetBSD__ |
226 | case 'h': | | 226 | case 'h': |
227 | #endif | | 227 | #endif |
228 | case '?': | | 228 | case '?': |
229 | default: | | 229 | default: |
230 | usage(0); | | 230 | usage(0); |
231 | /*NOTREACHED*/ | | 231 | /*NOTREACHED*/ |
232 | } | | 232 | } |
233 | } | | 233 | } |
234 | | | 234 | |
235 | argc -= optind; | | 235 | argc -= optind; |
236 | argv += optind; | | 236 | argv += optind; |
237 | | | 237 | |
238 | if (argc > 0) { | | 238 | if (argc > 0) { |
239 | while (argc--) | | 239 | while (argc--) |
240 | if (fileproc(*argv++) < 0) { | | 240 | if (fileproc(*argv++) < 0) { |
241 | err(1, "%s", argv[-1]); | | 241 | err(1, "%s", argv[-1]); |
242 | /*NOTREACHED*/ | | 242 | /*NOTREACHED*/ |
243 | } | | 243 | } |
244 | exit(0); | | 244 | exit(0); |
245 | } | | 245 | } |
246 | | | 246 | |
247 | so = pfkey_open(); | | 247 | so = pfkey_open(); |
248 | if (so < 0) { | | 248 | if (so < 0) { |
249 | perror("pfkey_open"); | | 249 | perror("pfkey_open"); |
250 | exit(1); | | 250 | exit(1); |
251 | } | | 251 | } |
252 | | | 252 | |
253 | switch (f_mode) { | | 253 | switch (f_mode) { |
254 | case MODE_CMDDUMP: | | 254 | case MODE_CMDDUMP: |
255 | sendkeyshort(f_policy ? SADB_X_SPDDUMP : SADB_DUMP); | | 255 | sendkeyshort(f_policy ? SADB_X_SPDDUMP : SADB_DUMP); |
256 | break; | | 256 | break; |
257 | case MODE_CMDFLUSH: | | 257 | case MODE_CMDFLUSH: |
258 | sendkeyshort(f_policy ? SADB_X_SPDFLUSH: SADB_FLUSH); | | 258 | sendkeyshort(f_policy ? SADB_X_SPDFLUSH: SADB_FLUSH); |
259 | break; | | 259 | break; |
260 | case MODE_SCRIPT: | | 260 | case MODE_SCRIPT: |
261 | if (get_supported() < 0) { | | 261 | if (get_supported() < 0) { |
262 | errx(1, "%s", ipsec_strerror()); | | 262 | errx(1, "%s", ipsec_strerror()); |
263 | /*NOTREACHED*/ | | 263 | /*NOTREACHED*/ |
264 | } | | 264 | } |
265 | if (parse(&fp)) | | 265 | if (parse(&fp)) |
266 | exit (1); | | 266 | exit (1); |
267 | break; | | 267 | break; |
268 | case MODE_STDIN: | | 268 | case MODE_STDIN: |
269 | if (get_supported() < 0) { | | 269 | if (get_supported() < 0) { |
270 | errx(1, "%s", ipsec_strerror()); | | 270 | errx(1, "%s", ipsec_strerror()); |
271 | /*NOTREACHED*/ | | 271 | /*NOTREACHED*/ |
272 | } | | 272 | } |
273 | stdin_loop(); | | 273 | stdin_loop(); |
274 | break; | | 274 | break; |
275 | case MODE_PROMISC: | | 275 | case MODE_PROMISC: |
276 | promisc(); | | 276 | promisc(); |
277 | /*NOTREACHED*/ | | 277 | /*NOTREACHED*/ |
278 | default: | | 278 | default: |
279 | usage(0); | | 279 | usage(0); |
280 | /*NOTREACHED*/ | | 280 | /*NOTREACHED*/ |
281 | } | | 281 | } |
282 | | | 282 | |
283 | exit(0); | | 283 | exit(0); |
284 | } | | 284 | } |
285 | | | 285 | |
286 | int | | 286 | int |
287 | get_supported() | | 287 | get_supported() |
288 | { | | 288 | { |
289 | | | 289 | |
290 | if (pfkey_send_register(so, SADB_SATYPE_UNSPEC) < 0) | | 290 | if (pfkey_send_register(so, SADB_SATYPE_UNSPEC) < 0) |
291 | return -1; | | 291 | return -1; |
292 | | | 292 | |
293 | if (pfkey_recv_register(so) < 0) | | 293 | if (pfkey_recv_register(so) < 0) |
294 | return -1; | | 294 | return -1; |
295 | | | 295 | |
296 | return (0); | | 296 | return (0); |
297 | } | | 297 | } |
298 | | | 298 | |
299 | void | | 299 | void |
300 | stdin_loop() | | 300 | stdin_loop() |
301 | { | | 301 | { |
302 | char line[1024], *semicolon, *comment; | | 302 | char line[1024], *semicolon, *comment; |
303 | size_t linelen = 0; | | 303 | size_t linelen = 0; |
304 | | | 304 | |
305 | memset (line, 0, sizeof(line)); | | 305 | memset (line, 0, sizeof(line)); |
306 | | | 306 | |
307 | parse_init(); | | 307 | parse_init(); |
308 | while (1) { | | 308 | while (1) { |
309 | #ifdef HAVE_READLINE | | 309 | #ifdef HAVE_READLINE |
310 | char *rbuf; | | 310 | char *rbuf; |
311 | rbuf = readline (""); | | 311 | rbuf = readline (""); |
312 | if (! rbuf) | | 312 | if (! rbuf) |
313 | break; | | 313 | break; |
314 | #else | | 314 | #else |
315 | char rbuf[1024]; | | 315 | char rbuf[1024]; |
316 | rbuf[0] = '\0'; | | 316 | rbuf[0] = '\0'; |
317 | fgets (rbuf, sizeof(rbuf), stdin); | | 317 | if (fgets(rbuf, sizeof(rbuf), stdin) == NULL) |
318 | if (!rbuf[0]) | | | |
319 | break; | | 318 | break; |
320 | if (rbuf[strlen(rbuf)-1] == '\n') | | 319 | if (rbuf[strlen(rbuf)-1] == '\n') |
321 | rbuf[strlen(rbuf)-1] = '\0'; | | 320 | rbuf[strlen(rbuf)-1] = '\0'; |
322 | #endif | | 321 | #endif |
323 | comment = strchr(rbuf, '#'); | | 322 | comment = strchr(rbuf, '#'); |
324 | if (comment) | | 323 | if (comment) |
325 | *comment = '\0'; | | 324 | *comment = '\0'; |
326 | | | 325 | |
327 | if (!rbuf[0]) | | 326 | if (!rbuf[0]) |
328 | continue; | | 327 | continue; |
329 | | | 328 | |
330 | linelen += snprintf (&line[linelen], sizeof(line) - linelen, | | 329 | linelen += snprintf (&line[linelen], sizeof(line) - linelen, |
331 | "%s%s", linelen > 0 ? " " : "", rbuf); | | 330 | "%s%s", linelen > 0 ? " " : "", rbuf); |
332 | | | 331 | |
333 | semicolon = strchr(line, ';'); | | 332 | semicolon = strchr(line, ';'); |
334 | while (semicolon) { | | 333 | while (semicolon) { |
335 | char saved_char = *++semicolon; | | 334 | char saved_char = *++semicolon; |
336 | *semicolon = '\0'; | | 335 | *semicolon = '\0'; |
337 | #ifdef HAVE_READLINE | | 336 | #ifdef HAVE_READLINE |
338 | add_history (line); | | 337 | add_history (line); |
339 | #endif | | 338 | #endif |
340 | | | 339 | |
341 | #ifdef HAVE_PFKEY_POLICY_PRIORITY | | 340 | #ifdef HAVE_PFKEY_POLICY_PRIORITY |
342 | last_msg_type = -1; /* invalid message type */ | | 341 | last_msg_type = -1; /* invalid message type */ |
343 | #endif | | 342 | #endif |
344 | | | 343 | |
345 | parse_string (line); | | 344 | parse_string (line); |
346 | if (exit_now) | | 345 | if (exit_now) |
347 | return; | | 346 | return; |
348 | if (saved_char) { | | 347 | if (saved_char) { |
349 | *semicolon = saved_char; | | 348 | *semicolon = saved_char; |
350 | linelen = strlen (semicolon); | | 349 | linelen = strlen (semicolon); |
351 | memmove (line, semicolon, linelen + 1); | | 350 | memmove (line, semicolon, linelen + 1); |
352 | semicolon = strchr(line, ';'); | | 351 | semicolon = strchr(line, ';'); |
353 | } | | 352 | } |
354 | else { | | 353 | else { |
355 | semicolon = NULL; | | 354 | semicolon = NULL; |
356 | linelen = 0; | | 355 | linelen = 0; |
357 | } | | 356 | } |
358 | } | | 357 | } |
359 | } | | 358 | } |
360 | } | | 359 | } |
361 | | | 360 | |
362 | void | | 361 | void |
363 | sendkeyshort(type) | | 362 | sendkeyshort(type) |
364 | u_int type; | | 363 | u_int type; |
365 | { | | 364 | { |
366 | struct sadb_msg msg; | | 365 | struct sadb_msg msg; |
367 | | | 366 | |
368 | msg.sadb_msg_version = PF_KEY_V2; | | 367 | msg.sadb_msg_version = PF_KEY_V2; |
369 | msg.sadb_msg_type = type; | | 368 | msg.sadb_msg_type = type; |
370 | msg.sadb_msg_errno = 0; | | 369 | msg.sadb_msg_errno = 0; |
371 | msg.sadb_msg_satype = SADB_SATYPE_UNSPEC; | | 370 | msg.sadb_msg_satype = SADB_SATYPE_UNSPEC; |
372 | msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); | | 371 | msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); |
373 | msg.sadb_msg_reserved = 0; | | 372 | msg.sadb_msg_reserved = 0; |
374 | msg.sadb_msg_seq = 0; | | 373 | msg.sadb_msg_seq = 0; |
375 | msg.sadb_msg_pid = getpid(); | | 374 | msg.sadb_msg_pid = getpid(); |
376 | | | 375 | |
377 | sendkeymsg((char *)&msg, sizeof(msg)); | | 376 | sendkeymsg((char *)&msg, sizeof(msg)); |
378 | | | 377 | |
379 | return; | | 378 | return; |
380 | } | | 379 | } |
381 | | | 380 | |
382 | void | | 381 | void |
383 | promisc() | | 382 | promisc() |
384 | { | | 383 | { |
385 | struct sadb_msg msg; | | 384 | struct sadb_msg msg; |
386 | u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ | | 385 | u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ |
387 | ssize_t l; | | 386 | ssize_t l; |
388 | | | 387 | |
389 | msg.sadb_msg_version = PF_KEY_V2; | | 388 | msg.sadb_msg_version = PF_KEY_V2; |
390 | msg.sadb_msg_type = SADB_X_PROMISC; | | 389 | msg.sadb_msg_type = SADB_X_PROMISC; |
391 | msg.sadb_msg_errno = 0; | | 390 | msg.sadb_msg_errno = 0; |
392 | msg.sadb_msg_satype = 1; | | 391 | msg.sadb_msg_satype = 1; |
393 | msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); | | 392 | msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); |
394 | msg.sadb_msg_reserved = 0; | | 393 | msg.sadb_msg_reserved = 0; |
395 | msg.sadb_msg_seq = 0; | | 394 | msg.sadb_msg_seq = 0; |
396 | msg.sadb_msg_pid = getpid(); | | 395 | msg.sadb_msg_pid = getpid(); |
397 | | | 396 | |
398 | if ((l = send(so, &msg, sizeof(msg), 0)) < 0) { | | 397 | if ((l = send(so, &msg, sizeof(msg), 0)) < 0) { |
399 | err(1, "send"); | | 398 | err(1, "send"); |
400 | /*NOTREACHED*/ | | 399 | /*NOTREACHED*/ |
401 | } | | 400 | } |
402 | | | 401 | |
403 | while (1) { | | 402 | while (1) { |
404 | struct sadb_msg *base; | | 403 | struct sadb_msg *base; |
405 | | | 404 | |
406 | if ((l = recv(so, rbuf, sizeof(*base), MSG_PEEK)) < 0) { | | 405 | if ((l = recv(so, rbuf, sizeof(*base), MSG_PEEK)) < 0) { |
407 | err(1, "recv"); | | 406 | err(1, "recv"); |
408 | /*NOTREACHED*/ | | 407 | /*NOTREACHED*/ |
409 | } | | 408 | } |
410 | | | 409 | |
411 | if (l != sizeof(*base)) | | 410 | if (l != sizeof(*base)) |
412 | continue; | | 411 | continue; |
413 | | | 412 | |
414 | base = (struct sadb_msg *)rbuf; | | 413 | base = (struct sadb_msg *)rbuf; |
415 | if ((l = recv(so, rbuf, PFKEY_UNUNIT64(base->sadb_msg_len), | | 414 | if ((l = recv(so, rbuf, PFKEY_UNUNIT64(base->sadb_msg_len), |
416 | 0)) < 0) { | | 415 | 0)) < 0) { |
417 | err(1, "recv"); | | 416 | err(1, "recv"); |
418 | /*NOTREACHED*/ | | 417 | /*NOTREACHED*/ |
419 | } | | 418 | } |
420 | printdate(); | | 419 | printdate(); |
421 | if (f_hexdump) { | | 420 | if (f_hexdump) { |
422 | int i; | | 421 | int i; |
423 | for (i = 0; i < l; i++) { | | 422 | for (i = 0; i < l; i++) { |
424 | if (i % 16 == 0) | | 423 | if (i % 16 == 0) |
425 | printf("%08x: ", i); | | 424 | printf("%08x: ", i); |
426 | printf("%02x ", rbuf[i] & 0xff); | | 425 | printf("%02x ", rbuf[i] & 0xff); |
427 | if (i % 16 == 15) | | 426 | if (i % 16 == 15) |
428 | printf("\n"); | | 427 | printf("\n"); |
429 | } | | 428 | } |
430 | if (l % 16) | | 429 | if (l % 16) |
431 | printf("\n"); | | 430 | printf("\n"); |
432 | } | | 431 | } |
433 | /* adjust base pointer for promisc mode */ | | 432 | /* adjust base pointer for promisc mode */ |
434 | if (base->sadb_msg_type == SADB_X_PROMISC) { | | 433 | if (base->sadb_msg_type == SADB_X_PROMISC) { |
435 | if ((ssize_t)sizeof(*base) < l) | | 434 | if ((ssize_t)sizeof(*base) < l) |
436 | base++; | | 435 | base++; |
437 | else | | 436 | else |
438 | base = NULL; | | 437 | base = NULL; |
439 | } | | 438 | } |
440 | if (base) { | | 439 | if (base) { |
441 | kdebug_sadb(base); | | 440 | kdebug_sadb(base); |
442 | printf("\n"); | | 441 | printf("\n"); |
443 | fflush(stdout); | | 442 | fflush(stdout); |
444 | } | | 443 | } |
445 | } | | 444 | } |
446 | } | | 445 | } |
447 | | | 446 | |
448 | int | | 447 | int |
449 | sendkeymsg(buf, len) | | 448 | sendkeymsg(buf, len) |
450 | char *buf; | | 449 | char *buf; |
451 | size_t len; | | 450 | size_t len; |
452 | { | | 451 | { |
453 | u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ | | 452 | u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ |
454 | ssize_t l; | | 453 | ssize_t l; |
455 | struct sadb_msg *msg; | | 454 | struct sadb_msg *msg; |
456 | | | 455 | |
457 | if (f_notreally) { | | 456 | if (f_notreally) { |
458 | goto end; | | 457 | goto end; |
459 | } | | 458 | } |
460 | | | 459 | |
461 | { | | 460 | { |
462 | struct timeval tv; | | 461 | struct timeval tv; |
463 | tv.tv_sec = 1; | | 462 | tv.tv_sec = 1; |
464 | tv.tv_usec = 0; | | 463 | tv.tv_usec = 0; |
465 | if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { | | 464 | if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { |
466 | perror("setsockopt"); | | 465 | perror("setsockopt"); |
467 | goto end; | | 466 | goto end; |
468 | } | | 467 | } |
469 | } | | 468 | } |
470 | | | 469 | |
471 | if (f_forever) | | 470 | if (f_forever) |
472 | shortdump_hdr(); | | 471 | shortdump_hdr(); |
473 | again: | | 472 | again: |
474 | if (f_verbose) { | | 473 | if (f_verbose) { |
475 | kdebug_sadb((struct sadb_msg *)buf); | | 474 | kdebug_sadb((struct sadb_msg *)buf); |
476 | printf("\n"); | | 475 | printf("\n"); |
477 | } | | 476 | } |
478 | if (f_hexdump) { | | 477 | if (f_hexdump) { |
479 | int i; | | 478 | int i; |
480 | for (i = 0; i < len; i++) { | | 479 | for (i = 0; i < len; i++) { |
481 | if (i % 16 == 0) | | 480 | if (i % 16 == 0) |
482 | printf("%08x: ", i); | | 481 | printf("%08x: ", i); |
483 | printf("%02x ", buf[i] & 0xff); | | 482 | printf("%02x ", buf[i] & 0xff); |
484 | if (i % 16 == 15) | | 483 | if (i % 16 == 15) |
485 | printf("\n"); | | 484 | printf("\n"); |
486 | } | | 485 | } |
487 | if (len % 16) | | 486 | if (len % 16) |
488 | printf("\n"); | | 487 | printf("\n"); |
489 | } | | 488 | } |
490 | | | 489 | |
491 | if ((l = send(so, buf, len, 0)) < 0) { | | 490 | if ((l = send(so, buf, len, 0)) < 0) { |
492 | perror("send"); | | 491 | perror("send"); |
493 | goto end; | | 492 | goto end; |
494 | } | | 493 | } |
495 | | | 494 | |
496 | msg = (struct sadb_msg *)rbuf; | | 495 | msg = (struct sadb_msg *)rbuf; |
497 | do { | | 496 | do { |
498 | if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { | | 497 | if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { |
499 | perror("recv"); | | 498 | perror("recv"); |
500 | goto end; | | 499 | goto end; |
501 | } | | 500 | } |
502 | | | 501 | |
503 | if (PFKEY_UNUNIT64(msg->sadb_msg_len) != l) { | | 502 | if (PFKEY_UNUNIT64(msg->sadb_msg_len) != l) { |
504 | warnx("invalid keymsg length"); | | 503 | warnx("invalid keymsg length"); |
505 | break; | | 504 | break; |
506 | } | | 505 | } |
507 | | | 506 | |
508 | if (f_verbose) { | | 507 | if (f_verbose) { |
509 | kdebug_sadb((struct sadb_msg *)rbuf); | | 508 | kdebug_sadb((struct sadb_msg *)rbuf); |
510 | printf("\n"); | | 509 | printf("\n"); |
511 | } | | 510 | } |
512 | if (postproc(msg, l) < 0) | | 511 | if (postproc(msg, l) < 0) |
513 | break; | | 512 | break; |
514 | } while (msg->sadb_msg_errno || msg->sadb_msg_seq); | | 513 | } while (msg->sadb_msg_errno || msg->sadb_msg_seq); |
515 | | | 514 | |
516 | if (f_forever) { | | 515 | if (f_forever) { |
517 | fflush(stdout); | | 516 | fflush(stdout); |
518 | sleep(1); | | 517 | sleep(1); |
519 | goto again; | | 518 | goto again; |
520 | } | | 519 | } |
521 | | | 520 | |
522 | end: | | 521 | end: |
523 | return (0); | | 522 | return (0); |
524 | } | | 523 | } |
525 | | | 524 | |
526 | int | | 525 | int |
527 | postproc(msg, len) | | 526 | postproc(msg, len) |
528 | struct sadb_msg *msg; | | 527 | struct sadb_msg *msg; |
529 | int len; | | 528 | int len; |
530 | { | | 529 | { |
531 | #ifdef HAVE_PFKEY_POLICY_PRIORITY | | 530 | #ifdef HAVE_PFKEY_POLICY_PRIORITY |
532 | static int priority_support_check = 0; | | 531 | static int priority_support_check = 0; |
533 | #endif | | 532 | #endif |
534 | | | 533 | |
535 | if (msg->sadb_msg_errno != 0) { | | 534 | if (msg->sadb_msg_errno != 0) { |
536 | char inf[80]; | | 535 | char inf[80]; |
537 | const char *errmsg = NULL; | | 536 | const char *errmsg = NULL; |
538 | | | 537 | |
539 | if (f_mode == MODE_SCRIPT) | | 538 | if (f_mode == MODE_SCRIPT) |
540 | snprintf(inf, sizeof(inf), "The result of line %d: ", lineno); | | 539 | snprintf(inf, sizeof(inf), "The result of line %d: ", lineno); |
541 | else | | 540 | else |
542 | inf[0] = '\0'; | | 541 | inf[0] = '\0'; |
543 | | | 542 | |
544 | switch (msg->sadb_msg_errno) { | | 543 | switch (msg->sadb_msg_errno) { |
545 | case ENOENT: | | 544 | case ENOENT: |
546 | switch (msg->sadb_msg_type) { | | 545 | switch (msg->sadb_msg_type) { |
547 | case SADB_DELETE: | | 546 | case SADB_DELETE: |
548 | case SADB_GET: | | 547 | case SADB_GET: |
549 | case SADB_X_SPDDELETE: | | 548 | case SADB_X_SPDDELETE: |
550 | errmsg = "No entry"; | | 549 | errmsg = "No entry"; |
551 | break; | | 550 | break; |
552 | case SADB_DUMP: | | 551 | case SADB_DUMP: |
553 | errmsg = "No SAD entries"; | | 552 | errmsg = "No SAD entries"; |
554 | break; | | 553 | break; |
555 | case SADB_X_SPDDUMP: | | 554 | case SADB_X_SPDDUMP: |
556 | errmsg = "No SPD entries"; | | 555 | errmsg = "No SPD entries"; |
557 | break; | | 556 | break; |
558 | } | | 557 | } |
559 | break; | | 558 | break; |
560 | default: | | 559 | default: |
561 | errmsg = strerror(msg->sadb_msg_errno); | | 560 | errmsg = strerror(msg->sadb_msg_errno); |
562 | } | | 561 | } |
563 | printf("%s%s.\n", inf, errmsg); | | 562 | printf("%s%s.\n", inf, errmsg); |
564 | return (-1); | | 563 | return (-1); |
565 | } | | 564 | } |
566 | | | 565 | |
567 | switch (msg->sadb_msg_type) { | | 566 | switch (msg->sadb_msg_type) { |
568 | case SADB_GET: | | 567 | case SADB_GET: |
569 | if (f_withports) | | 568 | if (f_withports) |
570 | pfkey_sadump_withports(msg); | | 569 | pfkey_sadump_withports(msg); |
571 | else | | 570 | else |
572 | pfkey_sadump(msg); | | 571 | pfkey_sadump(msg); |
573 | break; | | 572 | break; |
574 | | | 573 | |
575 | case SADB_DUMP: | | 574 | case SADB_DUMP: |
576 | /* filter out DEAD SAs */ | | 575 | /* filter out DEAD SAs */ |
577 | if (!f_all) { | | 576 | if (!f_all) { |
578 | caddr_t mhp[SADB_EXT_MAX + 1]; | | 577 | caddr_t mhp[SADB_EXT_MAX + 1]; |
579 | struct sadb_sa *sa; | | 578 | struct sadb_sa *sa; |
580 | pfkey_align(msg, mhp); | | 579 | pfkey_align(msg, mhp); |
581 | pfkey_check(mhp); | | 580 | pfkey_check(mhp); |
582 | if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { | | 581 | if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { |
583 | if (sa->sadb_sa_state == SADB_SASTATE_DEAD) | | 582 | if (sa->sadb_sa_state == SADB_SASTATE_DEAD) |
584 | break; | | 583 | break; |
585 | } | | 584 | } |
586 | } | | 585 | } |
587 | if (f_forever) { | | 586 | if (f_forever) { |
588 | /* TODO: f_withports */ | | 587 | /* TODO: f_withports */ |
589 | shortdump(msg); | | 588 | shortdump(msg); |
590 | } else { | | 589 | } else { |
591 | if (f_withports) | | 590 | if (f_withports) |
592 | pfkey_sadump_withports(msg); | | 591 | pfkey_sadump_withports(msg); |
593 | else | | 592 | else |
594 | pfkey_sadump(msg); | | 593 | pfkey_sadump(msg); |
595 | } | | 594 | } |
596 | msg = (struct sadb_msg *)((caddr_t)msg + | | 595 | msg = (struct sadb_msg *)((caddr_t)msg + |
597 | PFKEY_UNUNIT64(msg->sadb_msg_len)); | | 596 | PFKEY_UNUNIT64(msg->sadb_msg_len)); |
598 | if (f_verbose) { | | 597 | if (f_verbose) { |
599 | kdebug_sadb((struct sadb_msg *)msg); | | 598 | kdebug_sadb((struct sadb_msg *)msg); |
600 | printf("\n"); | | 599 | printf("\n"); |
601 | } | | 600 | } |
602 | break; | | 601 | break; |
603 | | | 602 | |
604 | case SADB_X_SPDGET: | | 603 | case SADB_X_SPDGET: |
605 | if (f_withports) | | 604 | if (f_withports) |
606 | pfkey_spdump_withports(msg); | | 605 | pfkey_spdump_withports(msg); |
607 | else | | 606 | else |
608 | pfkey_spdump(msg); | | 607 | pfkey_spdump(msg); |
609 | break; | | 608 | break; |
610 | | | 609 | |
611 | case SADB_X_SPDDUMP: | | 610 | case SADB_X_SPDDUMP: |
612 | if (f_withports) | | 611 | if (f_withports) |
613 | pfkey_spdump_withports(msg); | | 612 | pfkey_spdump_withports(msg); |
614 | else | | 613 | else |
615 | pfkey_spdump(msg); | | 614 | pfkey_spdump(msg); |
616 | if (msg->sadb_msg_seq == 0) break; | | 615 | if (msg->sadb_msg_seq == 0) break; |
617 | msg = (struct sadb_msg *)((caddr_t)msg + | | 616 | msg = (struct sadb_msg *)((caddr_t)msg + |
618 | PFKEY_UNUNIT64(msg->sadb_msg_len)); | | 617 | PFKEY_UNUNIT64(msg->sadb_msg_len)); |
619 | if (f_verbose) { | | 618 | if (f_verbose) { |
620 | kdebug_sadb((struct sadb_msg *)msg); | | 619 | kdebug_sadb((struct sadb_msg *)msg); |
621 | printf("\n"); | | 620 | printf("\n"); |
622 | } | | 621 | } |
623 | break; | | 622 | break; |
624 | #ifdef HAVE_PFKEY_POLICY_PRIORITY | | 623 | #ifdef HAVE_PFKEY_POLICY_PRIORITY |
625 | case SADB_X_SPDADD: | | 624 | case SADB_X_SPDADD: |
626 | if (last_msg_type == SADB_X_SPDADD && last_priority != 0 && | | 625 | if (last_msg_type == SADB_X_SPDADD && last_priority != 0 && |
627 | msg->sadb_msg_pid == getpid() && !priority_support_check) { | | 626 | msg->sadb_msg_pid == getpid() && !priority_support_check) { |
628 | priority_support_check = 1; | | 627 | priority_support_check = 1; |
629 | if (!verifypriority(msg)) | | 628 | if (!verifypriority(msg)) |
630 | printf ("WARNING: Kernel does not support policy priorities\n"); | | 629 | printf ("WARNING: Kernel does not support policy priorities\n"); |
631 | } | | 630 | } |
632 | break; | | 631 | break; |
633 | #endif | | 632 | #endif |
634 | } | | 633 | } |
635 | | | 634 | |
636 | return (0); | | 635 | return (0); |
637 | } | | 636 | } |
638 | | | 637 | |
639 | #ifdef HAVE_PFKEY_POLICY_PRIORITY | | 638 | #ifdef HAVE_PFKEY_POLICY_PRIORITY |
640 | int | | 639 | int |
641 | verifypriority(m) | | 640 | verifypriority(m) |
642 | struct sadb_msg *m; | | 641 | struct sadb_msg *m; |
643 | { | | 642 | { |
644 | caddr_t mhp[SADB_EXT_MAX + 1]; | | 643 | caddr_t mhp[SADB_EXT_MAX + 1]; |
645 | struct sadb_x_policy *xpl; | | 644 | struct sadb_x_policy *xpl; |
646 | | | 645 | |
647 | /* check pfkey message. */ | | 646 | /* check pfkey message. */ |
648 | if (pfkey_align(m, mhp)) { | | 647 | if (pfkey_align(m, mhp)) { |
649 | printf("(%s\n", ipsec_strerror()); | | 648 | printf("(%s\n", ipsec_strerror()); |
650 | return 0; | | 649 | return 0; |
651 | } | | 650 | } |
652 | if (pfkey_check(mhp)) { | | 651 | if (pfkey_check(mhp)) { |
653 | printf("%s\n", ipsec_strerror()); | | 652 | printf("%s\n", ipsec_strerror()); |
654 | return 0; | | 653 | return 0; |
655 | } | | 654 | } |
656 | | | 655 | |
657 | xpl = (struct sadb_x_policy *) mhp[SADB_X_EXT_POLICY]; | | 656 | xpl = (struct sadb_x_policy *) mhp[SADB_X_EXT_POLICY]; |
658 | | | 657 | |
659 | if (xpl == NULL) { | | 658 | if (xpl == NULL) { |
660 | printf("no X_POLICY extension.\n"); | | 659 | printf("no X_POLICY extension.\n"); |
661 | return 0; | | 660 | return 0; |
662 | } | | 661 | } |
663 | | | 662 | |
664 | /* now make sure they match */ | | 663 | /* now make sure they match */ |
665 | if (last_priority != xpl->sadb_x_policy_priority) | | 664 | if (last_priority != xpl->sadb_x_policy_priority) |
666 | return 0; | | 665 | return 0; |
667 | | | 666 | |
668 | return 1; | | 667 | return 1; |
669 | } | | 668 | } |
670 | #endif | | 669 | #endif |
671 | | | 670 | |
672 | int | | 671 | int |
673 | fileproc(filename) | | 672 | fileproc(filename) |
674 | const char *filename; | | 673 | const char *filename; |
675 | { | | 674 | { |
676 | int fd; | | 675 | int fd; |
677 | ssize_t len, l; | | 676 | ssize_t len, l; |
678 | u_char *p, *ep; | | 677 | u_char *p, *ep; |
679 | struct sadb_msg *msg; | | 678 | struct sadb_msg *msg; |
680 | u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ | | 679 | u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ |
681 | | | 680 | |
682 | fd = open(filename, O_RDONLY); | | 681 | fd = open(filename, O_RDONLY); |
683 | if (fd < 0) | | 682 | if (fd < 0) |
684 | return -1; | | 683 | return -1; |
685 | | | 684 | |
686 | l = 0; | | 685 | l = 0; |
687 | while (1) { | | 686 | while (1) { |
688 | len = read(fd, rbuf + l, sizeof(rbuf) - l); | | 687 | len = read(fd, rbuf + l, sizeof(rbuf) - l); |
689 | if (len < 0) { | | 688 | if (len < 0) { |
690 | close(fd); | | 689 | close(fd); |
691 | return -1; | | 690 | return -1; |
692 | } else if (len == 0) | | 691 | } else if (len == 0) |
693 | break; | | 692 | break; |
694 | l += len; | | 693 | l += len; |
695 | } | | 694 | } |
696 | | | 695 | |
697 | if (l < sizeof(struct sadb_msg)) { | | 696 | if (l < sizeof(struct sadb_msg)) { |
698 | close(fd); | | 697 | close(fd); |
699 | errno = EINVAL; | | 698 | errno = EINVAL; |
700 | return -1; | | 699 | return -1; |
701 | } | | 700 | } |
702 | close(fd); | | 701 | close(fd); |
703 | | | 702 | |
704 | p = rbuf; | | 703 | p = rbuf; |
705 | ep = rbuf + l; | | 704 | ep = rbuf + l; |
706 | | | 705 | |
707 | while (p < ep) { | | 706 | while (p < ep) { |
708 | msg = (struct sadb_msg *)p; | | 707 | msg = (struct sadb_msg *)p; |
709 | len = PFKEY_UNUNIT64(msg->sadb_msg_len); | | 708 | len = PFKEY_UNUNIT64(msg->sadb_msg_len); |
710 | postproc(msg, len); | | 709 | postproc(msg, len); |
711 | p += len; | | 710 | p += len; |
712 | } | | 711 | } |
713 | | | 712 | |
714 | return (0); | | 713 | return (0); |
715 | } | | 714 | } |
716 | | | 715 | |
717 | | | 716 | |
718 | /*------------------------------------------------------------*/ | | 717 | /*------------------------------------------------------------*/ |
719 | static const char *satype[] = { | | 718 | static const char *satype[] = { |
720 | NULL, NULL, "ah", "esp" | | 719 | NULL, NULL, "ah", "esp" |
721 | }; | | 720 | }; |
722 | static const char *sastate[] = { | | 721 | static const char *sastate[] = { |
723 | "L", "M", "D", "d" | | 722 | "L", "M", "D", "d" |
724 | }; | | 723 | }; |
725 | static const char *ipproto[] = { | | 724 | static const char *ipproto[] = { |
726 | /*0*/ "ip", "icmp", "igmp", "ggp", "ip4", | | 725 | /*0*/ "ip", "icmp", "igmp", "ggp", "ip4", |
727 | NULL, "tcp", NULL, "egp", NULL, | | 726 | NULL, "tcp", NULL, "egp", NULL, |
728 | /*10*/ NULL, NULL, NULL, NULL, NULL, | | 727 | /*10*/ NULL, NULL, NULL, NULL, NULL, |
729 | NULL, NULL, "udp", NULL, NULL, | | 728 | NULL, NULL, "udp", NULL, NULL, |
730 | /*20*/ NULL, NULL, "idp", NULL, NULL, | | 729 | /*20*/ NULL, NULL, "idp", NULL, NULL, |
731 | NULL, NULL, NULL, NULL, "tp", | | 730 | NULL, NULL, NULL, NULL, "tp", |
732 | /*30*/ NULL, NULL, NULL, NULL, NULL, | | 731 | /*30*/ NULL, NULL, NULL, NULL, NULL, |
733 | NULL, NULL, NULL, NULL, NULL, | | 732 | NULL, NULL, NULL, NULL, NULL, |
734 | /*40*/ NULL, "ip6", NULL, "rt6", "frag6", | | 733 | /*40*/ NULL, "ip6", NULL, "rt6", "frag6", |
735 | NULL, "rsvp", "gre", NULL, NULL, | | 734 | NULL, "rsvp", "gre", NULL, NULL, |
736 | /*50*/ "esp", "ah", NULL, NULL, NULL, | | 735 | /*50*/ "esp", "ah", NULL, NULL, NULL, |
737 | NULL, NULL, NULL, "icmp6", "none", | | 736 | NULL, NULL, NULL, "icmp6", "none", |
738 | /*60*/ "dst6", | | 737 | /*60*/ "dst6", |
739 | }; | | 738 | }; |
740 | | | 739 | |
741 | #define STR_OR_ID(x, tab) \ | | 740 | #define STR_OR_ID(x, tab) \ |
742 | (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) | | 741 | (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) |
743 | | | 742 | |
744 | const char * | | 743 | const char * |
745 | numstr(x) | | 744 | numstr(x) |
746 | int x; | | 745 | int x; |
747 | { | | 746 | { |
748 | static char buf[20]; | | 747 | static char buf[20]; |
749 | snprintf(buf, sizeof(buf), "#%d", x); | | 748 | snprintf(buf, sizeof(buf), "#%d", x); |
750 | return buf; | | 749 | return buf; |
751 | } | | 750 | } |
752 | | | 751 | |
753 | void | | 752 | void |
754 | shortdump_hdr() | | 753 | shortdump_hdr() |
755 | { | | 754 | { |
756 | printf("%-4s %-3s %-1s %-8s %-7s %s -> %s\n", | | 755 | printf("%-4s %-3s %-1s %-8s %-7s %s -> %s\n", |
757 | "time", "p", "s", "spi", "ltime", "src", "dst"); | | 756 | "time", "p", "s", "spi", "ltime", "src", "dst"); |
758 | } | | 757 | } |
759 | | | 758 | |
760 | void | | 759 | void |
761 | shortdump(msg) | | 760 | shortdump(msg) |
762 | struct sadb_msg *msg; | | 761 | struct sadb_msg *msg; |
763 | { | | 762 | { |
764 | caddr_t mhp[SADB_EXT_MAX + 1]; | | 763 | caddr_t mhp[SADB_EXT_MAX + 1]; |
765 | char buf[NI_MAXHOST], pbuf[NI_MAXSERV]; | | 764 | char buf[NI_MAXHOST], pbuf[NI_MAXSERV]; |
766 | struct sadb_sa *sa; | | 765 | struct sadb_sa *sa; |
767 | struct sadb_address *saddr; | | 766 | struct sadb_address *saddr; |
768 | struct sadb_lifetime *lts, *lth, *ltc; | | 767 | struct sadb_lifetime *lts, *lth, *ltc; |
769 | struct sockaddr *s; | | 768 | struct sockaddr *s; |
770 | u_int t; | | 769 | u_int t; |
771 | time_t cur = time(0); | | 770 | time_t cur = time(0); |
772 | | | 771 | |
773 | pfkey_align(msg, mhp); | | 772 | pfkey_align(msg, mhp); |
774 | pfkey_check(mhp); | | 773 | pfkey_check(mhp); |
775 | | | 774 | |
776 | printf("%02lu%02lu", (u_long)(cur % 3600) / 60, (u_long)(cur % 60)); | | 775 | printf("%02lu%02lu", (u_long)(cur % 3600) / 60, (u_long)(cur % 60)); |
777 | | | 776 | |
778 | printf(" %-3s", STR_OR_ID(msg->sadb_msg_satype, satype)); | | 777 | printf(" %-3s", STR_OR_ID(msg->sadb_msg_satype, satype)); |
779 | | | 778 | |
780 | if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { | | 779 | if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) { |
781 | printf(" %-1s", STR_OR_ID(sa->sadb_sa_state, sastate)); | | 780 | printf(" %-1s", STR_OR_ID(sa->sadb_sa_state, sastate)); |
782 | printf(" %08x", (u_int32_t)ntohl(sa->sadb_sa_spi)); | | 781 | printf(" %08x", (u_int32_t)ntohl(sa->sadb_sa_spi)); |
783 | } else | | 782 | } else |
784 | printf("%-1s %-8s", "?", "?"); | | 783 | printf("%-1s %-8s", "?", "?"); |
785 | | | 784 | |
786 | lts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT]; | | 785 | lts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT]; |
787 | lth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; | | 786 | lth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD]; |
788 | ltc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT]; | | 787 | ltc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT]; |
789 | if (lts && lth && ltc) { | | 788 | if (lts && lth && ltc) { |
790 | if (ltc->sadb_lifetime_addtime == 0) | | 789 | if (ltc->sadb_lifetime_addtime == 0) |
791 | t = (u_long)0; | | 790 | t = (u_long)0; |
792 | else | | 791 | else |
793 | t = (u_long)(cur - ltc->sadb_lifetime_addtime); | | 792 | t = (u_long)(cur - ltc->sadb_lifetime_addtime); |
794 | if (t >= 1000) | | 793 | if (t >= 1000) |
795 | strlcpy(buf, " big/", sizeof(buf)); | | 794 | strlcpy(buf, " big/", sizeof(buf)); |
796 | else | | 795 | else |
797 | snprintf(buf, sizeof(buf), " %3lu/", (u_long)t); | | 796 | snprintf(buf, sizeof(buf), " %3lu/", (u_long)t); |
798 | printf("%s", buf); | | 797 | printf("%s", buf); |
799 | | | 798 | |
800 | t = (u_long)lth->sadb_lifetime_addtime; | | 799 | t = (u_long)lth->sadb_lifetime_addtime; |
801 | if (t >= 1000) | | 800 | if (t >= 1000) |
802 | strlcpy(buf, "big", sizeof(buf)); | | 801 | strlcpy(buf, "big", sizeof(buf)); |
803 | else | | 802 | else |
804 | snprintf(buf, sizeof(buf), "%-3lu", (u_long)t); | | 803 | snprintf(buf, sizeof(buf), "%-3lu", (u_long)t); |
805 | printf("%s", buf); | | 804 | printf("%s", buf); |
806 | } else | | 805 | } else |
807 | printf(" ??\?/???"); /* backslash to avoid trigraph ??/ */ | | 806 | printf(" ??\?/???"); /* backslash to avoid trigraph ??/ */ |
808 | | | 807 | |
809 | printf(" "); | | 808 | printf(" "); |
810 | | | 809 | |
811 | if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]) != NULL) { | | 810 | if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]) != NULL) { |
812 | if (saddr->sadb_address_proto) | | 811 | if (saddr->sadb_address_proto) |
813 | printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); | | 812 | printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); |
814 | s = (struct sockaddr *)(saddr + 1); | | 813 | s = (struct sockaddr *)(saddr + 1); |
815 | getnameinfo(s, sysdep_sa_len(s), buf, sizeof(buf), | | 814 | getnameinfo(s, sysdep_sa_len(s), buf, sizeof(buf), |
816 | pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); | | 815 | pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); |
817 | if (strcmp(pbuf, "0") != 0) | | 816 | if (strcmp(pbuf, "0") != 0) |
818 | printf("%s[%s]", buf, pbuf); | | 817 | printf("%s[%s]", buf, pbuf); |
819 | else | | 818 | else |
820 | printf("%s", buf); | | 819 | printf("%s", buf); |
821 | } else | | 820 | } else |
822 | printf("?"); | | 821 | printf("?"); |
823 | | | 822 | |
824 | printf(" -> "); | | 823 | printf(" -> "); |
825 | | | 824 | |
826 | if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]) != NULL) { | | 825 | if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]) != NULL) { |
827 | if (saddr->sadb_address_proto) | | 826 | if (saddr->sadb_address_proto) |
828 | printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); | | 827 | printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto)); |
829 | | | 828 | |
830 | s = (struct sockaddr *)(saddr + 1); | | 829 | s = (struct sockaddr *)(saddr + 1); |
831 | getnameinfo(s, sysdep_sa_len(s), buf, sizeof(buf), | | 830 | getnameinfo(s, sysdep_sa_len(s), buf, sizeof(buf), |
832 | pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); | | 831 | pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); |
833 | if (strcmp(pbuf, "0") != 0) | | 832 | if (strcmp(pbuf, "0") != 0) |
834 | printf("%s[%s]", buf, pbuf); | | 833 | printf("%s[%s]", buf, pbuf); |
835 | else | | 834 | else |
836 | printf("%s", buf); | | 835 | printf("%s", buf); |
837 | } else | | 836 | } else |
838 | printf("?"); | | 837 | printf("?"); |
839 | | | 838 | |
840 | printf("\n"); | | 839 | printf("\n"); |
841 | } | | 840 | } |
842 | | | 841 | |
843 | /* From: tcpdump(1):gmt2local.c and util.c */ | | 842 | /* From: tcpdump(1):gmt2local.c and util.c */ |
844 | /* | | 843 | /* |
845 | * Print the timestamp | | 844 | * Print the timestamp |
846 | */ | | 845 | */ |
847 | static void | | 846 | static void |
848 | printdate() | | 847 | printdate() |
849 | { | | 848 | { |
850 | struct timeval tp; | | 849 | struct timeval tp; |
851 | int s; | | 850 | int s; |
852 | | | 851 | |
853 | if (gettimeofday(&tp, NULL) == -1) { | | 852 | if (gettimeofday(&tp, NULL) == -1) { |
854 | perror("gettimeofday"); | | 853 | perror("gettimeofday"); |
855 | return; | | 854 | return; |
856 | } | | 855 | } |
857 | | | 856 | |
858 | if (f_tflag == 1) { | | 857 | if (f_tflag == 1) { |
859 | /* Default */ | | 858 | /* Default */ |
860 | s = (tp.tv_sec + thiszone ) % 86400; | | 859 | s = (tp.tv_sec + thiszone ) % 86400; |
861 | (void)printf("%02d:%02d:%02d.%06u ", | | 860 | (void)printf("%02d:%02d:%02d.%06u ", |
862 | s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tp.tv_usec); | | 861 | s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tp.tv_usec); |
863 | } else if (f_tflag > 1) { | | 862 | } else if (f_tflag > 1) { |
864 | /* Unix timeval style */ | | 863 | /* Unix timeval style */ |
865 | (void)printf("%u.%06u ", | | 864 | (void)printf("%u.%06u ", |
866 | (u_int32_t)tp.tv_sec, (u_int32_t)tp.tv_usec); | | 865 | (u_int32_t)tp.tv_sec, (u_int32_t)tp.tv_usec); |
867 | } | | 866 | } |
868 | | | 867 | |
869 | printf("\n"); | | 868 | printf("\n"); |
870 | } | | 869 | } |
871 | | | 870 | |
872 | /* | | 871 | /* |
873 | * Returns the difference between gmt and local time in seconds. | | 872 | * Returns the difference between gmt and local time in seconds. |
874 | * Use gmtime() and localtime() to keep things simple. | | 873 | * Use gmtime() and localtime() to keep things simple. |
875 | */ | | 874 | */ |
876 | int32_t | | 875 | int32_t |
877 | gmt2local(time_t t) | | 876 | gmt2local(time_t t) |
878 | { | | 877 | { |
879 | register int dt, dir; | | 878 | register int dt, dir; |
880 | register struct tm *gmt, *loc; | | 879 | register struct tm *gmt, *loc; |
881 | struct tm sgmt; | | 880 | struct tm sgmt; |
882 | | | 881 | |
883 | if (t == 0) | | 882 | if (t == 0) |
884 | t = time(NULL); | | 883 | t = time(NULL); |
885 | gmt = &sgmt; | | 884 | gmt = &sgmt; |
886 | *gmt = *gmtime(&t); | | 885 | *gmt = *gmtime(&t); |
887 | loc = localtime(&t); | | 886 | loc = localtime(&t); |
888 | dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + | | 887 | dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + |
889 | (loc->tm_min - gmt->tm_min) * 60; | | 888 | (loc->tm_min - gmt->tm_min) * 60; |
890 | | | 889 | |
891 | /* | | 890 | /* |
892 | * If the year or julian day is different, we span 00:00 GMT | | 891 | * If the year or julian day is different, we span 00:00 GMT |
893 | * and must add or subtract a day. Check the year first to | | 892 | * and must add or subtract a day. Check the year first to |
894 | * avoid problems when the julian day wraps. | | 893 | * avoid problems when the julian day wraps. |
895 | */ | | 894 | */ |
896 | dir = loc->tm_year - gmt->tm_year; | | 895 | dir = loc->tm_year - gmt->tm_year; |
897 | if (dir == 0) | | 896 | if (dir == 0) |
898 | dir = loc->tm_yday - gmt->tm_yday; | | 897 | dir = loc->tm_yday - gmt->tm_yday; |
899 | dt += dir * 24 * 60 * 60; | | 898 | dt += dir * 24 * 60 * 60; |
900 | | | 899 | |
901 | return (dt); | | 900 | return (dt); |
902 | } | | 901 | } |