#pragma once #include #include #pragma pack(push,1) #define S4_CMD_CONNECT 1 #define S4_CMD_BIND 2 typedef struct { uint8_t ver,cmd; uint16_t port; uint32_t ip; } s4_req; #define S4_REQ_HEADER_VALID(r,l) (l>=sizeof(s4_req) && r->ver==4) #define S4_REQ_CONNECT_VALID(r,l) (S4_REQ_HEADER_VALID(r,l) && r->cmd==S4_CMD_CONNECT) #define S4_REP_OK 90 #define S4_REP_FAILED 91 typedef struct { uint8_t zero,rep; uint16_t port; uint32_t ip; } s4_rep; #define S5_AUTH_NONE 0 #define S5_AUTH_GSSAPI 1 #define S5_AUTH_USERPASS 2 #define S5_AUTH_UNACCEPTABLE 0xFF typedef struct { uint8_t ver,nmethods,methods[255]; } s5_handshake; #define S5_REQ_HANDHSHAKE_VALID(r,l) (l>=3 && r->ver==5 && r->nmethods && l>=(2+r->nmethods)) typedef struct { uint8_t ver,method; } s5_handshake_ack; #define S5_CMD_CONNECT 1 #define S5_CMD_BIND 2 #define S5_CMD_UDP_ASSOC 3 #define S5_ATYP_IP4 1 #define S5_ATYP_DOM 3 #define S5_ATYP_IP6 4 typedef struct { uint8_t ver,cmd,rsv,atyp; union { struct { struct in_addr addr; uint16_t port; } d4; struct { struct in6_addr addr; uint16_t port; } d6; struct { uint8_t len; char domport[255+2]; // max hostname + binary port } dd; }; } s5_req; #define S5_REQ_HEADER_VALID(r,l) (l>=4 && r->ver==5) #define S5_IP46_VALID(r,l) (r->atyp==S5_ATYP_IP4 && l>=(4+sizeof(r->d4)) || r->atyp==S5_ATYP_IP6 && l>=(4+sizeof(r->d6))) #define S5_REQ_CONNECT_VALID(r,l) (S5_REQ_HEADER_VALID(r,l) && r->cmd==S5_CMD_CONNECT && (S5_IP46_VALID(r,l) || r->atyp==S5_ATYP_DOM && l>=5 && l>=(5+r->dd.len))) #define S5_PORT_FROM_DD(r,l) (l>=(4+r->dd.len+2) ? ntohs(*(uint16_t*)(r->dd.domport+r->dd.len)) : 0) #define S5_REP_OK 0 #define S5_REP_GENERAL_FAILURE 1 #define S5_REP_NOT_ALLOWED_BY_RULESET 2 #define S5_REP_NETWORK_UNREACHABLE 3 #define S5_REP_HOST_UNREACHABLE 4 #define S5_REP_CONN_REFUSED 5 #define S5_REP_TTL_EXPIRED 6 #define S5_REP_COMMAND_NOT_SUPPORTED 7 #define S5_REP_ADDR_TYPE_NOT_SUPPORTED 8 typedef struct { uint8_t ver,rep,rsv,atyp; union { struct { struct in_addr addr; uint16_t port; } d4; }; } s5_rep; #pragma pack(pop)