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 methodes 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-2009 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/>.
35 #include "datatypes.h"
37 #include "plainPacket.h"
38 #include "anytunError.h"
40 PlainPacket::PlainPacket(uint32_t payload_length, bool allow_realloc) : Buffer(payload_length + sizeof(payload_type_t), allow_realloc)
42 payload_type_ = reinterpret_cast<payload_type_t*>(buf_);
43 payload_ = buf_ + sizeof(payload_type_t);
47 uint32_t PlainPacket::getHeaderLength()
49 return sizeof(payload_type_t);
52 payload_type_t PlainPacket::getPayloadType() const
55 return PAYLOAD_TYPE_T_NTOH(*payload_type_);
61 void PlainPacket::setPayloadType(payload_type_t payload_type)
67 if(payload_type == PAYLOAD_TYPE_TUN) {
69 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN);
73 char* ip_version_ptr = reinterpret_cast<char*>(payload_);
74 char ip_version = ip_version_ptr[0];
77 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN4);
78 } else if(ip_version == 6) {
79 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN6);
82 *payload_type_ = PAYLOAD_TYPE_T_HTON(payload_type);
86 uint32_t PlainPacket::getPayloadLength() const
92 return (length_ > sizeof(payload_type_t)) ? (length_ - sizeof(payload_type_t)) : 0;
95 void PlainPacket::setPayloadLength(uint32_t payload_length)
97 Buffer::setLength(payload_length + sizeof(payload_type_t));
98 // depending on allow_realloc buf_ may point to another address
99 // therefore in this case reinit() gets called by Buffer::setLength()
102 void PlainPacket::reinit()
104 payload_type_ = reinterpret_cast<payload_type_t*>(buf_);
105 payload_ = buf_ + sizeof(payload_type_t);
107 if(length_ <= (sizeof(payload_type_t))) {
111 if(length_ < (sizeof(payload_type_t))) {
112 payload_type_ = NULL;
113 AnytunError::throwErr() << "plain packet can't be initialized, buffer is too small";
118 uint8_t* PlainPacket::getPayload()
124 NetworkAddress PlainPacket::getSrcAddr() const
126 if(!payload_type_ || !payload_)
127 return NetworkAddress();
129 payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_);
131 if(type == PAYLOAD_TYPE_TAP) // Ehternet
134 return NetworkAddress();
136 else if(type == PAYLOAD_TYPE_TUN4) // IPv4
138 if(length_ < (sizeof(payload_type_t)+sizeof(struct ip)))
139 return NetworkAddress();
140 struct ip* hdr = reinterpret_cast<struct ip*>(payload_);
141 return NetworkAddress(hdr->ip_src);
143 else if(type == PAYLOAD_TYPE_TUN6) // IPv6
145 if(length_ < (sizeof(payload_type_t)+sizeof(struct ip6_hdr)))
146 return NetworkAddress();
147 struct ip6_hdr* hdr = reinterpret_cast<struct ip6_hdr*>(payload_);
148 return NetworkAddress(hdr->ip6_src);
150 return NetworkAddress();
153 NetworkAddress PlainPacket::getDstAddr() const
155 if(!payload_type_ || !payload_) {
156 return NetworkAddress();
159 payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_);
161 if(type == PAYLOAD_TYPE_TAP) { // Ehternet
163 return NetworkAddress();
164 } else if(type == PAYLOAD_TYPE_TUN4) { // IPv4
165 if(length_ < (sizeof(payload_type_t)+5*4)) {
166 return NetworkAddress();
168 char* hdr = reinterpret_cast<char*>(payload_);
169 boost::asio::ip::address_v4::bytes_type ip_octets;
170 for(int i=0; i<4; i++) {
171 ip_octets[i]=hdr[4*4+i];
173 return NetworkAddress(boost::asio::ip::address_v4(ip_octets));
174 } else if(type == PAYLOAD_TYPE_TUN6) { // IPv6
175 if(length_ < (sizeof(payload_type_t)+2*16+2*4)) {
176 return NetworkAddress();
178 char* hdr = reinterpret_cast<char*>(payload_);
179 boost::asio::ip::address_v6::bytes_type ip_octets;
180 for(int i=0; i<16; i++) {
181 ip_octets[i]=hdr[2*4+16+i];
183 return NetworkAddress(boost::asio::ip::address_v6(ip_octets));
185 return NetworkAddress();