Revert "Imported Upstream version 1.4" 46/214446/1
authorseonah moon <seonah1.moon@samsung.com>
Mon, 23 Sep 2019 06:08:42 +0000 (06:08 +0000)
committerseonah moon <seonah1.moon@samsung.com>
Mon, 23 Sep 2019 06:08:42 +0000 (06:08 +0000)
This reverts commit c9fb17e1cc63313b69dde33ee40ba89cb7ea2662.

Change-Id: I17f9cb8ddde058d9256cacf2cc57333e66ce0c6a

41 files changed:
Android.mk [deleted file]
BUGS [deleted file]
LICENSE [deleted file]
MODULE_LICENSE_APACHE2 [deleted file]
NOTICE [deleted file]
checksum.c [deleted file]
checksum.h [deleted file]
clatd.c [deleted file]
clatd.conf [deleted file]
clatd.h [deleted file]
clatd_microbenchmark.c [deleted file]
clatd_test.cpp [deleted file]
config.c [deleted file]
config.h [deleted file]
debug.h [deleted file]
dns64.c [deleted file]
dns64.h [deleted file]
dump.c [deleted file]
dump.h [deleted file]
getaddr.c [deleted file]
getaddr.h [deleted file]
icmp.c [deleted file]
icmp.h [deleted file]
ipv4.c [deleted file]
ipv6.c [deleted file]
logging.c [deleted file]
logging.h [deleted file]
mtu.c [deleted file]
mtu.h [deleted file]
netlink_callbacks.c [deleted file]
netlink_callbacks.h [deleted file]
netlink_msg.c [deleted file]
netlink_msg.h [deleted file]
ring.c [deleted file]
ring.h [deleted file]
setif.c [deleted file]
setif.h [deleted file]
translate.c [deleted file]
translate.h [deleted file]
tun.c [deleted file]
tun.h [deleted file]

