read on tunDevice works now
[anytun.git] / package.cpp
blob4cdba50e1924ed294aff0ac45774595f36db74ed
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 anytun.org <satp@wirdorange.org>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2
18 * as published by the Free Software Foundation.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program (see the file COPYING included with this
27 * distribution); if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <stdexcept>
32 #include <arpa/inet.h>
34 #include "datatypes.h"
36 #include "package.h"
38 Package::Package()
40 has_header_ = false;
41 has_payload_type_ = false;
42 has_auth_tag_ = false;
45 Package::Package(u_int32_t length) : Buffer(length)
47 has_header_ = false;
48 has_payload_type_ = false;
49 has_auth_tag_ = false;
52 Package::Package(const Buffer &src) : Buffer(src)
54 has_header_ = false;
55 has_payload_type_ = false;
56 has_auth_tag_ = false;
59 bool Package::hasHeader() const
61 return has_header_;
64 Package& Package::withHeader(bool b)
66 if(b && length_ >= sizeof(struct HeaderStruct))
67 has_header_ = true;
68 else
69 has_header_ = false;
71 return *this;
74 seq_nr_t Package::getSeqNr() const
76 if(!has_header_)
77 return 0;
79 struct HeaderStruct* header;
80 header = reinterpret_cast<struct HeaderStruct*>(buf_);
81 return SEQ_NR_T_NTOH(header->seq_nr);
84 sender_id_t Package::getSenderId() const
86 if(!has_header_)
87 return 0;
89 struct HeaderStruct* header;
90 header = reinterpret_cast<struct HeaderStruct*>(buf_);
91 return SENDER_ID_T_NTOH(header->sender_id);
94 Package& Package::addHeader(seq_nr_t seq_nr, sender_id_t sender_id)
96 if(!has_header_)
98 if(sizeof(struct HeaderStruct) > resizeFront(length_ + sizeof(struct HeaderStruct)))
99 return *this;
101 has_header_ = true;
103 struct HeaderStruct* header;
104 header = reinterpret_cast<struct HeaderStruct*>(buf_);
105 header->seq_nr = SEQ_NR_T_HTON(seq_nr);
106 header->sender_id = SENDER_ID_T_HTON(sender_id);
107 return *this;
110 Package& Package::removeHeader()
112 if(!has_header_)
113 return *this;
115 if(length_ >= sizeof(struct HeaderStruct))
116 resizeFront(length_ - sizeof(struct HeaderStruct));
118 has_header_ = false;
120 return *this;
123 Package& Package::setSeqNr(seq_nr_t seq_nr)
125 if(has_header_)
127 struct HeaderStruct* header;
128 header = reinterpret_cast<struct HeaderStruct*>(buf_);
129 header->seq_nr = SEQ_NR_T_HTON(seq_nr);
131 return *this;
134 Package& Package::setSenderId(sender_id_t sender_id)
136 if(has_header_)
138 struct HeaderStruct* header;
139 header = reinterpret_cast<struct HeaderStruct*>(buf_);
140 header->sender_id = SENDER_ID_T_HTON(sender_id);
142 return *this;
147 bool Package::hasPayloadType() const
149 return has_payload_type_;
152 Package& Package::withPayloadType(bool b)
154 if(b && length_ >= sizeof(payload_type_t))
155 has_payload_type_ = true;
156 else
157 has_payload_type_ = false;
159 return *this;
162 payload_type_t Package::getPayloadType() const
164 if(!has_payload_type_)
165 return 0;
167 if((!has_auth_tag_ && length_ < sizeof(payload_type_t)) ||
168 (has_auth_tag_ && length_ < (sizeof(payload_type_t) + sizeof(auth_tag_t))))
169 return 0;
171 payload_type_t* payload_type;
173 if(!has_auth_tag_)
174 payload_type = reinterpret_cast<payload_type_t*>(buf_ + length_ - sizeof(payload_type_t));
175 else
176 payload_type = reinterpret_cast<payload_type_t*>(buf_ + length_ - sizeof(payload_type_t) - sizeof(auth_tag_t));
177 return PAYLOAD_TYPE_T_NTOH(*payload_type);
180 Package& Package::addPayloadType(payload_type_t payload_type)
182 if(has_auth_tag_)
183 throw std::runtime_error("can't add payload_type with existing auth_tag");
185 if(!has_payload_type_)
187 u_int32_t new_length = length_ + sizeof(payload_type_t);
188 if(new_length > resizeBack(new_length))
189 return *this;
191 has_payload_type_ = true;
193 payload_type_t* payload_type_ptr;
194 payload_type_ptr = reinterpret_cast<payload_type_t*>(buf_ + length_ - sizeof(payload_type_t));
195 *payload_type_ptr = PAYLOAD_TYPE_T_HTON(payload_type);
196 return *this;
199 Package& Package::removePayloadType()
201 if(has_auth_tag_)
202 throw std::runtime_error("can't remove payload_type with existing auth_tag");
204 if(!has_payload_type_)
205 return *this;
207 if(length_ >= sizeof(payload_type_t))
208 resizeBack(length_ - sizeof(payload_type_t));
210 has_payload_type_ = false;
212 return *this;
217 bool Package::hasAuthTag() const
219 return has_auth_tag_;
222 Package& Package::withAuthTag(bool b)
224 if(b && length_ >= sizeof(auth_tag_t))
225 has_auth_tag_ = true;
226 else
227 has_auth_tag_ = false;
229 return *this;
232 auth_tag_t Package::getAuthTag() const
234 if(!has_auth_tag_)
235 return 0;
237 if(length_ < sizeof(auth_tag_t))
238 return 0;
240 auth_tag_t* auth_tag;
241 auth_tag = reinterpret_cast<auth_tag_t*>(buf_ + length_ - sizeof(auth_tag_t));
242 return AUTH_TAG_T_NTOH(*auth_tag);
245 Package& Package::addAuthTag(auth_tag_t auth_tag)
247 if(!has_auth_tag_)
249 u_int32_t new_length = length_ + sizeof(auth_tag_t);
250 if(new_length > resizeBack(new_length))
251 return *this;
253 has_auth_tag_ = true;
255 auth_tag_t* auth_tag_ptr;
256 auth_tag_ptr = reinterpret_cast<auth_tag_t*>(buf_ + length_ - sizeof(auth_tag_t));
257 *auth_tag_ptr = AUTH_TAG_T_HTON(auth_tag);
258 return *this;
261 Package& Package::removeAuthTag()
263 if(!has_auth_tag_)
264 return *this;
266 if(length_ >= sizeof(auth_tag_t))
267 resizeBack(length_ - sizeof(auth_tag_t));
269 has_auth_tag_ = false;
271 return *this;