/* * anytun * * The secure anycast tunneling protocol (satp) defines a protocol used * for communication between any combination of unicast and anycast * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel * mode and allows tunneling of every ETHER TYPE protocol (e.g. * ethernet, ip, arp ...). satp directly includes cryptography and * message authentication based on the methodes used by SRTP. It is * intended to deliver a generic, scaleable and secure solution for * tunneling and relaying of packets of any protocol. * * * Copyright (C) 2007 anytun.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING included with this * distribution); if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include "datatypes.h" #include "plainPacket.h" PlainPacket::PlainPacket(u_int32_t payload_length, bool allow_realloc) : Buffer(payload_length + sizeof(payload_type_t), allow_realloc) { payload_type_ = reinterpret_cast(buf_); payload_ = buf_ + sizeof(payload_type_t); *payload_type_ = 0; } payload_type_t PlainPacket::getPayloadType() const { if(payload_type_) return PAYLOAD_TYPE_T_NTOH(*payload_type_); return 0; } void PlainPacket::setPayloadType(payload_type_t payload_type) { if(!payload_type_) return; if(payload_type == PAYLOAD_TYPE_TUN) { if(!payload_) { *payload_type_ = PAYLOAD_TYPE_T_HTON(0); return; } struct ip* hdr = reinterpret_cast(payload_); if(hdr->ip_v == 4) *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN4); else if(hdr->ip_v == 6) *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN6); } else *payload_type_ = PAYLOAD_TYPE_T_HTON(payload_type); } u_int32_t PlainPacket::getPayloadLength() const { if(!payload_) return 0; return (length_ > sizeof(payload_type_t)) ? (length_ - sizeof(payload_type_t)) : 0; } void PlainPacket::setPayloadLength(u_int32_t payload_length) { Buffer::setLength(payload_length + sizeof(payload_type_t)); // depending on allow_realloc buf_ may point to another address // therefore in this case reinit() gets called by Buffer::setLength() } void PlainPacket::reinit() { payload_type_ = reinterpret_cast(buf_); payload_ = buf_ + sizeof(payload_type_t); if(length_ <= (sizeof(payload_type_t))) payload_ = NULL; if(length_ < (sizeof(payload_type_t))) { payload_type_ = NULL; throw std::runtime_error("packet can't be initialized, buffer is too small"); } } u_int8_t* PlainPacket::getPayload() { return payload_; } NetworkAddress PlainPacket::getSrcAddr() const { if(!payload_type_ || !payload_) return NetworkAddress(); payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_); if(type == PAYLOAD_TYPE_TAP) // Ehternet { // TODO return NetworkAddress(); } else if(type == PAYLOAD_TYPE_TUN4) // IPv4 { if(length_ < (sizeof(payload_type_t)+sizeof(struct ip))) return NetworkAddress(); struct ip* hdr = reinterpret_cast(payload_); return NetworkAddress(hdr->ip_src); } else if(type == PAYLOAD_TYPE_TUN6) // IPv6 { if(length_ < (sizeof(payload_type_t)+sizeof(struct ip6_hdr))) return NetworkAddress(); struct ip6_hdr* hdr = reinterpret_cast(payload_); return NetworkAddress(hdr->ip6_src); } return NetworkAddress(); } NetworkAddress PlainPacket::getDstAddr() const { if(!payload_type_ || !payload_) return NetworkAddress(); payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_); if(type == PAYLOAD_TYPE_TAP) // Ehternet { // TODO return NetworkAddress(); } else if(type == PAYLOAD_TYPE_TUN4) // IPv4 { if(length_ < (sizeof(payload_type_t)+sizeof(struct ip))) return NetworkAddress(); struct ip* hdr = reinterpret_cast(payload_); return NetworkAddress(hdr->ip_dst); } else if(type == PAYLOAD_TYPE_TUN6) // IPv6 { if(length_ < (sizeof(payload_type_t)+sizeof(struct ip6_hdr))) return NetworkAddress(); struct ip6_hdr* hdr = reinterpret_cast(payload_); return NetworkAddress(hdr->ip6_dst); } return NetworkAddress(); }