/[cvs]/eggdrop1.9/testcode/socks4.c
ViewVC logotype

Contents of /eggdrop1.9/testcode/socks4.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Thu Apr 25 04:19:54 2002 UTC (17 years, 1 month ago) by stdarg
Branch: MAIN
File MIME type: text/x-chdr
* sclient.c - test program to telnet using a proxy
* http.c/base64.c - http anonymous and authenticated proxies
* socks5.c - socks5 proxy with support for username/password authentication, ipv4, ipv6, and remote hostname resolution
* socks4.c socks4 proxy (no authentication)

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <netinet/in.h>
6 #include "my_socket.h"
7 #include "sockbuf.h"
8
9 typedef struct {
10 unsigned char ver;
11 unsigned char cmd;
12 unsigned short port;
13 unsigned int ip;
14 } socks4_request_t;
15
16 typedef struct {
17 char *host;
18 int port;
19 char *username;
20 int our_idx, their_idx;
21 int sock;
22 } proxy_info_t;
23
24 static int socks4_on_read(int idx, sockbuf_iobuf_t *data, proxy_info_t *info);
25 static int socks4_on_eof_and_err(int idx, void *err, proxy_info_t *info);
26 static int socks4_on_connect(int idx, void *ignore, proxy_info_t *info);
27
28 sockbuf_event_t socks4_events = {
29 (Function) 5,
30 (Function) "socks4 proxy",
31 socks4_on_read,
32 NULL,
33 socks4_on_eof_and_err,
34 socks4_on_eof_and_err,
35 socks4_on_connect
36 };
37
38 static void socks4_free(proxy_info_t *info)
39 {
40 free(info->host);
41 free(info->username);
42 sockbuf_delete(info->our_idx);
43 free(info);
44 }
45
46 static void socks4_err(proxy_info_t *info, int err)
47 {
48 errno = err;
49 sockbuf_filter(info->their_idx, SOCKBUF_ERR, -1, (void *)err);
50 socks4_free(info);
51 }
52
53 static int socks4_on_read(int idx, sockbuf_iobuf_t *data, proxy_info_t *info)
54 {
55 socks4_request_t reply;
56
57 if (data->len < sizeof(reply)) {
58 socks4_err(info, ECONNABORTED);
59 return(0);
60 }
61
62 memcpy(&reply, data->data, sizeof(reply));
63 if (reply.cmd != 90) {
64 socks4_err(info, ECONNREFUSED);
65 return(0);
66 }
67
68 /* Switch over the socket to their idx. */
69 sockbuf_set_sock(info->our_idx, -1, 0);
70 sockbuf_set_sock(info->their_idx, info->sock, SOCKBUF_CLIENT);
71 socks4_free(info);
72 return(0);
73 }
74
75 static int socks4_on_eof_and_err(int idx, void *err, proxy_info_t *info)
76 {
77 if (!err) err = (void *)ECONNREFUSED;
78 socks4_err(info, (int) err);
79 return(0);
80 }
81
82 static int socks4_on_connect(int idx, void *ignore, proxy_info_t *info)
83 {
84 char buf[512];
85 int len;
86 struct sockaddr_in addr;
87 socks4_request_t req;
88
89 req.ver = 4;
90 req.cmd = 1;
91 req.port = htons(info->port);
92 inet_pton(AF_INET, info->host, &addr);
93 req.ip = addr.sin_addr.s_addr;
94
95 memcpy(buf, &req, sizeof(req));
96
97 /* We want to copy the username plus the terminating null. */
98 len = strlen(info->username) + 1;
99 if (len > sizeof(buf) - sizeof(req)) {
100 len = sizeof(buf) - sizeof(req);
101 info->username[len-1] = 0;
102 }
103
104 memcpy(buf+sizeof(req), info->username, len);
105 len += sizeof(req);
106
107 sockbuf_write(idx, buf, len);
108 return(0);
109 }
110
111 int socks4_connect(int idx, char *proxy_host, int proxy_port, char *username, char *dest_ip, int dest_port)
112 {
113 int sock;
114 proxy_info_t *info;
115
116 sock = socket_create(proxy_host, proxy_port, NULL, 0, SOCKET_CLIENT|SOCKET_TCP|SOCKET_NONBLOCK);
117 if (sock < 0) return(-1);
118
119 info = (proxy_info_t *)malloc(sizeof(*info));
120 info->host = strdup(dest_ip);
121 info->port = dest_port;
122 if (!username) username = "";
123 info->username = strdup(username);
124
125 info->our_idx = sockbuf_new(sock, SOCKBUF_CLIENT);
126 if (idx >= 0) info->their_idx = idx;
127 else info->their_idx = sockbuf_new(-1, 0);
128
129 info->sock = sock;
130
131 sockbuf_set_handler(info->our_idx, socks4_events, info);
132
133 return(info->their_idx);
134 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23