summaryrefslogtreecommitdiff
path: root/src/uanytun.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2009-01-06 11:02:11 +0000
committerChristian Pointner <equinox@anytun.org>2009-01-06 11:02:11 +0000
commit3818e534e68111d7e932cfa1394069eddbb63799 (patch)
treee0f7ecda475b61ffb2970be9174560f3e8507624 /src/uanytun.c
parentcleaned up main_loop a little (diff)
cleaned up main_loop
Diffstat (limited to 'src/uanytun.c')
-rw-r--r--src/uanytun.c171
1 files changed, 93 insertions, 78 deletions
diff --git a/src/uanytun.c b/src/uanytun.c
index 609a873..b857afd 100644
--- a/src/uanytun.c
+++ b/src/uanytun.c
@@ -93,11 +93,11 @@ int init_libgcrypt()
#endif
#endif
-#ifndef NO_CRYPT
-int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_t* kd_in, key_derivation_t* kd_out, seq_win_t* seq_win)
-#else
-int init_main_loop(options_t* opt, cipher_t* c, key_derivation_t* kd_in, key_derivation_t* kd_out, seq_win_t* seq_win)
+#ifdef NO_CRYPT
+typedef u_int8_t auth_algo_t;
#endif
+
+int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_t* kd_in, key_derivation_t* kd_out, seq_win_t* seq_win)
{
int ret = cipher_init(c, opt->cipher_);
if(ret) {
@@ -145,6 +145,91 @@ int init_main_loop(options_t* opt, cipher_t* c, key_derivation_t* kd_in, key_der
return 0;
}
+int process_tun_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet,
+ cipher_t* c, auth_algo_t* aa, key_derivation_t* kd_out, seq_nr_t seq_nr)
+{
+ int len = tun_read(dev, plain_packet_get_payload(plain_packet), plain_packet_get_payload_length(plain_packet));
+ if(len == -1) {
+ log_printf(ERR, "error on reading from device: %m");
+ return 0;
+ }
+
+ plain_packet_set_payload_length(plain_packet, len);
+
+ if(dev->type_ = TYPE_TUN)
+ plain_packet_set_type(plain_packet, PAYLOAD_TYPE_TUN);
+ else if(dev->type_ = TYPE_TAP)
+ plain_packet_set_type(plain_packet, PAYLOAD_TYPE_TAP);
+ else
+ plain_packet_set_type(plain_packet, PAYLOAD_TYPE_UNKNOWN);
+
+ cipher_encrypt(c, kd_out, plain_packet, encrypted_packet, seq_nr, opt->sender_id_, opt->mux_);
+
+#ifndef NO_CRYPT
+ auth_algo_generate(aa, kd_out, encrypted_packet);
+#endif
+
+ len = udp_write(sock, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet));
+ if(len == -1)
+ log_printf(ERR, "error on sending udp packet: %m");
+
+ return 0;
+}
+
+int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet,
+ cipher_t* c, auth_algo_t* aa, key_derivation_t* kd_in, seq_win_t* seq_win)
+{
+ udp_endpoint_t remote;
+ memset(&remote, 0, sizeof(udp_endpoint_t));
+ int len = udp_read(sock, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet), &remote);
+ if(len == -1) {
+ log_printf(ERR, "error on receiving udp packet: %m");
+ return 0;
+ }
+
+ encrypted_packet_set_length(encrypted_packet, len);
+
+#ifndef NO_CRYPT
+ if(!auth_algo_check_tag(aa, kd_in, encrypted_packet)) {
+ log_printf(WARNING, "wrong authentication tag, discarding packet");
+ return 0;
+ }
+#endif
+
+ if(encrypted_packet_get_mux(encrypted_packet) != opt->mux_) {
+ log_printf(WARNING, "wrong mux value, discarding packet");
+ return 0;
+ }
+
+ int result = seq_win_check_and_add(seq_win, encrypted_packet_get_sender_id(encrypted_packet), encrypted_packet_get_seq_nr(encrypted_packet));
+ if(result > 0) {
+ log_printf(WARNING, "detected replay attack, discarding packet");
+ return 0;
+ }
+ else if(result < 0) {
+ log_printf(ERR, "memory error at sequence window");
+ return -2;
+ }
+
+ if(memcmp(&remote, &(sock->remote_end_), sizeof(remote))) {
+ memcpy(&(sock->remote_end_), &remote, sizeof(remote));
+ char* addrstring = udp_endpoint_to_string(remote);
+ log_printf(NOTICE, "autodetected remote host changed %s", addrstring);
+ free(addrstring);
+ }
+
+ int ret = cipher_decrypt(c, kd_in, encrypted_packet, plain_packet);
+ if(ret)
+ return ret;
+
+ len = tun_write(dev, plain_packet_get_payload(plain_packet), plain_packet_get_payload_length(plain_packet));
+ if(len == -1)
+ log_printf(ERR, "error on writing to device: %m");
+
+ return 0;
+}
+
+
int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt)
{
log_printf(INFO, "entering main loop");
@@ -153,23 +238,15 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt)
plain_packet_init(&plain_packet);
encrypted_packet_t encrypted_packet;
encrypted_packet_init(&encrypted_packet);
- int len = 0;
- udp_endpoint_t remote;
seq_nr_t seq_nr = 0;
fd_set readfds;
cipher_t c;
-#ifndef NO_CRYPT
auth_algo_t aa;
-#endif
key_derivation_t kd_in, kd_out;
seq_win_t seq_win;
-#ifndef NO_CRYPT
int ret = init_main_loop(opt, &c, &aa, &kd_in, &kd_out, &seq_win);
-#else
- int ret = init_main_loop(opt, &c, &kd_in, &kd_out, &seq_win);
-#endif
if(ret)
return ret;
@@ -198,76 +275,14 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt)
}
if(FD_ISSET(dev->fd_, &readfds)) {
- len = tun_read(dev, plain_packet_get_payload(&plain_packet), plain_packet_get_payload_length(&plain_packet));
- if(len == -1) {
- log_printf(ERR, "error on reading from device: %m");
- continue;
- }
-
- plain_packet_set_payload_length(&plain_packet, len);
-
- if(dev->type_ = TYPE_TUN)
- plain_packet_set_type(&plain_packet, PAYLOAD_TYPE_TUN);
- else if(dev->type_ = TYPE_TAP)
- plain_packet_set_type(&plain_packet, PAYLOAD_TYPE_TAP);
- else
- plain_packet_set_type(&plain_packet, PAYLOAD_TYPE_UNKNOWN);
-
- cipher_encrypt(&c, &kd_out, &plain_packet, &encrypted_packet, seq_nr, opt->sender_id_, opt->mux_);
+ return_value = process_tun_data(dev, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd_out, seq_nr);
seq_nr++;
-
-#ifndef NO_CRYPT
- auth_algo_generate(&aa, &kd_out, &encrypted_packet);
-#endif
-
- len = udp_write(sock, encrypted_packet_get_packet(&encrypted_packet), encrypted_packet_get_length(&encrypted_packet));
- if(len == -1)
- log_printf(ERR, "error on sending udp packet: %m");
+ continue;
}
if(FD_ISSET(sock->fd_, &readfds)) {
- len = udp_read(sock, encrypted_packet_get_packet(&encrypted_packet), encrypted_packet_get_length(&encrypted_packet), &remote);
- if(len == -1) {
- log_printf(ERR, "error on receiving udp packet: %m");
- continue;
- }
-
- encrypted_packet_set_length(&encrypted_packet, len);
-
-#ifndef NO_CRYPT
- if(!auth_algo_check_tag(&aa, &kd_out, &encrypted_packet)) {
- log_printf(WARNING, "wrong authentication tag, discarding packet");
- continue;
- }
-#endif
-
- if(encrypted_packet_get_mux(&encrypted_packet) != opt->mux_)
- continue;
-
- int result = seq_win_check_and_add(&seq_win, encrypted_packet_get_sender_id(&encrypted_packet), encrypted_packet_get_seq_nr(&encrypted_packet));
- if(result > 0) {
- log_printf(WARNING, "detected replay attack, discarding packet");
- continue;
- }
- else if(result < 0) {
- log_printf(ERR, "memory error at sequence window");
- return_value -1;
- break;
- }
-
-
- if(memcmp(&remote, &(sock->remote_end_), sizeof(remote))) {
- memcpy(&(sock->remote_end_), &remote, sizeof(remote));
- char* addrstring = udp_endpoint_to_string(remote);
- log_printf(NOTICE, "autodetected remote host changed %s", addrstring);
- free(addrstring);
- }
-
- cipher_decrypt(&c, &kd_in, &encrypted_packet, &plain_packet);
-
- len = tun_write(dev, plain_packet_get_payload(&plain_packet), plain_packet_get_payload_length(&plain_packet));
- if(len == -1)
- log_printf(ERR, "error on writing to device: %m");
+ return_value = process_sock_data(dev, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd_in, &seq_win);
+ continue;
}
}