TCPPacket.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "TCPPacket.hh"
18 //#include "TCPPacket.ih"
19 
20 // Custom includes
21 #include <iomanip>
22 #include <boost/io/ios_state.hpp>
23 #include <senf/Utils/IpChecksum.hh>
24 #include "IPv4Packet.hh"
25 #include "IPv6Packet.hh"
26 
27 #define prefix_
28 //-/////////////////////////////////////////////////////////////////////////////////////////////////
29 
32 
33 //-/////////////////////////////////////////////////////////////////////////////////////////////////
34 // senf::TCPPacketParser
35 
37  const
38 {
39  IpChecksum summer;
40  // first on to the awkward part: the IP pseudo header
41  IPv4Packet ipv4 (packet().rfind<IPv4Packet>(nothrow));
42  if (ipv4) {
43  // Pseudo header defined in RFC793
44  // begin
45  summer.feed( ipv4->source().i(),
46  ipv4->source().i() + IPv4Packet::Parser::source_t::fixed_bytes );
48  summer.feed( ipv4->destination().i(),
49  ipv4->destination().i() + IPv4PacketParser::destination_t::fixed_bytes );
50  // include zero byte
51  summer.feed( 0u );
54  summer.feed( 6u );
55 
56  // feed 1st byte and 2nd byte from field tcp length
57  summer.feed(boost::uint16_t(data().size()) & 0xff00);
58  summer.feed(boost::uint16_t(data().size()) & 0x00ff);
59  // end pseudo header
60  }
61  else {
62  // Pseudo header defined in RFC2460
63  IPv6Packet ipv6 (packet().rfind<IPv6Packet>(nothrow));
64  if (ipv6) {
65  summer.feed( ipv6->source().i(),
66  ipv6->source().i() + IPv6Packet::Parser::source_t::fixed_bytes );
68  // The destination used here must be the *final* destination ...
69  summer.feed( ipv6->destination().i(),
70  ipv6->destination().i() + IPv6PacketParser::destination_t::fixed_bytes );
71  // This is a simplification. The value is really 32bit to support UDP Jumbograms
72  // (RFC2147). However, skipping an even number of 0 bytes does not change the checksum
73  // RFC2460 specifies, that this must always be 6, not the value used in the ipv6
74  // header
75  // feed 1st byte and 2nd byte from field tcp length
76  summer.feed(boost::uint16_t(data().size()) & 0xff00);
77  summer.feed(boost::uint16_t(data().size()) & 0x00ff);
78  // include zero byte
79  summer.feed( 0u );
80  // add TCP protocol number
81  summer.feed( 6u );
82  }
83  }
84 
85  // since header are 16 / even 32bit aligned we don't have to care for padding. since IpChecksum
86  // cares for padding at the final summing we don't have to care is the payload is 16nbit-aligned, too.
87 
88  // iterate till checksum field and skip 2 bytes,
89  // iterate over rest of tcp header and tcp payload
90  summer.feed( i(), i()+16 );
91  summer.feed( i()+18, data().end() );
92 
93  boost::uint16_t rv (summer.sum());
94  return rv ? rv : 0xffffu;
95 
96 }
97 
98 //-/////////////////////////////////////////////////////////////////////////////////////////////////
99 // senf::TCPPacketType
100 
101 prefix_ void senf::TCPPacketType::dump(packet p, std::ostream & os)
102 {
103  boost::io::ios_all_saver ias(os);
104  os << "TCP:\n"
105  << senf::fieldName("source port") << p->source() << "\n"
106  << senf::fieldName("destination port") << p->destination() << "\n"
107  << senf::fieldName("sequence number") << p->sequencenumber() << "\n"
108  << senf::fieldName("acknowledgment number") << p->acknowledgmentnumber() << "\n"
109  << senf::fieldName("data offset") << p->dataoffset() << "\n"
110  << senf::fieldName("urgent flag") << p->urgf() << "\n"
111  << senf::fieldName("ack flag") << p->ackf() << "\n"
112  << senf::fieldName("push flag") << p->pshf() << "\n"
113  << senf::fieldName("reset flag") << p->rstf() << "\n"
114  << senf::fieldName("syn flag") << p->synf() << "\n"
115  << senf::fieldName("fin flag") << p->finf() << "\n"
116  << senf::fieldName("window size") << p->window() << "\n"
117  << senf::fieldName("checksum")
118  << "0x" << std::hex << std::setw(4) << std::setfill('0') << std::right << p->checksum() << "\n"
119  << senf::fieldName("urgent pointer") << p->urgentpointer() << "\n";
120 }
121 
123 {
124  p->dataoffset() << p.size();
125  p->checksum() << p->calcChecksum();
126 }
127 
128 //-/////////////////////////////////////////////////////////////////////////////////////////////////
129 #undef prefix_
130 
131 
132 // Local Variables:
133 // mode: c++
134 // fill-column: 100
135 // c-file-style: "senf"
136 // indent-tabs-mode: nil
137 // ispell-local-dictionary: "american"
138 // compile-command: "scons -u test"
139 // comment-column: 40
140 // End:
IPv6Packet public header.
Packet packet() const
Get packet this parser is parsing from.
SENF_PACKET_REGISTRY_REGISTER(senf::IPTypes, senf::TCPPacketType::ipType, senf::TCPPacket)
std::string fieldName(std::string const &s)
Definition: DumpFormat.cc:28
boost::uint16_t calcChecksum() const
calculate (pseudo-)header checksum
Definition: TCPPacket.cc:36
static void finalize(packet p)
Finalize packet.
Definition: TCPPacket.cc:122
TCPPacket public header.
static const IPTypes::key_t ipType
Definition: TCPPacket.hh:153
Protocol specific packet handle.
Definition: Packet.hh:87
data_iterator i() const
Return beginning of data to parse.
static void dump(packet p, std::ostream &os)
Dump given TCPPacket in readable form to given output stream.
Definition: TCPPacket.cc:101
nothrow
SENF_PACKET_INSTANTIATE_TEMPLATE(senf::TCPPacket)
#define prefix_
Definition: TCPPacket.cc:27
size_type size() const
Return size of packet in bytes.
PacketData & data() const
Access the packets raw data container.
IPv4Packet public header.
IP protocol number registry.
Definition: Registries.hh:60
boost::uint16_t sum() const
void feed(boost::uint8_t byte)