4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methods used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, either version 3 of the License, or
24 * Anytun is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with Anytun. If not, see <http://www.gnu.org/licenses/>.
32 * In addition, as a special exception, the copyright holders give
33 * permission to link the code of portions of this program with the
34 * OpenSSL library under certain conditions as described in each
35 * individual source file, and distribute linked combinations
37 * You must obey the GNU General Public License in all respects
38 * for all of the code used other than OpenSSL. If you modify
39 * file(s) with this exception, you may extend this exception to your
40 * version of the file(s), but you are not obligated to do so. If you
41 * do not wish to do so, delete this exception statement from your
42 * version. If you delete this exception statement from all source
43 * files in the program, then also delete it here.
48 #include "datatypes.h"
50 #include "plainPacket.h"
51 #include "anytunError.h"
53 PlainPacket::PlainPacket(uint32_t payload_length, bool allow_realloc) : Buffer(payload_length + sizeof(payload_type_t), allow_realloc)
55 payload_type_ = reinterpret_cast<payload_type_t*>(buf_);
56 payload_ = buf_ + sizeof(payload_type_t);
60 uint32_t PlainPacket::getHeaderLength()
62 return sizeof(payload_type_t);
65 payload_type_t PlainPacket::getPayloadType() const
68 return PAYLOAD_TYPE_T_NTOH(*payload_type_);
74 void PlainPacket::setPayloadType(payload_type_t payload_type)
80 if(payload_type == PAYLOAD_TYPE_TUN) {
82 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN);
86 char* ip_version_ptr = reinterpret_cast<char*>(payload_);
87 char ip_version = ip_version_ptr[0];
90 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN4);
91 } else if(ip_version == 6) {
92 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN6);
95 *payload_type_ = PAYLOAD_TYPE_T_HTON(payload_type);
99 uint32_t PlainPacket::getPayloadLength() const
105 return (length_ > sizeof(payload_type_t)) ? (length_ - sizeof(payload_type_t)) : 0;
108 void PlainPacket::setPayloadLength(uint32_t payload_length)
110 Buffer::setLength(payload_length + sizeof(payload_type_t));
111 // depending on allow_realloc buf_ may point to another address
112 // therefore in this case reinit() gets called by Buffer::setLength()
115 void PlainPacket::reinit()
117 payload_type_ = reinterpret_cast<payload_type_t*>(buf_);
118 payload_ = buf_ + sizeof(payload_type_t);
120 if(length_ <= (sizeof(payload_type_t))) {
124 if(length_ < (sizeof(payload_type_t))) {
125 payload_type_ = NULL;
126 AnytunError::throwErr() << "plain packet can't be initialized, buffer is too small";
131 uint8_t* PlainPacket::getPayload()
137 NetworkAddress PlainPacket::getSrcAddr() const
139 if(!payload_type_ || !payload_)
140 return NetworkAddress();
142 payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_);
144 if(type == PAYLOAD_TYPE_TAP) // Ehternet
147 return NetworkAddress();
149 else if(type == PAYLOAD_TYPE_TUN4) // IPv4
151 if(length_ < (sizeof(payload_type_t)+sizeof(struct ip)))
152 return NetworkAddress();
153 struct ip* hdr = reinterpret_cast<struct ip*>(payload_);
154 return NetworkAddress(hdr->ip_src);
156 else if(type == PAYLOAD_TYPE_TUN6) // IPv6
158 if(length_ < (sizeof(payload_type_t)+sizeof(struct ip6_hdr)))
159 return NetworkAddress();
160 struct ip6_hdr* hdr = reinterpret_cast<struct ip6_hdr*>(payload_);
161 return NetworkAddress(hdr->ip6_src);
163 return NetworkAddress();
166 NetworkAddress PlainPacket::getDstAddr() const
168 if(!payload_type_ || !payload_) {
169 return NetworkAddress();
172 payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_);
174 if(type == PAYLOAD_TYPE_TAP) { // Ehternet
176 return NetworkAddress();
177 } else if(type == PAYLOAD_TYPE_TUN4) { // IPv4
178 if(length_ < (sizeof(payload_type_t)+5*4)) {
179 return NetworkAddress();
181 char* hdr = reinterpret_cast<char*>(payload_);
182 boost::asio::ip::address_v4::bytes_type ip_octets;
183 for(int i=0; i<4; i++) {
184 ip_octets[i]=hdr[4*4+i];
186 return NetworkAddress(boost::asio::ip::address_v4(ip_octets));
187 } else if(type == PAYLOAD_TYPE_TUN6) { // IPv6
188 if(length_ < (sizeof(payload_type_t)+2*16+2*4)) {
189 return NetworkAddress();
191 char* hdr = reinterpret_cast<char*>(payload_);
192 boost::asio::ip::address_v6::bytes_type ip_octets;
193 for(int i=0; i<16; i++) {
194 ip_octets[i]=hdr[2*4+16+i];
196 return NetworkAddress(boost::asio::ip::address_v6(ip_octets));
198 return NetworkAddress();