got rid of NOPACKED (struct alignment works now under Windows)
[anytun.git] / src / plainPacket.cpp
bloba12a7c8583a88a237564231d05a0a60eb052018a
1 /*
2 * anytun
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-2008 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 version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
32 #include <stdexcept>
33 #include <iostream>
34 #include "datatypes.h"
35 #include "endian.h"
36 #include "plainPacket.h"
38 PlainPacket::PlainPacket(u_int32_t payload_length, bool allow_realloc) : Buffer(payload_length + sizeof(payload_type_t), allow_realloc)
40 payload_type_ = reinterpret_cast<payload_type_t*>(buf_);
41 payload_ = buf_ + sizeof(payload_type_t);
42 *payload_type_ = 0;
45 payload_type_t PlainPacket::getPayloadType() const
47 if(payload_type_)
48 return PAYLOAD_TYPE_T_NTOH(*payload_type_);
50 return 0;
53 void PlainPacket::setPayloadType(payload_type_t payload_type)
55 if(!payload_type_)
56 return;
58 if(payload_type == PAYLOAD_TYPE_TUN) {
59 if(!payload_) {
60 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN);
61 return;
64 char * ip_version_ptr = reinterpret_cast<char *>(payload_);
65 char ip_version = ip_version_ptr[0];
66 ip_version >>=4;
67 if(ip_version == 4)
68 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN4);
69 else if(ip_version == 6)
70 *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN6);
72 else
73 *payload_type_ = PAYLOAD_TYPE_T_HTON(payload_type);
76 u_int32_t PlainPacket::getPayloadLength() const
78 if(!payload_)
79 return 0;
81 return (length_ > sizeof(payload_type_t)) ? (length_ - sizeof(payload_type_t)) : 0;
84 void PlainPacket::setPayloadLength(u_int32_t payload_length)
86 Buffer::setLength(payload_length + sizeof(payload_type_t));
87 // depending on allow_realloc buf_ may point to another address
88 // therefore in this case reinit() gets called by Buffer::setLength()
91 void PlainPacket::reinit()
93 payload_type_ = reinterpret_cast<payload_type_t*>(buf_);
94 payload_ = buf_ + sizeof(payload_type_t);
96 if(length_ <= (sizeof(payload_type_t)))
97 payload_ = NULL;
99 if(length_ < (sizeof(payload_type_t))) {
100 payload_type_ = NULL;
101 throw std::runtime_error("packet can't be initialized, buffer is too small");
106 u_int8_t* PlainPacket::getPayload()
108 return payload_;
112 NetworkAddress PlainPacket::getSrcAddr() const
114 if(!payload_type_ || !payload_)
115 return NetworkAddress();
117 payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_);
119 if(type == PAYLOAD_TYPE_TAP) // Ehternet
121 // TODO
122 return NetworkAddress();
124 else if(type == PAYLOAD_TYPE_TUN4) // IPv4
126 if(length_ < (sizeof(payload_type_t)+sizeof(struct ip)))
127 return NetworkAddress();
128 struct ip* hdr = reinterpret_cast<struct ip*>(payload_);
129 return NetworkAddress(hdr->ip_src);
131 else if(type == PAYLOAD_TYPE_TUN6) // IPv6
133 if(length_ < (sizeof(payload_type_t)+sizeof(struct ip6_hdr)))
134 return NetworkAddress();
135 struct ip6_hdr* hdr = reinterpret_cast<struct ip6_hdr*>(payload_);
136 return NetworkAddress(hdr->ip6_src);
138 return NetworkAddress();
141 NetworkAddress PlainPacket::getDstAddr() const
143 if(!payload_type_ || !payload_)
144 return NetworkAddress();
146 payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_);
148 if(type == PAYLOAD_TYPE_TAP) // Ehternet
150 // TODO
151 return NetworkAddress();
153 else if(type == PAYLOAD_TYPE_TUN4) // IPv4
155 if(length_ < (sizeof(payload_type_t)+5*4))
156 return NetworkAddress();
157 char * hdr = reinterpret_cast<char *>(payload_);
158 boost::asio::ip::address_v4::bytes_type ip_octets;
159 for (int i=0; i<4;i++)
160 ip_octets[i]=hdr[4*4+i];
161 return NetworkAddress(boost::asio::ip::address_v4(ip_octets));
163 else if(type == PAYLOAD_TYPE_TUN6) // IPv6
165 if(length_ < (sizeof(payload_type_t)+2*16+2*4))
166 return NetworkAddress();
167 char * hdr = reinterpret_cast<char *>(payload_);
168 boost::asio::ip::address_v6::bytes_type ip_octets;
169 for (int i=0; i<16;i++)
170 ip_octets[i]=hdr[2*4+16+i];
171 return NetworkAddress(boost::asio::ip::address_v6(ip_octets));
173 return NetworkAddress();