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
34 #include "datatypes.h"
40 #include "keyDerivation.h"
42 #include "signalController.h"
43 #include "packetSource.h"
44 #include "tunDevice.h"
46 #include "seqWindow.h"
48 #define PAYLOAD_TYPE_TAP 0x6558
49 #define PAYLOAD_TYPE_TUN 0x0800
64 Param
* param
= reinterpret_cast<Param
*>(p
);
69 Packet
pack(1600); // fix me... mtu size
71 // read packet from device
72 int len
= param
->dev
.read(pack
);
75 if(param
->opt
.getRemoteAddr() == "")
79 if(param
->dev
.getType() == TunDevice::TYPE_TUN
)
80 pack
.addPayloadType(PAYLOAD_TYPE_TUN
);
81 else if(param
->dev
.getType() == TunDevice::TYPE_TAP
)
82 pack
.addPayloadType(PAYLOAD_TYPE_TAP
);
84 pack
.addPayloadType(0);
87 Buffer
tmp_key(16), tmp_salt(14);
88 param
->kd
.generate(label_satp_encryption
, seq
, tmp_key
, tmp_key
.getLength());
89 param
->kd
.generate(label_satp_salt
, seq
, tmp_salt
, tmp_salt
.getLength());
90 param
->c
.setKey(tmp_key
);
91 param
->c
.setSalt(tmp_salt
);
93 //std::cout << "Send Package: seq: " << seq << std::endl << "sID: " << param->opt.getSenderId() << std::endl;
94 //std::cout << "Package dump: " << pack.getBuf() << std::endl;
96 param
->c
.cypher(pack
, seq
, param
->opt
.getSenderId());
98 // add header to packet
99 pack
.addHeader(seq
, param
->opt
.getSenderId());
102 // calc auth_tag and add it to the packet
103 auth_tag_t at
= param
->a
.calc(pack
);
106 // send it out to remote host
107 param
->src
.send(pack
, param
->opt
.getRemoteAddr(), param
->opt
.getRemotePort());
112 void* sync_receiver(void* p
)
114 Param
* param
= reinterpret_cast<Param
*>(p
);
121 void* receiver(void* p
)
123 Param
* param
= reinterpret_cast<Param
*>(p
);
128 u_int16_t remote_port
;
129 u_int16_t sid
= 0, seq
= 0;
130 Packet
pack(1600); // fix me... mtu size
132 // read packet from socket
133 u_int32_t len
= param
->src
.recv(pack
, remote_host
, remote_port
);
134 pack
.resizeBack(len
);
135 pack
.withPayloadType(true).withHeader(true).withAuthTag(true);
137 // check auth_tag and remove it
138 auth_tag_t at
= pack
.getAuthTag();
139 pack
.removeAuthTag();
140 if(at
!= param
->a
.calc(pack
))
144 // if(param->opt.getRemoteAddr() == "")
146 param
->opt
.setRemoteAddrPort(remote_host
, remote_port
);
147 cLog
.msg(Log::PRIO_NOTICE
) << "autodetected remote host " << remote_host
<< ":" << remote_port
;
150 sid
= pack
.getSenderId();
151 seq
= pack
.getSeqNr();
152 // compare sender_id and seq with window
153 if(param
->seq
.hasSeqNr(pack
.getSenderId(), pack
.getSeqNr()))
155 param
->seq
.addSeqNr(pack
.getSenderId(), pack
.getSeqNr());
158 // decypher the packet
159 Buffer
tmp_key(16), tmp_salt(14);
160 param
->kd
.generate(label_satp_encryption
, seq
, tmp_key
, tmp_key
.getLength());
161 param
->kd
.generate(label_satp_salt
, seq
, tmp_salt
, tmp_salt
.getLength());
162 param
->c
.setKey(tmp_key
);
163 param
->c
.setSalt(tmp_salt
);
164 param
->c
.cypher(pack
, seq
, sid
);
166 //std::cout << "Received Package: seq: " << seq << std::endl << "sID: " << sid << std::endl;
167 //std::cout << "Package dump: " << pack.getBuf() << std::endl;
169 // check payload_type and remove it
170 if((param
->dev
.getType() == TunDevice::TYPE_TUN
&& pack
.getPayloadType() != PAYLOAD_TYPE_TUN
) ||
171 (param
->dev
.getType() == TunDevice::TYPE_TAP
&& pack
.getPayloadType() != PAYLOAD_TYPE_TAP
))
173 pack
.removePayloadType();
175 // write it on the device
176 param
->dev
.write(pack
);
181 int main(int argc
, char* argv
[])
183 std::cout
<< "anytun - secure anycast tunneling protocol" << std::endl
;
185 if(!opt
.parse(argc
, argv
))
190 cLog
.msg(Log::PRIO_NOTICE
) << "anytun started...";
192 SignalController sig
;
194 std::string
dev_type(opt
.getDevType());
195 TunDevice
dev(opt
.getDevName().c_str(), dev_type
=="" ? NULL
: dev_type
.c_str(), opt
.getIfconfigParamLocal().c_str(), opt
.getIfconfigParamRemoteNetmask().c_str());
196 SeqWindow
seq(opt
.getSeqWindowSize());
199 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
200 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
205 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
206 'i', 'j', 'k', 'l', 'm', 'n'
211 kd
.init(Buffer(key
, sizeof(key
)), Buffer(salt
, sizeof(salt
)));
217 if(opt
.getLocalAddr() == "")
218 src
= new UDPPacketSource(opt
.getLocalPort());
220 src
= new UDPPacketSource(opt
.getLocalAddr(), opt
.getLocalPort());
222 struct Param p
= {opt
, dev
, kd
, c
, a
, *src
, seq
};
224 std::cout
<< "dev created (opened)" << std::endl
;
225 std::cout
<< "dev opened - actual name is '" << p
.dev
.getActualName() << "'" << std::endl
;
226 std::cout
<< "dev type is '" << p
.dev
.getTypeString() << "'" << std::endl
;
228 pthread_t senderThread
;
229 pthread_create(&senderThread
, NULL
, sender
, &p
);
230 pthread_t receiverThread
;
231 pthread_create(&receiverThread
, NULL
, receiver
, &p
);
235 pthread_cancel(senderThread
);
236 pthread_cancel(receiverThread
);
237 pthread_join(senderThread
, NULL
);
238 pthread_join(receiverThread
, NULL
);