mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Add IP::fragment_offset and IP::flags
This commit is contained in:
@@ -68,6 +68,15 @@ namespace Tins {
|
||||
*/
|
||||
typedef IPv4Address address_type;
|
||||
|
||||
/**
|
||||
* Type used to represent the different IP flags.
|
||||
*/
|
||||
enum Flags {
|
||||
FLAG_RESERVED = 4,
|
||||
DONT_FRAGMENT = 2,
|
||||
MORE_FRAGMENTS = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum indicating the option's class.
|
||||
*
|
||||
@@ -292,10 +301,36 @@ namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Getter for the fragment offset field.
|
||||
*
|
||||
* This method is deprecated. Use IP::fragment_offset and IP::flags.
|
||||
*
|
||||
* \deprecated
|
||||
* \return The fragment offset for this IP PDU.
|
||||
* \sa IP::fragment_offset
|
||||
* \sa IP::flags
|
||||
*/
|
||||
uint16_t frag_off() const { return Endian::be_to_host(_ip.frag_off); }
|
||||
TINS_DEPRECATED(uint16_t frag_off() const) { return Endian::be_to_host(_ip.frag_off); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the fragment offset field.
|
||||
*
|
||||
* This will return the fragment offset field, as present in the packet,
|
||||
* which indicates the offset of this fragment in blocks of 8 bytes.
|
||||
*
|
||||
* \return The fragment offset, measured in units of 8 byte blocks
|
||||
*/
|
||||
small_uint<13> fragment_offset() const {
|
||||
return Endian::be_to_host(_ip.frag_off) & 0x1fff;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the flags field.
|
||||
*
|
||||
* \return The IP flags field
|
||||
*/
|
||||
Flags flags() const {
|
||||
return static_cast<Flags>((_ip.frag_off & 0xe0) >> 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the time to live field.
|
||||
@@ -362,9 +397,32 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Setter for the fragment offset field.
|
||||
*
|
||||
* This method is deprecated. Use IP::fragment_offset and IP::flags.
|
||||
*
|
||||
* \deprecated
|
||||
* \param new_frag_off The new fragment offset.
|
||||
* \sa IP::fragment_offset
|
||||
* \sa IP::flags
|
||||
*/
|
||||
void frag_off(uint16_t new_frag_off);
|
||||
TINS_DEPRECATED(void frag_off(uint16_t new_frag_off));
|
||||
|
||||
/**
|
||||
* \brief Setter for the fragment offset field.
|
||||
*
|
||||
* The value provided is measured in units of 8 byte blocks. This means that
|
||||
* if you want this packet to have a fragment offset of <i>X</i>,
|
||||
* you need to provide <i>X / 8</i> as the argument to this method.
|
||||
*
|
||||
* \param new_frag_off The new fragment offset, measured in units of 8 byte blocks.
|
||||
*/
|
||||
void fragment_offset(small_uint<13> new_frag_off);
|
||||
|
||||
/**
|
||||
* \brief Setter for the flags field.
|
||||
*
|
||||
* \param new_flags The new IP flags field value.
|
||||
*/
|
||||
void flags(Flags new_flags);
|
||||
|
||||
/**
|
||||
* \brief Setter for the time to live field.
|
||||
|
||||
12
src/ip.cpp
12
src/ip.cpp
@@ -157,9 +157,7 @@ void IP::init_ip_fields() {
|
||||
}
|
||||
|
||||
bool IP::is_fragmented() const {
|
||||
// It's 0 if offset == 0 && more_frag == 0
|
||||
// It's 0x4000 if dont_fragment = 1
|
||||
return frag_off() != 0 && frag_off() != 0x4000;
|
||||
return flags() == IP::MORE_FRAGMENTS || fragment_offset() != 0;
|
||||
}
|
||||
|
||||
/* Setters */
|
||||
@@ -180,6 +178,14 @@ void IP::frag_off(uint16_t new_frag_off) {
|
||||
_ip.frag_off = Endian::host_to_be(new_frag_off);
|
||||
}
|
||||
|
||||
void IP::fragment_offset(small_uint<13> new_frag_off) {
|
||||
_ip.frag_off = (_ip.frag_off & 0xe0) | Endian::host_to_be<uint16_t>(new_frag_off);
|
||||
}
|
||||
|
||||
void IP::flags(Flags new_flags) {
|
||||
_ip.frag_off = (_ip.frag_off & 0xff1f) | (new_flags << 5);
|
||||
}
|
||||
|
||||
void IP::ttl(uint8_t new_ttl) {
|
||||
_ip.ttl = new_ttl;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ void IPv4Stream::add_fragment(IP *ip) {
|
||||
return;
|
||||
fragments.insert(it, IPv4Fragment(ip->inner_pdu(), offset));
|
||||
received_size += ip->inner_pdu()->size();
|
||||
if(!extract_more_frag(ip)) {
|
||||
if(ip->flags() != IP::MORE_FRAGMENTS) {
|
||||
total_size = offset + ip->inner_pdu()->size();
|
||||
received_end = true;
|
||||
}
|
||||
@@ -83,12 +83,9 @@ PDU *IPv4Stream::allocate_pdu() const {
|
||||
}
|
||||
|
||||
uint16_t IPv4Stream::extract_offset(const IP *ip) {
|
||||
return (ip->frag_off() & 0x1fff) * 8;
|
||||
return ip->fragment_offset() * 8;
|
||||
}
|
||||
|
||||
bool IPv4Stream::extract_more_frag(const IP *ip) {
|
||||
return (ip->frag_off() & 0x2000) != 0;
|
||||
}
|
||||
} // namespace Internals
|
||||
|
||||
IPv4Reassembler::IPv4Reassembler(overlapping_technique technique)
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user