[Pkg-privacy-commits] [onioncat] 69/340: merged current tap-branch into trunk
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 13:04:25 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch debian
in repository onioncat.
commit 621277dc4fae5c3316927d270b2499ea0be8c533
Author: eagle <eagle at 58e1ccc2-750e-0410-8d0d-f93ca75ab447>
Date: Tue Oct 28 21:15:02 2008 +0000
merged current tap-branch into trunk
git-svn-id: http://www.cypherpunk.at/svn/onioncat/trunk@341 58e1ccc2-750e-0410-8d0d-f93ca75ab447
---
src/Makefile.am | 2 +-
src/Makefile.in | 5 +-
src/ocat.c | 16 ++-
src/ocat.h | 18 ++-
src/ocateth.c | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/ocatipv4route.c | 14 ++-
src/ocatpeer.c | 3 +-
src/ocatroute.c | 51 +++++++-
src/ocatsetup.c | 4 +-
src/ocattun.c | 33 +++--
10 files changed, 468 insertions(+), 23 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 68b27e8..b2b1726 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
bin_PROGRAMS = ocat
-ocat_SOURCES = ocat.c ocatlog.c ocatroute.c ocatthread.c ocattun.c ocatv6conv.c ocatcompat.c ocatpeer.c ocatsetup.c ocatipv4route.c
+ocat_SOURCES = ocat.c ocatlog.c ocatroute.c ocatthread.c ocattun.c ocatv6conv.c ocatcompat.c ocatpeer.c ocatsetup.c ocatipv4route.c ocateth.c
include_HEADERS = ocat.h strlcpy.c strlcat.c
diff --git a/src/Makefile.in b/src/Makefile.in
index e761638..f930659 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -48,7 +48,7 @@ PROGRAMS = $(bin_PROGRAMS)
am_ocat_OBJECTS = ocat.$(OBJEXT) ocatlog.$(OBJEXT) ocatroute.$(OBJEXT) \
ocatthread.$(OBJEXT) ocattun.$(OBJEXT) ocatv6conv.$(OBJEXT) \
ocatcompat.$(OBJEXT) ocatpeer.$(OBJEXT) ocatsetup.$(OBJEXT) \
- ocatipv4route.$(OBJEXT)
+ ocatipv4route.$(OBJEXT) ocateth.$(OBJEXT)
ocat_OBJECTS = $(am_ocat_OBJECTS)
ocat_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
@@ -152,7 +152,7 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-ocat_SOURCES = ocat.c ocatlog.c ocatroute.c ocatthread.c ocattun.c ocatv6conv.c ocatcompat.c ocatpeer.c ocatsetup.c ocatipv4route.c
+ocat_SOURCES = ocat.c ocatlog.c ocatroute.c ocatthread.c ocattun.c ocatv6conv.c ocatcompat.c ocatpeer.c ocatsetup.c ocatipv4route.c ocateth.c
include_HEADERS = ocat.h strlcpy.c strlcat.c
all: all-am
@@ -222,6 +222,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocat.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocatcompat.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocateth.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocatipv4route.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocatlog.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocatpeer.Po at am__quote@
diff --git a/src/ocat.c b/src/ocat.c
index e658090..d29178b 100644
--- a/src/ocat.c
+++ b/src/ocat.c
@@ -200,12 +200,26 @@ int main(int argc, char *argv[])
ctrl_handler((void*) c);
}
+ memcpy(&setup.ocat_hwaddr[3], &setup.ocat_addr.s6_addr[13], 3);
+ if (setup.use_tap);
+ {
+ log_msg(L_NOTICE, "MAC address %02x:%02x:%02x:%02x:%02x:%02x",
+ setup.ocat_hwaddr[0], setup.ocat_hwaddr[1], setup.ocat_hwaddr[2], setup.ocat_hwaddr[3], setup.ocat_hwaddr[4], setup.ocat_hwaddr[5]);
+ if (pipe(setup.icmpv6fd) == -1)
+ log_msg(L_FATAL, "cannot create multicast pipe: %s", strerror(errno)), exit(1);
+ run_ocat_thread("icmpv6", icmpv6_handler, NULL);
+ }
+
#ifndef WITHOUT_TUN
// create TUN device
setup.tunfd[0] = setup.tunfd[1] = tun_alloc(tunname, setup.ocat_addr);
#endif
- log_msg(L_NOTICE, "local IP is %s on %s", ip6addr, tunname);
+ log_msg(L_NOTICE, "IPv6 address %s", ip6addr);
+ log_msg(L_NOTICE, "TUN/TAP device %s", tunname);
+ if (setup.ipv4_enable)
+ log_msg(L_NOTICE, "IP address %s", inet_ntoa(setup.ocat_addr4));
+
log_debug("tun frameheader v6 = 0x%08x, v4 = 0x%08x", ntohl(setup.fhd_key[IPV6_KEY]), ntohl(setup.fhd_key[IPV4_KEY]));
// start socket receiver thread
diff --git a/src/ocat.h b/src/ocat.h
index fcf6888..b655132 100644
--- a/src/ocat.h
+++ b/src/ocat.h
@@ -37,6 +37,7 @@
#elif HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
#endif
+#include <net/ethernet.h>
#ifndef ETHERTYPE_IPV6
#define ETHERTYPE_IPV6 0x86dd
@@ -118,6 +119,10 @@
#define E_RT_NOTORGW -6
#define E_RT_GWSELF -7
+//! maximum number of MAC address entries in table
+#define MAX_MAC_ENTRY 128
+//! maximum age of MAC address in table
+#define MAX_MAC_AGE 120
#define IPV4_KEY 0
#define IPV6_KEY 1
@@ -158,6 +163,8 @@ struct OcatSetup
char *config_file;
int config_read;
int use_tap;
+ int icmpv6fd[2];
+ uint8_t ocat_hwaddr[ETH_ALEN];
};
typedef struct PacketQueue
@@ -175,7 +182,7 @@ typedef struct SocksHdr
char cmd;
uint16_t port;
struct in_addr addr;
-} __attribute__ ((packed)) SocksHdr_t;
+} __attribute__((packed)) SocksHdr_t;
typedef struct OcatPeer
{
@@ -223,6 +230,13 @@ typedef struct IPv4Route
struct in6_addr gw;
} IPv4Route_t;
+typedef struct MACTable
+{
+ struct in6_addr in6addr;
+ uint8_t hwaddr[ETH_ALEN];
+ time_t age;
+} MACTable_t;
+
/*
// next header value for ocat internal use (RFC3692)
#define OCAT_NEXT_HEADER 254
@@ -350,6 +364,8 @@ struct in6_addr *ipv4_lookup_route(uint32_t);
int parse_route(const char *);
void print_routes(FILE *);
+/* ocateth.c */
+void *icmpv6_handler(void *);
#endif
diff --git a/src/ocateth.c b/src/ocateth.c
new file mode 100644
index 0000000..f932aab
--- /dev/null
+++ b/src/ocateth.c
@@ -0,0 +1,345 @@
+/* Copyright 2008 Bernhard R. Fischer, Daniel Haslinger.
+ *
+ * This file is part of OnionCat.
+ *
+ * OnionCat is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OnionCat 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 OnionCat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*! ocateth.c
+ * Contains Ethernet (for TAP) and ICMPv6 (for NDP) code.
+ *
+ * @author Bernhard Fischer <rahra _at_ cypherpunk at>
+ * @version 2008/10/10
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_LINUX_SOCKIOS_H
+#include <linux/sockios.h>
+#endif
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+
+#include <net/ethernet.h>
+#include <netinet/icmp6.h>
+
+#include "ocat.h"
+
+
+static MACTable_t mac_tbl_[MAX_MAC_ENTRY];
+static int mac_cnt_ = 0;
+static pthread_mutex_t mac_mutex_ = PTHREAD_MUTEX_INITIALIZER;
+
+
+/*! Pseudo header for IPv6 checksum calculation.
+ * RFC2460 8.1, (RFC1885 2.3) RFC2463, RFC1071. */
+
+void mac_cleanup(void)
+{
+ int i;
+
+ pthread_mutex_lock(&mac_mutex_);
+
+ for (i = 0; i < mac_cnt_; i++)
+ if (mac_tbl_[i].age + MAX_MAC_AGE < time(NULL))
+ {
+ memmove(&mac_tbl_[i], &mac_tbl_[i + 1], sizeof(MACTable_t) * (MAX_MAC_ENTRY - i));
+ mac_cnt_--;
+ i--;
+ }
+
+ pthread_mutex_unlock(&mac_mutex_);
+}
+
+
+int mac_get_mac(const struct in6_addr *in6, uint8_t *hwaddr)
+{
+ int i;
+
+ pthread_mutex_lock(&mac_mutex_);
+
+ for (i = 0; i < mac_cnt_; i++)
+ if (IN6_ARE_ADDR_EQUAL(in6, &mac_tbl_[i].in6addr))
+ {
+ memcpy(hwaddr, &mac_tbl_[i].hwaddr, ETH_ALEN);
+ mac_tbl_[i].age = time(NULL);
+ break;
+ }
+
+ pthread_mutex_unlock(&mac_mutex_);
+
+ return i < mac_cnt_ ? i : -1;
+}
+
+
+int mac_get_ip(const uint8_t *hwaddr, struct in6_addr *in6)
+{
+ int i;
+
+ pthread_mutex_lock(&mac_mutex_);
+
+ for (i = 0; i < mac_cnt_; i++)
+ if (!memcmp(hwaddr, &mac_tbl_[i].hwaddr, ETH_ALEN))
+ {
+ memcpy(in6, &mac_tbl_[i].in6addr, sizeof(struct in6_addr));
+ mac_tbl_[i].age = time(NULL);
+ break;
+ }
+
+ pthread_mutex_unlock(&mac_mutex_);
+
+ return i < mac_cnt_ ? i : -1;
+}
+
+
+int mac_add_entry(const uint8_t *hwaddr, const struct in6_addr *in6)
+{
+ int e = -1;
+
+ pthread_mutex_lock(&mac_mutex_);
+
+ if (mac_cnt_ < MAX_MAC_ENTRY)
+ {
+ memcpy(&mac_tbl_[mac_cnt_].hwaddr, hwaddr, ETH_ALEN);
+ memcpy(&mac_tbl_[mac_cnt_].in6addr, in6, sizeof(struct in6_addr));
+ mac_tbl_[mac_cnt_].age = time(NULL);
+ e = ++mac_cnt_;
+ }
+
+ pthread_mutex_unlock(&mac_mutex_);
+
+ return e;
+}
+
+
+struct ip6_psh
+{
+ struct in6_addr src;
+ struct in6_addr dst;
+ uint32_t len;
+ char _pad[3];
+ uint8_t nxt;
+} __attribute__((packed));
+
+
+#if 0
+/*! Swap to memory areas. Those may not overlap.*/
+int memswp(void *dst, void *src, int len)
+{
+ char tmp[FRAME_SIZE];
+
+ if (len > FRAME_SIZE)
+ {
+ log_debug("buffers too large to swap");
+ return -1;
+ }
+
+ memcpy(tmp, dst, len);
+ memcpy(dst, src, len);
+ memcpy(src, tmp, len);
+
+ return len;
+}
+#endif
+
+
+/*! Calculate 16 bit one's complement sum (RFC1071).
+ * @param buf Pointer to buffer.
+ * @param len Number of bytes in buffer.
+ */
+uint16_t checksum(const uint16_t *buf, int len)
+{
+ uint32_t sum = 0;
+
+// len >>= 1;
+ // sum up all 16 bit words
+ // (Note that it's endiness independent)
+ for (; len > 1 ; len -= 2, buf++)
+ sum += *buf;
+
+ // add last byte if buffer has odd length
+ if (len)
+ sum += *((uint8_t*) buf);
+
+ // add carries
+ while (sum >> 16)
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ // return complement
+ return ~sum;
+}
+
+
+void *icmpv6_handler(void *p)
+{
+ char buf[FRAME_SIZE], ckbuf[FRAME_SIZE];
+ struct ether_header *eh = (struct ether_header*) (buf + 4);
+ struct ip6_hdr *ip6 = (struct ip6_hdr*) (eh + 1); // ip6 header starts behind ether_header
+ struct icmp6_hdr *icmp6 = (struct icmp6_hdr*) (ip6 + 1); // imcp6 header starts behind ip6 header
+ struct nd_neighbor_solicit *nds = (struct nd_neighbor_solicit*) icmp6;
+ struct nd_neighbor_advert *nda = (struct nd_neighbor_advert*) icmp6;
+ struct nd_opt_hdr *ohd = (struct nd_opt_hdr*) (nds + 1);
+ struct ip6_psh *ip6ph = (struct ip6_psh*) ckbuf;
+ int rlen;
+
+ memset(ckbuf, 0, sizeof(struct ip6_psh));
+
+// if (pipe(setup.icmpv6fd) == -1)
+// log_msg(L_FATAL, "cannot create pipe: %s", strerror(errno)), exit(1);
+
+ while ((rlen = read(setup.icmpv6fd[0], buf, FRAME_SIZE)) != -1)
+ {
+ log_debug("received %d bytes on icmp pipe", rlen);
+
+ if (rlen < 4 + sizeof(struct ether_header) + sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr))
+ {
+ log_debug("frame too short: %d < %d", rlen, 4 + sizeof(struct ether_header) + sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr));
+ continue;
+ }
+
+ // just to be on the safe side check icmpv6_mcast and ethertype
+// if ((*((uint16_t*) &buf[4]) != 0x3333) || (*((uint16_t*) &buf[12]) != htons(ETHERTYPE_IPV6)))
+ if (eh->ether_type != htons(ETHERTYPE_IPV6))
+ {
+ log_debug("protocol 0x%04x not implemented yet", htons(eh->ether_type));
+ continue;
+ }
+
+ if (ip6->ip6_nxt != IPPROTO_ICMPV6)
+ {
+ log_debug("frame contains not ICMPV6, next header = %d", ip6->ip6_nxt);
+ continue;
+ }
+
+ if (icmp6->icmp6_type != ND_NEIGHBOR_SOLICIT)
+ {
+ log_debug("icmpv6 type %d not implemented", icmp6->icmp6_type);
+ continue;
+ }
+
+ log_debug("ICMPv6 ND_NEIGHBOR_SOLICIT received");
+
+ memcpy(&ip6ph->src, &ip6->ip6_src, sizeof(struct in6_addr));
+ memcpy(&ip6ph->dst, &ip6->ip6_dst, sizeof(struct in6_addr));
+ ip6ph->len = ip6->ip6_plen;
+ ip6ph->nxt = IPPROTO_ICMPV6;
+ memcpy(ip6ph + 1, icmp6, ntohs(ip6->ip6_plen));
+
+ if (checksum((uint16_t*) ip6ph, ntohs(ip6->ip6_plen) + sizeof(struct ip6_psh)))
+ {
+ log_msg(L_ERROR, "icmpv6 checksum wrong");
+ continue;
+ }
+
+ log_debug("checksum correct, generating response");
+ memcpy(eh->ether_dhost, eh->ether_shost, ETH_ALEN);
+ memcpy(eh->ether_shost, setup.ocat_hwaddr, ETH_ALEN);
+
+ memcpy(&ip6->ip6_dst, &ip6->ip6_src, sizeof(struct in6_addr));
+ memcpy(&ip6->ip6_src, &nds->nd_ns_target, sizeof(struct in6_addr));
+ icmp6->icmp6_type = ND_NEIGHBOR_ADVERT;
+ icmp6->icmp6_code = 0;
+ icmp6->icmp6_cksum = 0;
+
+ memcpy(&ip6ph->src, &ip6->ip6_src, sizeof(struct in6_addr));
+ memcpy(&ip6ph->dst, &ip6->ip6_dst, sizeof(struct in6_addr));
+ ip6ph->len = ip6->ip6_plen;
+ ip6ph->nxt = IPPROTO_ICMPV6;
+
+ nda->nd_na_flags_reserved = ND_NA_FLAG_SOLICITED;
+ ohd->nd_opt_type = ND_OPT_TARGET_LINKADDR;
+ memcpy(ohd + 1, setup.ocat_hwaddr, ETH_ALEN);
+
+ memcpy(ip6ph + 1, icmp6, ntohs(ip6->ip6_plen));
+
+ icmp6->icmp6_cksum = checksum((uint16_t*) ip6ph, ntohs(ip6->ip6_plen) + sizeof(struct ip6_psh));
+
+ log_debug("writing %d bytes to tunfd %d", rlen, setup.tunfd[1]);
+ if (write(setup.tunfd[1], buf, rlen) < rlen)
+ log_msg(L_ERROR, "short write");
+ }
+
+ log_msg(L_FATAL, "error reading from pipe fd %d: %s", setup.icmpv6fd[0], strerror(errno));
+ exit(1);
+}
+
+
+#if 0
+#ifdef DEBUG
+static char hexbuf_[FRAME_SIZE];
+static char convbuf_[] = "0123456789ABCDEF";
+
+char *buf2hex(const char *buf, int len)
+{
+ char *b = hexbuf_;
+ for (; len; buf++, len--)
+ {
+ *b++ = convbuf_[((*buf) >> 4) & 0xf];
+ *b++ = convbuf_[(*buf) & 0xf];
+ *b++ = ' ';
+ }
+ *(b - 1) = '\0';
+ return hexbuf_;
+}
+
+#endif
+
+
+void *icmpv6_handler(void *p)
+{
+ char buf[FRAME_SIZE];
+ int s, offset = 2, rlen;
+ struct sockaddr_in6 in6;
+ socklen_t slen;
+
+ if ((s = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1)
+ {
+ log_msg(L_ERROR, "could not create ICMPv6 socket: %s", strerror(errno));
+ return NULL;
+ }
+
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)) == -1)
+ log_msg(L_ERROR, "could not set IPV6_CHECKSUM on raw socket: %s", strerror(errno));
+
+ for (;;)
+ {
+ slen = sizeof(in6);
+ if ((rlen = recvfrom(s, buf, FRAME_SIZE, 0, (struct sockaddr*) &in6, &slen)) == -1)
+ {
+ log_msg(L_ERROR, "could not recvfrom(): %s", strerror(errno));
+ continue;
+ }
+ log_debug("received %d bytes on raw socket %d", rlen, s);
+ log_debug("%s", buf2hex(buf, rlen));
+ }
+}
+#endif
+
diff --git a/src/ocatipv4route.c b/src/ocatipv4route.c
index 77ba99f..775131c 100644
--- a/src/ocatipv4route.c
+++ b/src/ocatipv4route.c
@@ -61,13 +61,15 @@ int ipv4_add_route(IPv4Route_t *route, IPv4Route_t **root, uint32_t cur_nm)
if (route->netmask == cur_nm /*(*root)->netmask*/)
{
- if (!memcmp(&(*root)->gw, &in6addr_any, sizeof(struct in6_addr)))
+ //if (!memcmp(&(*root)->gw, &in6addr_any, sizeof(struct in6_addr)))
+ if (IN6_ARE_ADDR_EQUAL(&(*root)->gw, &in6addr_any))
{
memcpy(&(*root)->gw, &route->gw, sizeof(struct in6_addr));
return 0;
}
- if (!memcmp(&(*root)->gw, &route->gw, sizeof(struct in6_addr)))
+ //if (!memcmp(&(*root)->gw, &route->gw, sizeof(struct in6_addr)))
+ if (IN6_ARE_ADDR_EQUAL(&(*root)->gw, &route->gw))
return 0;
log_msg(L_ERROR, "route already exists");
@@ -103,7 +105,8 @@ IPv4Route_t *ipv4_lookup_route__(uint32_t ip, IPv4Route_t *route, uint32_t cur_n
if (route->next[BRANCH(ip, cur_nm)])
return ipv4_lookup_route__(ip, route->next[BRANCH(ip, cur_nm)], cur_nm);
- if (memcmp(&route->gw, &in6addr_any, sizeof(struct in6_addr)))
+ //if (memcmp(&route->gw, &in6addr_any, sizeof(struct in6_addr)))
+ if (!IN6_ARE_ADDR_EQUAL(&route->gw, &in6addr_any))
return route;
return NULL;
@@ -141,7 +144,8 @@ void ipv4_print(IPv4Route_t *route, void *f)
char addr[INET6_ADDRSTRLEN];
struct in_addr iaddr;
- if (!memcmp(&route->gw, &in6addr_any, sizeof(struct in6_addr)))
+ //if (!memcmp(&route->gw, &in6addr_any, sizeof(struct in6_addr)))
+ if (IN6_ARE_ADDR_EQUAL(&route->gw, &in6addr_any))
return;
iaddr.s_addr = htonl(route->dest);
@@ -194,7 +198,7 @@ int parse_route(const char *rs)
if (!has_tor_prefix(&route.gw))
return E_RT_NOTORGW;
- if (!memcmp(&route.gw, &setup.ocat_addr, sizeof(setup.ocat_addr)))
+ if (IN6_ARE_ADDR_EQUAL(&route.gw, &setup.ocat_addr))
return E_RT_GWSELF;
route.netmask = ntohl(route.netmask);
diff --git a/src/ocatpeer.c b/src/ocatpeer.c
index 6644523..41e17d0 100644
--- a/src/ocatpeer.c
+++ b/src/ocatpeer.c
@@ -81,7 +81,8 @@ OcatPeer_t *search_peer(const struct in6_addr *addr)
OcatPeer_t *peer;
for (peer = peer_; peer; peer = peer->next)
- if (!memcmp(addr, &peer->addr, sizeof(struct in6_addr)))
+ //if (!memcmp(addr, &peer->addr, sizeof(struct in6_addr)))
+ if (IN6_ARE_ADDR_EQUAL(addr, &peer->addr))
return peer;
return NULL;
}
diff --git a/src/ocatroute.c b/src/ocatroute.c
index d616d5c..839c133 100644
--- a/src/ocatroute.c
+++ b/src/ocatroute.c
@@ -36,6 +36,7 @@
#include <sys/time.h>
#include <sys/select.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#ifdef HAVE_LINUX_SOCKIOS_H
@@ -48,6 +49,8 @@
#include <netinet/ip.h>
#endif
+#include <net/ethernet.h>
+
#include "ocat.h"
#ifdef HAVE_STRUCT_IPHDR
@@ -434,7 +437,8 @@ void *socket_receiver(void *p)
}
// set IP address if it is not set yet and frame is valid
- if (!memcmp(&peer->addr, &in6addr_any, sizeof(struct in6_addr)))
+ //if (!memcmp(&peer->addr, &in6addr_any, sizeof(struct in6_addr)))
+ if (IN6_ARE_ADDR_EQUAL(&peer->addr, &in6addr_any))
{
if (*peer->tunhdr == setup.fhd_key[IPV6_KEY])
memcpy(&peer->addr, &((struct ip6_hdr*)peer->fragbuf)->ip6_src, sizeof(struct in6_addr));
@@ -764,7 +768,8 @@ void socks_queue(const struct in6_addr *addr, int perm)
pthread_mutex_lock(&socks_queue_mutex_);
for (squeue = socks_queue_; squeue; squeue = squeue->next)
- if (!memcmp(&squeue->addr, addr, sizeof(struct in6_addr)))
+ //if (!memcmp(&squeue->addr, addr, sizeof(struct in6_addr)))
+ if (IN6_ARE_ADDR_EQUAL(&squeue->addr, addr))
break;
if (!squeue)
{
@@ -850,12 +855,22 @@ void *socks_connector(void *p)
}
+#define PACKET_LOG
+
void packet_forwarder(void)
{
char buf[FRAME_SIZE];
int rlen;
struct in6_addr *dest;
struct in_addr in;
+ struct ether_header *eh = (struct ether_header*) &buf[4];
+#ifdef PACKET_LOG
+ int pktlog;
+
+ log_debug("opening packetlog");
+ if ((pktlog = open("pkt_log", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1)
+ log_debug("could not open packet log: %s", strerror(errno));
+#endif
for (;;)
{
@@ -874,6 +889,38 @@ void packet_forwarder(void)
log_debug("received on tunfd %d, framesize %d + 4", setup.tunfd[0], rlen - 4);
+#ifdef PACKET_LOG
+ if ((pktlog != -1) && (write(pktlog, buf, rlen) == -1))
+ log_debug("could write frame to packet log: %s", strerror(errno));
+#endif
+
+ // just to be on the safe side but this should never happen
+ if ((!setup.use_tap && (rlen < 4)) || (setup.use_tap && (rlen < 4 + sizeof(struct ether_header))))
+ {
+ log_msg(L_ERROR, "frame effektively too short (rlen = %d)", rlen);
+ continue;
+ }
+
+ // in case of TAP device handle ethernet header
+ if (setup.use_tap)
+ {
+ if (eh->ether_dhost[0] & 1)
+ {
+ log_debug("forwarding %d bytes eth multicast to icmp pipe", rlen);
+ if (write(setup.icmpv6fd[1], buf, rlen) < rlen)
+ log_msg(L_ERROR, "error writing to icmp pipe");
+ continue;
+ }
+ // remove ethernet header from buffer
+ // FIXME: it would be better to adjust pointers instead of moving data
+ if (memcmp(eh->ether_dhost, setup.ocat_hwaddr, ETH_ALEN))
+ {
+ log_msg(L_ERROR, "destination MAC is not OCat, dropping frame");
+ continue;
+ }
+ memmove(eh, eh + 1, rlen - 4 - sizeof(struct ether_header));
+ }
+
if (*((uint32_t*) buf) == setup.fhd_key[IPV6_KEY])
{
if (((rlen - 4) < IP6HLEN))
diff --git a/src/ocatsetup.c b/src/ocatsetup.c
index 0a50e5b..a735b85 100644
--- a/src/ocatsetup.c
+++ b/src/ocatsetup.c
@@ -37,6 +37,8 @@ struct OcatSetup setup = {
4, OCAT_UNAME, {0}, {{{0}}}, 0, 0, 1, OCAT_DIR, TUN_DEV,
0, TOR_PREFIX4, TOR_PREFIX4_MASK,
NULL, 1,
- 0 // use_tap
+ 0, // use_tap
+ {-1, -1}, // icmpv6fd
+ {0x00, 0x00, 0x6c, 0x00, 0x00, 0x00} // ocat_hwaddr (OnionCat MAC address)
};
diff --git a/src/ocattun.c b/src/ocattun.c
index d9a5e35..43fe148 100644
--- a/src/ocattun.c
+++ b/src/ocattun.c
@@ -83,10 +83,13 @@ int tun_alloc(char *dev, struct in6_addr addr)
if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0)
perror("TUNSETIFF"), exit(1);
strlcpy(dev, ifr.ifr_name, IFNAMSIZ);
- sprintf(buf, "ifconfig %s add %s/%d up", dev, astr, TOR_PREFIX_LEN);
- log_msg(L_NOTICE, "configuring tun IP: \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(L_ERROR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ if (!setup.use_tap)
+ {
+ sprintf(buf, "ifconfig %s add %s/%d up", dev, astr, TOR_PREFIX_LEN);
+ log_msg(L_NOTICE, "configuring tun IP: \"%s\"", buf);
+ if (system(buf) == -1)
+ log_msg(L_ERROR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ }
// according to drivers/net/tun.c only IFF_MULTICAST and IFF_PROMISC are supported.
/* ifr.ifr_flags = IFF_UP | IFF_RUNNING | IFF_MULTICAST | IFF_NOARP;
@@ -115,15 +118,18 @@ int tun_alloc(char *dev, struct in6_addr addr)
#endif
- sprintf(buf, "ifconfig tun0 inet6 %s/%d up", astr, TOR_PREFIX_LEN);
- log_debug("setting IP on tun: \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(L_ERROR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ if (!setup.use_tap)
+ {
+ sprintf(buf, "ifconfig tun0 inet6 %s/%d up", astr, TOR_PREFIX_LEN);
+ log_debug("setting IP on tun: \"%s\"", buf);
+ if (system(buf) == -1)
+ log_msg(L_ERROR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ }
#endif
// setting up IPv4 address
- if (setup.ipv4_enable)
+ if (setup.ipv4_enable && !setup.use_tap)
{
sprintf(buf, "ifconfig %s %s netmask %s", dev, astr4, inet_ntoa(netmask));
log_msg(L_NOTICE, "configuring tun IP: \"%s\"", buf);
@@ -131,6 +137,15 @@ int tun_alloc(char *dev, struct in6_addr addr)
log_msg(L_ERROR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
}
+ // bring up tap device
+ if (setup.use_tap)
+ {
+ sprintf(buf, "ifconfig %s up", dev);
+ log_msg(L_NOTICE, "bringing up TAP device \"%s\"", buf);
+ if (system(buf) == -1)
+ log_msg(L_ERROR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ }
+
return fd;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/onioncat.git
More information about the Pkg-privacy-commits
mailing list