/[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.2 - (show annotations) (download) (as text)
Wed Jun 19 04:51:54 2002 UTC (16 years, 9 months ago) by stdarg
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +29 -32 lines
File MIME type: text/x-chdr
* I think the sockbuf api is almost done

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23