4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1998-1999,2001 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include <sys/socket.h>
31 #include <netinet/in.h>
35 static void put_method(char *cp
, int method
);
36 static void put_socks5_addr(char *cp
, const unsigned char *buf
, int fraglen
);
37 static void put_socks4_res(char *cp
, int code
);
38 static void put_socks5_res(char *cp
, int code
);
41 interpret_socks_call(flags
, line
, fraglen
)
46 unsigned char *buf
= (unsigned char *)line
;
48 struct in_addr ipaddr
;
61 (void) memcpy(&ipaddr
, &buf
[4],
65 addrtoname(AF_INET
, &ipaddr
),
66 (n
== 1)? "CONNECT": "BIND",
67 (buf
[2] << 8) | buf
[3]);
70 (void) sprintf(cp
, " User=");
73 i
< 40 && i
< fraglen
;
89 (void) sprintf(cp
, "SOCKS4 OP=%u", n
);
94 if (2 + n
== fraglen
) {
96 "SOCKS5 CONTACT NMETHODS=%d:", n
);
98 for (i
= 0; i
< n
&& 2 + i
< fraglen
; ++i
) {
99 put_method(cp
, buf
[2 + i
]);
102 } else if (fraglen
>= 6 && buf
[2] == 0) {
105 if (n
< 1 || n
> 3) {
107 "SOCKS (send data): %s",
108 show_string(line
, fraglen
, 20));
118 cmd
= "ASSOCIATE_UDP";
121 (void) sprintf(cp
, "SOCKS5 %s ", cmd
);
123 put_socks5_addr(cp
, &buf
[3],
127 (void) sprintf(cp
, "SOCKS (send data): %s",
128 show_string(line
, fraglen
, 20));
132 (void) sprintf(cp
, "SOCKS (send data): %s",
133 show_string(line
, fraglen
, 20));
136 (void) sprintf(cp
, "SOCKS (send data): %s",
137 show_string(line
, fraglen
, 20));
140 } /* if (flags & F_SUM) */
142 if (flags
& F_DTAIL
) {
143 show_header("SOCKS: ", "SOCKS Header", fraglen
);
149 (void) sprintf(cp
, "Version = 4");
154 (void) sprintf(get_line(0, 0),
156 (n
== 1)? "CONNECT": "BIND");
158 (void) memcpy(&ipaddr
, &buf
[4],
160 (void) sprintf(get_line(0, 0),
161 "Destination = %s:%u",
164 (buf
[2] << 8) | buf
[3]);
187 (void) sprintf(get_line(0, 0),
188 "Operation = %u (unknown)", n
);
192 (void) sprintf(cp
, "Version = 5");
194 if (2 + n
== fraglen
) {
195 (void) sprintf(get_line(0, 0),
196 "Number of methods = %u", n
);
198 i
< n
&& 2 + i
< fraglen
; ++i
) {
203 put_method(cp
, buf
[2 + i
]);
205 } else if (fraglen
>= 6 && buf
[2] == 0) {
207 if (n
< 1 || n
> 3) {
209 "SOCKS (send data): %s",
221 cmd
= "ASSOCIATE_UDP";
224 (void) sprintf(get_line(0, 0),
225 "Operation = %s ", cmd
);
226 put_socks5_addr(get_line(0, 0),
227 &buf
[3], fraglen
- 3);
232 " SOCKS (send data): %s",
233 show_string(line
, fraglen
,
238 "SOCKS (send data): %s",
239 show_string(line
, fraglen
, 20));
244 "SOCKS (send data): %s",
245 show_string(line
, fraglen
, 20));
253 interpret_socks_reply(flags
, line
, fraglen
)
258 unsigned char *buf
= (unsigned char *)line
;
260 struct in_addr ipaddr
;
267 (void) sprintf(cp
, "SOCKS4 ");
270 (void) memcpy(&ipaddr
, &buf
[4],
272 (void) sprintf(cp
, "%s:%u ",
273 addrtoname(AF_INET
, &ipaddr
),
274 (buf
[2] << 8) | buf
[3]);
277 /* reply version, no SOCKS version in v4 */
278 put_socks4_res(cp
, buf
[1]);
281 (void) sprintf(cp
, "SOCKS5 method accepted:");
283 put_method(cp
, buf
[1]);
286 (void) sprintf(cp
, "SOCKS (recv data)");
289 (void) sprintf(cp
, "SOCKS (recv data)");
292 if (flags
& F_DTAIL
) {
293 show_header("SOCKS: ", "SOCKS Header", fraglen
);
299 /* reply version, no SOCKS version in v4 */
301 "Reply version = 0 (SOCKS version 4)");
303 (void) memcpy(&ipaddr
, &buf
[4],
305 (void) sprintf(get_line(0, 0),
306 "Destination %s:%u ",
307 addrtoname(AF_INET
, &ipaddr
),
308 (buf
[2] << 8) | buf
[3]);
311 (void) sprintf(cp
, "Result code = %u ", buf
[1]);
313 put_socks4_res(cp
, buf
[1]);
316 (void) sprintf(cp
, "Reply version = 5");
319 (void) sprintf(cp
, "Method accepted =");
321 put_method(cp
, buf
[1]);
322 } else if (fraglen
>= 6 && buf
[2] == 0x00) {
324 (void) sprintf(cp
, "Status = ");
326 put_socks5_res(cp
, buf
[1]);
327 put_socks5_addr(get_line(0, 0),
328 &buf
[3], fraglen
- 3);
332 (void) sprintf(cp
, "(recv data)");
335 (void) sprintf(cp
, "(recv data)");
344 put_method(char *cp
, int method
)
348 (void) sprintf(cp
, " NOAUTH");
351 (void) sprintf(cp
, " GSSAPI");
354 (void) sprintf(cp
, " USERNAME/PASSWD");
357 (void) sprintf(cp
, " NONE");
360 (void) sprintf(cp
, " 0x%02x (unknown)", method
);
365 put_socks5_addr(char *cp
, const unsigned char *buf
, int fraglen
)
367 struct in_addr ipaddr
;
373 (void) sprintf(cp
, "Address = ");
375 if (1 + 4 + 2 <= fraglen
) {
376 (void) memcpy(&ipaddr
, &buf
[1], sizeof (ipaddr
));
377 (void) sprintf(cp
, "%s:%u",
378 addrtoname(AF_INET
, &ipaddr
),
379 (buf
[5] << 8) | buf
[5 + 1]);
381 (void) strcat(cp
, "(IPv4)");
385 (void) sprintf(cp
, "Domain name = ");
387 for (i
= 0; i
<= buf
[1] && 1 + i
< fraglen
; ++i
)
389 if (1 + i
+ 2 <= fraglen
)
390 (void) sprintf(cp
, ":%u",
391 (buf
[1 + i
] << 8) | buf
[1 + i
+ 1]);
397 (void) sprintf(cp
, "Address = ");
398 if (1 + 16 <= fraglen
) {
399 for (i
= 0; i
< 16; ++i
) {
402 (void) sprintf(cp
, "%u", buf
[1 + i
]);
405 if (1 + 16 + 2 <= fraglen
) {
406 (void) sprintf(cp
, ":%u",
407 (buf
[1 + 16] << 8) | buf
[1 + 16 + 1]);
410 (void) strcat(cp
, "(IPv6)");
413 (void) sprintf(cp
, "Address type = 0x%02x (unknown)", buf
[0]);
418 put_socks4_res(char *cp
, int code
)
422 (void) sprintf(cp
, "request granted");
425 (void) sprintf(cp
, "request rejected or failed");
428 (void) sprintf(cp
, "socksd can't connect to client's identd");
431 (void) sprintf(cp
, "identity mismatch");
434 (void) sprintf(cp
, "0x%02x (unknown)", code
);
439 put_socks5_res(char *cp
, int code
)
443 (void) strcpy(cp
, "succeeded");
446 (void) strcpy(cp
, "general SOCKS server failure");
449 (void) strcpy(cp
, "connection not allowed by ruleset");
452 (void) strcpy(cp
, "network unreachable");
455 (void) strcpy(cp
, "host unreachable");
458 (void) strcpy(cp
, "connection refused");
461 (void) strcpy(cp
, "TTL expired");
464 (void) strcpy(cp
, "command not supported");
467 (void) strcpy(cp
, "address type not supported");
470 (void) sprintf(cp
, "code 0x%02x", code
);