1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Improved documentation on several classes.

This commit is contained in:
Matias Fontanini
2014-09-14 14:13:25 -03:00
parent 977231cf46
commit 74cca6a483
7 changed files with 241 additions and 50 deletions

View File

@@ -47,10 +47,61 @@ namespace Tins {
class PDU;
/**
* \brief Class that enables sending the created PDUs
* \class PacketSender
* \brief Sends packets through a network interface.
*
* PacketSender class is responsible for sending the packets using the
* correct PDU layer. It is responsible for opening the raw sockets.
* This class allows sending packets through a network interface.
* It can send basically two types of packets:
*
* - Those that contain a link layer PDU (EthernetII, SLL, etc). These
* will be serialized and sent through an interface that has to be
* specified. This can be done by providing it when you call
* PacketSender::send, or set a default one using
* PacketSender::default_interface.
* - Those that don't contain a link layer PDU. In this case, the
* kernel will be responsible for picking the appropriate network interface
* based on the destination address.
*
* Sending packets can be done via PacketSender::send:
*
* \code
* // Construct a packet which uses an EthernetII link layer.
* EthernetII pkt1 = ...;
*
* // Construct a packet sender, which we'll use to send packets.
* PacketSender sender;
*
* // Send it through interface eth0
* sender.send(pkt1, "eth0");
*
* // Set the default interface to eth0
* sender.default_interface("eth0");
*
* // This is now equivalent to the previous send.
* sender.send(pkt1);
*
* // Construct a packet which has no link layer protocol.
* IP ip = IP("192.168.0.1") / TCP(22, 928);
*
* // Here the kernel will figure out which interface to use and it will
* // append the appropriate link layer protocol PDU. It will also perform
* // the necessary ARP lookups in order to use the destination host's
* // hardware address.
* //
* // libtins will find which is the appropriate source IP address to use.
* // This will be done by the kernel as well, but it's required when
* // calculating checksums.
* sender.send(ip);
* \endcode
*
* PacketSender also supports sending a packet and waiting for a response.
* This can be done by using PacketSender::send_recv.
*
* This class opens sockets as it needs to, and closes them when the object
* is destructed.
*
* \sa PacketSender::send
* \sa PacketSender::send_recv
*/
class PacketSender {
public:
@@ -209,9 +260,19 @@ namespace Tins {
* \brief Sends a PDU and waits for its response.
*
* This method is used to send PDUs and receive their response.
* It opens the required socket(if it's not open yet). This can be used
* to expect responses for ICMP, ARP, and such packets that are normally
* answered by the host that receives the packet.
* The packet is sent, and then a response is awaited.
* PDU::matches_pdu is called on the packet sent in order to
* check whether a packet received is a response.
*
* This will match every response to a packet. For example,
* if you send a TCP packet, any response matching the same
* IP addresses and ports will be taken as a response to it.
* This also happens for other protocols, such as ARP, ICMP,
* DHCP, DNS, IP, etc.
*
* If you send a packet and get an ICMP response indicating
* an error (such as host unreachable, ttl exceeded, etc),
* that packet will be considered a response.
*
* \param pdu The PDU to send.
* \return Returns the response PDU, 0 if not response was received.
@@ -220,12 +281,11 @@ namespace Tins {
/**
* \brief Sends a PDU and waits for its response.
*
* Sends a packet and receives a response. This overload takes
* a NetworkInterface.
*
* This method is used to send PDUs and receive their response.
* It opens the required socket(if it's not open yet). This can be used
* to expect responses for ICMP, ARP, and such packets that are normally
* answered by the host that receives the packet.
*
* \sa PacketSender::send_recv(PDU&);
* \param pdu The PDU to send.
* \param iface The network interface in which to send and receive.
* \return Returns the response PDU, 0 if not response was received.
@@ -235,9 +295,12 @@ namespace Tins {
#ifndef WIN32
/**
* \brief Receives a layer 2 PDU response to a previously sent PDU.
*
* This method is used internally. You should just use PacketSender::send_recv.
*
* This PacketSender will receive data from a raw socket, open using the corresponding flag,
* according to the given type of protocol, until a match for the given PDU is received.
* This PacketSender will receive data from a raw socket, open using
* the corresponding flag, according to the given type of protocol, until
* a match for the given PDU is received.
*
* \param pdu The PDU which will try to match the responses.
* \param link_addr The sockaddr struct which will be used to receive the PDU.
@@ -249,6 +312,8 @@ namespace Tins {
/**
* \brief Sends a level 2 PDU.
*
* This method is used internally. You should just use PacketSender::send.
*
* This method sends a layer 2 PDU, using a raw socket, open
* using the corresponding flag, according to the given type of
@@ -266,6 +331,8 @@ namespace Tins {
/**
* \brief Receives a layer 3 PDU response to a previously sent PDU.
*
* This method is used internally. You should just use PacketSender::send_recv.
*
* This PacketSender will receive data from a raw socket, open using the corresponding flag,
* according to the given type of protocol, until a match for the given PDU is received.
@@ -280,6 +347,8 @@ namespace Tins {
/**
* \brief Sends a level 3 PDU.
*
* This method is used internally. You should just use PacketSender::send.
*
* This method sends a layer 3 PDU, using a raw socket, open using the corresponding flag,
* according to the given type of protocol.

View File

@@ -119,7 +119,8 @@ public:
/**
* \brief Constructs a PacketWriter.
*
* \deprecated Use the other constructor, which takes a DataLinkType.
* \deprecated Use the PacketWriter(const std::string&, const DataLinkType<T>&)
* constructor.
*
* \param file_name The file in which to store the written PDUs.
* \param lt The link type which will be written to this file.
@@ -158,7 +159,9 @@ public:
#endif
/**
* Destructor.
* \brief Destructor.
*
* Gracefully closes the output file.
*/
~PacketWriter();

View File

@@ -53,12 +53,56 @@ namespace Tins {
* \class PDU
* \brief Base class for protocol data units.
*
* Every PDU implementation must inherit this class. PDUs can be serialized,
* therefore allowing a PacketSender to send them through the corresponding
* sockets.
* Every PDU implementation inherits from this class.
*
* PDUs can contain 0 or 1 inner PDU. By stacking several PDUs together,
* you can construct packets. These are created upwards: upper layers
* will be children of the lower ones.
*
* If you want to find a specific protocol within a PDU chain, you can use
* PDU::find_pdu and PDU::rfind_pdu. Both of them take a template parameter
* that indicates the PDU type you are looking for. The first one returns a
* pointer to the first object of that type, and the second one returns a
* reference (and throws if it is not found).
*
* PDUs are created upwards: upper layers will be children of the
* lower ones.
* For example:
*
* \code
* // Take a whole packet from somewhere.
* EthernetII packet = ...;
*
* // Find the IP layer
* const IP* ip = packet.find_pdu<IP>();
* if(ip) {
* // If the pointer is not null, then it will point to the IP layer
* }
*
* // Find the TCP layer. This will throw a pdu_not_found exception
* // if there is no TCP layer in this packet.
* const TCP& tcp = packet.rfind_pdu<TCP>();
* \endcode
*
* PDU objects can be serialized. Serialization converts the entire PDU
* stack into a vector of bytes. This process might modify some parameters
* on packets depending on which protocols are used in it. For example:
*
* - If the lowest protocol layer is IP (this means that there is no
* link layer protocol in the packet), then it calculates the source address
* that should be used in that IP PDU. \sa IP
* - If a protocol contains a checksum field, its value will be calculated
* and included in its serialized contents.
* - If a protocol contains a "next protocol" field, it is also set based
* on the type of the next PDU in the packet.
*
* If you want to serialize a packet, just use PDU::serialize:
*
* \code
* // Construct a packet
* EthernetII packet = EthernetII() / IP() / TCP() / RawPDU("hello");
*
* // Now serialize it. This is a std::vector<uint8_t>.
* PDU::serialization_type buffer = packet.serialize();
* \endcode
*/
class PDU {
public:

View File

@@ -78,7 +78,9 @@ public:
cached_size() {}
/**
* Forwards the call to the cached PDU. \sa PDU::header_size.
* Forwards the call to the cached PDU.
*
* \sa PDU::header_size.
*/
uint32_t header_size() const {
if(cached_serialization.empty())
@@ -87,42 +89,54 @@ public:
}
/**
* Forwards the call to the cached PDU. \sa PDU::clone.
* Forwards the call to the cached PDU.
*
* \sa PDU::clone.
*/
PDUCacher *clone() const {
return new PDUCacher<T>(*this);
}
/**
* Forwards the call to the cached PDU. \sa PDU::send.
* Forwards the call to the cached PDU.
*
* \sa PDU::send.
*/
void send(PacketSender &sender, const NetworkInterface &iface) {
cached.send(sender, iface);
}
/**
* Forwards the call to the cached PDU. \sa PDU::recv_responde.
* Forwards the call to the cached PDU.
*
* \sa PDU::recv_responde.
*/
PDU *recv_response(PacketSender &sender, const NetworkInterface &iface) {
return cached.recv_response(sender, iface);
}
/**
* Forwards the call to the cached PDU. \sa PDU::matches_response.
* Forwards the call to the cached PDU.
*
* \sa PDU::matches_response.
*/
bool matches_response(const uint8_t *ptr, uint32_t total_sz) const {
return cached.matches_response(ptr, total_sz);
}
/**
* Forwards the call to the cached PDU. \sa PDU::matches_flag.
* Forwards the call to the cached PDU.
*
* \sa PDU::matches_flag.
*/
bool matches_flag(PDUType flag) const {
return cached.matches_flag(flag);
}
/**
* Forwards the call to the cached PDU. \sa PDU::pdu_type.
* Forwards the call to the cached PDU.
*
* \sa PDU::pdu_type.
*/
PDUType pdu_type() const {
return cached.pdu_type();

View File

@@ -265,7 +265,8 @@ namespace Tins {
class Sniffer : public BaseSniffer {
public:
/**
* \deprecated
* \deprecated This enum is no longer necessary. You should use the
* Sniffer(const std::string&, const SnifferConfiguration&) constructor.
*/
enum promisc_type {
NON_PROMISC,
@@ -293,7 +294,8 @@ namespace Tins {
* By default the interface won't be put into promiscuous mode, and won't
* be put into monitor mode.
*
* \deprecated Use the constructor that takes a SnifferConfiguration.
* \deprecated Use the Sniffer(const std::string&, const SnifferConfiguration&)
* constructor.
* \param device The device which will be sniffed.
* \param max_packet_size The maximum packet size to be read.
* \param promisc bool indicating wether to put the interface in promiscuous mode.(optional)
@@ -309,7 +311,8 @@ namespace Tins {
* The maximum capture size is set to 65535. By default the interface won't
* be put into promiscuous mode, and won't be put into monitor mode.
*
* \deprecated Use the constructor that takes a SnifferConfiguration.
* \deprecated Use the Sniffer(const std::string&, const SnifferConfiguration&)
* constructor.
* \param device The device which will be sniffed.
* \param promisc Indicates if the interface should be put in promiscuous mode.
* \param filter A capture filter to be used on the sniffing session.(optional);

View File

@@ -46,10 +46,30 @@
namespace Tins {
/**
* \class TCP
* \brief Class that represents an TCP PDU.
* \brief Represents a TCP PDU.
*
* TCP is the representation of the TCP PDU. Instances of this class
* must be sent over a level 3 PDU, this will otherwise fail.
* This class represents a TCP PDU.
*
* When sending TCP PDUs, the checksum is calculated automatically
* every time you send the packet.
*
* While sniffing, the payload sent in each packet will be wrapped
* in a RawPDU, which is set as the TCP object's inner_pdu. Therefore,
* if you are sniffing and want to see the TCP packet's payload,
* you need to do the following:
*
* \code
* // Get a packet from somewhere.
* TCP tcp = ...;
*
* // Extract the RawPDU object.
* const RawPDU& raw = tcp.rfind_pdu<RawPDU>();
*
* // Finally, take the payload (this is a vector<uint8_t>)
* const RawPDU::payload_type& payload = raw.payload();
* \endcode
*
* \sa RawPDU
*/
class TCP : public PDU {
@@ -78,7 +98,7 @@ namespace Tins {
/**
* \brief TCP options enum.
*
* This enum identifies valid options supported by TCP PDU.
* This enum defines option types supported by TCP PDU.
*/
enum OptionTypes {
EOL = 0,
@@ -120,6 +140,7 @@ namespace Tins {
*
* Creates an instance of TCP. Destination and source port can
* be provided, otherwise both will be 0.
*
* \param dport Destination port.
* \param sport Source port.
* */
@@ -129,7 +150,7 @@ namespace Tins {
* \brief Constructs TCP object from a buffer.
*
* If there is not enough size for a TCP header, or any of the
* TLV options are malformed a malformed_packet exception is
* TLV options are malformed, a malformed_packet exception is
* thrown.
*
* Any extra data will be stored in a RawPDU.
@@ -142,56 +163,56 @@ namespace Tins {
/**
* \brief Getter for the destination port field.
*
* \return The destination port in an uint16_t.
* \return The destination port field value.
*/
uint16_t dport() const { return Endian::be_to_host(_tcp.dport); }
/**
* \brief Getter for the source port field.
*
* \return The source port in an uint16_t.
* \return The source port field value.
*/
uint16_t sport() const { return Endian::be_to_host(_tcp.sport); }
/**
* \brief Getter for the sequence number field.
*
* \return The sequence number in an uint32_t.
* \return The sequence number field value.
*/
uint32_t seq() const { return Endian::be_to_host(_tcp.seq); }
/**
* \brief Getter for the acknowledge number field.
*
* \return The acknowledge number in an uint32_t.
* \return The acknowledge number field value.
*/
uint32_t ack_seq() const { return Endian::be_to_host(_tcp.ack_seq); }
/**
* \brief Getter for the window size field.
*
* \return The window size in an uint32_t.
* \return The window size field value.
*/
uint16_t window() const { return Endian::be_to_host(_tcp.window); }
/**
* \brief Getter for the checksum field.
*
* \return The checksum field in an uint16_t.
* \return The checksum field value.
*/
uint16_t checksum() const { return Endian::be_to_host(_tcp.check); }
/**
* \brief Getter for the urgent pointer field.
*
* \return The urgent pointer in an uint16_t.
* \return The urgent pointer field value.
*/
uint16_t urg_ptr() const { return Endian::be_to_host(_tcp.urg_ptr); }
/**
* \brief Getter for the data offset field.
*
* \return Data offset in an uint8_t.
* \return The data offset field value.
*/
small_uint<4> data_offset() const { return this->_tcp.doff; }
@@ -204,7 +225,24 @@ namespace Tins {
/**
* \brief Gets the value of a flag.
*
* This method gets the value of a specific flag. If you
* want to check for multiple flags at the same time,
* use TCP::flags.
*
* If you want to check if this PDU has the SYN flag on,
* you can do it like this:
*
* \code
* // Get a TCP packet from somewhere.
* TCP tcp = ...;
*
* if(tcp.get_flag(TCP::SYN)) {
* // The SYN flag is on!
* }
* \endcode
*
* \sa TCP::flags
* \param tcp_flag The polled flag.
* \return The value of the flag.
*/
@@ -220,8 +258,9 @@ namespace Tins {
*
* \code
* TCP tcp = ...;
* if(tcp.flags() == (TCP::SYN | TCP::ACK))
* if(tcp.flags() == (TCP::SYN | TCP::ACK)) {
* // It's a SYN+ACK!
* }
* \endcode
*
* \return The value of the flags field.
@@ -379,11 +418,13 @@ namespace Tins {
* same time.
*
* \code
* // Get a TCP packet from somewhere and set the flags to SYN && ACK
* TCP tcp = ...;
* tcp.flags(TCP::SYN | TCP::ACK);
* // ...
* // only set the ACK, keeping the rest of the old flags.
* tcp.flags(tcp.flags() | TCP::ACK);
*
* // Now also set the PSH flag, without modifying
* // the rest of the flags.
* tcp.flags(tcp.flags() | TCP::PSH);
* \endcode
*
* \param value The new value of the flags.

View File

@@ -38,10 +38,27 @@ namespace Tins {
/**
* \class UDP
* \brief Class that represents an UDP PDU.
* \brief Represents an UDP PDU.
*
* UDP is the representation of the UDP PDU. Instances of this class
* must be sent over a level 3 PDU, this will otherwise fail.
* This class represents an UDP PDU.
*
* While sniffing, the payload sent in each packet will be wrapped
* in a RawPDU, which is set as the UDP object's inner_pdu. Therefore,
* if you are sniffing and want to see the UDP packet's payload,
* you need to do the following:
*
* \code
* // Get a packet from somewhere.
* UDP udp = ...;
*
* // Extract the RawPDU object.
* const RawPDU& raw = udp.rfind_pdu<RawPDU>();
*
* // Finally, take the payload (this is a vector<uint8_t>)
* const RawPDU::payload_type& payload = raw.payload();
* \endcode
*
* \sa RawPDU
*/
class UDP : public PDU {
public: