summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2014-06-09 13:55:50 +0900
committerLorenzo Colitti <lorenzo@google.com>2014-06-13 10:16:49 +0900
commit10c1adce5e85b429bf45bf7f0208c6c37245fbfb (patch)
tree86b771567e6dc6ad59f649667b718e8dd4b8751c
parentd44fac888a441cf21111358f43384f3942399d5d (diff)
downloadandroid_external_android-clat-10c1adce5e85b429bf45bf7f0208c6c37245fbfb.tar.gz
android_external_android-clat-10c1adce5e85b429bf45bf7f0208c6c37245fbfb.tar.bz2
android_external_android-clat-10c1adce5e85b429bf45bf7f0208c6c37245fbfb.zip
Mark the raw socket used by clatd.
This is required to use clatd on a non-default network. Bug: 15340961 Change-Id: I289e5600da31e963a13c00679fa816f576678d61
-rw-r--r--clatd.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/clatd.c b/clatd.c
index 001c4cb..0ee3831 100644
--- a/clatd.c
+++ b/clatd.c
@@ -178,7 +178,7 @@ void interface_poll(const struct tun_data *tunnel) {
// Update our packet socket filter to reflect the new 464xlat IP address.
if (!configure_packet_socket(tunnel->read_fd6)) {
// Things aren't going to work. Bail out and hope we have better luck next time.
- // We don't log an error here because attach_filter has already done so.
+ // We don't log an error here because configure_packet_socket has already done so.
exit(1);
}
}
@@ -244,10 +244,12 @@ void drop_root() {
}
}
-/* function: open_socket
- * opens raw and packet sockets
+/* function: open_sockets
+ * opens a packet socket to receive IPv6 packets and a raw socket to send them
+ * tunnel - tun device data
+ * mark - the socket mark to use for the sending raw socket
*/
-void open_sockets(struct tun_data *tunnel) {
+void open_sockets(struct tun_data *tunnel, uint32_t mark) {
int rawsock = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
if (rawsock < 0) {
logmsg(ANDROID_LOG_FATAL, "raw socket failed: %s", strerror(errno));
@@ -258,6 +260,9 @@ void open_sockets(struct tun_data *tunnel) {
if (setsockopt(rawsock, SOL_IPV6, IPV6_CHECKSUM, &off, sizeof(off)) < 0) {
logmsg(ANDROID_LOG_WARN, "could not disable checksum on raw socket: %s", strerror(errno));
}
+ if (mark != MARK_UNSET && setsockopt(rawsock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
+ logmsg(ANDROID_LOG_ERROR, "could not set mark on raw socket: %s", strerror(errno));
+ }
tunnel->write_fd6 = rawsock;
@@ -412,6 +417,18 @@ void print_help() {
printf("-i [uplink interface]\n");
printf("-p [plat prefix]\n");
printf("-n [NetId]\n");
+ printf("-m [socket mark]\n");
+}
+
+/* function: parse_unsigned
+ * parses a string as a decimal/hex/octal unsigned integer
+ * str - the string to parse
+ * out - the unsigned integer to write to, gets clobbered on failure
+ */
+int parse_unsigned(const char *str, unsigned *out) {
+ char *end_ptr;
+ *out = strtoul(str, &end_ptr, 0);
+ return *str && !*end_ptr;
}
/* function: main
@@ -420,12 +437,13 @@ void print_help() {
int main(int argc, char **argv) {
struct tun_data tunnel;
int opt;
- char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL;
+ char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL, *mark_str = NULL;
unsigned net_id = NETID_UNSET;
+ uint32_t mark = MARK_UNSET;
strcpy(tunnel.device4, DEVICENAME4);
- while((opt = getopt(argc, argv, "i:p:n:h")) != -1) {
+ while((opt = getopt(argc, argv, "i:p:n:m:h")) != -1) {
switch(opt) {
case 'i':
uplink_interface = optarg;
@@ -436,6 +454,9 @@ int main(int argc, char **argv) {
case 'n':
net_id_str = optarg;
break;
+ case 'm':
+ mark_str = optarg;
+ break;
case 'h':
default:
print_help();
@@ -446,18 +467,21 @@ int main(int argc, char **argv) {
if(uplink_interface == NULL) {
logmsg(ANDROID_LOG_FATAL, "clatd called without an interface");
- printf("I need an interface\n");
exit(1);
}
- if (net_id_str != NULL) {
- char *end_ptr;
- net_id = strtoul(net_id_str, &end_ptr, 0);
- if (*net_id_str == 0 || *end_ptr != 0) {
- logmsg(ANDROID_LOG_FATAL, "clatd called with invalid NetID %s", net_id_str);
- exit(1);
- }
+
+ if (net_id_str != NULL && !parse_unsigned(net_id_str, &net_id)) {
+ logmsg(ANDROID_LOG_FATAL, "invalid NetID %s", net_id_str);
+ exit(1);
}
- logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s", CLATD_VERSION, uplink_interface);
+
+ if (mark_str != NULL && !parse_unsigned(mark_str, &mark)) {
+ logmsg(ANDROID_LOG_FATAL, "invalid mark %s", mark_str);
+ exit(1);
+ }
+
+ logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s", CLATD_VERSION,
+ uplink_interface, net_id_str, mark_str);
// open the tunnel device and our raw sockets before dropping privs
tunnel.fd4 = tun_open();
@@ -466,7 +490,7 @@ int main(int argc, char **argv) {
exit(1);
}
- open_sockets(&tunnel);
+ open_sockets(&tunnel, mark);
// run under a regular user
drop_root();