diff --git a/Android.mk b/Android.mk
deleted file mode 100644 (file)
index 5f2fe63..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=clatd.c dump.c checksum.c translate.c icmp.c ipv4.c ipv6.c config.c dns64.c logging.c getaddr.c netlink_callbacks.c netlink_msg.c setif.c mtu.c tun.c ring.c
-
-LOCAL_CFLAGS := -Wall -Werror -Wunused-parameter
-LOCAL_C_INCLUDES := external/libnl/include bionic/libc/dns/include
-LOCAL_STATIC_LIBRARIES := libnl
-LOCAL_SHARED_LIBRARIES := libcutils liblog libnetutils
-
-# The clat daemon.
-LOCAL_MODULE := clatd
-
-include $(BUILD_EXECUTABLE)
-
-
-# The configuration file.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := clatd.conf
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
-
-
-# Unit tests.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := clatd_test
-LOCAL_CFLAGS := -Wall -Werror -Wunused-parameter
-LOCAL_SRC_FILES := clatd_test.cpp checksum.c translate.c icmp.c ipv4.c ipv6.c logging.c config.c tun.c
-LOCAL_MODULE_TAGS := eng tests
-LOCAL_SHARED_LIBRARIES := liblog
-
-include $(BUILD_NATIVE_TEST)
-
-# Microbenchmark.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := clatd_microbenchmark
-LOCAL_CFLAGS := -Wall -Werror -Wunused-parameter
-LOCAL_SRC_FILES := clatd_microbenchmark.c checksum.c tun.c
-LOCAL_MODULE_TAGS := eng tests
-
-include $(BUILD_NATIVE_TEST)
diff --git a/BUGS b/BUGS
deleted file mode 100644 (file)
index 70aeb9f..0000000
--- a/BUGS
+++ /dev/null
@@ -1,5 +0,0 @@
-known problems/assumptions:
- - does not handle protocols other than ICMP, UDP, TCP and GRE
- - assumes the handset has its own (routed) /64 ipv6 subnet
- - assumes the /128 ipv6 subnet it generates can use the nat64 gateway
- - assumes the nat64 gateway has the ipv4 address in the last 32 bits of the ipv6 address (that it uses a /96 plat subnet)
diff --git a/LICENSE b/LICENSE
deleted file mode 100644 (file)
index 261eeb9..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/NOTICE b/NOTICE
deleted file mode 100644 (file)
index 5943b54..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,189 +0,0 @@
-   Copyright (c) 2010-2012, Daniel Drown
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/checksum.c b/checksum.c
deleted file mode 100644 (file)
index 23a7c02..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * checksum.c - ipv4/ipv6 checksum calculation
- */
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/udp.h>
-#include <netinet/tcp.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-
-#include "checksum.h"
-
-/* function: ip_checksum_add
- * adds data to a checksum
- * current - the current checksum (or 0 to start a new checksum)
- * data        - the data to add to the checksum
- * len         - length of data
- */
-uint32_t ip_checksum_add(uint32_t current, const void *data, int len) {
-  uint32_t checksum = current;
-  int left = len;
-  const uint16_t *data_16 = data;
-
-  while(left > 1) {
-    checksum += *data_16;
-    data_16++;
-    left -= 2;
-  }
-  if(left) {
-    checksum += *(uint8_t *)data_16;
-  }
-
-  return checksum;
-}
-
-/* function: ip_checksum_fold
- * folds a 32-bit partial checksum into 16 bits
- * temp_sum - sum from ip_checksum_add
- * returns: the folded checksum in network byte order
- */
-uint16_t ip_checksum_fold(uint32_t temp_sum) {
-  while(temp_sum > 0xffff)
-    temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF);
-
-  return temp_sum;
-}
-
-/* function: ip_checksum_finish
- * folds and closes the checksum
- * temp_sum - sum from ip_checksum_add
- * returns: a header checksum value in network byte order
- */
-uint16_t ip_checksum_finish(uint32_t temp_sum) {
-  return ~ip_checksum_fold(temp_sum);
-}
-
-/* function: ip_checksum
- * combined ip_checksum_add and ip_checksum_finish
- * data - data to checksum
- * len  - length of data
- */
-uint16_t ip_checksum(const void *data, int len) {
-  uint32_t temp_sum;
-
-  temp_sum = ip_checksum_add(0,data,len);
-  return ip_checksum_finish(temp_sum);
-}
-
-/* function: ipv6_pseudo_header_checksum
- * calculate the pseudo header checksum for use in tcp/udp/icmp headers
- * ip6      - the ipv6 header
- * len      - the transport length (transport header + payload)
- * protocol - the transport layer protocol, can be different from ip6->ip6_nxt for fragments
- */
-uint32_t ipv6_pseudo_header_checksum(const struct ip6_hdr *ip6, uint16_t len, uint8_t protocol) {
-  uint32_t checksum_len, checksum_next;
-  checksum_len = htonl((uint32_t) len);
-  checksum_next = htonl(protocol);
-
-  uint32_t current = 0;
-  current = ip_checksum_add(current, &(ip6->ip6_src), sizeof(struct in6_addr));
-  current = ip_checksum_add(current, &(ip6->ip6_dst), sizeof(struct in6_addr));
-  current = ip_checksum_add(current, &checksum_len, sizeof(checksum_len));
-  current = ip_checksum_add(current, &checksum_next, sizeof(checksum_next));
-
-  return current;
-}
-
-/* function: ipv4_pseudo_header_checksum
- * calculate the pseudo header checksum for use in tcp/udp headers
- * ip      - the ipv4 header
- * len     - the transport length (transport header + payload)
- */
-uint32_t ipv4_pseudo_header_checksum(const struct iphdr *ip, uint16_t len) {
-  uint16_t temp_protocol, temp_length;
-
-  temp_protocol = htons(ip->protocol);
-  temp_length = htons(len);
-
-  uint32_t current = 0;
-  current = ip_checksum_add(current, &(ip->saddr), sizeof(uint32_t));
-  current = ip_checksum_add(current, &(ip->daddr), sizeof(uint32_t));
-  current = ip_checksum_add(current, &temp_protocol, sizeof(uint16_t));
-  current = ip_checksum_add(current, &temp_length, sizeof(uint16_t));
-
-  return current;
-}
-
-/* function: ip_checksum_adjust
- * calculates a new checksum given a previous checksum and the old and new pseudo-header checksums
- * checksum    - the header checksum in the original packet in network byte order
- * old_hdr_sum - the pseudo-header checksum of the original packet
- * new_hdr_sum - the pseudo-header checksum of the translated packet
- * returns: the new header checksum in network byte order
- */
-uint16_t ip_checksum_adjust(uint16_t checksum, uint32_t old_hdr_sum, uint32_t new_hdr_sum) {
-  // Algorithm suggested in RFC 1624.
-  // http://tools.ietf.org/html/rfc1624#section-3
-  checksum = ~checksum;
-  uint16_t folded_sum = ip_checksum_fold(checksum + new_hdr_sum);
-  uint16_t folded_old = ip_checksum_fold(old_hdr_sum);
-  if (folded_sum > folded_old) {
-    return ~(folded_sum - folded_old);
-  } else {
-    return ~(folded_sum - folded_old - 1);  // end-around borrow
-  }
-}
diff --git a/checksum.h b/checksum.h
deleted file mode 100644 (file)
index d0af88e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * checksum.h - checksum functions
- */
-#ifndef __CHECKSUM_H__
-#define __CHECKSUM_H__
-
-#include <stdint.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-
-uint32_t ip_checksum_add(uint32_t current, const void *data, int len);
-uint16_t ip_checksum_finish(uint32_t temp_sum);
-uint16_t ip_checksum(const void *data, int len);
-
-uint32_t ipv6_pseudo_header_checksum(const struct ip6_hdr *ip6, uint16_t len, uint8_t protocol);
-uint32_t ipv4_pseudo_header_checksum(const struct iphdr *ip, uint16_t len);
-
-uint16_t ip_checksum_adjust(uint16_t checksum, uint32_t old_hdr_sum, uint32_t new_hdr_sum);
-
-#endif /* __CHECKSUM_H__ */
diff --git a/clatd.c b/clatd.c
deleted file mode 100644 (file)
index faeb679..0000000
--- a/clatd.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Copyright 2012 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * clatd.c - tun interface setup and main event loop
- */
-#include <poll.h>
-#include <signal.h>
-#include <time.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/prctl.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-
-#include <sys/capability.h>
-#include <sys/uio.h>
-#include <linux/filter.h>
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <net/if.h>
-
-#include <private/android_filesystem_config.h>
-
-#include "translate.h"
-#include "clatd.h"
-#include "config.h"
-#include "logging.h"
-#include "resolv_netid.h"
-#include "setif.h"
-#include "mtu.h"
-#include "getaddr.h"
-#include "dump.h"
-#include "tun.h"
-#include "ring.h"
-
-#define DEVICEPREFIX "v4-"
-
-/* 40 bytes IPv6 header - 20 bytes IPv4 header + 8 bytes fragment header */
-#define MTU_DELTA 28
-
-volatile sig_atomic_t running = 1;
-
-/* function: stop_loop
- * signal handler: stop the event loop
- */
-void stop_loop() {
-  running = 0;
-}
-
-/* function: configure_packet_socket
- * Binds the packet socket and attaches the receive filter to it.
- * sock - the socket to configure
- */
-int configure_packet_socket(int sock) {
-  struct sockaddr_ll sll = {
-    .sll_family   = AF_PACKET,
-    .sll_protocol = htons(ETH_P_IPV6),
-    .sll_ifindex  = if_nametoindex((char *) &Global_Clatd_Config.default_pdp_interface),
-    .sll_pkttype  = PACKET_OTHERHOST,  // The 464xlat IPv6 address is not assigned to the kernel.
-  };
-  if (bind(sock, (struct sockaddr *) &sll, sizeof(sll))) {
-    logmsg(ANDROID_LOG_FATAL, "binding packet socket: %s", strerror(errno));
-    return 0;
-  }
-
-  uint32_t *ipv6 = Global_Clatd_Config.ipv6_local_subnet.s6_addr32;
-  struct sock_filter filter_code[] = {
-    // Load the first four bytes of the IPv6 destination address (starts 24 bytes in).
-    // Compare it against the first four bytes of our IPv6 address, in host byte order (BPF loads
-    // are always in host byte order). If it matches, continue with next instruction (JMP 0). If it
-    // doesn't match, jump ahead to statement that returns 0 (ignore packet). Repeat for the other
-    // three words of the IPv6 address, and if they all match, return PACKETLEN (accept packet).
-    BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  24),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[0]), 0, 7),
-    BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  28),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[1]), 0, 5),
-    BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  32),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[2]), 0, 3),
-    BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  36),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[3]), 0, 1),
-    BPF_STMT(BPF_RET | BPF_K,              PACKETLEN),
-    BPF_STMT(BPF_RET | BPF_K, 0)
-  };
-  struct sock_fprog filter = {
-    sizeof(filter_code) / sizeof(filter_code[0]),
-    filter_code
-  };
-
-  if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter))) {
-    logmsg(ANDROID_LOG_FATAL, "attach packet filter failed: %s", strerror(errno));
-    return 0;
-  }
-
-  return 1;
-}
-
-/* function: configure_tun_ip
- * configures the ipv4 and ipv6 addresses on the tunnel interface
- * tunnel - tun device data
- */
-void configure_tun_ip(const struct tun_data *tunnel) {
-  int status;
-
-  // Pick an IPv4 address to use by finding a free address in the configured prefix. Technically,
-  // there is a race here - if another clatd calls config_select_ipv4_address after we do, but
-  // before we call add_address, it can end up having the same IP address as we do. But the time
-  // window in which this can happen is extremely small, and even if we end up with a duplicate
-  // address, the only damage is that IPv4 TCP connections won't be reset until both interfaces go
-  // down.
-  in_addr_t localaddr = config_select_ipv4_address(&Global_Clatd_Config.ipv4_local_subnet,
-                                                   Global_Clatd_Config.ipv4_local_prefixlen);
-  if (localaddr == INADDR_NONE) {
-    logmsg(ANDROID_LOG_FATAL,"No free IPv4 address in %s/%d",
-           inet_ntoa(Global_Clatd_Config.ipv4_local_subnet),
-           Global_Clatd_Config.ipv4_local_prefixlen);
-    exit(1);
-  }
-  Global_Clatd_Config.ipv4_local_subnet.s_addr = localaddr;
-
-  // Configure the interface before bringing it up. As soon as we bring the interface up, the
-  // framework will be notified and will assume the interface's configuration has been finalized.
-  status = add_address(tunnel->device4, AF_INET, &Global_Clatd_Config.ipv4_local_subnet,
-      32, &Global_Clatd_Config.ipv4_local_subnet);
-  if(status < 0) {
-    logmsg(ANDROID_LOG_FATAL,"configure_tun_ip/if_address(4) failed: %s",strerror(-status));
-    exit(1);
-  }
-
-  char addrstr[INET_ADDRSTRLEN];
-  inet_ntop(AF_INET, &Global_Clatd_Config.ipv4_local_subnet, addrstr, sizeof(addrstr));
-  logmsg(ANDROID_LOG_INFO, "Using IPv4 address %s on %s", addrstr, tunnel->device4);
-
-  if((status = if_up(tunnel->device4, Global_Clatd_Config.ipv4mtu)) < 0) {
-    logmsg(ANDROID_LOG_FATAL,"configure_tun_ip/if_up(4) failed: %s",strerror(-status));
-    exit(1);
-  }
-}
-
-/* function: drop_root
- * drops root privs but keeps the needed capability
- */
-void drop_root() {
-  gid_t groups[] = { AID_INET, AID_VPN };
-  if(setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0) {
-    logmsg(ANDROID_LOG_FATAL,"drop_root/setgroups failed: %s",strerror(errno));
-    exit(1);
-  }
-
-  prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
-
-  if(setgid(AID_CLAT) < 0) {
-    logmsg(ANDROID_LOG_FATAL,"drop_root/setgid failed: %s",strerror(errno));
-    exit(1);
-  }
-  if(setuid(AID_CLAT) < 0) {
-    logmsg(ANDROID_LOG_FATAL,"drop_root/setuid failed: %s",strerror(errno));
-    exit(1);
-  }
-
-  struct __user_cap_header_struct header;
-  struct __user_cap_data_struct cap;
-  memset(&header, 0, sizeof(header));
-  memset(&cap, 0, sizeof(cap));
-
-  header.version = _LINUX_CAPABILITY_VERSION;
-  header.pid = 0; // 0 = change myself
-  cap.effective = cap.permitted = (1 << CAP_NET_ADMIN);
-
-  if(capset(&header, &cap) < 0) {
-    logmsg(ANDROID_LOG_FATAL,"drop_root/capset failed: %s",strerror(errno));
-    exit(1);
-  }
-}
-
-/* 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, uint32_t mark) {
-  int rawsock = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW);
-  if (rawsock < 0) {
-    logmsg(ANDROID_LOG_FATAL, "raw socket failed: %s", strerror(errno));
-    exit(1);
-  }
-
-  int off = 0;
-  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;
-
-  tunnel->read_fd6 = ring_create(tunnel);
-  if (tunnel->read_fd6 < 0) {
-    exit(1);
-  }
-}
-
-/* function: update_clat_ipv6_address
- * picks the clat IPv6 address and configures packet translation to use it.
- * tunnel - tun device data
- * interface - uplink interface name
- * returns: 1 on success, 0 on failure
- */
-int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interface) {
-  union anyip *interface_ip;
-  char addrstr[INET6_ADDRSTRLEN];
-
-  // TODO: check that the prefix length is /64.
-  interface_ip = getinterface_ip(interface, AF_INET6);
-  if (!interface_ip) {
-    logmsg(ANDROID_LOG_ERROR, "Unable to find an IPv6 address on interface %s", interface);
-    return 0;
-  }
-
-  // If our prefix hasn't changed, do nothing. (If this is the first time we configure an IPv6
-  // address, Global_Clatd_Config.ipv6_local_subnet will be ::, which won't match our new prefix.)
-  if (ipv6_prefix_equal(&interface_ip->ip6, &Global_Clatd_Config.ipv6_local_subnet)) {
-    free(interface_ip);
-    return 1;
-  }
-
-  // Generate an interface ID.
-  config_generate_local_ipv6_subnet(&interface_ip->ip6);
-  inet_ntop(AF_INET6, &interface_ip->ip6, addrstr, sizeof(addrstr));
-
-  if (IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_local_subnet)) {
-    // Startup.
-    logmsg(ANDROID_LOG_INFO, "Using IPv6 address %s on %s", addrstr, interface);
-  } else {
-    // Prefix change.
-    char from_addr[INET6_ADDRSTRLEN];
-    inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, from_addr, sizeof(from_addr));
-    logmsg(ANDROID_LOG_INFO, "clat IPv6 address changed from %s to %s", from_addr, addrstr);
-    del_anycast_address(tunnel->write_fd6, &Global_Clatd_Config.ipv6_local_subnet);
-  }
-
-  // Start translating packets to the new prefix.
-  Global_Clatd_Config.ipv6_local_subnet = interface_ip->ip6;
-  add_anycast_address(tunnel->write_fd6, &Global_Clatd_Config.ipv6_local_subnet, interface);
-  free(interface_ip);
-
-  // 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 configure_packet_socket has already done so.
-      exit(1);
-  }
-
-  return 1;
-}
-
-/* function: configure_interface
- * reads the configuration and applies it to the interface
- * uplink_interface - network interface to use to reach the ipv6 internet
- * plat_prefix      - PLAT prefix to use
- * tunnel           - tun device data
- * net_id           - NetID to use, NETID_UNSET indicates use of default network
- */
-void configure_interface(const char *uplink_interface, const char *plat_prefix, struct tun_data *tunnel, unsigned net_id) {
-  int error;
-
-  if(!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix, net_id)) {
-    logmsg(ANDROID_LOG_FATAL,"read_config failed");
-    exit(1);
-  }
-
-  if(Global_Clatd_Config.mtu > MAXMTU) {
-    logmsg(ANDROID_LOG_WARN,"Max MTU is %d, requested %d", MAXMTU, Global_Clatd_Config.mtu);
-    Global_Clatd_Config.mtu = MAXMTU;
-  }
-  if(Global_Clatd_Config.mtu <= 0) {
-    Global_Clatd_Config.mtu = getifmtu(Global_Clatd_Config.default_pdp_interface);
-    logmsg(ANDROID_LOG_WARN,"ifmtu=%d",Global_Clatd_Config.mtu);
-  }
-  if(Global_Clatd_Config.mtu < 1280) {
-    logmsg(ANDROID_LOG_WARN,"mtu too small = %d", Global_Clatd_Config.mtu);
-    Global_Clatd_Config.mtu = 1280;
-  }
-
-  if(Global_Clatd_Config.ipv4mtu <= 0 ||
-     Global_Clatd_Config.ipv4mtu > Global_Clatd_Config.mtu - MTU_DELTA) {
-    Global_Clatd_Config.ipv4mtu = Global_Clatd_Config.mtu - MTU_DELTA;
-    logmsg(ANDROID_LOG_WARN,"ipv4mtu now set to = %d",Global_Clatd_Config.ipv4mtu);
-  }
-
-  error = tun_alloc(tunnel->device4, tunnel->fd4);
-  if(error < 0) {
-    logmsg(ANDROID_LOG_FATAL,"tun_alloc/4 failed: %s",strerror(errno));
-    exit(1);
-  }
-
-  error = set_nonblocking(tunnel->fd4);
-  if (error < 0) {
-    logmsg(ANDROID_LOG_FATAL, "set_nonblocking failed: %s", strerror(errno));
-    exit(1);
-  }
-
-  configure_tun_ip(tunnel);
-}
-
-/* function: read_packet
- * reads a packet from the tunnel fd and translates it
- * read_fd  - file descriptor to read original packet from
- * write_fd - file descriptor to write translated packet to
- * to_ipv6  - whether the packet is to be translated to ipv6 or ipv4
- */
-void read_packet(int read_fd, int write_fd, int to_ipv6) {
-  ssize_t readlen;
-  uint8_t buf[PACKETLEN], *packet;
-
-  readlen = read(read_fd, buf, PACKETLEN);
-
-  if(readlen < 0) {
-    if (errno != EAGAIN) {
-      logmsg(ANDROID_LOG_WARN,"read_packet/read error: %s", strerror(errno));
-    }
-    return;
-  } else if(readlen == 0) {
-    logmsg(ANDROID_LOG_WARN,"read_packet/tun interface removed");
-    running = 0;
-    return;
-  }
-
-  struct tun_pi *tun_header = (struct tun_pi *) buf;
-  if (readlen < (ssize_t) sizeof(*tun_header)) {
-    logmsg(ANDROID_LOG_WARN,"read_packet/short read: got %ld bytes", readlen);
-    return;
-  }
-
-  uint16_t proto = ntohs(tun_header->proto);
-  if (proto != ETH_P_IP) {
-    logmsg(ANDROID_LOG_WARN, "%s: unknown packet type = 0x%x", __func__, proto);
-    return;
-  }
-
-  if(tun_header->flags != 0) {
-    logmsg(ANDROID_LOG_WARN, "%s: unexpected flags = %d", __func__, tun_header->flags);
-  }
-
-  packet = (uint8_t *) (tun_header + 1);
-  readlen -= sizeof(*tun_header);
-  translate_packet(write_fd, to_ipv6, packet, readlen);
-}
-
-/* function: event_loop
- * reads packets from the tun network interface and passes them down the stack
- * tunnel - tun device data
- */
-void event_loop(struct tun_data *tunnel) {
-  time_t last_interface_poll;
-  struct pollfd wait_fd[] = {
-    { tunnel->read_fd6, POLLIN, 0 },
-    { tunnel->fd4, POLLIN, 0 },
-  };
-
-  // start the poll timer
-  last_interface_poll = time(NULL);
-
-  while(running) {
-    if(poll(wait_fd, 2, NO_TRAFFIC_INTERFACE_POLL_FREQUENCY*1000) == -1) {
-      if(errno != EINTR) {
-        logmsg(ANDROID_LOG_WARN,"event_loop/poll returned an error: %s",strerror(errno));
-      }
-    } else {
-      // Call read_packet if the socket has data to be read, but also if an
-      // error is waiting. If we don't call read() after getting POLLERR, a
-      // subsequent poll() will return immediately with POLLERR again,
-      // causing this code to spin in a loop. Calling read() will clear the
-      // socket error flag instead.
-      if (wait_fd[0].revents) {
-        ring_read(&tunnel->ring, tunnel->fd4, 0 /* to_ipv6 */);
-      }
-      if (wait_fd[1].revents) {
-        read_packet(tunnel->fd4, tunnel->write_fd6, 1 /* to_ipv6 */);
-      }
-    }
-
-    time_t now = time(NULL);
-    if(last_interface_poll < (now - INTERFACE_POLL_FREQUENCY)) {
-      update_clat_ipv6_address(tunnel, Global_Clatd_Config.default_pdp_interface);
-      last_interface_poll = now;
-    }
-  }
-}
-
-/* function: print_help
- * in case the user is running this on the command line
- */
-void print_help() {
-  printf("android-clat arguments:\n");
-  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
- * allocate and setup the tun device, then run the event loop
- */
-int main(int argc, char **argv) {
-  struct tun_data tunnel;
-  int opt;
-  char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL, *mark_str = NULL;
-  unsigned net_id = NETID_UNSET;
-  uint32_t mark = MARK_UNSET;
-  unsigned len;
-
-  while((opt = getopt(argc, argv, "i:p:n:m:h")) != -1) {
-    switch(opt) {
-      case 'i':
-        uplink_interface = optarg;
-        break;
-      case 'p':
-        plat_prefix = optarg;
-        break;
-      case 'n':
-        net_id_str = optarg;
-        break;
-      case 'm':
-        mark_str = optarg;
-        break;
-      case 'h':
-        print_help();
-        exit(0);
-      default:
-        logmsg(ANDROID_LOG_FATAL, "Unknown option -%c. Exiting.", (char) optopt);
-        exit(1);
-    }
-  }
-
-  if(uplink_interface == NULL) {
-    logmsg(ANDROID_LOG_FATAL, "clatd called without an interface");
-    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);
-  }
-
-  if (mark_str != NULL && !parse_unsigned(mark_str, &mark)) {
-    logmsg(ANDROID_LOG_FATAL, "invalid mark %s", mark_str);
-    exit(1);
-  }
-
-  len = snprintf(tunnel.device4, sizeof(tunnel.device4), "%s%s", DEVICEPREFIX, uplink_interface);
-  if (len >= sizeof(tunnel.device4)) {
-    logmsg(ANDROID_LOG_FATAL, "interface name too long '%s'", tunnel.device4);
-    exit(1);
-  }
-
-  logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s",
-         CLATD_VERSION, uplink_interface,
-         net_id_str ? net_id_str : "(none)",
-         mark_str ? mark_str : "(none)");
-
-  // open our raw sockets before dropping privs
-  open_sockets(&tunnel, mark);
-
-  // run under a regular user
-  drop_root();
-
-  // we can create tun devices as non-root because we're in the VPN group.
-  tunnel.fd4 = tun_open();
-  if(tunnel.fd4 < 0) {
-    logmsg(ANDROID_LOG_FATAL, "tun_open4 failed: %s", strerror(errno));
-    exit(1);
-  }
-
-  // When run from netd, the environment variable ANDROID_DNS_MODE is set to
-  // "local", but that only works for the netd process itself.
-  unsetenv("ANDROID_DNS_MODE");
-
-  configure_interface(uplink_interface, plat_prefix, &tunnel, net_id);
-
-  update_clat_ipv6_address(&tunnel, uplink_interface);
-
-  // Loop until someone sends us a signal or brings down the tun interface.
-  if(signal(SIGTERM, stop_loop) == SIG_ERR) {
-    logmsg(ANDROID_LOG_FATAL, "sigterm handler failed: %s", strerror(errno));
-    exit(1);
-  }
-
-  event_loop(&tunnel);
-
-  logmsg(ANDROID_LOG_INFO,"Shutting down clat on %s", uplink_interface);
-  del_anycast_address(tunnel.write_fd6, &Global_Clatd_Config.ipv6_local_subnet);
-
-  return 0;
-}
diff --git a/clatd.conf b/clatd.conf
deleted file mode 100644 (file)
index ff80975..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Host IID to use as the source of CLAT traffic.
-# This is a /128 taken out of the /64 on the parent interface.
-# A host IID of :: means to generate a checksum-neutral, random IID.
-ipv6_host_id ::
-
-# IPv4 address configuration to use when selecting a host address. The first
-# clat daemon started will use the address specified by ipv4_local_subnet. If
-# more than one daemon is run at the same time, subsequent daemons will use
-# other addresses in the prefix of length ipv4_local prefixlen that contains
-# ipv4_local_subnet. The default is to use the IANA-assigned range 192.0.0.0/29,
-# which allows up to 8 clat daemons (.4, .5, .6, .7, .0, .1, .2, .3).
-ipv4_local_subnet 192.0.0.4
-ipv4_local_prefixlen 29
-
-# get the plat_subnet from dns lookups (requires DNS64)
-plat_from_dns64 yes
-# hostname to use to lookup plat subnet. must contain only A records
-plat_from_dns64_hostname ipv4only.arpa
-
-# plat subnet to send ipv4 traffic to. This is a /96 subnet.
-# This setting only makes sense with: plat_from_dns64 no
-#plat_subnet 2001:db8:1:2:3:4::
diff --git a/clatd.h b/clatd.h
deleted file mode 100644 (file)
index f421f46..0000000
--- a/clatd.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * clatd.h - main system definitions
- */
-#ifndef __CLATD_H__
-#define __CLATD_H__
-
-#include <sys/uio.h>
-
-#define MAXMTU 1500
-#define PACKETLEN (MAXMTU+sizeof(struct tun_pi))
-#define CLATD_VERSION "1.4"
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-// how frequently (in seconds) to poll for an address change while traffic is passing
-#define INTERFACE_POLL_FREQUENCY 30
-
-// how frequently (in seconds) to poll for an address change while there is no traffic
-#define NO_TRAFFIC_INTERFACE_POLL_FREQUENCY 90
-
-// A clat_packet is an array of iovec structures representing a packet that we are translating.
-// The CLAT_POS_XXX constants represent the array indices within the clat_packet that contain
-// specific parts of the packet. The packet_* functions operate on all the packet segments past a
-// given position.
-typedef enum {
-    CLAT_POS_TUNHDR, CLAT_POS_IPHDR, CLAT_POS_FRAGHDR, CLAT_POS_TRANSPORTHDR,
-    CLAT_POS_ICMPERR_IPHDR, CLAT_POS_ICMPERR_FRAGHDR, CLAT_POS_ICMPERR_TRANSPORTHDR,
-    CLAT_POS_PAYLOAD, CLAT_POS_MAX
-} clat_packet_index;
-typedef struct iovec clat_packet[CLAT_POS_MAX];
-
-#endif /* __CLATD_H__ */
diff --git a/clatd_microbenchmark.c b/clatd_microbenchmark.c
deleted file mode 100644 (file)
index fed3100..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * clatd_microbenchmark.c - micro-benchmark for clatd tun send path
- *
- * Run with:
- *
- * adb push {$ANDROID_PRODUCT_OUT,}/data/nativetest/clatd_microbenchmark/clatd_microbenchmark
- * adb shell /data/nativetest/clatd_microbenchmark/clatd_microbenchmark
- *
- */
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/udp.h>
-#include <arpa/inet.h>
-#include <linux/if.h>
-#include <linux/if_tun.h>
-
-#include "checksum.h"
-#include "tun.h"
-
-#define DEVICENAME "clat4"
-
-#define PORT 51339
-#define PAYLOADSIZE (1280 - sizeof(struct iphdr) - sizeof(struct udphdr))
-#define NUMPACKETS 1000000
-#define SEC_TO_NANOSEC (1000 * 1000 * 1000)
-
-void init_sockaddr_in(struct sockaddr_in *sin, const char *addr) {
-    sin->sin_family = AF_INET;
-    sin->sin_port = 0;
-    sin->sin_addr.s_addr = inet_addr(addr);
-}
-
-void die(const char *str) {
-    perror(str);
-    exit(1);
-}
-
-int setup_tun() {
-    int fd = tun_open();
-    if (fd == -1) die("tun_open");
-
-    char dev[IFNAMSIZ] = DEVICENAME;
-    int ret = tun_alloc(dev, fd);
-    if (ret == -1) die("tun_alloc");
-    struct ifreq ifr = {
-        .ifr_name = DEVICENAME,
-    };
-
-    int s = socket(AF_INET, SOCK_DGRAM, 0);
-    init_sockaddr_in((struct sockaddr_in *) &ifr.ifr_addr, "192.0.0.4");
-    if (ioctl(s, SIOCSIFADDR, &ifr) < 0) die("SIOCSIFADDR");
-    init_sockaddr_in((struct sockaddr_in *) &ifr.ifr_addr, "255.255.255.248");
-    if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0) die("SIOCSIFNETMASK");
-    if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) die("SIOCGIFFLAGS");
-    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
-    if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) die("SIOCSIFFLAGS");
-    return fd;
-}
-
-int send_packet(int fd, uint8_t payload[], int len, uint32_t payload_checksum) {
-    struct tun_pi tun = { 0, htons(ETH_P_IP) };
-    struct udphdr udp = {
-        .source = htons(1234),
-        .dest = htons(PORT),
-        .len = htons(len + sizeof(udp)),
-        .check = 0,
-    };
-    struct iphdr ip = {
-        .version = 4,
-        .ihl = 5,
-        .tot_len = htons(len + sizeof(ip) + sizeof(udp)),
-        .frag_off = htons(IP_DF),
-        .ttl = 55,
-        .protocol = IPPROTO_UDP,
-        .saddr = htonl(0xc0000006),  // 192.0.0.6
-        .daddr = htonl(0xc0000004),  // 192.0.0.4
-    };
-    clat_packet out = {
-        { &tun, sizeof(tun) },  // tun header
-        { &ip, sizeof(ip) },    // IP header
-        { NULL, 0 },            // Fragment header
-        { &udp, sizeof(udp) },  // Transport header
-        { NULL, 0 },            // ICMP error IP header
-        { NULL, 0 },            // ICMP error fragment header
-        { NULL, 0 },            // ICMP error transport header
-        { payload, len },       // Payload
-    };
-
-    ip.check = ip_checksum(&ip, sizeof(ip));
-
-    uint32_t sum;
-    sum = ipv4_pseudo_header_checksum(&ip, ntohs(udp.len));
-    sum = ip_checksum_add(sum, &udp, sizeof(udp));
-    sum += payload_checksum;
-    udp.check = ip_checksum_finish(sum);
-
-    return send_tun(fd, out, sizeof(out) / sizeof(out[0]));
-}
-
-double timedelta(const struct timespec tv1, const struct timespec tv2) {
-    struct timespec end = tv2;
-    if (end.tv_nsec < tv1.tv_nsec) {
-        end.tv_sec -= 1;
-        end.tv_nsec += SEC_TO_NANOSEC;
-    }
-    double seconds = (end.tv_sec - tv1.tv_sec);
-    seconds += (((double) (end.tv_nsec - tv1.tv_nsec)) / SEC_TO_NANOSEC);
-    return seconds;
-}
-
-void benchmark(const char *name, int fd, int s, int num, int do_read,
-               uint8_t payload[], int len, uint32_t payload_sum) {
-    int i;
-    char buf[4096];
-    struct timespec tv1, tv2;
-    int write_err = 0, read_err = 0;
-    clock_gettime(CLOCK_MONOTONIC, &tv1);
-    for (i = 0; i < num; i++) {
-        if (send_packet(fd, payload, len, payload_sum) == -1) write_err++;
-        if (do_read && recvfrom(s, buf, sizeof(buf), 0, NULL, NULL) == -1) {
-            read_err++;
-            if (errno == ETIMEDOUT) {
-                printf("Timed out after %d packets!\n", i);
-                break;
-            }
-        }
-    }
-    clock_gettime(CLOCK_MONOTONIC, &tv2);
-    double seconds = timedelta(tv1, tv2);
-    int pps = (int) (i / seconds);
-    double mbps = (i * PAYLOADSIZE / 1000000 * 8 / seconds);
-    printf("%s: %d packets in %.2fs (%d pps, %.2f Mbps), ", name, i, seconds, pps, mbps);
-    printf("read err %d (%.2f%%), write err %d (%.2f%%)\n",
-           read_err, (float) read_err / i * 100,
-           write_err, (float) write_err / i * 100);
-}
-
-int open_socket() {
-    int sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-
-    int on = 1;
-    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) die("SO_REUSEADDR");
-
-    struct timeval tv = { 1, 0 };
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) die("SO_RCVTIMEO");
-
-    struct sockaddr_in addr = {
-        .sin_family = AF_INET,
-        .sin_port = ntohs(PORT),
-        .sin_addr = { INADDR_ANY }
-    };
-    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) die ("bind");
-
-   return sock;
-}
-
-int main() {
-    int fd = setup_tun();
-    int sock = open_socket();
-
-    int i;
-    uint8_t payload[PAYLOADSIZE];
-    for (i = 0; i < (int) sizeof(payload); i++) {
-        payload[i] = (uint8_t) i;
-    }
-    uint32_t payload_sum = ip_checksum_add(0, payload, sizeof(payload));
-
-    // Check things are working.
-    char buf[4096];
-    if (send_packet(fd, payload, sizeof(payload), payload_sum) == -1) die("send_packet");
-    if (recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL) == -1) die("recvfrom");
-
-    benchmark("Blocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum);
-    close(fd);
-
-    fd = setup_tun();
-    set_nonblocking(fd);
-    benchmark("No read", fd, sock, NUMPACKETS, 0, payload, sizeof(payload), payload_sum);
-    close(fd);
-
-    fd = setup_tun();
-    set_nonblocking(fd);
-    benchmark("Nonblocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum);
-    close(fd);
-
-    return 0;
-}
diff --git a/clatd_test.cpp b/clatd_test.cpp
deleted file mode 100644 (file)
index 7e218f0..0000000
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * clatd_test.cpp - unit tests for clatd
- */
-
-#include <iostream>
-
-#include <stdio.h>
-#include <arpa/inet.h>
-#include <netinet/in6.h>
-#include <sys/uio.h>
-
-#include <gtest/gtest.h>
-
-extern "C" {
-#include "checksum.h"
-#include "translate.h"
-#include "config.h"
-#include "clatd.h"
-}
-
-// For convenience.
-#define ARRAYSIZE(x) sizeof((x)) / sizeof((x)[0])
-
-// Default translation parameters.
-static const char kIPv4LocalAddr[] = "192.0.0.4";
-static const char kIPv6LocalAddr[] = "2001:db8:0:b11::464";
-static const char kIPv6PlatSubnet[] = "64:ff9b::";
-
-// Test packet portions. Defined as macros because it's easy to concatenate them to make packets.
-#define IPV4_HEADER(p, c1, c2) \
-    0x45, 0x00,    0,   41,  /* Version=4, IHL=5, ToS=0x80, len=41 */     \
-    0x00, 0x00, 0x40, 0x00,  /* ID=0x0000, flags=IP_DF, offset=0 */       \
-      55,  (p), (c1), (c2),  /* TTL=55, protocol=p, checksum=c1,c2 */     \
-     192,    0,    0,    4,  /* Src=192.0.0.4 */                          \
-       8,    8,    8,    8,  /* Dst=8.8.8.8 */
-#define IPV4_UDP_HEADER IPV4_HEADER(IPPROTO_UDP, 0x73, 0xb0)
-#define IPV4_ICMP_HEADER IPV4_HEADER(IPPROTO_ICMP, 0x73, 0xc0)
-
-#define IPV6_HEADER(p) \
-    0x60, 0x00,    0,    0,  /* Version=6, tclass=0x00, flowlabel=0 */    \
-       0,   21,  (p),   55,  /* plen=11, nxthdr=p, hlim=55 */             \
-    0x20, 0x01, 0x0d, 0xb8,  /* Src=2001:db8:0:b11::464 */                \
-    0x00, 0x00, 0x0b, 0x11,                                               \
-    0x00, 0x00, 0x00, 0x00,                                               \
-    0x00, 0x00, 0x04, 0x64,                                               \
-    0x00, 0x64, 0xff, 0x9b,  /* Dst=64:ff9b::8.8.8.8 */                   \
-    0x00, 0x00, 0x00, 0x00,                                               \
-    0x00, 0x00, 0x00, 0x00,                                               \
-    0x08, 0x08, 0x08, 0x08,
-#define IPV6_UDP_HEADER IPV6_HEADER(IPPROTO_UDP)
-#define IPV6_ICMPV6_HEADER IPV6_HEADER(IPPROTO_ICMPV6)
-
-#define UDP_LEN 21
-#define UDP_HEADER \
-    0xc8, 0x8b,    0,   53,  /* Port 51339->53 */                         \
-    0x00, UDP_LEN, 0,    0,  /* Length 21, checksum empty for now */
-
-#define PAYLOAD 'H', 'e', 'l', 'l', 'o', ' ', 0x4e, 0xb8, 0x96, 0xe7, 0x95, 0x8c, 0x00
-
-#define IPV4_PING \
-    0x08, 0x00, 0x88, 0xd0,  /* Type 8, code 0, checksum 0x88d0 */        \
-    0xd0, 0x0d, 0x00, 0x03,  /* ID=0xd00d, seq=3 */
-
-#define IPV6_PING \
-    0x80, 0x00, 0xc3, 0x42,  /* Type 128, code 0, checksum 0xc342 */      \
-    0xd0, 0x0d, 0x00, 0x03,  /* ID=0xd00d, seq=3 */
-
-// Macros to return pseudo-headers from packets.
-#define IPV4_PSEUDOHEADER(ip, tlen)                                  \
-  ip[12], ip[13], ip[14], ip[15],        /* Source address      */   \
-  ip[16], ip[17], ip[18], ip[19],        /* Destination address */   \
-  0, ip[9],                              /* 0, protocol         */   \
-  ((tlen) >> 16) & 0xff, (tlen) & 0xff,  /* Transport length */
-
-#define IPV6_PSEUDOHEADER(ip6, protocol, tlen)                       \
-  ip6[8],  ip6[9],  ip6[10], ip6[11],  /* Source address */          \
-  ip6[12], ip6[13], ip6[14], ip6[15],                                \
-  ip6[16], ip6[17], ip6[18], ip6[19],                                \
-  ip6[20], ip6[21], ip6[22], ip6[23],                                \
-  ip6[24], ip6[25], ip6[26], ip6[27],  /* Destination address */     \
-  ip6[28], ip6[29], ip6[30], ip6[31],                                \
-  ip6[32], ip6[33], ip6[34], ip6[35],                                \
-  ip6[36], ip6[37], ip6[38], ip6[39],                                \
-  ((tlen) >> 24) & 0xff,               /* Transport length */        \
-  ((tlen) >> 16) & 0xff,                                             \
-  ((tlen) >> 8) & 0xff,                                              \
-  (tlen) & 0xff,                                                     \
-  0, 0, 0, (protocol),
-
-// A fragmented DNS request.
-static const uint8_t kIPv4Frag1[] = {
-    0x45, 0x00, 0x00, 0x24, 0xfe, 0x47, 0x20, 0x00, 0x40, 0x11,
-    0x8c, 0x6d, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
-    0x14, 0x5d, 0x00, 0x35, 0x00, 0x29, 0x68, 0xbb, 0x50, 0x47,
-    0x01, 0x00, 0x00, 0x01, 0x00, 0x00
-};
-static const uint8_t kIPv4Frag2[] = {
-    0x45, 0x00, 0x00, 0x24, 0xfe, 0x47, 0x20, 0x02, 0x40, 0x11,
-    0x8c, 0x6b, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x04, 0x69, 0x70, 0x76, 0x34, 0x06,
-    0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65
-};
-static const uint8_t kIPv4Frag3[] = {
-    0x45, 0x00, 0x00, 0x1d, 0xfe, 0x47, 0x00, 0x04, 0x40, 0x11,
-    0xac, 0x70, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
-    0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
-};
-static const uint8_t *kIPv4Fragments[] = { kIPv4Frag1, kIPv4Frag2, kIPv4Frag3 };
-static const size_t kIPv4FragLengths[] = { sizeof(kIPv4Frag1), sizeof(kIPv4Frag2),
-                                           sizeof(kIPv4Frag3) };
-
-static const uint8_t kIPv6Frag1[] = {
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0x40, 0x20, 0x01,
-    0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
-    0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0xfe, 0x47, 0x14, 0x5d,
-    0x00, 0x35, 0x00, 0x29, 0xeb, 0x91, 0x50, 0x47, 0x01, 0x00,
-    0x00, 0x01, 0x00, 0x00
-};
-
-static const uint8_t kIPv6Frag2[] = {
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0x40, 0x20, 0x01,
-    0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
-    0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0xfe, 0x47, 0x00, 0x00,
-    0x00, 0x00, 0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 0x67, 0x6f,
-    0x6f, 0x67, 0x6c, 0x65
-};
-
-static const uint8_t kIPv6Frag3[] = {
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x11, 0x2c, 0x40, 0x20, 0x01,
-    0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
-    0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0xfe, 0x47, 0x03, 0x63,
-    0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
-};
-static const uint8_t *kIPv6Fragments[] = { kIPv6Frag1, kIPv6Frag2, kIPv6Frag3 };
-static const size_t kIPv6FragLengths[] = { sizeof(kIPv6Frag1), sizeof(kIPv6Frag2),
-                                           sizeof(kIPv6Frag3) };
-
-static const uint8_t kReassembledIPv4[] = {
-    0x45, 0x00, 0x00, 0x3d, 0xfe, 0x47, 0x00, 0x00, 0x40, 0x11,
-    0xac, 0x54, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
-    0x14, 0x5d, 0x00, 0x35, 0x00, 0x29, 0x68, 0xbb, 0x50, 0x47,
-    0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 0x67, 0x6f, 0x6f, 0x67,
-    0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
-    0x01
-};
-
-// Expected checksums.
-static const uint32_t kUdpPartialChecksum     = 0xd5c8;
-static const uint32_t kPayloadPartialChecksum = 0x31e9c;
-static const uint16_t kUdpV4Checksum          = 0xd0c7;
-static const uint16_t kUdpV6Checksum          = 0xa74a;
-
-uint8_t ip_version(const uint8_t *packet) {
-  uint8_t version = packet[0] >> 4;
-  return version;
-}
-
-int is_ipv4_fragment(struct iphdr *ip) {
-  // A packet is a fragment if its fragment offset is nonzero or if the MF flag is set.
-  return ntohs(ip->frag_off) & (IP_OFFMASK | IP_MF);
-}
-
-int is_ipv6_fragment(struct ip6_hdr *ip6, size_t len) {
-  if (ip6->ip6_nxt != IPPROTO_FRAGMENT) {
-    return 0;
-  }
-  struct ip6_frag *frag = (struct ip6_frag *) (ip6 + 1);
-  return len >= sizeof(*ip6) + sizeof(*frag) &&
-          (frag->ip6f_offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG));
-}
-
-int ipv4_fragment_offset(struct iphdr *ip) {
-  return ntohs(ip->frag_off) & IP_OFFMASK;
-}
-
-int ipv6_fragment_offset(struct ip6_frag *frag) {
-  return ntohs((frag->ip6f_offlg & IP6F_OFF_MASK) >> 3);
-}
-
-void check_packet(const uint8_t *packet, size_t len, const char *msg) {
-  void *payload;
-  size_t payload_length = 0;
-  uint32_t pseudo_checksum = 0;
-  uint8_t protocol = 0;
-  int version = ip_version(packet);
-  switch (version) {
-    case 4: {
-      struct iphdr *ip = (struct iphdr *) packet;
-      ASSERT_GE(len, sizeof(*ip)) << msg << ": IPv4 packet shorter than IPv4 header\n";
-      EXPECT_EQ(5, ip->ihl) << msg << ": Unsupported IP header length\n";
-      EXPECT_EQ(len, ntohs(ip->tot_len)) << msg << ": Incorrect IPv4 length\n";
-      EXPECT_EQ(0, ip_checksum(ip, sizeof(*ip))) << msg << ": Incorrect IP checksum\n";
-      protocol = ip->protocol;
-      payload = ip + 1;
-      if (!is_ipv4_fragment(ip)) {
-        payload_length = len - sizeof(*ip);
-        pseudo_checksum = ipv4_pseudo_header_checksum(ip, payload_length);
-      }
-      ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMP)
-          << msg << ": Unsupported IPv4 protocol " << protocol << "\n";
-      break;
-    }
-    case 6: {
-      struct ip6_hdr *ip6 = (struct ip6_hdr *) packet;
-      ASSERT_GE(len, sizeof(*ip6)) << msg << ": IPv6 packet shorter than IPv6 header\n";
-      EXPECT_EQ(len - sizeof(*ip6), htons(ip6->ip6_plen)) << msg << ": Incorrect IPv6 length\n";
-
-      if (ip6->ip6_nxt == IPPROTO_FRAGMENT) {
-        struct ip6_frag *frag = (struct ip6_frag *) (ip6 + 1);
-        ASSERT_GE(len, sizeof(*ip6) + sizeof(*frag))
-            << msg << ": IPv6 fragment: short fragment header\n";
-        protocol = frag->ip6f_nxt;
-        payload = frag + 1;
-        // Even though the packet has a Fragment header, it might not be a fragment.
-        if (!is_ipv6_fragment(ip6, len)) {
-          payload_length = len - sizeof(*ip6) - sizeof(*frag);
-        }
-      } else {
-        // Since there are no extension headers except Fragment, this must be the payload.
-        protocol = ip6->ip6_nxt;
-        payload = ip6 + 1;
-        payload_length = len - sizeof(*ip6);
-      }
-      ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMPV6)
-          << msg << ": Unsupported IPv6 next header " << protocol;
-      if (payload_length) {
-        pseudo_checksum = ipv6_pseudo_header_checksum(ip6, payload_length, protocol);
-      }
-      break;
-    }
-    default:
-      FAIL() << msg << ": Unsupported IP version " << version << "\n";
-      return;
-  }
-
-  // If we understand the payload, verify the checksum.
-  if (payload_length) {
-    uint16_t checksum;
-    switch(protocol) {
-      case IPPROTO_UDP:
-      case IPPROTO_TCP:
-      case IPPROTO_ICMPV6:
-        checksum = ip_checksum_finish(ip_checksum_add(pseudo_checksum, payload, payload_length));
-        break;
-      case IPPROTO_ICMP:
-        checksum = ip_checksum(payload, payload_length);
-        break;
-      default:
-        checksum = 0;  // Don't check.
-        break;
-    }
-    EXPECT_EQ(0, checksum) << msg << ": Incorrect transport checksum\n";
-  }
-
-  if (protocol == IPPROTO_UDP) {
-    struct udphdr *udp = (struct udphdr *) payload;
-    EXPECT_NE(0, udp->check) << msg << ": UDP checksum 0 should be 0xffff";
-    // If this is not a fragment, check the UDP length field.
-    if (payload_length) {
-      EXPECT_EQ(payload_length, ntohs(udp->len)) << msg << ": Incorrect UDP length\n";
-    }
-  }
-}
-
-void reassemble_packet(const uint8_t **fragments, const size_t lengths[], int numpackets,
-                       uint8_t *reassembled, size_t *reassembled_len, const char *msg) {
-  struct iphdr *ip = NULL;
-  struct ip6_hdr *ip6 = NULL;
-  size_t  total_length, pos = 0;
-  uint8_t protocol = 0;
-  uint8_t version = ip_version(fragments[0]);
-
-  for (int i = 0; i < numpackets; i++) {
-    const uint8_t *packet = fragments[i];
-    int len = lengths[i];
-    int headersize, payload_offset;
-
-    ASSERT_EQ(ip_version(packet), version) << msg << ": Inconsistent fragment versions\n";
-    check_packet(packet, len, "Fragment sanity check");
-
-    switch (version) {
-      case 4: {
-        struct iphdr *ip_orig = (struct iphdr *) packet;
-        headersize = sizeof(*ip_orig);
-        ASSERT_TRUE(is_ipv4_fragment(ip_orig))
-            << msg << ": IPv4 fragment #" << i + 1 << " not a fragment\n";
-        ASSERT_EQ(pos, ipv4_fragment_offset(ip_orig) * 8 + ((i != 0) ? sizeof(*ip): 0))
-            << msg << ": IPv4 fragment #" << i + 1 << ": inconsistent offset\n";
-
-        headersize = sizeof(*ip_orig);
-        payload_offset = headersize;
-        if (pos == 0) {
-          ip = (struct iphdr *) reassembled;
-        }
-        break;
-      }
-      case 6: {
-        struct ip6_hdr *ip6_orig = (struct ip6_hdr *) packet;
-        struct ip6_frag *frag = (struct ip6_frag *) (ip6_orig + 1);
-        ASSERT_TRUE(is_ipv6_fragment(ip6_orig, len))
-            << msg << ": IPv6 fragment #" << i + 1 << " not a fragment\n";
-        ASSERT_EQ(pos, ipv6_fragment_offset(frag) * 8 + ((i != 0) ? sizeof(*ip6): 0))
-            << msg << ": IPv6 fragment #" << i + 1 << ": inconsistent offset\n";
-
-        headersize = sizeof(*ip6_orig);
-        payload_offset = sizeof(*ip6_orig) + sizeof(*frag);
-        if (pos == 0) {
-          ip6 = (struct ip6_hdr *) reassembled;
-          protocol = frag->ip6f_nxt;
-        }
-        break;
-      }
-      default:
-        FAIL() << msg << ": Invalid IP version << " << version;
-    }
-
-    // If this is the first fragment, copy the header.
-    if (pos == 0) {
-      ASSERT_LT(headersize, (int) *reassembled_len) << msg << ": Reassembly buffer too small\n";
-      memcpy(reassembled, packet, headersize);
-      total_length = headersize;
-      pos += headersize;
-    }
-
-    // Copy the payload.
-    int payload_length = len - payload_offset;
-    total_length += payload_length;
-    ASSERT_LT(total_length, *reassembled_len) << msg << ": Reassembly buffer too small\n";
-    memcpy(reassembled + pos, packet + payload_offset, payload_length);
-    pos += payload_length;
-  }
-
-
-  // Fix up the reassembled headers to reflect fragmentation and length (and IPv4 checksum).
-  ASSERT_EQ(total_length, pos) << msg << ": Reassembled packet length incorrect\n";
-  if (ip) {
-    ip->frag_off &= ~htons(IP_MF);
-    ip->tot_len = htons(total_length);
-    ip->check = 0;
-    ip->check = ip_checksum(ip, sizeof(*ip));
-    ASSERT_FALSE(is_ipv4_fragment(ip)) << msg << ": reassembled IPv4 packet is a fragment!\n";
-  }
-  if (ip6) {
-    ip6->ip6_nxt = protocol;
-    ip6->ip6_plen = htons(total_length - sizeof(*ip6));
-    ASSERT_FALSE(is_ipv6_fragment(ip6, ip6->ip6_plen))
-        << msg << ": reassembled IPv6 packet is a fragment!\n";
-  }
-
-  *reassembled_len = total_length;
-}
-
-void check_data_matches(const void *expected, const void *actual, size_t len, const char *msg) {
-  if (memcmp(expected, actual, len)) {
-    // Hex dump, 20 bytes per line, one space between bytes (1 byte = 3 chars), indented by 4.
-    int hexdump_len = len * 3 + (len / 20 + 1) * 5;
-    char expected_hexdump[hexdump_len], actual_hexdump[hexdump_len];
-    unsigned pos = 0;
-    for (unsigned i = 0; i < len; i++) {
-      if (i % 20 == 0) {
-        sprintf(expected_hexdump + pos, "\n   ");
-        sprintf(actual_hexdump + pos, "\n   ");
-        pos += 4;
-      }
-      sprintf(expected_hexdump + pos, " %02x", ((uint8_t *) expected)[i]);
-      sprintf(actual_hexdump + pos, " %02x", ((uint8_t *) actual)[i]);
-      pos += 3;
-    }
-    FAIL() << msg << ": Data doesn't match"
-           << "\n  Expected:" << (char *) expected_hexdump
-           << "\n  Actual:" << (char *) actual_hexdump << "\n";
-  }
-}
-
-void fix_udp_checksum(uint8_t* packet) {
-  uint32_t pseudo_checksum;
-  uint8_t version = ip_version(packet);
-  struct udphdr *udp;
-  switch (version) {
-    case 4: {
-      struct iphdr *ip = (struct iphdr *) packet;
-      udp = (struct udphdr *) (ip + 1);
-      pseudo_checksum = ipv4_pseudo_header_checksum(ip, ntohs(udp->len));
-      break;
-    }
-    case 6: {
-      struct ip6_hdr *ip6 = (struct ip6_hdr *) packet;
-      udp = (struct udphdr *) (ip6 + 1);
-      pseudo_checksum = ipv6_pseudo_header_checksum(ip6, ntohs(udp->len), IPPROTO_UDP);
-      break;
-    }
-    default:
-      FAIL() << "unsupported IP version" << version << "\n";
-      return;
-    }
-
-  udp->check = 0;
-  udp->check = ip_checksum_finish(ip_checksum_add(pseudo_checksum, udp, ntohs(udp->len)));
-}
-
-// Testing stub for send_rawv6. The real version uses sendmsg() with a
-// destination IPv6 address, and attempting to call that on our test socketpair
-// fd results in EINVAL.
-extern "C" void send_rawv6(int fd, clat_packet out, int iov_len) {
-    writev(fd, out, iov_len);
-}
-
-void do_translate_packet(const uint8_t *original, size_t original_len, uint8_t *out, size_t *outlen,
-                         const char *msg) {
-  int fds[2];
-  if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, fds)) {
-    abort();
-  }
-
-  char foo[512];
-  snprintf(foo, sizeof(foo), "%s: Invalid original packet", msg);
-  check_packet(original, original_len, foo);
-
-  int read_fd, write_fd;
-  uint16_t expected_proto;
-  int version = ip_version(original);
-  switch (version) {
-    case 4:
-      expected_proto = htons(ETH_P_IPV6);
-      read_fd = fds[1];
-      write_fd = fds[0];
-      break;
-    case 6:
-      expected_proto = htons(ETH_P_IP);
-      read_fd = fds[0];
-      write_fd = fds[1];
-      break;
-    default:
-      FAIL() << msg << ": Unsupported IP version " << version << "\n";
-      break;
-  }
-
-  translate_packet(write_fd, (version == 4), original, original_len);
-
-  snprintf(foo, sizeof(foo), "%s: Invalid translated packet", msg);
-  if (version == 6) {
-    // Translating to IPv4. Expect a tun header.
-    struct tun_pi new_tun_header;
-    struct iovec iov[] = {
-      { &new_tun_header, sizeof(new_tun_header) },
-      { out, *outlen }
-    };
-    int len = readv(read_fd, iov, 2);
-    if (len > (int) sizeof(new_tun_header)) {
-      ASSERT_LT((size_t) len, *outlen) << msg << ": Translated packet buffer too small\n";
-      EXPECT_EQ(expected_proto, new_tun_header.proto) << msg << "Unexpected tun proto\n";
-      *outlen = len - sizeof(new_tun_header);
-      check_packet(out, *outlen, msg);
-    } else {
-      FAIL() << msg << ": Packet was not translated: len=" << len;
-      *outlen = 0;
-    }
-  } else {
-    // Translating to IPv6. Expect raw packet.
-    *outlen = read(read_fd, out, *outlen);
-    check_packet(out, *outlen, msg);
-  }
-}
-
-void check_translated_packet(const uint8_t *original, size_t original_len,
-                             const uint8_t *expected, size_t expected_len, const char *msg) {
-  uint8_t translated[MAXMTU];
-  size_t translated_len = sizeof(translated);
-  do_translate_packet(original, original_len, translated, &translated_len, msg);
-  EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n";
-  check_data_matches(expected, translated, translated_len, msg);
-}
-
-void check_fragment_translation(const uint8_t *original[], const size_t original_lengths[],
-                                const uint8_t *expected[], const size_t expected_lengths[],
-                                int numfragments, const char *msg) {
-  for (int i = 0; i < numfragments; i++) {
-    // Check that each of the fragments translates as expected.
-    char frag_msg[512];
-    snprintf(frag_msg, sizeof(frag_msg), "%s: fragment #%d", msg, i + 1);
-    check_translated_packet(original[i], original_lengths[i],
-                            expected[i], expected_lengths[i], frag_msg);
-  }
-
-  // Sanity check that reassembling the original and translated fragments produces valid packets.
-  uint8_t reassembled[MAXMTU];
-  size_t reassembled_len = sizeof(reassembled);
-  reassemble_packet(original, original_lengths, numfragments, reassembled, &reassembled_len, msg);
-  check_packet(reassembled, reassembled_len, msg);
-
-  uint8_t translated[MAXMTU];
-  size_t translated_len = sizeof(translated);
-  do_translate_packet(reassembled, reassembled_len, translated, &translated_len, msg);
-  check_packet(translated, translated_len, msg);
-}
-
-int get_transport_checksum(const uint8_t *packet) {
-  struct iphdr *ip;
-  struct ip6_hdr *ip6;
-  uint8_t protocol;
-  const void *payload;
-
-  int version = ip_version(packet);
-  switch (version) {
-    case 4:
-      ip = (struct iphdr *) packet;
-      if (is_ipv4_fragment(ip)) {
-          return -1;
-      }
-      protocol = ip->protocol;
-      payload = ip + 1;
-      break;
-    case 6:
-      ip6 = (struct ip6_hdr *) packet;
-      protocol = ip6->ip6_nxt;
-      payload = ip6 + 1;
-      break;
-    default:
-      return -1;
-  }
-
-  switch (protocol) {
-    case IPPROTO_UDP:
-      return ((struct udphdr *) payload)->check;
-
-    case IPPROTO_TCP:
-      return ((struct tcphdr *) payload)->check;
-
-    case IPPROTO_FRAGMENT:
-    default:
-      return -1;
-  }
-}
-
-struct clat_config Global_Clatd_Config;
-
-class ClatdTest : public ::testing::Test {
- protected:
-  virtual void SetUp() {
-    inet_pton(AF_INET, kIPv4LocalAddr, &Global_Clatd_Config.ipv4_local_subnet);
-    inet_pton(AF_INET6, kIPv6PlatSubnet, &Global_Clatd_Config.plat_subnet);
-    inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet);
-    Global_Clatd_Config.ipv6_host_id = in6addr_any;
-    Global_Clatd_Config.use_dynamic_iid = 1;
-  }
-};
-
-void expect_ipv6_addr_equal(struct in6_addr *expected, struct in6_addr *actual) {
-  if (!IN6_ARE_ADDR_EQUAL(expected, actual)) {
-    char expected_str[INET6_ADDRSTRLEN], actual_str[INET6_ADDRSTRLEN];
-    inet_ntop(AF_INET6, expected, expected_str, sizeof(expected_str));
-    inet_ntop(AF_INET6, actual, actual_str, sizeof(actual_str));
-    FAIL()
-        << "Unexpected IPv6 address:: "
-        << "\n  Expected: " << expected_str
-        << "\n  Actual:   " << actual_str
-        << "\n";
-  }
-}
-
-TEST_F(ClatdTest, TestIPv6PrefixEqual) {
-  EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.plat_subnet,
-                                &Global_Clatd_Config.plat_subnet));
-  EXPECT_FALSE(ipv6_prefix_equal(&Global_Clatd_Config.plat_subnet,
-                                 &Global_Clatd_Config.ipv6_local_subnet));
-
-  struct in6_addr subnet2 = Global_Clatd_Config.ipv6_local_subnet;
-  EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &subnet2));
-  EXPECT_TRUE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet));
-
-  subnet2.s6_addr[6] = 0xff;
-  EXPECT_FALSE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &subnet2));
-  EXPECT_FALSE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet));
-}
-
-int count_onebits(const void *data, size_t size) {
-  int onebits = 0;
-  for (size_t pos = 0; pos < size; pos++) {
-    uint8_t *byte = ((uint8_t*) data) + pos;
-    for (int shift = 0; shift < 8; shift++) {
-      onebits += (*byte >> shift) & 1;
-    }
-  }
-  return onebits;
-}
-
-TEST_F(ClatdTest, TestCountOnebits) {
-  uint64_t i;
-  i = 1;
-  ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
-  i <<= 61;
-  ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
-  i |= ((uint64_t) 1 << 33);
-  ASSERT_EQ(2, count_onebits(&i, sizeof(i)));
-  i = 0xf1000202020000f0;
-  ASSERT_EQ(5 + 1 + 1 + 1 + 4, count_onebits(&i, sizeof(i)));
-}
-
-TEST_F(ClatdTest, TestGenIIDConfigured) {
-  struct in6_addr myaddr, expected;
-  Global_Clatd_Config.use_dynamic_iid = 0;
-  ASSERT_TRUE(inet_pton(AF_INET6, "::bad:ace:d00d", &Global_Clatd_Config.ipv6_host_id));
-  ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:0:bad:ace:d00d", &expected));
-  ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &myaddr));
-  config_generate_local_ipv6_subnet(&myaddr);
-  expect_ipv6_addr_equal(&expected, &myaddr);
-
-  Global_Clatd_Config.use_dynamic_iid = 1;
-  config_generate_local_ipv6_subnet(&myaddr);
-  EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&expected, &myaddr));
-}
-
-TEST_F(ClatdTest, TestGenIIDRandom) {
-  struct in6_addr interface_ipv6;
-  ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &interface_ipv6));
-  Global_Clatd_Config.ipv6_host_id = in6addr_any;
-
-  // Generate a boatload of random IIDs.
-  int onebits = 0;
-  uint64_t prev_iid = 0;
-  for (int i = 0; i < 100000; i++) {
-    struct in6_addr myaddr =  interface_ipv6;
-
-    config_generate_local_ipv6_subnet(&myaddr);
-
-    // Check the generated IP address is in the same prefix as the interface IPv6 address.
-    EXPECT_TRUE(ipv6_prefix_equal(&interface_ipv6, &myaddr));
-
-    // Check that consecutive IIDs are not the same.
-    uint64_t iid = * (uint64_t*) (&myaddr.s6_addr[8]);
-    ASSERT_TRUE(iid != prev_iid)
-        << "Two consecutive random IIDs are the same: "
-        << std::showbase << std::hex
-        << iid << "\n";
-    prev_iid = iid;
-
-    // Check that the IID is checksum-neutral with the NAT64 prefix and the
-    // local prefix.
-    struct in_addr *ipv4addr = &Global_Clatd_Config.ipv4_local_subnet;
-    struct in6_addr *plat_subnet = &Global_Clatd_Config.plat_subnet;
-
-    uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, ipv4addr, sizeof(*ipv4addr)));
-    uint16_t c2 = ip_checksum_finish(ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
-                                     ip_checksum_add(0, &myaddr, sizeof(myaddr)));
-
-    if (c1 != c2) {
-      char myaddr_str[INET6_ADDRSTRLEN], plat_str[INET6_ADDRSTRLEN], ipv4_str[INET6_ADDRSTRLEN];
-      inet_ntop(AF_INET6, &myaddr, myaddr_str, sizeof(myaddr_str));
-      inet_ntop(AF_INET6, plat_subnet, plat_str, sizeof(plat_str));
-      inet_ntop(AF_INET, ipv4addr, ipv4_str, sizeof(ipv4_str));
-      FAIL()
-          << "Bad IID: " << myaddr_str
-          << " not checksum-neutral with " << ipv4_str << " and " << plat_str
-          << std::showbase << std::hex
-          << "\n  IPv4 checksum: " << c1
-          << "\n  IPv6 checksum: " << c2
-          << "\n";
-    }
-
-    // Check that IIDs are roughly random and use all the bits by counting the
-    // total number of bits set to 1 in a random sample of 100000 generated IIDs.
-    onebits += count_onebits(&iid, sizeof(iid));
-  }
-  EXPECT_LE(3190000, onebits);
-  EXPECT_GE(3210000, onebits);
-}
-
-extern "C" addr_free_func config_is_ipv4_address_free;
-int never_free(in_addr_t /* addr */) { return 0; }
-int always_free(in_addr_t /* addr */) { return 1; }
-int only2_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 2; }
-int over6_free(in_addr_t addr) { return (ntohl(addr) & 0xff) >= 6; }
-int only10_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 10; }
-
-TEST_F(ClatdTest, SelectIPv4Address) {
-  struct in_addr addr;
-
-  inet_pton(AF_INET, kIPv4LocalAddr, &addr);
-
-  addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
-
-  // If no addresses are free, return INADDR_NONE.
-  config_is_ipv4_address_free = never_free;
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 16));
-
-  // If the configured address is free, pick that. But a prefix that's too big is invalid.
-  config_is_ipv4_address_free = always_free;
-  EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 29));
-  EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 20));
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 15));
-
-  // A prefix length of 32 works, but anything above it is invalid.
-  EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 32));
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 33));
-
-  // If another address is free, pick it.
-  config_is_ipv4_address_free = over6_free;
-  EXPECT_EQ(inet_addr("192.0.0.6"), config_select_ipv4_address(&addr, 29));
-
-  // Check that we wrap around to addresses that are lower than the first address.
-  config_is_ipv4_address_free = only2_free;
-  EXPECT_EQ(inet_addr("192.0.0.2"), config_select_ipv4_address(&addr, 29));
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 30));
-
-  // If a free address exists outside the prefix, we don't pick it.
-  config_is_ipv4_address_free = only10_free;
-  EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
-  EXPECT_EQ(inet_addr("192.0.0.10"), config_select_ipv4_address(&addr, 24));
-
-  // Now try using the real function which sees if IP addresses are free using bind().
-  // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8.
-  config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
-  addr.s_addr = inet_addr("8.8.8.8");
-  EXPECT_EQ(inet_addr("8.8.8.8"), config_select_ipv4_address(&addr, 29));
-
-  addr.s_addr = inet_addr("127.0.0.1");
-  EXPECT_EQ(inet_addr("127.0.0.2"), config_select_ipv4_address(&addr, 29));
-}
-
-TEST_F(ClatdTest, DataSanitycheck) {
-  // Sanity checks the data.
-  uint8_t v4_header[] = { IPV4_UDP_HEADER };
-  ASSERT_EQ(sizeof(struct iphdr), sizeof(v4_header)) << "Test IPv4 header: incorrect length\n";
-
-  uint8_t v6_header[] = { IPV6_UDP_HEADER };
-  ASSERT_EQ(sizeof(struct ip6_hdr), sizeof(v6_header)) << "Test IPv6 header: incorrect length\n";
-
-  uint8_t udp_header[] = { UDP_HEADER };
-  ASSERT_EQ(sizeof(struct udphdr), sizeof(udp_header)) << "Test UDP header: incorrect length\n";
-
-  // Sanity checks check_packet.
-  struct udphdr *udp;
-  uint8_t v4_udp_packet[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
-  udp = (struct udphdr *) (v4_udp_packet + sizeof(struct iphdr));
-  fix_udp_checksum(v4_udp_packet);
-  ASSERT_EQ(kUdpV4Checksum, udp->check) << "UDP/IPv4 packet checksum sanity check\n";
-  check_packet(v4_udp_packet, sizeof(v4_udp_packet), "UDP/IPv4 packet sanity check");
-
-  uint8_t v6_udp_packet[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
-  udp = (struct udphdr *) (v6_udp_packet + sizeof(struct ip6_hdr));
-  fix_udp_checksum(v6_udp_packet);
-  ASSERT_EQ(kUdpV6Checksum, udp->check) << "UDP/IPv6 packet checksum sanity check\n";
-  check_packet(v6_udp_packet, sizeof(v6_udp_packet), "UDP/IPv6 packet sanity check");
-
-  uint8_t ipv4_ping[] = { IPV4_ICMP_HEADER IPV4_PING PAYLOAD };
-  check_packet(ipv4_ping, sizeof(ipv4_ping), "IPv4 ping sanity check");
-
-  uint8_t ipv6_ping[] = { IPV6_ICMPV6_HEADER IPV6_PING PAYLOAD };
-  check_packet(ipv6_ping, sizeof(ipv6_ping), "IPv6 ping sanity check");
-
-  // Sanity checks reassemble_packet.
-  uint8_t reassembled[MAXMTU];
-  size_t total_length = sizeof(reassembled);
-  reassemble_packet(kIPv4Fragments, kIPv4FragLengths, ARRAYSIZE(kIPv4Fragments),
-                    reassembled, &total_length, "Reassembly sanity check");
-  check_packet(reassembled, total_length, "IPv4 Reassembled packet is valid");
-  ASSERT_EQ(sizeof(kReassembledIPv4), total_length) << "IPv4 reassembly sanity check: length\n";
-  ASSERT_TRUE(!is_ipv4_fragment((struct iphdr *) reassembled))
-      << "Sanity check: reassembled packet is a fragment!\n";
-  check_data_matches(kReassembledIPv4, reassembled, total_length, "IPv4 reassembly sanity check");
-
-  total_length = sizeof(reassembled);
-  reassemble_packet(kIPv6Fragments, kIPv6FragLengths, ARRAYSIZE(kIPv6Fragments),
-                    reassembled, &total_length, "IPv6 reassembly sanity check");
-  ASSERT_TRUE(!is_ipv6_fragment((struct ip6_hdr *) reassembled, total_length))
-      << "Sanity check: reassembled packet is a fragment!\n";
-  check_packet(reassembled, total_length, "IPv6 Reassembled packet is valid");
-}
-
-TEST_F(ClatdTest, PseudoChecksum) {
-  uint32_t pseudo_checksum;
-
-  uint8_t v4_header[] = { IPV4_UDP_HEADER };
-  uint8_t v4_pseudo_header[] = { IPV4_PSEUDOHEADER(v4_header, UDP_LEN) };
-  pseudo_checksum = ipv4_pseudo_header_checksum((struct iphdr *) v4_header, UDP_LEN);
-  EXPECT_EQ(ip_checksum_finish(pseudo_checksum),
-            ip_checksum(v4_pseudo_header, sizeof(v4_pseudo_header)))
-            << "ipv4_pseudo_header_checksum incorrect\n";
-
-  uint8_t v6_header[] = { IPV6_UDP_HEADER };
-  uint8_t v6_pseudo_header[] = { IPV6_PSEUDOHEADER(v6_header, IPPROTO_UDP, UDP_LEN) };
-  pseudo_checksum = ipv6_pseudo_header_checksum((struct ip6_hdr *) v6_header, UDP_LEN, IPPROTO_UDP);
-  EXPECT_EQ(ip_checksum_finish(pseudo_checksum),
-            ip_checksum(v6_pseudo_header, sizeof(v6_pseudo_header)))
-            << "ipv6_pseudo_header_checksum incorrect\n";
-}
-
-TEST_F(ClatdTest, TransportChecksum) {
-  uint8_t udphdr[] = { UDP_HEADER };
-  uint8_t payload[] = { PAYLOAD };
-  EXPECT_EQ(kUdpPartialChecksum, ip_checksum_add(0, udphdr, sizeof(udphdr)))
-            << "UDP partial checksum\n";
-  EXPECT_EQ(kPayloadPartialChecksum, ip_checksum_add(0, payload, sizeof(payload)))
-            << "Payload partial checksum\n";
-
-  uint8_t ip[] = { IPV4_UDP_HEADER };
-  uint8_t ip6[] = { IPV6_UDP_HEADER };
-  uint32_t ipv4_pseudo_sum = ipv4_pseudo_header_checksum((struct iphdr *) ip, UDP_LEN);
-  uint32_t ipv6_pseudo_sum = ipv6_pseudo_header_checksum((struct ip6_hdr *) ip6, UDP_LEN,
-                                                         IPPROTO_UDP);
-
-  EXPECT_EQ(0x3ad0U, ipv4_pseudo_sum) << "IPv4 pseudo-checksum sanity check\n";
-  EXPECT_EQ(0x2644bU, ipv6_pseudo_sum) << "IPv6 pseudo-checksum sanity check\n";
-  EXPECT_EQ(
-      kUdpV4Checksum,
-      ip_checksum_finish(ipv4_pseudo_sum + kUdpPartialChecksum + kPayloadPartialChecksum))
-      << "Unexpected UDP/IPv4 checksum\n";
-  EXPECT_EQ(
-      kUdpV6Checksum,
-      ip_checksum_finish(ipv6_pseudo_sum + kUdpPartialChecksum + kPayloadPartialChecksum))
-      << "Unexpected UDP/IPv6 checksum\n";
-
-  EXPECT_EQ(kUdpV6Checksum,
-      ip_checksum_adjust(kUdpV4Checksum, ipv4_pseudo_sum, ipv6_pseudo_sum))
-      << "Adjust IPv4/UDP checksum to IPv6\n";
-  EXPECT_EQ(kUdpV4Checksum,
-      ip_checksum_adjust(kUdpV6Checksum, ipv6_pseudo_sum, ipv4_pseudo_sum))
-      << "Adjust IPv6/UDP checksum to IPv4\n";
-}
-
-TEST_F(ClatdTest, AdjustChecksum) {
-  struct checksum_data {
-    uint16_t checksum;
-    uint32_t old_hdr_sum;
-    uint32_t new_hdr_sum;
-    uint16_t result;
-  } DATA[] = {
-    { 0x1423, 0xb8ec, 0x2d757, 0xf5b5 },
-    { 0xf5b5, 0x2d757, 0xb8ec, 0x1423 },
-    { 0xdd2f, 0x5555, 0x3285, 0x0000 },
-    { 0x1215, 0x5560, 0x15560 + 20, 0x1200 },
-    { 0xd0c7, 0x3ad0, 0x2644b, 0xa74a },
-  };
-  unsigned i = 0;
-
-  for (i = 0; i < ARRAYSIZE(DATA); i++) {
-    struct checksum_data *data = DATA + i;
-    uint16_t result = ip_checksum_adjust(data->checksum, data->old_hdr_sum, data->new_hdr_sum);
-    EXPECT_EQ(result, data->result)
-        << "Incorrect checksum" << std::showbase << std::hex
-        << "\n  Expected: " << data->result
-        << "\n  Actual:   " << result
-        << "\n    checksum=" << data->checksum
-        << " old_sum=" << data->old_hdr_sum << " new_sum=" << data->new_hdr_sum << "\n";
-  }
-}
-
-TEST_F(ClatdTest, Translate) {
-  uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
-  uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
-  fix_udp_checksum(udp_ipv4);
-  fix_udp_checksum(udp_ipv6);
-  check_translated_packet(udp_ipv4, sizeof(udp_ipv4), udp_ipv6, sizeof(udp_ipv6),
-                          "UDP/IPv4 -> UDP/IPv6 translation");
-  check_translated_packet(udp_ipv6, sizeof(udp_ipv6), udp_ipv4, sizeof(udp_ipv4),
-                          "UDP/IPv6 -> UDP/IPv4 translation");
-
-  uint8_t ipv4_ping[] = { IPV4_ICMP_HEADER IPV4_PING PAYLOAD };
-  uint8_t ipv6_ping[] = { IPV6_ICMPV6_HEADER IPV6_PING PAYLOAD };
-  check_translated_packet(ipv4_ping, sizeof(ipv4_ping), ipv6_ping, sizeof(ipv6_ping),
-                          "ICMP->ICMPv6 translation");
-  check_translated_packet(ipv6_ping, sizeof(ipv6_ping), ipv4_ping, sizeof(ipv4_ping),
-                          "ICMPv6->ICMP translation");
-}
-
-TEST_F(ClatdTest, Fragmentation) {
-  check_fragment_translation(kIPv4Fragments, kIPv4FragLengths,
-                             kIPv6Fragments, kIPv6FragLengths,
-                             ARRAYSIZE(kIPv4Fragments), "IPv4->IPv6 fragment translation");
-
-  check_fragment_translation(kIPv6Fragments, kIPv6FragLengths,
-                             kIPv4Fragments, kIPv4FragLengths,
-                             ARRAYSIZE(kIPv6Fragments), "IPv6->IPv4 fragment translation");
-}
-
-void check_translate_checksum_neutral(const uint8_t *original, size_t original_len,
-                                      size_t expected_len, const char *msg) {
-  uint8_t translated[MAXMTU];
-  size_t translated_len = sizeof(translated);
-  do_translate_packet(original, original_len, translated, &translated_len, msg);
-  EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n";
-  // do_translate_packet already checks packets for validity and verifies the checksum.
-  int original_check = get_transport_checksum(original);
-  int translated_check = get_transport_checksum(translated);
-  ASSERT_NE(-1, original_check);
-  ASSERT_NE(-1, translated_check);
-  ASSERT_EQ(original_check, translated_check)
-      << "Not checksum neutral: original and translated checksums differ\n";
-}
-
-TEST_F(ClatdTest, TranslateChecksumNeutral) {
-  // Generate a random clat IPv6 address and check that translation is checksum-neutral.
-  Global_Clatd_Config.ipv6_host_id = in6addr_any;
-  ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54",
-                        &Global_Clatd_Config.ipv6_local_subnet));
-  config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet);
-  ASSERT_NE((uint32_t) 0x00000464, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
-  ASSERT_NE((uint32_t) 0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
-
-  // Check that translating UDP packets is checksum-neutral. First, IPv4.
-  uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
-  fix_udp_checksum(udp_ipv4);
-  check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20,
-                                   "UDP/IPv4 -> UDP/IPv6 checksum neutral");
-
-  // Now try IPv6.
-  uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
-  // The test packet uses the static IID, not the random IID. Fix up the source address.
-  struct ip6_hdr *ip6 = (struct ip6_hdr *) udp_ipv6;
-  memcpy(&ip6->ip6_src, &Global_Clatd_Config.ipv6_local_subnet, sizeof(ip6->ip6_src));
-  fix_udp_checksum(udp_ipv6);
-  check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20,
-                                   "UDP/IPv4 -> UDP/IPv6 checksum neutral");
-}
diff --git a/config.c b/config.c
deleted file mode 100644 (file)
index b147868..0000000
--- a/config.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * config.c - configuration settings
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <arpa/inet.h>
-#include <stdio.h>
-#include <limits.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <cutils/config_utils.h>
-#include <netutils/ifc.h>
-
-#include "config.h"
-#include "dns64.h"
-#include "logging.h"
-#include "getaddr.h"
-#include "clatd.h"
-#include "checksum.h"
-
-struct clat_config Global_Clatd_Config;
-
-/* function: config_item_str
- * locates the config item and returns the pointer to a string, or NULL on failure.  Caller frees pointer
- * root       - parsed configuration
- * item_name  - name of config item to locate
- * defaultvar - value to use if config item isn't present
- */
-char *config_item_str(cnode *root, const char *item_name, const char *defaultvar) {
-  const char *tmp;
-
-  if(!(tmp = config_str(root, item_name, defaultvar))) {
-    logmsg(ANDROID_LOG_FATAL,"%s config item needed",item_name);
-    return NULL;
-  }
-  return strdup(tmp);
-}
-
-/* function: config_item_int16_t
- * locates the config item, parses the integer, and returns the pointer ret_val_ptr, or NULL on failure
- * root        - parsed configuration
- * item_name   - name of config item to locate
- * defaultvar  - value to use if config item isn't present
- * ret_val_ptr - pointer for return value storage
- */
-int16_t *config_item_int16_t(cnode *root, const char *item_name, const char *defaultvar, int16_t *ret_val_ptr) {
-  const char *tmp;
-  char *endptr;
-  long int conf_int;
-
-  if(!(tmp = config_str(root, item_name, defaultvar))) {
-    logmsg(ANDROID_LOG_FATAL,"%s config item needed",item_name);
-    return NULL;
-  }
-
-  errno = 0;
-  conf_int = strtol(tmp,&endptr,10);
-  if(errno > 0) {
-    logmsg(ANDROID_LOG_FATAL,"%s config item is not numeric: %s (error=%s)",item_name,tmp,strerror(errno));
-    return NULL;
-  }
-  if(endptr == tmp || *tmp == '\0') {
-    logmsg(ANDROID_LOG_FATAL,"%s config item is not numeric: %s",item_name,tmp);
-    return NULL;
-  }
-  if(*endptr != '\0') {
-    logmsg(ANDROID_LOG_FATAL,"%s config item contains non-numeric characters: %s",item_name,endptr);
-    return NULL;
-  }
-  if(conf_int > INT16_MAX || conf_int < INT16_MIN) {
-    logmsg(ANDROID_LOG_FATAL,"%s config item is too big/small: %d",item_name,conf_int);
-    return NULL;
-  }
-  *ret_val_ptr = conf_int;
-  return ret_val_ptr;
-}
-
-/* function: config_item_ip
- * locates the config item, parses the ipv4 address, and returns the pointer ret_val_ptr, or NULL on failure
- * root        - parsed configuration
- * item_name   - name of config item to locate
- * defaultvar  - value to use if config item isn't present
- * ret_val_ptr - pointer for return value storage
- */
-struct in_addr *config_item_ip(cnode *root, const char *item_name, const char *defaultvar, struct in_addr *ret_val_ptr) {
-  const char *tmp;
-  int status;
-
-  if(!(tmp = config_str(root, item_name, defaultvar))) {
-    logmsg(ANDROID_LOG_FATAL,"%s config item needed",item_name);
-    return NULL;
-  }
-
-  status = inet_pton(AF_INET, tmp, ret_val_ptr);
-  if(status <= 0) {
-    logmsg(ANDROID_LOG_FATAL,"invalid IPv4 address specified for %s: %s", item_name, tmp);
-    return NULL;
-  }
-
-  return ret_val_ptr;
-}
-
-/* function: config_item_ip6
- * locates the config item, parses the ipv6 address, and returns the pointer ret_val_ptr, or NULL on failure
- * root        - parsed configuration
- * item_name   - name of config item to locate
- * defaultvar  - value to use if config item isn't present
- * ret_val_ptr - pointer for return value storage
- */
-struct in6_addr *config_item_ip6(cnode *root, const char *item_name, const char *defaultvar, struct in6_addr *ret_val_ptr) {
-  const char *tmp;
-  int status;
-
-  if(!(tmp = config_str(root, item_name, defaultvar))) {
-    logmsg(ANDROID_LOG_FATAL,"%s config item needed",item_name);
-    return NULL;
-  }
-
-  status = inet_pton(AF_INET6, tmp, ret_val_ptr);
-  if(status <= 0) {
-    logmsg(ANDROID_LOG_FATAL,"invalid IPv6 address specified for %s: %s", item_name, tmp);
-    return NULL;
-  }
-
-  return ret_val_ptr;
-}
-
-/* function: free_config
- * frees the memory used by the global config variable
- */
-void free_config() {
-  if(Global_Clatd_Config.plat_from_dns64_hostname) {
-    free(Global_Clatd_Config.plat_from_dns64_hostname);
-    Global_Clatd_Config.plat_from_dns64_hostname = NULL;
-  }
-}
-
-/* function: ipv6_prefix_equal
- * compares the prefixes two ipv6 addresses. assumes the prefix lengths are both /64.
- * a1 - first address
- * a2 - second address
- * returns: 0 if the subnets are different, 1 if they are the same.
- */
-int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2) {
-    return !memcmp(a1, a2, 8);
-}
-
-/* function: dns64_detection
- * does dns lookups to set the plat subnet or exits on failure, waits forever for a dns response with a query backoff timer
- * net_id - (optional) netId to use, NETID_UNSET indicates use of default network
- */
-void dns64_detection(unsigned net_id) {
-  int backoff_sleep, status;
-  struct in6_addr tmp_ptr;
-
-  backoff_sleep = 1;
-
-  while(1) {
-    status = plat_prefix(Global_Clatd_Config.plat_from_dns64_hostname,net_id,&tmp_ptr);
-    if(status > 0) {
-      memcpy(&Global_Clatd_Config.plat_subnet, &tmp_ptr, sizeof(struct in6_addr));
-      return;
-    }
-    logmsg(ANDROID_LOG_WARN, "dns64_detection -- error, sleeping for %d seconds", backoff_sleep);
-    sleep(backoff_sleep);
-    backoff_sleep *= 2;
-    if(backoff_sleep >= 120) {
-      backoff_sleep = 120;
-    }
-  }
-}
-
-/* function: gen_random_iid
- * picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix
- * myaddr            - IPv6 address to write to
- * ipv4_local_subnet - clat IPv4 address
- * plat_subnet       - NAT64 prefix
- */
-void gen_random_iid(struct in6_addr *myaddr, struct in_addr *ipv4_local_subnet,
-                    struct in6_addr *plat_subnet) {
-  // Fill last 8 bytes of IPv6 address with random bits.
-  arc4random_buf(&myaddr->s6_addr[8], 8);
-
-  // Make the IID checksum-neutral. That is, make it so that:
-  //   checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6)
-  // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4):
-  //   checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix)
-  // Do this by adjusting the two bytes in the middle of the IID.
-
-  uint16_t middlebytes = (myaddr->s6_addr[11] << 8) + myaddr->s6_addr[12];
-
-  uint32_t c1 = ip_checksum_add(0, ipv4_local_subnet, sizeof(*ipv4_local_subnet));
-  uint32_t c2 = ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
-                ip_checksum_add(0, myaddr, sizeof(*myaddr));
-
-  uint16_t delta = ip_checksum_adjust(middlebytes, c1, c2);
-  myaddr->s6_addr[11] = delta >> 8;
-  myaddr->s6_addr[12] = delta & 0xff;
-}
-
-// Factored out to a separate function for testability.
-int connect_is_ipv4_address_free(in_addr_t addr) {
-  int s = socket(AF_INET, SOCK_DGRAM, 0);
-  if (s == -1) {
-    return 0;
-  }
-
-  // Attempt to connect to the address. If the connection succeeds and getsockname returns the same
-  // the address then the address is already assigned to the system and we can't use it.
-  struct sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = { addr }, .sin_port = 53 };
-  socklen_t len = sizeof(sin);
-  int inuse = connect(s, (struct sockaddr *) &sin, sizeof(sin)) == 0 &&
-              getsockname(s, (struct sockaddr *) &sin, &len) == 0 &&
-              (size_t) len >= sizeof(sin) &&
-              sin.sin_addr.s_addr == addr;
-
-  close(s);
-  return !inuse;
-}
-
-addr_free_func config_is_ipv4_address_free = connect_is_ipv4_address_free;
-
-/* function: config_select_ipv4_address
- * picks a free IPv4 address, starting from ip and trying all addresses in the prefix in order
- * ip        - the IP address from the configuration file
- * prefixlen - the length of the prefix from which addresses may be selected.
- * returns: the IPv4 address, or INADDR_NONE if no addresses were available
- */
-in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen) {
-  in_addr_t chosen = INADDR_NONE;
-
-  // Don't accept prefixes that are too large because we scan addresses one by one.
-  if (prefixlen < 16 || prefixlen > 32) {
-      return chosen;
-  }
-
-  // All these are in host byte order.
-  in_addr_t mask = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen);
-  in_addr_t ipv4 = ntohl(ip->s_addr);
-  in_addr_t first_ipv4 = ipv4;
-  in_addr_t prefix = ipv4 & mask;
-
-  // Pick the first IPv4 address in the pool, wrapping around if necessary.
-  // So, for example, 192.0.0.4 -> 192.0.0.5 -> 192.0.0.6 -> 192.0.0.7 -> 192.0.0.0.
-  do {
-     if (config_is_ipv4_address_free(htonl(ipv4))) {
-       chosen = htonl(ipv4);
-       break;
-     }
-     ipv4 = prefix | ((ipv4 + 1) & ~mask);
-  } while (ipv4 != first_ipv4);
-
-  return chosen;
-}
-
-/* function: config_generate_local_ipv6_subnet
- * generates the local ipv6 subnet when given the interface ip
- * requires config.ipv6_host_id
- * interface_ip - in: interface ip, out: local ipv6 host address
- */
-void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip) {
-  int i;
-
-  if (Global_Clatd_Config.use_dynamic_iid) {
-    /* Generate a random interface ID. */
-    gen_random_iid(interface_ip,
-                   &Global_Clatd_Config.ipv4_local_subnet,
-                   &Global_Clatd_Config.plat_subnet);
-  } else {
-    /* Use the specified interface ID. */
-    for(i = 2; i < 4; i++) {
-      interface_ip->s6_addr32[i] = Global_Clatd_Config.ipv6_host_id.s6_addr32[i];
-    }
-  }
-}
-
-/* function: read_config
- * reads the config file and parses it into the global variable Global_Clatd_Config. returns 0 on failure, 1 on success
- * file             - filename to parse
- * uplink_interface - interface to use to reach the internet and supplier of address space
- * plat_prefix      - (optional) plat prefix to use, otherwise follow config file
- * net_id           - (optional) netId to use, NETID_UNSET indicates use of default network
- */
-int read_config(const char *file, const char *uplink_interface, const char *plat_prefix,
-        unsigned net_id) {
-  cnode *root = config_node("", "");
-  void *tmp_ptr = NULL;
-  unsigned flags;
-
-  if(!root) {
-    logmsg(ANDROID_LOG_FATAL,"out of memory");
-    return 0;
-  }
-
-  memset(&Global_Clatd_Config, '\0', sizeof(Global_Clatd_Config));
-
-  config_load_file(root, file);
-  if(root->first_child == NULL) {
-    logmsg(ANDROID_LOG_FATAL,"Could not read config file %s", file);
-    goto failed;
-  }
-
-  Global_Clatd_Config.default_pdp_interface = strdup(uplink_interface);
-  if (!Global_Clatd_Config.default_pdp_interface)
-    goto failed;
-
-  if(!config_item_int16_t(root, "mtu", "-1", &Global_Clatd_Config.mtu))
-    goto failed;
-
-  if(!config_item_int16_t(root, "ipv4mtu", "-1", &Global_Clatd_Config.ipv4mtu))
-    goto failed;
-
-  if(!config_item_ip(root, "ipv4_local_subnet", DEFAULT_IPV4_LOCAL_SUBNET,
-                     &Global_Clatd_Config.ipv4_local_subnet))
-    goto failed;
-
-  if(!config_item_int16_t(root, "ipv4_local_prefixlen", DEFAULT_IPV4_LOCAL_PREFIXLEN,
-                          &Global_Clatd_Config.ipv4_local_prefixlen))
-    goto failed;
-
-  if(plat_prefix) { // plat subnet is coming from the command line
-    if(inet_pton(AF_INET6, plat_prefix, &Global_Clatd_Config.plat_subnet) <= 0) {
-      logmsg(ANDROID_LOG_FATAL,"invalid IPv6 address specified for plat prefix: %s", plat_prefix);
-      goto failed;
-    }
-  } else {
-    tmp_ptr = (void *)config_item_str(root, "plat_from_dns64", "yes");
-    if(!tmp_ptr || strcmp(tmp_ptr, "no") == 0) {
-      free(tmp_ptr);
-
-      if(!config_item_ip6(root, "plat_subnet", NULL, &Global_Clatd_Config.plat_subnet)) {
-        logmsg(ANDROID_LOG_FATAL, "plat_from_dns64 disabled, but no plat_subnet specified");
-        goto failed;
-      }
-    } else {
-      free(tmp_ptr);
-
-      if(!(Global_Clatd_Config.plat_from_dns64_hostname = config_item_str(root, "plat_from_dns64_hostname", DEFAULT_DNS64_DETECTION_HOSTNAME)))
-        goto failed;
-      dns64_detection(net_id);
-    }
-  }
-
-  if (!config_item_ip6(root, "ipv6_host_id", "::", &Global_Clatd_Config.ipv6_host_id))
-    goto failed;
-
-  /* In order to prevent multiple devices attempting to use the same clat address, never use a
-     statically-configured interface ID on a broadcast interface such as wifi. */
-  if (!IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_host_id)) {
-    ifc_init();
-    ifc_get_info(Global_Clatd_Config.default_pdp_interface, NULL, NULL, &flags);
-    ifc_close();
-    Global_Clatd_Config.use_dynamic_iid = (flags & IFF_BROADCAST) != 0;
-  } else {
-    Global_Clatd_Config.use_dynamic_iid = 1;
-  }
-
-  return 1;
-
-failed:
-  free(root);
-  free_config();
-  return 0;
-}
-
-/* function; dump_config
- * prints the current config
- */
-void dump_config() {
-  char charbuffer[INET6_ADDRSTRLEN];
-
-  logmsg(ANDROID_LOG_DEBUG,"mtu = %d",Global_Clatd_Config.mtu);
-  logmsg(ANDROID_LOG_DEBUG,"ipv4mtu = %d",Global_Clatd_Config.ipv4mtu);
-  logmsg(ANDROID_LOG_DEBUG,"ipv6_local_subnet = %s",inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, charbuffer, sizeof(charbuffer)));
-  logmsg(ANDROID_LOG_DEBUG,"ipv4_local_subnet = %s",inet_ntop(AF_INET, &Global_Clatd_Config.ipv4_local_subnet, charbuffer, sizeof(charbuffer)));
-  logmsg(ANDROID_LOG_DEBUG,"ipv4_local_prefixlen = %d", Global_Clatd_Config.ipv4_local_prefixlen);
-  logmsg(ANDROID_LOG_DEBUG,"plat_subnet = %s",inet_ntop(AF_INET6, &Global_Clatd_Config.plat_subnet, charbuffer, sizeof(charbuffer)));
-  logmsg(ANDROID_LOG_DEBUG,"default_pdp_interface = %s",Global_Clatd_Config.default_pdp_interface);
-}
diff --git a/config.h b/config.h
deleted file mode 100644 (file)
index e31a81d..0000000
--- a/config.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * config.h - configuration settings
- */
-#ifndef __CONFIG_H__
-#define __CONFIG_H__
-
-#include <netinet/in.h>
-#include <linux/if.h>
-
-#define DEFAULT_IPV4_LOCAL_SUBNET "192.0.0.4"
-#define DEFAULT_IPV4_LOCAL_PREFIXLEN "29"
-#define DEFAULT_DNS64_DETECTION_HOSTNAME "ipv4only.arpa"
-
-struct clat_config {
-  int16_t mtu, ipv4mtu;
-  struct in6_addr ipv6_local_subnet;
-  struct in6_addr ipv6_host_id;
-  struct in_addr ipv4_local_subnet;
-  int16_t ipv4_local_prefixlen;
-  struct in6_addr plat_subnet;
-  char *default_pdp_interface;
-  char *plat_from_dns64_hostname;
-  int use_dynamic_iid;
-};
-
-extern struct clat_config Global_Clatd_Config;
-
-int read_config(const char *file, const char *uplink_interface, const char *plat_prefix,
-        unsigned net_id);
-void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip);
-in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen);
-int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2);
-
-typedef int (*addr_free_func)(in_addr_t addr);
-
-#endif /* __CONFIG_H__ */
diff --git a/debug.h b/debug.h
deleted file mode 100644 (file)
index 8e09672..0000000
--- a/debug.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * debug.h - debug settings
- */
-#ifndef __DEBUG_H__
-#define __DEBUG_H__
-
-// set to 1 to enable debug logging and packet dumping.
-#define CLAT_DEBUG 0
-
-#endif /* __DEBUG_H__ */
diff --git a/dns64.c b/dns64.c
deleted file mode 100644 (file)
index 4e9252d..0000000
--- a/dns64.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * dns64.c - find the nat64 prefix with a dns64 lookup
- */
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <strings.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "dns64.h"
-#include "logging.h"
-#include "resolv_netid.h"
-
-/* function: plat_prefix
- * looks up an ipv4-only hostname and looks for a nat64 /96 prefix, returns 1 on success, 0 on failure
- * ipv4_name  - name to lookup
- * net_id     - (optional) netId to use, NETID_UNSET indicates use of default network
- * prefix     - the plat /96 prefix
- */
-int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix) {
-  const struct addrinfo hints = {
-    .ai_family = AF_INET6,
-  };
-  int status;
-  struct addrinfo *result = NULL;
-  struct in6_addr plat_addr;
-  char plat_addr_str[INET6_ADDRSTRLEN];
-
-  logmsg(ANDROID_LOG_INFO, "Detecting NAT64 prefix from DNS...");
-
-  status = android_getaddrinfofornet(ipv4_name, NULL, &hints, net_id, MARK_UNSET, &result);
-  if (status != 0 || result == NULL) {
-    logmsg(ANDROID_LOG_ERROR, "plat_prefix/dns(%s) status = %d/%s",
-           ipv4_name, status, gai_strerror(status));
-    return 0;
-  }
-
-  // Use only the first result.  If other records are present, possibly with
-  // differing DNS64 prefixes they are ignored (there is very little sensible
-  // that could be done with them at this time anyway).
-
-  if (result->ai_family != AF_INET6) {
-    logmsg(ANDROID_LOG_WARN, "plat_prefix/unexpected address family: %d", result->ai_family);
-    return 0;
-  }
-  plat_addr = ((struct sockaddr_in6 *)result->ai_addr)->sin6_addr;
-  // Only /96 DNS64 prefixes are supported at this time.
-  plat_addr.s6_addr32[3] = 0;
-  freeaddrinfo(result);
-
-  logmsg(ANDROID_LOG_INFO, "Detected NAT64 prefix %s/96",
-         inet_ntop(AF_INET6, &plat_addr, plat_addr_str, sizeof(plat_addr_str)));
-  *prefix = plat_addr;
-  return 1;
-}
diff --git a/dns64.h b/dns64.h
deleted file mode 100644 (file)
index f5eaea8..0000000
--- a/dns64.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * dns64.h - find the nat64 prefix with a dns64 lookup
- */
-#ifndef __DNS64_H__
-#define __DNS64_H__
-
-int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix);
-
-#endif
diff --git a/dump.c b/dump.c
deleted file mode 100644 (file)
index 27b75d1..0000000
--- a/dump.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * dump.c - print various headers for debugging
- */
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/udp.h>
-#include <netinet/tcp.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <linux/icmp.h>
-
-#include "debug.h"
-#include "checksum.h"
-#include "clatd.h"
-#include "logging.h"
-
-#if CLAT_DEBUG
-
-/* print ip header */
-void dump_ip(struct iphdr *header) {
-  u_int16_t frag_flags;
-  char addrstr[INET6_ADDRSTRLEN];
-
-  frag_flags = ntohs(header->frag_off);
-
-  printf("IP packet\n");
-  printf("header_len = %x\n",header->ihl);
-  printf("version = %x\n",header->version);
-  printf("tos = %x\n",header->tos);
-  printf("tot_len = %x\n",ntohs(header->tot_len));
-  printf("id = %x\n",ntohs(header->id));
-  printf("frag: ");
-  if(frag_flags & IP_RF) {
-    printf("(RF) ");
-  }
-  if(frag_flags & IP_DF) {
-    printf("DF ");
-  }
-  if(frag_flags & IP_MF) {
-    printf("MF ");
-  }
-  printf("offset = %x\n",frag_flags & IP_OFFMASK);
-  printf("ttl = %x\n",header->ttl);
-  printf("protocol = %x\n",header->protocol);
-  printf("checksum = %x\n",ntohs(header->check));
-  inet_ntop(AF_INET, &header->saddr, addrstr, sizeof(addrstr));
-  printf("saddr = %s\n",addrstr);
-  inet_ntop(AF_INET, &header->daddr, addrstr, sizeof(addrstr));
-  printf("daddr = %s\n",addrstr);
-}
-
-/* print ip6 header */
-void dump_ip6(struct ip6_hdr *header) {
-  char addrstr[INET6_ADDRSTRLEN];
-
-  printf("ipv6\n");
-  printf("version = %x\n",header->ip6_vfc >> 4);
-  printf("traffic class = %x\n",header->ip6_flow >> 20);
-  printf("flow label = %x\n",ntohl(header->ip6_flow & 0x000fffff));
-  printf("payload len = %x\n",ntohs(header->ip6_plen));
-  printf("next header = %x\n",header->ip6_nxt);
-  printf("hop limit = %x\n",header->ip6_hlim);
-
-  inet_ntop(AF_INET6, &header->ip6_src, addrstr, sizeof(addrstr));
-  printf("source = %s\n",addrstr);
-
-  inet_ntop(AF_INET6, &header->ip6_dst, addrstr, sizeof(addrstr));
-  printf("dest = %s\n",addrstr);
-}
-
-/* print icmp header */
-void dump_icmp(struct icmphdr *icmp) {
-  printf("ICMP\n");
-
-  printf("icmp.type = %x ",icmp->type);
-  if(icmp->type == ICMP_ECHOREPLY) {
-    printf("echo reply");
-  } else if(icmp->type == ICMP_ECHO) {
-    printf("echo request");
-  } else {
-    printf("other");
-  }
-  printf("\n");
-  printf("icmp.code = %x\n",icmp->code);
-  printf("icmp.checksum = %x\n",ntohs(icmp->checksum));
-  if(icmp->type == ICMP_ECHOREPLY || icmp->type == ICMP_ECHO) {
-    printf("icmp.un.echo.id = %x\n",ntohs(icmp->un.echo.id));
-    printf("icmp.un.echo.sequence = %x\n",ntohs(icmp->un.echo.sequence));
-  }
-}
-
-/* print icmp6 header */
-void dump_icmp6(struct icmp6_hdr *icmp6) {
-  printf("ICMP6\n");
-  printf("type = %x",icmp6->icmp6_type);
-  if(icmp6->icmp6_type == ICMP6_ECHO_REQUEST) {
-    printf("(echo request)");
-  } else if(icmp6->icmp6_type == ICMP6_ECHO_REPLY) {
-    printf("(echo reply)");
-  }
-  printf("\n");
-  printf("code = %x\n",icmp6->icmp6_code);
-
-  printf("checksum = %x\n",icmp6->icmp6_cksum);
-
-  if((icmp6->icmp6_type == ICMP6_ECHO_REQUEST) || (icmp6->icmp6_type == ICMP6_ECHO_REPLY)) {
-    printf("icmp6_id = %x\n",icmp6->icmp6_id);
-    printf("icmp6_seq = %x\n",icmp6->icmp6_seq);
-  }
-}
-
-/* print udp header */
-void dump_udp_generic(const struct udphdr *udp, uint32_t temp_checksum,
-                      const uint8_t *payload, size_t payload_size) {
-  uint16_t my_checksum;
-
-  temp_checksum = ip_checksum_add(temp_checksum, udp, sizeof(struct udphdr));
-  temp_checksum = ip_checksum_add(temp_checksum, payload, payload_size);
-  my_checksum = ip_checksum_finish(temp_checksum);
-
-  printf("UDP\n");
-  printf("source = %x\n",ntohs(udp->source));
-  printf("dest = %x\n",ntohs(udp->dest));
-  printf("len = %x\n",ntohs(udp->len));
-  printf("check = %x (mine %x)\n",udp->check,my_checksum);
-}
-
-/* print ipv4/udp header */
-void dump_udp(const struct udphdr *udp, const struct iphdr *ip,
-              const uint8_t *payload, size_t payload_size) {
-  uint32_t temp_checksum;
-  temp_checksum = ipv4_pseudo_header_checksum(ip, sizeof(*udp) + payload_size);
-  dump_udp_generic(udp, temp_checksum, payload, payload_size);
-}
-
-/* print ipv6/udp header */
-void dump_udp6(const struct udphdr *udp, const struct ip6_hdr *ip6,
-               const uint8_t *payload, size_t payload_size) {
-  uint32_t temp_checksum;
-  temp_checksum = ipv6_pseudo_header_checksum(ip6, sizeof(*udp) + payload_size, IPPROTO_UDP);
-  dump_udp_generic(udp, temp_checksum, payload, payload_size);
-}
-
-/* print tcp header */
-void dump_tcp_generic(const struct tcphdr *tcp, const uint8_t *options, size_t options_size, uint32_t temp_checksum, const uint8_t *payload, size_t payload_size) {
-  uint16_t my_checksum;
-
-  temp_checksum = ip_checksum_add(temp_checksum, tcp, sizeof(struct tcphdr));
-  if(options) {
-    temp_checksum = ip_checksum_add(temp_checksum, options, options_size);
-  }
-  temp_checksum = ip_checksum_add(temp_checksum, payload, payload_size);
-  my_checksum = ip_checksum_finish(temp_checksum);
-
-  printf("TCP\n");
-  printf("source = %x\n",ntohs(tcp->source));
-  printf("dest = %x\n",ntohs(tcp->dest));
-  printf("seq = %x\n",ntohl(tcp->seq));
-  printf("ack = %x\n",ntohl(tcp->ack_seq));
-  printf("d_off = %x\n",tcp->doff);
-  printf("res1 = %x\n",tcp->res1);
-#ifdef __BIONIC__
-  printf("CWR = %x\n",tcp->cwr);
-  printf("ECE = %x\n",tcp->ece);
-#else
-  printf("CWR/ECE = %x\n",tcp->res2);
-#endif
-  printf("urg = %x  ack = %x  psh = %x  rst = %x  syn = %x  fin = %x\n",
-      tcp->urg, tcp->ack, tcp->psh, tcp->rst, tcp->syn, tcp->fin);
-  printf("window = %x\n",ntohs(tcp->window));
-  printf("check = %x [mine %x]\n",tcp->check,my_checksum);
-  printf("urgent = %x\n",tcp->urg_ptr);
-
-  if(options) {
-    size_t i;
-
-    printf("options: ");
-    for(i=0; i<options_size; i++) {
-      printf("%x ",*(options+i));
-    }
-    printf("\n");
-  }
-}
-
-/* print ipv4/tcp header */
-void dump_tcp(const struct tcphdr *tcp, const struct iphdr *ip,
-              const uint8_t *payload, size_t payload_size,
-              const uint8_t *options, size_t options_size) {
-  uint32_t temp_checksum;
-
-  temp_checksum = ipv4_pseudo_header_checksum(ip, sizeof(*tcp) + options_size + payload_size);
-  dump_tcp_generic(tcp, options, options_size, temp_checksum, payload, payload_size);
-}
-
-/* print ipv6/tcp header */
-void dump_tcp6(const struct tcphdr *tcp, const struct ip6_hdr *ip6,
-               const uint8_t *payload, size_t payload_size,
-               const uint8_t *options, size_t options_size) {
-  uint32_t temp_checksum;
-
-  temp_checksum = ipv6_pseudo_header_checksum(ip6, sizeof(*tcp) + options_size + payload_size, IPPROTO_TCP);
-  dump_tcp_generic(tcp, options, options_size, temp_checksum, payload, payload_size);
-}
-
-/* generic hex dump */
-void logcat_hexdump(const char *info, const uint8_t *data, size_t len) {
-  char output[PACKETLEN*3+2];
-  size_t i;
-
-  output[0] = '\0';
-  for(i = 0; i < len && i < PACKETLEN; i++) {
-    snprintf(output + i*3, 4, " %02x", data[i]);
-  }
-  output[len*3+3] = '\0';
-
-  logmsg(ANDROID_LOG_WARN,"info %s len %d data%s", info, len, output);
-}
-
-void dump_iovec(const struct iovec *iov, int iov_len) {
-  int i;
-  char *str;
-  for (i = 0; i < iov_len; i++) {
-    asprintf(&str, "iov[%d]: ", i);
-    logcat_hexdump(str, iov[i].iov_base, iov[i].iov_len);
-    free(str);
-  }
-}
-#endif  // CLAT_DEBUG
diff --git a/dump.h b/dump.h
deleted file mode 100644 (file)
index bb41b3b..0000000
--- a/dump.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * dump.h - debug functions
- */
-#ifndef __DUMP_H__
-#define __DUMP_H__
-
-void dump_ip(struct iphdr *header);
-void dump_icmp(struct icmphdr *icmp);
-void dump_udp(const struct udphdr *udp, const struct iphdr *ip,
-              const uint8_t *payload, size_t payload_size);
-void dump_tcp(const struct tcphdr *tcp, const struct iphdr *ip,
-              const uint8_t *payload, size_t payload_size,
-              const char *options, size_t options_size);
-
-void dump_ip6(struct ip6_hdr *header);
-void dump_icmp6(struct icmp6_hdr *icmp6);
-void dump_udp6(const struct udphdr *udp, const struct ip6_hdr *ip6,
-               const uint8_t *payload, size_t payload_size);
-void dump_tcp6(const struct tcphdr *tcp, const struct ip6_hdr *ip6,
-               const uint8_t *payload, size_t payload_size,
-               const char *options, size_t options_size);
-
-void logcat_hexdump(const char *info, const uint8_t *data, size_t len);
-void dump_iovec(const struct iovec *iov, int iov_len);
-
-#endif /* __DUMP_H__ */
diff --git a/getaddr.c b/getaddr.c
deleted file mode 100644 (file)
index 5cae78b..0000000
--- a/getaddr.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2012 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * getaddr.c - get a locally configured address
- */
-#include <netinet/in.h>
-#include <strings.h>
-#include <string.h>
-#include <net/if.h>
-
-#include <linux/rtnetlink.h>
-#include <netlink/handlers.h>
-#include <netlink/msg.h>
-
-#include "getaddr.h"
-#include "netlink_msg.h"
-#include "logging.h"
-
-// shared state between getinterface_ip and getaddr_cb
-struct target {
-  int family;
-  unsigned int ifindex;
-  union anyip ip;
-  int foundip;
-};
-
-/* function: getaddr_cb
- * callback for getinterface_ip
- * msg  - netlink message
- * data - (struct target) info for which address we're looking for
- */
-static int getaddr_cb(struct nl_msg *msg, void *data) {
-  struct ifaddrmsg *ifa_p;
-  struct rtattr *rta_p;
-  int rta_len;
-  struct target *targ_p = (struct target *)data;
-
-  ifa_p = (struct ifaddrmsg *)nlmsg_data(nlmsg_hdr(msg));
-  rta_p = (struct rtattr *)IFA_RTA(ifa_p);
-
-  if(ifa_p->ifa_index != targ_p->ifindex)
-    return NL_OK;
-
-  if(ifa_p->ifa_scope != RT_SCOPE_UNIVERSE)
-    return NL_OK;
-
-  rta_len = RTM_PAYLOAD(nlmsg_hdr(msg));
-  for (; RTA_OK(rta_p, rta_len); rta_p = RTA_NEXT(rta_p, rta_len)) {
-    switch(rta_p->rta_type) {
-      case IFA_ADDRESS:
-        if((targ_p->family == AF_INET6) && !(ifa_p->ifa_flags & IFA_F_SECONDARY)) {
-          memcpy(&targ_p->ip.ip6, RTA_DATA(rta_p), rta_p->rta_len - sizeof(struct rtattr));
-          targ_p->foundip = 1;
-          return NL_OK;
-        }
-        break;
-      case IFA_LOCAL:
-        if(targ_p->family == AF_INET) {
-          memcpy(&targ_p->ip.ip4, RTA_DATA(rta_p), rta_p->rta_len - sizeof(struct rtattr));
-          targ_p->foundip = 1;
-          return NL_OK;
-        }
-        break;
-    }
-  }
-
-  return NL_OK;
-}
-
-/* function: error_handler
- * error callback for getinterface_ip
- * nla  - source of the error message
- * err  - netlink message
- * arg  - (struct target) info for which address we're looking for
- */
-static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla,
-                         __attribute__((unused)) struct nlmsgerr *err,
-                         __attribute__((unused)) void *arg) {
-  return NL_OK;
-}
-
-/* function: getinterface_ip
- * finds the first global non-privacy IP of the given family for the given interface, or returns NULL.  caller frees pointer
- * interface - interface to look for
- * family    - family
- */
-union anyip *getinterface_ip(const char *interface, int family) {
-  struct ifaddrmsg ifa;
-  struct nl_cb *callbacks = NULL;
-  struct target targ;
-  union anyip *retval = NULL;
-
-  targ.family = family;
-  targ.foundip = 0;
-  targ.ifindex = if_nametoindex(interface);
-  if(targ.ifindex == 0) {
-    return NULL; // interface not found
-  }
-
-  memset(&ifa, 0, sizeof(ifa));
-  ifa.ifa_family = targ.family;
-
-  callbacks = nl_cb_alloc(NL_CB_DEFAULT);
-  if(!callbacks) {
-    goto cleanup;
-  }
-  nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, getaddr_cb, &targ);
-  nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, &targ);
-
-  // sends message and waits for a response
-  send_ifaddrmsg(RTM_GETADDR, NLM_F_REQUEST | NLM_F_ROOT, &ifa, callbacks);
-
-  if(targ.foundip) {
-    retval = malloc(sizeof(union anyip));
-    if(!retval) {
-      logmsg(ANDROID_LOG_FATAL,"getinterface_ip/out of memory");
-      goto cleanup;
-    }
-    memcpy(retval, &targ.ip, sizeof(union anyip));
-  }
-
-cleanup:
-  if(callbacks)
-    nl_cb_put(callbacks);
-
-  return retval;
-}
diff --git a/getaddr.h b/getaddr.h
deleted file mode 100644 (file)
index 5718e62..0000000
--- a/getaddr.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * getaddr.h - get a locally configured address
- */
-#ifndef __GETADDR_H__
-#define __GETADDR_H__
-
-union anyip {
-  struct in6_addr ip6;
-  struct in_addr ip4;
-};
-
-union anyip *getinterface_ip(const char *interface, int family);
-
-#endif
diff --git a/icmp.c b/icmp.c
deleted file mode 100644 (file)
index 75a4a4d..0000000
--- a/icmp.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * icmp.c - convenience functions for translating ICMP and ICMPv6 packets.
- */
-
-#include <netinet/in.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/icmp6.h>
-#include <linux/icmp.h>
-
-#include "logging.h"
-#include "icmp.h"
-
-/* function: icmp_guess_ttl
- * Guesses the number of hops a received packet has traversed based on its TTL.
- * ttl - the ttl of the received packet.
- */
-uint8_t icmp_guess_ttl(uint8_t ttl) {
-  if (ttl > 128) {
-    return 255 - ttl;
-  } else if (ttl > 64) {
-    return 128 - ttl;
-  } else if (ttl > 32) {
-    return 64 - ttl;
-  } else {
-    return 32 - ttl;
-  }
-}
-
-/* function: is_icmp_error
- * Determines whether an ICMP type is an error message.
- * type: the ICMP type
- */
-int is_icmp_error(uint8_t type) {
-  return type == 3 || type == 11 || type == 12;
-}
-
-/* function: is_icmp6_error
- * Determines whether an ICMPv6 type is an error message.
- * type: the ICMPv6 type
- */
-int is_icmp6_error(uint8_t type) {
-  return type < 128;
-}
-
-/* function: icmp_to_icmp6_type
- * Maps ICMP types to ICMPv6 types. Partial implementation of RFC 6145, section 4.2.
- * type - the ICMPv6 type
- */
-uint8_t icmp_to_icmp6_type(uint8_t type, uint8_t code) {
-  switch (type) {
-    case ICMP_ECHO:
-      return ICMP6_ECHO_REQUEST;
-
-    case ICMP_ECHOREPLY:
-      return ICMP6_ECHO_REPLY;
-
-    case ICMP_TIME_EXCEEDED:
-      return ICMP6_TIME_EXCEEDED;
-
-    case ICMP_DEST_UNREACH:
-      // These two types need special translation which we don't support yet.
-      if (code != ICMP_UNREACH_PROTOCOL && code != ICMP_UNREACH_NEEDFRAG) {
-        return ICMP6_DST_UNREACH;
-      }
-  }
-
-  // We don't understand this ICMP type. Return parameter problem so the caller will bail out.
-  logmsg_dbg(ANDROID_LOG_DEBUG, "icmp_to_icmp6_type: unhandled ICMP type %d", type);
-  return ICMP6_PARAM_PROB;
-}
-
-/* function: icmp_to_icmp6_code
- * Maps ICMP codes to ICMPv6 codes. Partial implementation of RFC 6145, section 4.2.
- * type - the ICMP type
- * code - the ICMP code
- */
-uint8_t icmp_to_icmp6_code(uint8_t type, uint8_t code) {
-  switch (type) {
-    case ICMP_ECHO:
-    case ICMP_ECHOREPLY:
-      return 0;
-
-    case ICMP_TIME_EXCEEDED:
-      return code;
-
-    case ICMP_DEST_UNREACH:
-      switch (code) {
-        case ICMP_UNREACH_NET:
-        case ICMP_UNREACH_HOST:
-          return ICMP6_DST_UNREACH_NOROUTE;
-
-        case ICMP_UNREACH_PORT:
-          return ICMP6_DST_UNREACH_NOPORT;
-
-        case ICMP_UNREACH_NET_PROHIB:
-        case ICMP_UNREACH_HOST_PROHIB:
-        case ICMP_UNREACH_FILTER_PROHIB:
-        case ICMP_UNREACH_PRECEDENCE_CUTOFF:
-          return ICMP6_DST_UNREACH_ADMIN;
-
-        // Otherwise, we don't understand this ICMP type/code combination. Fall through.
-      }
-  }
-  logmsg_dbg(ANDROID_LOG_DEBUG, "icmp_to_icmp6_code: unhandled ICMP type/code %d/%d", type, code);
-  return 0;
-}
-
-/* function: icmp6_to_icmp_type
- * Maps ICMPv6 types to ICMP types. Partial implementation of RFC 6145, section 5.2.
- * type - the ICMP type
- */
-uint8_t icmp6_to_icmp_type(uint8_t type, uint8_t code) {
-  switch (type) {
-    case ICMP6_ECHO_REQUEST:
-      return ICMP_ECHO;
-
-    case ICMP6_ECHO_REPLY:
-      return ICMP_ECHOREPLY;
-
-    case ICMP6_DST_UNREACH:
-      return ICMP_DEST_UNREACH;
-
-    case ICMP6_TIME_EXCEEDED:
-      return ICMP_TIME_EXCEEDED;
-  }
-
-  // We don't understand this ICMP type. Return parameter problem so the caller will bail out.
-  logmsg_dbg(ANDROID_LOG_DEBUG, "icmp6_to_icmp_type: unhandled ICMP type/code %d/%d", type, code);
-  return ICMP_PARAMETERPROB;
-}
-
-/* function: icmp6_to_icmp_code
- * Maps ICMPv6 codes to ICMP codes. Partial implementation of RFC 6145, section 5.2.
- * type - the ICMPv6 type
- * code - the ICMPv6 code
- */
-uint8_t icmp6_to_icmp_code(uint8_t type, uint8_t code) {
-  switch (type) {
-    case ICMP6_ECHO_REQUEST:
-    case ICMP6_ECHO_REPLY:
-    case ICMP6_TIME_EXCEEDED:
-      return code;
-
-    case ICMP6_DST_UNREACH:
-      switch (code) {
-        case ICMP6_DST_UNREACH_NOROUTE:
-          return ICMP_UNREACH_HOST;
-
-        case ICMP6_DST_UNREACH_ADMIN:
-          return ICMP_UNREACH_HOST_PROHIB;
-
-        case ICMP6_DST_UNREACH_BEYONDSCOPE:
-          return ICMP_UNREACH_HOST;
-
-        case ICMP6_DST_UNREACH_ADDR:
-          return ICMP_HOST_UNREACH;
-
-        case ICMP6_DST_UNREACH_NOPORT:
-          return ICMP_UNREACH_PORT;
-
-        // Otherwise, we don't understand this ICMPv6 type/code combination. Fall through.
-      }
-  }
-
-  logmsg_dbg(ANDROID_LOG_DEBUG, "icmp6_to_icmp_code: unhandled ICMP type/code %d/%d", type, code);
-  return 0;
-}
diff --git a/icmp.h b/icmp.h
deleted file mode 100644 (file)
index 632e92d..0000000
--- a/icmp.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * icmp.c - convenience functions for translating ICMP and ICMPv6 packets.
- */
-
-#ifndef __ICMP_H__
-#define __ICMP_H__
-
-#include <stdint.h>
-
-// Guesses the number of hops a received packet has traversed based on its TTL.
-uint8_t icmp_guess_ttl(uint8_t ttl);
-
-// Determines whether an ICMP type is an error message.
-int is_icmp_error(uint8_t type);
-
-// Determines whether an ICMPv6 type is an error message.
-int is_icmp6_error(uint8_t type);
-
-// Maps ICMP types to ICMPv6 types. Partial implementation of RFC 6145, section 4.2.
-uint8_t icmp_to_icmp6_type(uint8_t type, uint8_t code);
-
-// Maps ICMP codes to ICMPv6 codes. Partial implementation of RFC 6145, section 4.2.
-uint8_t icmp_to_icmp6_code(uint8_t type, uint8_t code);
-
-// Maps ICMPv6 types to ICMP types. Partial implementation of RFC 6145, section 5.2.
-uint8_t icmp6_to_icmp_type(uint8_t type, uint8_t code);
-
-// Maps ICMPv6 codes to ICMP codes. Partial implementation of RFC 6145, section 5.2.
-uint8_t icmp6_to_icmp_code(uint8_t type, uint8_t code);
-
-#endif /* __ICMP_H__ */
diff --git a/ipv4.c b/ipv4.c
deleted file mode 100644 (file)
index 4b0db39..0000000
--- a/ipv4.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ipv4.c - takes ipv4 packets, finds their headers, and then calls translation functions on them
- */
-#include <string.h>
-
-#include "translate.h"
-#include "checksum.h"
-#include "logging.h"
-#include "debug.h"
-#include "dump.h"
-
-/* function: icmp_packet
- * translates an icmp packet
- * out      - output packet
- * icmp     - pointer to icmp header in packet
- * checksum - pseudo-header checksum
- * len      - size of ip payload
- * returns: the highest position in the output clat_packet that's filled in
- */
-int icmp_packet(clat_packet out, clat_packet_index pos, const struct icmphdr *icmp,
-                uint32_t checksum, size_t len) {
-  const uint8_t *payload;
-  size_t payload_size;
-
-  if(len < sizeof(struct icmphdr)) {
-    logmsg_dbg(ANDROID_LOG_ERROR, "icmp_packet/(too small)");
-    return 0;
-  }
-
-  payload = (const uint8_t *) (icmp + 1);
-  payload_size = len - sizeof(struct icmphdr);
-
-  return icmp_to_icmp6(out, pos, icmp, checksum, payload, payload_size);
-}
-
-/* function: ipv4_packet
- * translates an ipv4 packet
- * out    - output packet
- * packet - packet data
- * len    - size of packet
- * returns: the highest position in the output clat_packet that's filled in
- */
-int ipv4_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, size_t len) {
-  const struct iphdr *header = (struct iphdr *) packet;
-  struct ip6_hdr *ip6_targ = (struct ip6_hdr *) out[pos].iov_base;
-  struct ip6_frag *frag_hdr;
-  size_t frag_hdr_len;
-  uint8_t nxthdr;
-  const uint8_t *next_header;
-  size_t len_left;
-  uint32_t old_sum, new_sum;
-  int iov_len;
-
-  if(len < sizeof(struct iphdr)) {
-    logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/too short for an ip header");
-    return 0;
-  }
-
-  if(header->ihl < 5) {
-    logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/ip header length set to less than 5: %x", header->ihl);
-    return 0;
-  }
-
-  if((size_t) header->ihl * 4 > len) { // ip header length larger than entire packet
-    logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/ip header length set too large: %x", header->ihl);
-    return 0;
-  }
-
-  if(header->version != 4) {
-    logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/ip header version not 4: %x", header->version);
-    return 0;
-  }
-
-  /* rfc6145 - If any IPv4 options are present in the IPv4 packet, they MUST be
-   * ignored and the packet translated normally; there is no attempt to
-   * translate the options.
-   */
-
-  next_header = packet + header->ihl*4;
-  len_left = len - header->ihl * 4;
-
-  nxthdr = header->protocol;
-  if (nxthdr == IPPROTO_ICMP) {
-    // ICMP and ICMPv6 have different protocol numbers.
-    nxthdr = IPPROTO_ICMPV6;
-  }
-
-  /* Fill in the IPv6 header. We need to do this before we translate the packet because TCP and
-   * UDP include parts of the IP header in the checksum. Set the length to zero because we don't
-   * know it yet.
-   */
-  fill_ip6_header(ip6_targ, 0, nxthdr, header);
-  out[pos].iov_len = sizeof(struct ip6_hdr);
-
-  /* Calculate the pseudo-header checksum.
-   * Technically, the length that is used in the pseudo-header checksum is the transport layer
-   * length, which is not the same as len_left in the case of fragmented packets. But since
-   * translation does not change the transport layer length, the checksum is unaffected.
-   */
-  old_sum = ipv4_pseudo_header_checksum(header, len_left);
-  new_sum = ipv6_pseudo_header_checksum(ip6_targ, len_left, nxthdr);
-
-  // If the IPv4 packet is fragmented, add a Fragment header.
-  frag_hdr = (struct ip6_frag *) out[pos + 1].iov_base;
-  frag_hdr_len = maybe_fill_frag_header(frag_hdr, ip6_targ, header);
-  out[pos + 1].iov_len = frag_hdr_len;
-
-  if (frag_hdr_len && frag_hdr->ip6f_offlg & IP6F_OFF_MASK) {
-    // Non-first fragment. Copy the rest of the packet as is.
-    iov_len = generic_packet(out, pos + 2, next_header, len_left);
-  } else if (nxthdr == IPPROTO_ICMPV6) {
-    iov_len = icmp_packet(out, pos + 2, (const struct icmphdr *) next_header, new_sum, len_left);
-  } else if (nxthdr == IPPROTO_TCP) {
-    iov_len = tcp_packet(out, pos + 2, (const struct tcphdr *) next_header, old_sum, new_sum,
-                         len_left);
-  } else if (nxthdr == IPPROTO_UDP) {
-    iov_len = udp_packet(out, pos + 2, (const struct udphdr *) next_header, old_sum, new_sum,
-                         len_left);
-  } else if (nxthdr == IPPROTO_GRE) {
-    iov_len = generic_packet(out, pos + 2, next_header, len_left);
-  } else {
-#if CLAT_DEBUG
-    logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/unknown protocol: %x",header->protocol);
-    logcat_hexdump("ipv4/protocol", packet, len);
-#endif
-    return 0;
-  }
-
-  // Set the length.
-  ip6_targ->ip6_plen = htons(packet_length(out, pos));
-  return iov_len;
-}
diff --git a/ipv6.c b/ipv6.c
deleted file mode 100644 (file)
index b485313..0000000
--- a/ipv6.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ipv6.c - takes ipv6 packets, finds their headers, and then calls translation functions on them
- */
-#include <string.h>
-
-#include <arpa/inet.h>
-
-#include "translate.h"
-#include "checksum.h"
-#include "logging.h"
-#include "dump.h"
-#include "config.h"
-#include "debug.h"
-
-/* function: icmp6_packet
- * takes an icmp6 packet and sets it up for translation
- * out      - output packet
- * icmp6    - pointer to icmp6 header in packet
- * checksum - pseudo-header checksum (unused)
- * len      - size of ip payload
- * returns: the highest position in the output clat_packet that's filled in
- */
-int icmp6_packet(clat_packet out, clat_packet_index pos, const struct icmp6_hdr *icmp6,
-                 size_t len) {
-  const uint8_t *payload;
-  size_t payload_size;
-
-  if(len < sizeof(struct icmp6_hdr)) {
-    logmsg_dbg(ANDROID_LOG_ERROR, "icmp6_packet/(too small)");
-    return 0;
-  }
-
-  payload = (const uint8_t *) (icmp6 + 1);
-  payload_size = len - sizeof(struct icmp6_hdr);
-
-  return icmp6_to_icmp(out, pos, icmp6, payload, payload_size);
-}
-
-/* function: log_bad_address
- * logs a bad address to android's log buffer if debugging is turned on
- * fmt     - printf-style format, use %s to place the address
- * badaddr - the bad address in question
- */
-#if CLAT_DEBUG
-void log_bad_address(const char *fmt, const struct in6_addr *src, const struct in6_addr *dst) {
-  char srcstr[INET6_ADDRSTRLEN];
-  char dststr[INET6_ADDRSTRLEN];
-
-  inet_ntop(AF_INET6, src, srcstr, sizeof(srcstr));
-  inet_ntop(AF_INET6, dst, dststr, sizeof(dststr));
-  logmsg_dbg(ANDROID_LOG_ERROR, fmt, srcstr, dststr);
-}
-#else
-#define log_bad_address(fmt, src, dst)
-#endif
-
-/* function: ipv6_packet
- * takes an ipv6 packet and hands it off to the layer 4 protocol function
- * out    - output packet
- * packet - packet data
- * len    - size of packet
- * returns: the highest position in the output clat_packet that's filled in
- */
-int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, size_t len) {
-  const struct ip6_hdr *ip6 = (struct ip6_hdr *) packet;
-  struct iphdr *ip_targ = (struct iphdr *) out[pos].iov_base;
-  struct ip6_frag *frag_hdr = NULL;
-  uint8_t protocol;
-  const uint8_t *next_header;
-  size_t len_left;
-  uint32_t old_sum, new_sum;
-  int iov_len;
-
-  if(len < sizeof(struct ip6_hdr)) {
-    logmsg_dbg(ANDROID_LOG_ERROR, "ipv6_packet/too short for an ip6 header: %d", len);
-    return 0;
-  }
-
-  if(IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
-    log_bad_address("ipv6_packet/multicast %s->%s", &ip6->ip6_src, &ip6->ip6_dst);
-    return 0; // silently ignore
-  }
-
-  // If the packet is not from the plat subnet to the local subnet, or vice versa, drop it, unless
-  // it's an ICMP packet (which can come from anywhere). We do not send IPv6 packets from the plat
-  // subnet to the local subnet, but these can appear as inner packets in ICMP errors, so we need
-  // to translate them. We accept third-party ICMPv6 errors, even though their source addresses
-  // cannot be translated, so that things like unreachables and traceroute will work. fill_ip_header
-  // takes care of faking a source address for them.
-  if (!(is_in_plat_subnet(&ip6->ip6_src) &&
-        IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &Global_Clatd_Config.ipv6_local_subnet)) &&
-      !(is_in_plat_subnet(&ip6->ip6_dst) &&
-        IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &Global_Clatd_Config.ipv6_local_subnet)) &&
-      ip6->ip6_nxt != IPPROTO_ICMPV6) {
-    log_bad_address("ipv6_packet/wrong source address: %s->%s", &ip6->ip6_src, &ip6->ip6_dst);
-    return 0;
-  }
-
-  next_header = packet + sizeof(struct ip6_hdr);
-  len_left = len - sizeof(struct ip6_hdr);
-
-  protocol = ip6->ip6_nxt;
-
-  /* Fill in the IPv4 header. We need to do this before we translate the packet because TCP and
-   * UDP include parts of the IP header in the checksum. Set the length to zero because we don't
-   * know it yet.
-   */
-  fill_ip_header(ip_targ, 0, protocol, ip6);
-  out[pos].iov_len = sizeof(struct iphdr);
-
-  // If there's a Fragment header, parse it and decide what the next header is.
-  // Do this before calculating the pseudo-header checksum because it updates the next header value.
-  if (protocol == IPPROTO_FRAGMENT) {
-    frag_hdr = (struct ip6_frag *) next_header;
-    if (len_left < sizeof(*frag_hdr)) {
-      logmsg_dbg(ANDROID_LOG_ERROR, "ipv6_packet/too short for fragment header: %d", len);
-      return 0;
-    }
-
-    next_header += sizeof(*frag_hdr);
-    len_left -= sizeof(*frag_hdr);
-
-    protocol = parse_frag_header(frag_hdr, ip_targ);
-  }
-
-  // ICMP and ICMPv6 have different protocol numbers.
-  if (protocol == IPPROTO_ICMPV6) {
-    protocol = IPPROTO_ICMP;
-    ip_targ->protocol = IPPROTO_ICMP;
-  }
-
-  /* Calculate the pseudo-header checksum.
-   * Technically, the length that is used in the pseudo-header checksum is the transport layer
-   * length, which is not the same as len_left in the case of fragmented packets. But since
-   * translation does not change the transport layer length, the checksum is unaffected.
-   */
-  old_sum = ipv6_pseudo_header_checksum(ip6, len_left, protocol);
-  new_sum = ipv4_pseudo_header_checksum(ip_targ, len_left);
-
-  // Does not support IPv6 extension headers except Fragment.
-  if (frag_hdr && (frag_hdr->ip6f_offlg & IP6F_OFF_MASK)) {
-    iov_len = generic_packet(out, pos + 2, next_header, len_left);
-  } else if (protocol == IPPROTO_ICMP) {
-    iov_len = icmp6_packet(out, pos + 2, (const struct icmp6_hdr *) next_header, len_left);
-  } else if (protocol == IPPROTO_TCP) {
-    iov_len = tcp_packet(out, pos + 2, (const struct tcphdr *) next_header, old_sum, new_sum,
-                         len_left);
-  } else if (protocol == IPPROTO_UDP) {
-    iov_len = udp_packet(out, pos + 2, (const struct udphdr *) next_header, old_sum, new_sum,
-                         len_left);
-  } else if (protocol == IPPROTO_GRE) {
-    iov_len = generic_packet(out, pos + 2, next_header, len_left);
-  } else {
-#if CLAT_DEBUG
-    logmsg(ANDROID_LOG_ERROR, "ipv6_packet/unknown next header type: %x", ip6->ip6_nxt);
-    logcat_hexdump("ipv6/nxthdr", packet, len);
-#endif
-    return 0;
-  }
-
-  // Set the length and calculate the checksum.
-  ip_targ->tot_len = htons(ntohs(ip_targ->tot_len) + packet_length(out, pos));
-  ip_targ->check = ip_checksum(ip_targ, sizeof(struct iphdr));
-  return iov_len;
-}
diff --git a/logging.c b/logging.c
deleted file mode 100644 (file)
index c90b1cf..0000000
--- a/logging.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * logging.c - print a log message
- */
-
-#include <stdarg.h>
-#include <android/log.h>
-
-#include "logging.h"
-#include "debug.h"
-
-/* function: logmsg
- * prints a log message to android's log buffer
- * prio - the log message priority
- * fmt  - printf format specifier
- * ...  - printf format arguments
- */
-void logmsg(int prio, const char *fmt, ...) {
-  va_list ap;
-
-  va_start(ap, fmt);
-  __android_log_vprint(prio, "clatd", fmt, ap);
-  va_end(ap);
-}
-
-/* function: logmsg_dbg
- * prints a log message to android's log buffer if CLAT_DEBUG is set
- * prio - the log message priority
- * fmt  - printf format specifier
- * ...  - printf format arguments
- */
-#if CLAT_DEBUG
-void logmsg_dbg(int prio, const char *fmt, ...) {
-  va_list ap;
-
-  va_start(ap, fmt);
-  __android_log_vprint(prio, "clatd", fmt, ap);
-  va_end(ap);
-}
-#else
-void logmsg_dbg(__attribute__((unused)) int prio, __attribute__((unused)) const char *fmt, ...) {}
-#endif
diff --git a/logging.h b/logging.h
deleted file mode 100644 (file)
index 1f4b6b6..0000000
--- a/logging.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * logging.h - print a log message
- */
-
-#ifndef __LOGGING_H__
-#define __LOGGING_H__
-// for the priorities
-#include <android/log.h>
-
-void logmsg(int prio, const char *fmt, ...);
-void logmsg_dbg(int prio, const char *fmt, ...);
-
-#endif
diff --git a/mtu.c b/mtu.c
deleted file mode 100644 (file)
index 975bf0e..0000000
--- a/mtu.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * mtu.c - get interface mtu
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-
-#include "mtu.h"
-
-/* function: getifmtu
- * returns the interface mtu or -1 on failure
- * ifname - interface name
- */
-int getifmtu(const char *ifname) {
-  int fd;
-  struct ifreq if_mtu;
-
-  fd = socket(AF_INET, SOCK_STREAM, 0);
-  if(fd < 0) {
-    return -1;
-  }
-  strncpy(if_mtu.ifr_name, ifname, IFNAMSIZ);
-  if_mtu.ifr_name[IFNAMSIZ - 1] = '\0';
-  if(ioctl(fd, SIOCGIFMTU, &if_mtu) < 0) {
-    return -1;
-  }
-  return if_mtu.ifr_mtu;
-}
diff --git a/mtu.h b/mtu.h
deleted file mode 100644 (file)
index c330c24..0000000
--- a/mtu.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * mtu.c - get interface mtu
- */
-
-#ifndef __MTU_H__
-#define __MTU_H__
-
-int getifmtu(const char *ifname);
-
-#endif
diff --git a/netlink_callbacks.c b/netlink_callbacks.c
deleted file mode 100644 (file)
index a79aa76..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2012 Daniel Drown <dan-android@drown.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * netlink_callbacks.c - generic callbacks for netlink responses
- */
-#include <netinet/in.h>
-#include <net/if.h>
-
-#include <linux/rtnetlink.h>
-#include <netlink/handlers.h>
-#include <netlink/msg.h>
-
-/* function: ack_handler
- * generic netlink callback for ack messages
- * msg  - netlink message
- * data - pointer to an int, stores the success code
- */
-static int ack_handler(__attribute__((unused)) struct nl_msg *msg, void *data) {
-  int *retval = data;
-  *retval = 0;
-  return NL_OK;
-}
-
-/* function: error_handler
- * generic netlink callback for error messages
- * nla  - error source
- * err  - netlink error message
- * arg  - pointer to an int, stores the error code
- */
-static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla,
-                         struct nlmsgerr *err, void *arg) {
-  int *retval = arg;
-  if(err->error < 0) {
-    *retval = err->error;
-  } else {
-    *retval = 0; // NLMSG_ERROR used as reply type on no error
-  }
-  return NL_OK;
-}
-
-/* function: alloc_ack_callbacks
- * allocates a set of netlink callbacks.  returns NULL on failure.  callbacks will modify retval with <0 meaning failure
- * retval - shared state between caller and callback functions
- */
-struct nl_cb *alloc_ack_callbacks(int *retval) {
-  struct nl_cb *callbacks;
-
-  callbacks = nl_cb_alloc(NL_CB_DEFAULT);
-  if(!callbacks) {
-    return NULL;
-  }
-  nl_cb_set(callbacks, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, retval);
-  nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, retval);
-  return callbacks;
-}
diff --git a/netlink_callbacks.h b/netlink_callbacks.h
deleted file mode 100644 (file)
index 298ad3e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2012 Daniel Drown <dan-android@drown.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * netlink_callbacks.h - callbacks for netlink responses
- */
-
-#ifndef __NETLINK_CALLBACKS_H__
-#define __NETLINK_CALLBACKS_H__
-
-struct nl_cb *alloc_ack_callbacks(int *retval);
-
-#endif
diff --git a/netlink_msg.c b/netlink_msg.c
deleted file mode 100644 (file)
index 958559c..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2012 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * netlink_msg.c - send an ifaddrmsg/ifinfomsg/rtmsg via netlink
- */
-
-#include <netinet/in.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <string.h>
-#include <errno.h>
-
-#include <netlink-local.h>
-#include <netlink-types.h>
-#include <netlink/socket.h>
-#include <netlink/netlink.h>
-#include <netlink/msg.h>
-
-#include "netlink_msg.h"
-#include "netlink_callbacks.h"
-
-/* function: family_size
- * returns the size of the address structure for the given family, or 0 on error
- * family - AF_INET or AF_INET6
- */
-size_t inet_family_size(int family) {
-  if(family == AF_INET) {
-    return sizeof(struct in_addr);
-  } else if(family == AF_INET6) {
-    return sizeof(struct in6_addr);
-  } else {
-    return 0;
-  }
-}
-
-/* function: nlmsg_alloc_generic
- * allocates a netlink message with the given struct inside of it. returns NULL on failure
- * type           - netlink message type
- * flags          - netlink message flags
- * payload_struct - pointer to a struct to add to netlink message
- * payload_len    - bytelength of structure
- */
-struct nl_msg *nlmsg_alloc_generic(uint16_t type, uint16_t flags, void *payload_struct, size_t payload_len) {
-  struct nl_msg *msg;
-
-  msg = nlmsg_alloc();
-  if(!msg) {
-    return NULL;
-  }
-
-  if ((sizeof(struct nl_msg) + payload_len) > msg->nm_size) {
-    nlmsg_free(msg);
-    return NULL;
-  }
-
-  msg->nm_nlh->nlmsg_len = NLMSG_LENGTH(payload_len);
-  msg->nm_nlh->nlmsg_flags = flags;
-  msg->nm_nlh->nlmsg_type = type;
-
-  memcpy(nlmsg_data(msg->nm_nlh), payload_struct, payload_len);
-
-  return msg;
-}
-
-/* function: nlmsg_alloc_ifaddr
- * allocates a netlink message with a struct ifaddrmsg inside of it. returns NULL on failure
- * type  - netlink message type
- * flags - netlink message flags
- * ifa   - ifaddrmsg to copy into the new netlink message
- */
-struct nl_msg *nlmsg_alloc_ifaddr(uint16_t type, uint16_t flags, struct ifaddrmsg *ifa) {
-  return nlmsg_alloc_generic(type, flags, ifa, sizeof(*ifa));
-}
-
-/* function: nlmsg_alloc_ifinfo
- * allocates a netlink message with a struct ifinfomsg inside of it. returns NULL on failure
- * type  - netlink message type
- * flags - netlink message flags
- * ifi   - ifinfomsg to copy into the new netlink message
- */
-struct nl_msg *nlmsg_alloc_ifinfo(uint16_t type, uint16_t flags, struct ifinfomsg *ifi) {
-  return nlmsg_alloc_generic(type, flags, ifi, sizeof(*ifi));
-}
-
-/* function: nlmsg_alloc_rtmsg
- * allocates a netlink message with a struct rtmsg inside of it. returns NULL on failure
- * type  - netlink message type
- * flags - netlink message flags
- * rt    - rtmsg to copy into the new netlink message
- */
-struct nl_msg *nlmsg_alloc_rtmsg(uint16_t type, uint16_t flags, struct rtmsg *rt) {
-  return nlmsg_alloc_generic(type, flags, rt, sizeof(*rt));
-}
-
-/* function: netlink_set_kernel_only
- * sets a socket to receive messages only from the kernel
- * sock - socket to connect
- */
-int netlink_set_kernel_only(struct nl_sock *nl_sk) {
-  struct sockaddr_nl addr = { AF_NETLINK, 0, 0, 0 };
-
-  if (!nl_sk) {
-    return -EFAULT;
-  }
-
-  int sockfd = nl_socket_get_fd(nl_sk);
-  return connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));
-}
-
-/* function: send_netlink_msg
- * sends a netlink message, reads a response, and hands the response(s) to the callbacks
- * msg       - netlink message to send
- * callbacks - callbacks to use on responses
- */
-void send_netlink_msg(struct nl_msg *msg, struct nl_cb *callbacks) {
-  struct nl_sock *nl_sk;
-
-  nl_sk = nl_socket_alloc();
-  if(!nl_sk)
-    goto cleanup;
-
-  if(nl_connect(nl_sk, NETLINK_ROUTE) != 0)
-    goto cleanup;
-
-  if(nl_send_auto_complete(nl_sk, msg) < 0)
-    goto cleanup;
-
-  if(netlink_set_kernel_only(nl_sk) < 0)
-    goto cleanup;
-
-  nl_recvmsgs(nl_sk, callbacks);
-
-cleanup:
-  if(nl_sk)
-    nl_socket_free(nl_sk);
-}
-
-/* function: send_ifaddrmsg
- * sends a netlink/ifaddrmsg message and hands the responses to the callbacks
- * type      - netlink message type
- * flags     - netlink message flags
- * ifa       - ifaddrmsg to send
- * callbacks - callbacks to use with the responses
- */
-void send_ifaddrmsg(uint16_t type, uint16_t flags, struct ifaddrmsg *ifa, struct nl_cb *callbacks) {
-  struct nl_msg *msg = NULL;
-
-  msg = nlmsg_alloc_ifaddr(type, flags, ifa);
-  if(!msg)
-    return;
-
-  send_netlink_msg(msg, callbacks);
-
-  nlmsg_free(msg);
-}
-
-/* function: netlink_sendrecv
- * send a nl_msg and return an int status - only supports OK/ERROR responses
- * msg - msg to send
- */
-int netlink_sendrecv(struct nl_msg *msg) {
-  struct nl_cb *callbacks = NULL;
-  int retval = -EIO;
-
-  callbacks = alloc_ack_callbacks(&retval);
-  if(!callbacks) {
-    return -ENOMEM;
-  }
-
-  send_netlink_msg(msg, callbacks);
-
-  nl_cb_put(callbacks);
-
-  return retval;
-}
diff --git a/netlink_msg.h b/netlink_msg.h
deleted file mode 100644 (file)
index 13e1f28..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2012 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * netlink_msg.h - send an ifaddrmsg/ifinfomsg via netlink
- */
-#ifndef __NETLINK_IFMSG_H__
-#define __NETLINK_IFMSG_H__
-
-size_t inet_family_size(int family);
-struct nl_msg *nlmsg_alloc_ifaddr(uint16_t type, uint16_t flags, struct ifaddrmsg *ifa);
-struct nl_msg *nlmsg_alloc_ifinfo(uint16_t type, uint16_t flags, struct ifinfomsg *ifi);
-struct nl_msg *nlmsg_alloc_rtmsg(uint16_t type, uint16_t flags, struct rtmsg *rt);
-void send_netlink_msg(struct nl_msg *msg, struct nl_cb *callbacks);
-void send_ifaddrmsg(uint16_t type, uint16_t flags, struct ifaddrmsg *ifa, struct nl_cb *callbacks);
-int netlink_sendrecv(struct nl_msg *msg);
-int netlink_set_kernel_only(struct nl_sock *nl_sk);
-
-#endif
diff --git a/ring.c b/ring.c
deleted file mode 100644 (file)
index 5e99fd5..0000000
--- a/ring.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ring.c - packet ring buffer functions
- */
-
-#include <errno.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <sys/mman.h>
-#include <linux/if.h>
-#include <linux/if_packet.h>
-
-#include "logging.h"
-#include "ring.h"
-#include "translate.h"
-#include "tun.h"
-
-int ring_create(struct tun_data *tunnel) {
-  int packetsock = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
-  if (packetsock < 0) {
-    logmsg(ANDROID_LOG_FATAL, "packet socket failed: %s", strerror(errno));
-    return -1;
-  }
-
-  int ver = TPACKET_V2;
-  if (setsockopt(packetsock, SOL_PACKET, PACKET_VERSION, (void *) &ver, sizeof(ver))) {
-    logmsg(ANDROID_LOG_FATAL, "setsockopt(PACKET_VERSION, %d) failed: %s", ver, strerror(errno));
-    return -1;
-  }
-
-  int on = 1;
-  if (setsockopt(packetsock, SOL_PACKET, PACKET_LOSS, (void *) &on, sizeof(on))) {
-    logmsg(ANDROID_LOG_WARN, "PACKET_LOSS failed: %s", strerror(errno));
-  }
-
-  struct packet_ring *ring = &tunnel->ring;
-  ring->numblocks = TP_NUM_BLOCKS;
-
-  int total_frames = TP_FRAMES * ring->numblocks;
-
-  struct tpacket_req req = {
-      .tp_frame_size = TP_FRAME_SIZE,  // Frame size.
-      .tp_block_size = TP_BLOCK_SIZE,  // Frames per block.
-      .tp_block_nr = ring->numblocks,  // Number of blocks.
-      .tp_frame_nr = total_frames,     // Total frames.
-  };
-
-  if (setsockopt(packetsock, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req)) < 0) {
-    logmsg(ANDROID_LOG_FATAL, "PACKET_RX_RING failed: %s", strerror(errno));
-    return -1;
-  }
-
-  size_t buflen = TP_BLOCK_SIZE * ring->numblocks;
-  ring->base = mmap(NULL, buflen, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED|MAP_POPULATE,
-                    packetsock, 0);
-  if (ring->base == MAP_FAILED) {
-    logmsg(ANDROID_LOG_FATAL, "mmap %lu failed: %s", buflen, strerror(errno));
-    return -1;
-  }
-
-  ring->block = 0;
-  ring->slot = 0;
-  ring->numslots = TP_BLOCK_SIZE / TP_FRAME_SIZE;
-  ring->next = (struct tpacket2_hdr *) ring->base;
-
-  logmsg(ANDROID_LOG_INFO, "Using ring buffer with %d frames (%d bytes) at %p",
-         total_frames, buflen, ring->base);
-
-  return packetsock;
-}
-
-/* function: ring_advance
- * advances to the next position in the packet ring
- * ring - packet ring buffer
- */
-static struct tpacket2_hdr* ring_advance(struct packet_ring *ring) {
-  uint8_t *next = (uint8_t *) ring->next;
-
-  ring->slot++;
-  next += TP_FRAME_SIZE;
-
-  if (ring->slot == ring->numslots) {
-    ring->slot = 0;
-    ring->block++;
-
-    if (ring->block < ring->numblocks) {
-      next += TP_FRAME_GAP;
-    } else {
-      ring->block = 0;
-      next = (uint8_t *) ring->base;
-    }
-  }
-
-  ring->next = (struct tpacket2_hdr *) next;
-  return ring->next;
-}
-
-/* function: ring_read
- * reads a packet from the ring buffer and translates it
- * read_fd  - file descriptor to read original packet from
- * write_fd - file descriptor to write translated packet to
- * to_ipv6  - whether the packet is to be translated to ipv6 or ipv4
- */
-void ring_read(struct packet_ring *ring, int write_fd, int to_ipv6) {
-  struct tpacket2_hdr *tp = ring->next;
-  if (tp->tp_status & TP_STATUS_USER) {
-    uint8_t *packet = ((uint8_t *) tp) + tp->tp_net;
-    translate_packet(write_fd, to_ipv6, packet, tp->tp_len);
-    tp->tp_status = TP_STATUS_KERNEL;
-    tp = ring_advance(ring);
-  }
-}
diff --git a/ring.h b/ring.h
deleted file mode 100644 (file)
index b9b8c11..0000000
--- a/ring.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ring.c - packet ring buffer functions
- */
-#ifndef __RING_H__
-#define __RING_H__
-
-#include <linux/if.h>
-#include <linux/if_packet.h>
-
-#include "clatd.h"
-
-struct tun_data;
-
-// Frame size. Must be a multiple of TPACKET_ALIGNMENT (=16)
-// Why the 16? http://lxr.free-electrons.com/source/net/packet/af_packet.c?v=3.4#L1764
-#define TP_FRAME_SIZE (TPACKET_ALIGN(MAXMTU) + TPACKET_ALIGN(TPACKET2_HDRLEN) + 16)
-
-// Block size. Must be a multiple of the page size, and a power of two for efficient memory use.
-#define TP_BLOCK_SIZE 65536
-
-// In order to save memory, our frames are not an exact divider of the block size. Therefore, the
-// mmaped region will have gaps corresponding to the empty space at the end of each block.
-#define TP_FRAMES (TP_BLOCK_SIZE / TP_FRAME_SIZE)
-#define TP_FRAME_GAP (TP_BLOCK_SIZE % TP_FRAME_SIZE)
-
-// TODO: Make this configurable. This requires some refactoring because the packet socket is
-// opened before we drop privileges, but the configuration file is read after. A value of 16
-// results in 656 frames (1048576 bytes).
-#define TP_NUM_BLOCKS 16
-
-struct packet_ring {
-  uint8_t *base;
-  struct tpacket2_hdr *next;
-  int slot, numslots;
-  int block, numblocks;
-};
-
-int ring_create(struct tun_data *tunnel);
-void ring_read(struct packet_ring *ring, int write_fd, int to_ipv6);
-
-#endif
diff --git a/setif.c b/setif.c
deleted file mode 100644 (file)
index 07f5bac..0000000
--- a/setif.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2012 Daniel Drown <dan-android@drown.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * setif.c - network interface configuration
- */
-#include <errno.h>
-#include <netinet/in.h>
-#include <net/if.h>
-
-#include <linux/rtnetlink.h>
-#include <netlink/handlers.h>
-#include <netlink/msg.h>
-
-#include "logging.h"
-#include "netlink_msg.h"
-
-#define DEBUG_OPTNAME(a) case (a): { optname = #a; break; }
-
-/* function: add_address
- * adds an IP address to/from an interface, returns 0 on success and <0 on failure
- * ifname    - name of interface to change
- * family    - address family (AF_INET, AF_INET6)
- * address   - pointer to a struct in_addr or in6_addr
- * prefixlen - bitlength of network (example: 24 for AF_INET's 255.255.255.0)
- * broadcast - broadcast address (only for AF_INET, ignored for AF_INET6)
- */
-int add_address(const char *ifname, int family, const void *address, int prefixlen, const void *broadcast) {
-  int retval;
-  size_t addr_size;
-  struct ifaddrmsg ifa;
-  struct nl_msg *msg = NULL;
-
-  addr_size = inet_family_size(family);
-  if(addr_size == 0) {
-    retval = -EAFNOSUPPORT;
-    goto cleanup;
-  }
-
-  memset(&ifa, 0, sizeof(ifa));
-  if (!(ifa.ifa_index = if_nametoindex(ifname))) {
-    retval = -ENODEV;
-    goto cleanup;
-  }
-  ifa.ifa_family = family;
-  ifa.ifa_prefixlen = prefixlen;
-  ifa.ifa_scope = RT_SCOPE_UNIVERSE;
-
-  msg = nlmsg_alloc_ifaddr(RTM_NEWADDR, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE, &ifa);
-  if(!msg) {
-    retval = -ENOMEM;
-    goto cleanup;
-  }
-
-  if(nla_put(msg, IFA_LOCAL, addr_size, address) < 0) {
-    retval = -ENOMEM;
-    goto cleanup;
-  }
-  if(family == AF_INET6) {
-    // AF_INET6 gets IFA_LOCAL + IFA_ADDRESS
-    if(nla_put(msg, IFA_ADDRESS, addr_size, address) < 0) {
-      retval = -ENOMEM;
-      goto cleanup;
-    }
-  } else if(family == AF_INET) {
-    // AF_INET gets IFA_LOCAL + IFA_BROADCAST
-    if(nla_put(msg, IFA_BROADCAST, addr_size, broadcast) < 0) {
-      retval = -ENOMEM;
-      goto cleanup;
-    }
-  } else {
-    retval = -EAFNOSUPPORT;
-    goto cleanup;
-  }
-
-  retval = netlink_sendrecv(msg);
-
-cleanup:
-  if(msg)
-    nlmsg_free(msg);
-
-  return retval;
-}
-
-/* function: if_up
- * sets interface link state to up and sets mtu, returns 0 on success and <0 on failure
- * ifname - interface name to change
- * mtu    - new mtu
- */
-int if_up(const char *ifname, int mtu) {
-  int retval = -1;
-  struct ifinfomsg ifi;
-  struct nl_msg *msg = NULL;
-
-  memset(&ifi, 0, sizeof(ifi));
-  if (!(ifi.ifi_index = if_nametoindex(ifname))) {
-    retval = -ENODEV;
-    goto cleanup;
-  }
-  ifi.ifi_change = IFF_UP;
-  ifi.ifi_flags = IFF_UP;
-
-  msg = nlmsg_alloc_ifinfo(RTM_SETLINK, NLM_F_ACK | NLM_F_REQUEST | NLM_F_ROOT, &ifi);
-  if(!msg) {
-    retval = -ENOMEM;
-    goto cleanup;
-  }
-
-  if(nla_put(msg, IFLA_MTU, 4, &mtu) < 0) {
-    retval = -ENOMEM;
-    goto cleanup;
-  }
-
-  retval = netlink_sendrecv(msg);
-
-cleanup:
-  if(msg)
-    nlmsg_free(msg);
-
-  return retval;
-}
-
-static int do_anycast_setsockopt(int sock, int what, struct in6_addr *addr, int ifindex) {
-  struct ipv6_mreq mreq = { *addr, ifindex };
-  char *optname;
-  int ret;
-
-  switch (what) {
-    DEBUG_OPTNAME(IPV6_JOIN_ANYCAST)
-    DEBUG_OPTNAME(IPV6_LEAVE_ANYCAST)
-    default:
-      optname = "???";
-      break;
-  }
-
-  ret = setsockopt(sock, SOL_IPV6, what, &mreq, sizeof(mreq));
-  if (ret) {
-    logmsg(ANDROID_LOG_ERROR, "%s: setsockopt(%s): %s", __func__, optname, strerror(errno));
-  }
-
-  return ret;
-}
-
-/* function: add_anycast_address
- * adds an anycast IPv6 address to an interface, returns 0 on success and <0 on failure
- * sock      - the socket to add the address to
- * addr      - the IP address to add
- * ifname    - name of interface to add the address to
- */
-int add_anycast_address(int sock, struct in6_addr *addr, const char *ifname) {
-  int ifindex;
-
-  ifindex = if_nametoindex(ifname);
-  if (!ifindex) {
-    logmsg(ANDROID_LOG_ERROR, "%s: unknown ifindex for interface %s", __func__, ifname);
-    return -ENODEV;
-  }
-
-  return do_anycast_setsockopt(sock, IPV6_JOIN_ANYCAST, addr, ifindex);
-}
-
-/* function: del_anycast_address
- * removes an anycast IPv6 address from the system, returns 0 on success and <0 on failure
- * sock      - the socket to remove from, must have had the address added via add_anycast_address
- * addr      - the IP address to remove
- */
-int del_anycast_address(int sock, struct in6_addr *addr) {
-  return do_anycast_setsockopt(sock, IPV6_LEAVE_ANYCAST, addr, 0);
-}
diff --git a/setif.h b/setif.h
deleted file mode 100644 (file)
index d31eed5..0000000
--- a/setif.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2012 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * setif.h - network interface configuration
- */
-#ifndef __SETIF_H__
-#define __SETIF_H__
-
-int add_address(const char *ifname, int family, const void *address, int cidr, const void *broadcast);
-int if_up(const char *ifname, int mtu);
-
-int add_anycast_address(int sock, const struct in6_addr *addr, const char *interface);
-int del_anycast_address(int sock, const struct in6_addr *addr);
-
-#endif
diff --git a/translate.c b/translate.c
deleted file mode 100644 (file)
index ddc9bac..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * translate.c - CLAT functions / partial implementation of rfc6145
- */
-#include <string.h>
-
-#include "icmp.h"
-#include "translate.h"
-#include "checksum.h"
-#include "clatd.h"
-#include "config.h"
-#include "logging.h"
-#include "debug.h"
-#include "tun.h"
-
-/* function: packet_checksum
- * calculates the checksum over all the packet components starting from pos
- * checksum - checksum of packet components before pos
- * packet   - packet to calculate the checksum of
- * pos      - position to start counting from
- * returns  - the completed 16-bit checksum, ready to write into a checksum header field
- */
-uint16_t packet_checksum(uint32_t checksum, clat_packet packet, clat_packet_index pos) {
-  int i;
-  for (i = pos; i < CLAT_POS_MAX; i++) {
-    if (packet[i].iov_len > 0) {
-      checksum = ip_checksum_add(checksum, packet[i].iov_base, packet[i].iov_len);
-    }
-  }
-  return ip_checksum_finish(checksum);
-}
-
-/* function: packet_length
- * returns the total length of all the packet components after pos
- * packet - packet to calculate the length of
- * pos    - position to start counting after
- * returns: the total length of the packet components after pos
- */
-uint16_t packet_length(clat_packet packet, clat_packet_index pos) {
-  size_t len = 0;
-  int i;
-  for (i = pos + 1; i < CLAT_POS_MAX; i++) {
-    len += packet[i].iov_len;
-  }
-  return len;
-}
-
-/* function: is_in_plat_subnet
- * returns true iff the given IPv6 address is in the plat subnet.
- * addr - IPv6 address
- */
-int is_in_plat_subnet(const struct in6_addr *addr6) {
-  // Assumes a /96 plat subnet.
-  return (addr6 != NULL) && (memcmp(addr6, &Global_Clatd_Config.plat_subnet, 12) == 0);
-}
-
-/* function: ipv6_addr_to_ipv4_addr
- * return the corresponding ipv4 address for the given ipv6 address
- * addr6 - ipv6 address
- * returns: the IPv4 address
- */
-uint32_t ipv6_addr_to_ipv4_addr(const struct in6_addr *addr6) {
-  if (is_in_plat_subnet(addr6)) {
-    // Assumes a /96 plat subnet.
-    return addr6->s6_addr32[3];
-  } else if (IN6_ARE_ADDR_EQUAL(addr6, &Global_Clatd_Config.ipv6_local_subnet)) {
-    // Special-case our own address.
-    return Global_Clatd_Config.ipv4_local_subnet.s_addr;
-  } else {
-    // Third party packet. Let the caller deal with it.
-    return INADDR_NONE;
-  }
-}
-
-/* function: ipv4_addr_to_ipv6_addr
- * return the corresponding ipv6 address for the given ipv4 address
- * addr4 - ipv4 address
- */
-struct in6_addr ipv4_addr_to_ipv6_addr(uint32_t addr4) {
-  struct in6_addr addr6;
-  // Both addresses are in network byte order (addr4 comes from a network packet, and the config
-  // file entry is read using inet_ntop).
-  if (addr4 == Global_Clatd_Config.ipv4_local_subnet.s_addr) {
-    return Global_Clatd_Config.ipv6_local_subnet;
-  } else {
-    // Assumes a /96 plat subnet.
-    addr6 = Global_Clatd_Config.plat_subnet;
-    addr6.s6_addr32[3] = addr4;
-    return addr6;
-  }
-}
-
-/* function: fill_tun_header
- * fill in the header for the tun fd
- * tun_header - tunnel header, already allocated
- * proto      - ethernet protocol id: ETH_P_IP(ipv4) or ETH_P_IPV6(ipv6)
- */
-void fill_tun_header(struct tun_pi *tun_header, uint16_t proto) {
-  tun_header->flags = 0;
-  tun_header->proto = htons(proto);
-}
-
-/* function: fill_ip_header
- * generate an ipv4 header from an ipv6 header
- * ip_targ     - (ipv4) target packet header, source: original ipv4 addr, dest: local subnet addr
- * payload_len - length of other data inside packet
- * protocol    - protocol number (tcp, udp, etc)
- * old_header  - (ipv6) source packet header, source: nat64 prefix, dest: local subnet prefix
- */
-void fill_ip_header(struct iphdr *ip, uint16_t payload_len, uint8_t protocol,
-                    const struct ip6_hdr *old_header) {
-  int ttl_guess;
-  memset(ip, 0, sizeof(struct iphdr));
-
-  ip->ihl = 5;
-  ip->version = 4;
-  ip->tos = 0;
-  ip->tot_len = htons(sizeof(struct iphdr) + payload_len);
-  ip->id = 0;
-  ip->frag_off = htons(IP_DF);
-  ip->ttl = old_header->ip6_hlim;
-  ip->protocol = protocol;
-  ip->check = 0;
-
-  ip->saddr = ipv6_addr_to_ipv4_addr(&old_header->ip6_src);
-  ip->daddr = ipv6_addr_to_ipv4_addr(&old_header->ip6_dst);
-
-  // Third-party ICMPv6 message. This may have been originated by an native IPv6 address.
-  // In that case, the source IPv6 address can't be translated and we need to make up an IPv4
-  // source address. For now, use 255.0.0.<ttl>, which at least looks useful in traceroute.
-  if ((uint32_t) ip->saddr == INADDR_NONE) {
-    ttl_guess = icmp_guess_ttl(old_header->ip6_hlim);
-    ip->saddr = htonl((0xff << 24) + ttl_guess);
-  }
-}
-
-/* function: fill_ip6_header
- * generate an ipv6 header from an ipv4 header
- * ip6         - (ipv6) target packet header, source: local subnet prefix, dest: nat64 prefix
- * payload_len - length of other data inside packet
- * protocol    - protocol number (tcp, udp, etc)
- * old_header  - (ipv4) source packet header, source: local subnet addr, dest: internet's ipv4 addr
- */
-void fill_ip6_header(struct ip6_hdr *ip6, uint16_t payload_len, uint8_t protocol,
-                     const struct iphdr *old_header) {
-  memset(ip6, 0, sizeof(struct ip6_hdr));
-
-  ip6->ip6_vfc = 6 << 4;
-  ip6->ip6_plen = htons(payload_len);
-  ip6->ip6_nxt = protocol;
-  ip6->ip6_hlim = old_header->ttl;
-
-  ip6->ip6_src = ipv4_addr_to_ipv6_addr(old_header->saddr);
-  ip6->ip6_dst = ipv4_addr_to_ipv6_addr(old_header->daddr);
-}
-
-/* function: maybe_fill_frag_header
- * fills a fragmentation header
- * generate an ipv6 fragment header from an ipv4 header
- * frag_hdr    - target (ipv6) fragmentation header
- * ip6_targ    - target (ipv6) header
- * old_header  - (ipv4) source packet header
- * returns: the length of the fragmentation header if present, or zero if not present
- */
-size_t maybe_fill_frag_header(struct ip6_frag *frag_hdr, struct ip6_hdr *ip6_targ,
-                              const struct iphdr *old_header) {
-  uint16_t frag_flags = ntohs(old_header->frag_off);
-  uint16_t frag_off = frag_flags & IP_OFFMASK;
-  if (frag_off == 0 && (frag_flags & IP_MF) == 0) {
-    // Not a fragment.
-    return 0;
-  }
-
-  frag_hdr->ip6f_nxt = ip6_targ->ip6_nxt;
-  frag_hdr->ip6f_reserved = 0;
-  // In IPv4, the offset is the bottom 13 bits; in IPv6 it's the top 13 bits.
-  frag_hdr->ip6f_offlg = htons(frag_off << 3);
-  if (frag_flags & IP_MF) {
-    frag_hdr->ip6f_offlg |= IP6F_MORE_FRAG;
-  }
-  frag_hdr->ip6f_ident = htonl(ntohs(old_header->id));
-  ip6_targ->ip6_nxt = IPPROTO_FRAGMENT;
-
-  return sizeof(*frag_hdr);
-}
-
-/* function: parse_frag_header
- * return the length of the fragmentation header if present, or zero if not present
- * generate an ipv6 fragment header from an ipv4 header
- * frag_hdr    - (ipv6) fragmentation header
- * ip_targ     - target (ipv4) header
- * returns: the next header value
- */
-uint8_t parse_frag_header(const struct ip6_frag *frag_hdr, struct iphdr *ip_targ) {
-  uint16_t frag_off = (ntohs(frag_hdr->ip6f_offlg & IP6F_OFF_MASK) >> 3);
-  if (frag_hdr->ip6f_offlg & IP6F_MORE_FRAG) {
-    frag_off |= IP_MF;
-  }
-  ip_targ->frag_off = htons(frag_off);
-  ip_targ->id = htons(ntohl(frag_hdr->ip6f_ident) & 0xffff);
-  ip_targ->protocol = frag_hdr->ip6f_nxt;
-  return frag_hdr->ip6f_nxt;
-}
-
-/* function: icmp_to_icmp6
- * translate ipv4 icmp to ipv6 icmp
- * out          - output packet
- * icmp         - source packet icmp header
- * checksum     - pseudo-header checksum
- * payload      - icmp payload
- * payload_size - size of payload
- * returns: the highest position in the output clat_packet that's filled in
- */
-int icmp_to_icmp6(clat_packet out, clat_packet_index pos, const struct icmphdr *icmp,
-                  uint32_t checksum, const uint8_t *payload, size_t payload_size) {
-  struct icmp6_hdr *icmp6_targ = out[pos].iov_base;
-  uint8_t icmp6_type;
-  int clat_packet_len;
-
-  memset(icmp6_targ, 0, sizeof(struct icmp6_hdr));
-
-  icmp6_type = icmp_to_icmp6_type(icmp->type, icmp->code);
-  icmp6_targ->icmp6_type = icmp6_type;
-  icmp6_targ->icmp6_code = icmp_to_icmp6_code(icmp->type, icmp->code);
-
-  out[pos].iov_len = sizeof(struct icmp6_hdr);
-
-  if (pos == CLAT_POS_TRANSPORTHDR &&
-      is_icmp_error(icmp->type) &&
-      icmp6_type != ICMP6_PARAM_PROB) {
-    // An ICMP error we understand, one level deep.
-    // Translate the nested packet (the one that caused the error).
-    clat_packet_len = ipv4_packet(out, pos + 1, payload, payload_size);
-
-    // The pseudo-header checksum was calculated on the transport length of the original IPv4
-    // packet that we were asked to translate. This transport length is 20 bytes smaller than it
-    // needs to be, because the ICMP error contains an IPv4 header, which we will be translating to
-    // an IPv6 header, which is 20 bytes longer. Fix it up here.
-    // We only need to do this for ICMP->ICMPv6, not ICMPv6->ICMP, because ICMP does not use the
-    // pseudo-header when calculating its checksum (as the IPv4 header has its own checksum).
-    checksum = checksum + htons(20);
-  } else if (icmp6_type == ICMP6_ECHO_REQUEST || icmp6_type == ICMP6_ECHO_REPLY) {
-    // Ping packet.
-    icmp6_targ->icmp6_id = icmp->un.echo.id;
-    icmp6_targ->icmp6_seq = icmp->un.echo.sequence;
-    out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload;
-    out[CLAT_POS_PAYLOAD].iov_len = payload_size;
-    clat_packet_len = CLAT_POS_PAYLOAD + 1;
-  } else {
-    // Unknown type/code. The type/code conversion functions have already logged an error.
-    return 0;
-  }
-
-  icmp6_targ->icmp6_cksum = 0;  // Checksum field must be 0 when calculating checksum.
-  icmp6_targ->icmp6_cksum = packet_checksum(checksum, out, pos);
-
-  return clat_packet_len;
-}
-
-/* function: icmp6_to_icmp
- * translate ipv6 icmp to ipv4 icmp
- * out          - output packet
- * icmp6        - source packet icmp6 header
- * payload      - icmp6 payload
- * payload_size - size of payload
- * returns: the highest position in the output clat_packet that's filled in
- */
-int icmp6_to_icmp(clat_packet out, clat_packet_index pos, const struct icmp6_hdr *icmp6,
-                  const uint8_t *payload, size_t payload_size) {
-  struct icmphdr *icmp_targ = out[pos].iov_base;
-  uint8_t icmp_type;
-  int clat_packet_len;
-
-  memset(icmp_targ, 0, sizeof(struct icmphdr));
-
-  icmp_type = icmp6_to_icmp_type(icmp6->icmp6_type, icmp6->icmp6_code);
-  icmp_targ->type = icmp_type;
-  icmp_targ->code = icmp6_to_icmp_code(icmp6->icmp6_type, icmp6->icmp6_code);
-
-  out[pos].iov_len = sizeof(struct icmphdr);
-
-  if (pos == CLAT_POS_TRANSPORTHDR &&
-      is_icmp6_error(icmp6->icmp6_type) &&
-      icmp_type != ICMP_PARAMETERPROB) {
-    // An ICMPv6 error we understand, one level deep.
-    // Translate the nested packet (the one that caused the error).
-    clat_packet_len = ipv6_packet(out, pos + 1, payload, payload_size);
-  } else if (icmp_type == ICMP_ECHO || icmp_type == ICMP_ECHOREPLY) {
-    // Ping packet.
-    icmp_targ->un.echo.id = icmp6->icmp6_id;
-    icmp_targ->un.echo.sequence = icmp6->icmp6_seq;
-    out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload;
-    out[CLAT_POS_PAYLOAD].iov_len = payload_size;
-    clat_packet_len = CLAT_POS_PAYLOAD + 1;
-  } else {
-      // Unknown type/code. The type/code conversion functions have already logged an error.
-    return 0;
-  }
-
-  icmp_targ->checksum = 0;  // Checksum field must be 0 when calculating checksum.
-  icmp_targ->checksum = packet_checksum(0, out, pos);
-
-  return clat_packet_len;
-}
-
-/* function: generic_packet
- * takes a generic IP packet and sets it up for translation
- * out      - output packet
- * pos      - position in the output packet of the transport header
- * payload  - pointer to IP payload
- * len      - size of ip payload
- * returns: the highest position in the output clat_packet that's filled in
- */
-int generic_packet(clat_packet out, clat_packet_index pos, const uint8_t *payload, size_t len) {
-  out[pos].iov_len = 0;
-  out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload;
-  out[CLAT_POS_PAYLOAD].iov_len = len;
-
-  return CLAT_POS_PAYLOAD + 1;
-}
-
-/* function: udp_packet
- * takes a udp packet and sets it up for translation
- * out      - output packet
- * udp      - pointer to udp header in packet
- * old_sum  - pseudo-header checksum of old header
- * new_sum  - pseudo-header checksum of new header
- * len      - size of ip payload
- */
-int udp_packet(clat_packet out, clat_packet_index pos, const struct udphdr *udp,
-               uint32_t old_sum, uint32_t new_sum, size_t len) {
-  const uint8_t *payload;
-  size_t payload_size;
-
-  if(len < sizeof(struct udphdr)) {
-    logmsg_dbg(ANDROID_LOG_ERROR,"udp_packet/(too small)");
-    return 0;
-  }
-
-  payload = (const uint8_t *) (udp + 1);
-  payload_size = len - sizeof(struct udphdr);
-
-  return udp_translate(out, pos, udp, old_sum, new_sum, payload, payload_size);
-}
-
-/* function: tcp_packet
- * takes a tcp packet and sets it up for translation
- * out      - output packet
- * tcp      - pointer to tcp header in packet
- * checksum - pseudo-header checksum
- * len      - size of ip payload
- * returns: the highest position in the output clat_packet that's filled in
- */
-int tcp_packet(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp,
-               uint32_t old_sum, uint32_t new_sum, size_t len) {
-  const uint8_t *payload;
-  size_t payload_size, header_size;
-
-  if(len < sizeof(struct tcphdr)) {
-    logmsg_dbg(ANDROID_LOG_ERROR,"tcp_packet/(too small)");
-    return 0;
-  }
-
-  if(tcp->doff < 5) {
-    logmsg_dbg(ANDROID_LOG_ERROR,"tcp_packet/tcp header length set to less than 5: %x", tcp->doff);
-    return 0;
-  }
-
-  if((size_t) tcp->doff*4 > len) {
-    logmsg_dbg(ANDROID_LOG_ERROR,"tcp_packet/tcp header length set too large: %x", tcp->doff);
-    return 0;
-  }
-
-  header_size = tcp->doff * 4;
-  payload = ((const uint8_t *) tcp) + header_size;
-  payload_size = len - header_size;
-
-  return tcp_translate(out, pos, tcp, header_size, old_sum, new_sum, payload, payload_size);
-}
-
-/* function: udp_translate
- * common between ipv4/ipv6 - setup checksum and send udp packet
- * out          - output packet
- * udp          - udp header
- * old_sum      - pseudo-header checksum of old header
- * new_sum      - pseudo-header checksum of new header
- * payload      - tcp payload
- * payload_size - size of payload
- * returns: the highest position in the output clat_packet that's filled in
- */
-int udp_translate(clat_packet out, clat_packet_index pos, const struct udphdr *udp,
-                  uint32_t old_sum, uint32_t new_sum, const uint8_t *payload, size_t payload_size) {
-  struct udphdr *udp_targ = out[pos].iov_base;
-
-  memcpy(udp_targ, udp, sizeof(struct udphdr));
-
-  out[pos].iov_len = sizeof(struct udphdr);
-  out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload;
-  out[CLAT_POS_PAYLOAD].iov_len = payload_size;
-
-  if (udp_targ->check) {
-    udp_targ->check = ip_checksum_adjust(udp->check, old_sum, new_sum);
-  } else {
-    // Zero checksums are special. RFC 768 says, "An all zero transmitted checksum value means that
-    // the transmitter generated no checksum (for debugging or for higher level protocols that
-    // don't care)." However, in IPv6 zero UDP checksums were only permitted by RFC 6935 (2013). So
-    // for safety we recompute it.
-    udp_targ->check = 0;  // Checksum field must be 0 when calculating checksum.
-    udp_targ->check = packet_checksum(new_sum, out, pos);
-  }
-
-  // RFC 768: "If the computed checksum is zero, it is transmitted as all ones (the equivalent
-  // in one's complement arithmetic)."
-  if (!udp_targ->check) {
-    udp_targ->check = 0xffff;
-  }
-
-  return CLAT_POS_PAYLOAD + 1;
-}
-
-/* function: tcp_translate
- * common between ipv4/ipv6 - setup checksum and send tcp packet
- * out          - output packet
- * tcp          - tcp header
- * header_size  - size of tcp header including options
- * checksum     - partial checksum covering ipv4/ipv6 header
- * payload      - tcp payload
- * payload_size - size of payload
- * returns: the highest position in the output clat_packet that's filled in
- */
-int tcp_translate(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp,
-                  size_t header_size, uint32_t old_sum, uint32_t new_sum,
-                  const uint8_t *payload, size_t payload_size) {
-  struct tcphdr *tcp_targ = out[pos].iov_base;
-  out[pos].iov_len = header_size;
-
-  if (header_size > MAX_TCP_HDR) {
-    // A TCP header cannot be more than MAX_TCP_HDR bytes long because it's a 4-bit field that
-    // counts in 4-byte words. So this can never happen unless there is a bug in the caller.
-    logmsg(ANDROID_LOG_ERROR, "tcp_translate: header too long %d > %d, truncating",
-           header_size, MAX_TCP_HDR);
-    header_size = MAX_TCP_HDR;
-  }
-
-  memcpy(tcp_targ, tcp, header_size);
-
-  out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload;
-  out[CLAT_POS_PAYLOAD].iov_len = payload_size;
-
-  tcp_targ->check = ip_checksum_adjust(tcp->check, old_sum, new_sum);
-
-  return CLAT_POS_PAYLOAD + 1;
-}
-
-// Weak symbol so we can override it in the unit test.
-void send_rawv6(int fd, clat_packet out, int iov_len) __attribute__((weak));
-
-void send_rawv6(int fd, clat_packet out, int iov_len) {
-  // A send on a raw socket requires a destination address to be specified even if the socket's
-  // protocol is IPPROTO_RAW. This is the address that will be used in routing lookups; the
-  // destination address in the packet header only affects what appears on the wire, not where the
-  // packet is sent to.
-  static struct sockaddr_in6 sin6 = { AF_INET6, 0, 0, { { { 0, 0, 0, 0 } } }, 0 };
-  static struct msghdr msg = {
-    .msg_name = &sin6,
-    .msg_namelen = sizeof(sin6),
-  };
-
-  msg.msg_iov = out,
-  msg.msg_iovlen = iov_len,
-  sin6.sin6_addr = ((struct ip6_hdr *) out[CLAT_POS_IPHDR].iov_base)->ip6_dst;
-  sendmsg(fd, &msg, 0);
-}
-
-/* function: translate_packet
- * takes a packet, translates it, and writes it to fd
- * fd         - fd to write translated packet to
- * to_ipv6    - true if translating to ipv6, false if translating to ipv4
- * packet     - packet
- * packetsize - size of packet
- */
-void translate_packet(int fd, int to_ipv6, const uint8_t *packet, size_t packetsize) {
-  int iov_len = 0;
-
-  // Allocate buffers for all packet headers.
-  struct tun_pi tun_targ;
-  char iphdr[sizeof(struct ip6_hdr)];
-  char fraghdr[sizeof(struct ip6_frag)];
-  char transporthdr[MAX_TCP_HDR];
-  char icmp_iphdr[sizeof(struct ip6_hdr)];
-  char icmp_fraghdr[sizeof(struct ip6_frag)];
-  char icmp_transporthdr[MAX_TCP_HDR];
-
-  // iovec of the packets we'll send. This gets passed down to the translation functions.
-  clat_packet out = {
-    { &tun_targ, 0 },                 // Tunnel header.
-    { iphdr, 0 },                     // IP header.
-    { fraghdr, 0 },                   // Fragment header.
-    { transporthdr, 0 },              // Transport layer header.
-    { icmp_iphdr, 0 },                // ICMP error inner IP header.
-    { icmp_fraghdr, 0 },              // ICMP error fragmentation header.
-    { icmp_transporthdr, 0 },         // ICMP error transport layer header.
-    { NULL, 0 },                      // Payload. No buffer, it's a pointer to the original payload.
-  };
-
-  if (to_ipv6) {
-    iov_len = ipv4_packet(out, CLAT_POS_IPHDR, packet, packetsize);
-    if (iov_len > 0) {
-      send_rawv6(fd, out, iov_len);
-    }
-  } else {
-    iov_len = ipv6_packet(out, CLAT_POS_IPHDR, packet, packetsize);
-    if (iov_len > 0) {
-      fill_tun_header(&tun_targ, ETH_P_IP);
-      out[CLAT_POS_TUNHDR].iov_len = sizeof(tun_targ);
-      send_tun(fd, out, iov_len);
-    }
-  }
-}
diff --git a/translate.h b/translate.h
deleted file mode 100644 (file)
index aa8b736..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * translate.h - translate from one version of ip to another
- */
-#ifndef __TRANSLATE_H__
-#define __TRANSLATE_H__
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/udp.h>
-#include <netinet/tcp.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <linux/icmp.h>
-#include <linux/if_tun.h>
-
-#include "clatd.h"
-
-#define MAX_TCP_HDR (15 * 4)   // Data offset field is 4 bits and counts in 32-bit words.
-
-// Calculates the checksum over all the packet components starting from pos.
-uint16_t packet_checksum(uint32_t checksum, clat_packet packet, clat_packet_index pos);
-
-// Returns the total length of the packet components after pos.
-uint16_t packet_length(clat_packet packet, clat_packet_index pos);
-
-// Returns true iff the given IPv6 address is in the plat subnet.
-int is_in_plat_subnet(const struct in6_addr *addr6);
-
-// Functions to create tun, IPv4, and IPv6 headers.
-void fill_tun_header(struct tun_pi *tun_header, uint16_t proto);
-void fill_ip_header(struct iphdr *ip_targ, uint16_t payload_len, uint8_t protocol,
-                    const struct ip6_hdr *old_header);
-void fill_ip6_header(struct ip6_hdr *ip6, uint16_t payload_len, uint8_t protocol,
-                     const struct iphdr *old_header);
-
-// Translate and send packets.
-void translate_packet(int fd, int to_ipv6, const uint8_t *packet, size_t packetsize);
-
-// Translate IPv4 and IPv6 packets.
-int ipv4_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, size_t len);
-int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, size_t len);
-
-// Deal with fragmented packets.
-size_t maybe_fill_frag_header(struct ip6_frag *frag_hdr, struct ip6_hdr *ip6_targ,
-                              const struct iphdr *old_header);
-uint8_t parse_frag_header(const struct ip6_frag *frag_hdr, struct iphdr *ip_targ);
-
-// Deal with fragmented packets.
-size_t maybe_fill_frag_header(struct ip6_frag *frag_hdr, struct ip6_hdr *ip6_targ,
-                              const struct iphdr *old_header);
-uint8_t parse_frag_header(const struct ip6_frag *frag_hdr, struct iphdr *ip_targ);
-
-// Translate ICMP packets.
-int icmp_to_icmp6(clat_packet out, clat_packet_index pos, const struct icmphdr *icmp,
-                  uint32_t checksum, const uint8_t *payload, size_t payload_size);
-int icmp6_to_icmp(clat_packet out, clat_packet_index pos, const struct icmp6_hdr *icmp6,
-                  const uint8_t *payload, size_t payload_size);
-
-// Translate generic IP packets.
-int generic_packet(clat_packet out, clat_packet_index pos, const uint8_t *payload, size_t len);
-
-// Translate TCP and UDP packets.
-int tcp_packet(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp,
-               uint32_t old_sum, uint32_t new_sum, size_t len);
-int udp_packet(clat_packet out, clat_packet_index pos, const struct udphdr *udp,
-               uint32_t old_sum, uint32_t new_sum, size_t len);
-
-int tcp_translate(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp,
-                  size_t header_size, uint32_t old_sum, uint32_t new_sum,
-                  const uint8_t *payload, size_t payload_size);
-int udp_translate(clat_packet out, clat_packet_index pos, const struct udphdr *udp,
-                  uint32_t old_sum, uint32_t new_sum,
-                  const uint8_t *payload, size_t payload_size);
-
-#endif /* __TRANSLATE_H__ */
diff --git a/tun.c b/tun.c
deleted file mode 100644 (file)
index 49f0ea7..0000000
--- a/tun.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * tun.c - tun device functions
- */
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include "clatd.h"
-
-/* function: tun_open
- * tries to open the tunnel device
- */
-int tun_open() {
-  int fd;
-
-  fd = open("/dev/tun", O_RDWR);
-  if(fd < 0) {
-    fd = open("/dev/net/tun", O_RDWR);
-  }
-
-  return fd;
-}
-
-/* function: tun_alloc
- * creates a tun interface and names it
- * dev - the name for the new tun device
- */
-int tun_alloc(char *dev, int fd) {
-  struct ifreq ifr;
-  int err;
-
-  memset(&ifr, 0, sizeof(ifr));
-
-  ifr.ifr_flags = IFF_TUN;
-  if( *dev ) {
-    strncpy(ifr.ifr_name, dev, IFNAMSIZ);
-    ifr.ifr_name[IFNAMSIZ-1] = '\0';
-  }
-
-  if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
-    close(fd);
-    return err;
-  }
-  strcpy(dev, ifr.ifr_name);
-  return 0;
-}
-
-/* function: set_nonblocking
- * sets a filedescriptor to non-blocking mode
- * fd - the filedescriptor
- * returns: 0 on success, -1 on failure
- */
-int set_nonblocking(int fd) {
-  int flags = fcntl(fd, F_GETFL);
-  if (flags == -1) {
-    return flags;
-  }
-  return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-}
-
-/* function: send_tun
- * sends a clat_packet to a tun interface
- * fd      - the tun filedescriptor
- * out     - the packet to send
- * iov_len - the number of entries in the clat_packet
- * returns: number of bytes read on success, -1 on failure
- */
-int send_tun(int fd, clat_packet out, int iov_len) {
-  return writev(fd, out, iov_len);
-}
diff --git a/tun.h b/tun.h
deleted file mode 100644 (file)
index bcdd10e..0000000
--- a/tun.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * tun.h - tun device functions
- */
-#ifndef __TUN_H__
-#define __TUN_H__
-
-#include <linux/if.h>
-
-#include "clatd.h"
-#include "ring.h"
-
-struct tun_data {
-  char device4[IFNAMSIZ];
-  int read_fd6, write_fd6, fd4;
-  struct packet_ring ring;
-};
-
-int tun_open();
-int tun_alloc(char *dev, int fd);
-int send_tun(int fd, clat_packet out, int iov_len);
-int set_nonblocking(int fd);
-
-#endif