Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- namespace ZontWelg_Socks5UDP.Socks
- {
- public class SocksError : Exception {
- public SocksError(String parMessage) : base(parMessage) { }
- }
- // Socks5 refrence: http://tools.ietf.org/pdf/rfc1928.pdf
- public class SocksConnection {
- private Socket tcp_sock;
- private Socket udp_sock;
- private String prox_addr;
- private ushort prox_port;
- private String remote_addr;
- private ushort remote_port;
- private String sock_bnd_addr;
- private ushort sock_bnd_port;
- #region Constants
- public const int SOCKS5_VERSION = 0x05;
- public const int SOCKS5_NO_AUTHENTICATION_REQUIRED = 0x00;
- public const int SOCKS5_GSSAPI = 0x01;
- public const int SOCKS5_USERNAME_PASSWORD = 0x02;
- public const int SOCKS5_IANA_ASSIGNED = 0x03;
- public const int SOCKS5_RESERVED_FOR_PRIVATE_METHODS = 0x80;
- public const int SOCKS5_NO_ACCEPTABLE_METHODS = 0xFF;
- public const int SOCKS5_CMD_CONNECT = 0x01;
- public const int SOCKS5_CMD_BIND = 0x02;
- public const int SOCKS5_CMD_UDP_ASSOCIATE = 0x03;
- public const int SOCKS5_ATYP_IPV4 = 0x01;
- public const int SOCKS5_ATYP_DOMAIN = 0x02;
- public const int SOCKS5_ATYP_IPV6 = 0x03;
- public const int SOCKS5_REPLY_SUCCSESS = 0x00;
- public const int SOCKS5_REPLY_GENERAL_SOCKS_SRV_FAILURE = 0x01;
- public const int SOCKS5_REPLY_CONN_NOT_ALLOWED_RULLSET = 0x02;
- public const int SOCKS5_REPLY_NETWORK_UNRECHABLE = 0x03;
- public const int SOCKS5_REPLY_HOST_UNRECHABLE = 0x04;
- public const int SOCKS5_REPLY_CONN_REFUSED = 0x05;
- public const int SOCKS5_REPLY_TTL_EXPIRED = 0x06;
- public const int SOCKS5_REPLY_COMMAND_NOT_SUPPORTED = 0x07;
- public const int SOCKS5_REPLY_ADDR_TYPE_NOT_SUPPORTED = 0x08;
- public const int SOCKS5_REPLY_UNASSIGNED = 0xFF;
- #endregion
- public static SocksConnection makeSocks5(string prox_addr, ushort prox_port, string dst_adr, ushort dst_port) {
- SocksConnection conn = new SocksConnection();
- conn.prox_addr = prox_addr;
- conn.prox_port = prox_port;
- conn.remote_addr = dst_adr;
- conn.remote_port = dst_port;
- conn.tcp_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- conn.tcp_sock.Connect(prox_addr, prox_port);
- // Sending auth method to socks5
- /*
- +----+----------+----------+
- |VER | NMETHODS | METHODS |
- +----+----------+----------+
- | 1 | 1 | 1 to 255 |
- +----+----------+----------+
- */
- byte[] auth_req = { 0x05, 0x01, 0x00 };
- conn.tcp_sock.Send(auth_req);
- byte[] receive_buff = new byte[2];
- conn.tcp_sock.Receive(receive_buff);
- switch (receive_buff[1]) {
- case SOCKS5_NO_AUTHENTICATION_REQUIRED:
- // no socks5 auth need, can send udp commands after connection
- conn.UDPCommand(SOCKS5_CMD_UDP_ASSOCIATE);
- break;
- case SOCKS5_USERNAME_PASSWORD:
- // socks5 proxy need auth user
- break;
- case SOCKS5_NO_ACCEPTABLE_METHODS:
- // no acceptable methods
- throw new SocksError("There's no acceptable methods for socks5 connection.");
- }
- return conn;
- }
- private void UDPCommand(int udp_command) {
- /*
- +----+-----+-------+------+----------+----------+
- |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
- +----+-----+-------+------+----------+----------+
- | 1 | 1 | X’00’ | 1 | Variable | 2 |
- +----+-----+-------+------+----------+----------+
- */
- udp_sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- udp_sock.Bind(new IPEndPoint(IPAddress.Any, 0));
- int index = 0;
- byte[] cmd = new byte[256];
- cmd[index++] = SOCKS5_VERSION; //version
- cmd[index++] = (byte)udp_command; //command
- cmd[index++] = 0x00; //reserved
- // Dst address
- IPAddress rem_addr = IPAddress.Parse(remote_addr);
- if (rem_addr == null)
- throw new SocksError("Remote address is null, can't sent UDP command to socks5 proxy server.");
- switch (rem_addr.AddressFamily) {
- case AddressFamily.InterNetwork:
- cmd[index++] = SOCKS5_ATYP_IPV4; //ATYP
- break;
- case AddressFamily.InterNetworkV6:
- cmd[index++] = SOCKS5_ATYP_IPV6; //ATYP
- break;
- }
- // Copy DST address to socks request
- //byte[] addr_bytes = rem_addr.GetAddressBytes();
- //for (int i = 0; i < addr_bytes.Length; i++) {
- // cmd[index++] = addr_bytes[i];
- //}
- cmd[index++] = 0x00;
- cmd[index++] = 0x00;
- cmd[index++] = 0x00;
- cmd[index++] = 0x00;
- // Copy DST port to socks request
- byte[] port_bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)remote_port));
- for (int i = 0; i < port_bytes.Length; i++) {
- cmd[index++] = port_bytes[i];
- }
- tcp_sock.Send(cmd);
- /*
- +----+-----+-------+------+----------+----------+
- |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
- +----+-----+-------+------+----------+----------+
- | 1 | 1 | X’00’ | 1 | Variable | 2 |
- +----+-----+-------+------+----------+----------+
- o VER protocol version: X’05’
- o REP Reply field:
- o X’00’ succeeded
- o X’01’ general SOCKS server failure
- o X’02’ connection not allowed by ruleset
- o X’03’ Network unreachable
- o X’04’ Host unreachable
- o X’05’ Connection refused
- o X’06’ TTL expired
- o X’07’ Command not supported
- o X’08’ Address type not supported
- o X’09’ to X’FF’ unassigned
- o RSV RESERVED
- o ATYP address type of following address
- o IP V4 address: X’01’
- o DOMAINNAME: X’03’
- o IP V6 address: X’04’
- o BND.ADDR server bound address
- o BND.PORT server bound port in network octet order
- */
- byte[] response = new byte[256];
- tcp_sock.Receive(response);
- switch (response[1]) {
- case SOCKS5_REPLY_SUCCSESS:
- //TODO: good!
- break;
- case SOCKS5_REPLY_ADDR_TYPE_NOT_SUPPORTED:
- tcp_sock.Close();
- throw new SocksError("(COMMAND) Address type is not supported by socks5 server.");
- case SOCKS5_REPLY_COMMAND_NOT_SUPPORTED:
- tcp_sock.Close();
- throw new SocksError(string.Format("(COMMAND) Command '{0}' not supported by socks5 server.", udp_command));
- case SOCKS5_REPLY_CONN_NOT_ALLOWED_RULLSET:
- tcp_sock.Close();
- throw new SocksError("(COMMAND) Connection is not allowed by socks5 server ruleset.");
- case SOCKS5_REPLY_CONN_REFUSED:
- tcp_sock.Close();
- throw new SocksError("(COMMAND) Connection refused by socks5 server.");
- case SOCKS5_REPLY_GENERAL_SOCKS_SRV_FAILURE:
- tcp_sock.Close();
- throw new SocksError("(COMMAND) General socks failed on socks5 server.");
- case SOCKS5_REPLY_HOST_UNRECHABLE:
- tcp_sock.Close();
- throw new SocksError("(COMMAND) Remote host was unrechable, socks5 server can't connect.");
- case SOCKS5_REPLY_NETWORK_UNRECHABLE:
- tcp_sock.Close();
- throw new SocksError("(COMMAND) Socks5 server error, remote network unrechable.");
- case SOCKS5_REPLY_TTL_EXPIRED:
- tcp_sock.Close();
- throw new SocksError("(COMMAND) Connection failed, TTL was expired, retry connection.");
- case SOCKS5_REPLY_UNASSIGNED:
- tcp_sock.Close();
- throw new SocksError("(COMMAND) Unassigned reply 0xFF.");
- }
- sock_bnd_addr = string.Format("{0}.{1}.{2}.{3}", response[4], response[5], response[6], response[7]);
- if (response[4] == 0x00 && response[5] == 0x00 && response[6] == 0x00 && response[7] == 0x00) {
- sock_bnd_addr = prox_addr;
- }
- ushort bp = BitConverter.ToUInt16( response, 8 );
- sock_bnd_port = (ushort)IPAddress.NetworkToHostOrder((short)bp);
- udp_sock.Connect(prox_addr, sock_bnd_port);
- }
- public void SendBuffer(byte[] bytes) {
- byte[] buffer = new byte[10 + bytes.Length];
- makeDgramHeader().CopyTo(buffer, 0);
- bytes.CopyTo(buffer, 10);
- udp_sock.Send(buffer);
- }
- private byte[] makeDgramHeader() {
- /*
- +----+------+------+----------+----------+----------+
- |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
- +----+------+------+----------+----------+----------+
- | 2 | 1 | 1 | Variable | 2 | Variable |
- +----+------+------+----------+----------+----------+
- o RSV Reserved X’0000’
- o FRAG Current fragment number
- o ATYP address type of following addresses:
- o IP V4 address: X’01’
- o DOMAINNAME: X’03’
- o IP V6 address: X’04’
- o DST.ADDR desired destination address
- o DST.PORT desired destination port
- o DATA user data
- */
- byte[] header = new byte[10];
- header[0] = 0x00;
- header[1] = 0x00;
- header[2] = 0x01;
- header[3] = SOCKS5_ATYP_IPV4;
- IPAddress.Parse(remote_addr).GetAddressBytes().CopyTo(header, 4);
- //header[4] = 0x00;
- //header[5] = 0x00;
- //header[6] = 0x00;
- //header[7] = 0x00;
- BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)remote_port)).CopyTo(header, 8);
- return header;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement