123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- //
- // socks4.hpp
- // ~~~~~~~~~~
- //
- // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef SOCKS4_HPP
- #define SOCKS4_HPP
- #include <array>
- #include <string>
- #include <boost/asio/buffer.hpp>
- #include <boost/asio/ip/tcp.hpp>
- namespace socks4 {
- const unsigned char version = 0x04;
- class request
- {
- public:
- enum command_type
- {
- connect = 0x01,
- bind = 0x02
- };
- request(command_type cmd, const boost::asio::ip::tcp::endpoint& endpoint,
- const std::string& user_id)
- : version_(version),
- command_(cmd),
- user_id_(user_id),
- null_byte_(0)
- {
- // Only IPv4 is supported by the SOCKS 4 protocol.
- if (endpoint.protocol() != boost::asio::ip::tcp::v4())
- {
- throw boost::system::system_error(
- boost::asio::error::address_family_not_supported);
- }
- // Convert port number to network byte order.
- unsigned short port = endpoint.port();
- port_high_byte_ = (port >> 8) & 0xff;
- port_low_byte_ = port & 0xff;
- // Save IP address in network byte order.
- address_ = endpoint.address().to_v4().to_bytes();
- }
- std::array<boost::asio::const_buffer, 7> buffers() const
- {
- return
- {
- {
- boost::asio::buffer(&version_, 1),
- boost::asio::buffer(&command_, 1),
- boost::asio::buffer(&port_high_byte_, 1),
- boost::asio::buffer(&port_low_byte_, 1),
- boost::asio::buffer(address_),
- boost::asio::buffer(user_id_),
- boost::asio::buffer(&null_byte_, 1)
- }
- };
- }
- private:
- unsigned char version_;
- unsigned char command_;
- unsigned char port_high_byte_;
- unsigned char port_low_byte_;
- boost::asio::ip::address_v4::bytes_type address_;
- std::string user_id_;
- unsigned char null_byte_;
- };
- class reply
- {
- public:
- enum status_type
- {
- request_granted = 0x5a,
- request_failed = 0x5b,
- request_failed_no_identd = 0x5c,
- request_failed_bad_user_id = 0x5d
- };
- reply()
- : null_byte_(0),
- status_()
- {
- }
- std::array<boost::asio::mutable_buffer, 5> buffers()
- {
- return
- {
- {
- boost::asio::buffer(&null_byte_, 1),
- boost::asio::buffer(&status_, 1),
- boost::asio::buffer(&port_high_byte_, 1),
- boost::asio::buffer(&port_low_byte_, 1),
- boost::asio::buffer(address_)
- }
- };
- }
- bool success() const
- {
- return null_byte_ == 0 && status_ == request_granted;
- }
- unsigned char status() const
- {
- return status_;
- }
- boost::asio::ip::tcp::endpoint endpoint() const
- {
- unsigned short port = port_high_byte_;
- port = (port << 8) & 0xff00;
- port = port | port_low_byte_;
- boost::asio::ip::address_v4 address(address_);
- return boost::asio::ip::tcp::endpoint(address, port);
- }
- private:
- unsigned char null_byte_;
- unsigned char status_;
- unsigned char port_high_byte_;
- unsigned char port_low_byte_;
- boost::asio::ip::address_v4::bytes_type address_;
- };
- } // namespace socks4
- #endif // SOCKS4_HPP
|