clat: split read_packet in twain

This does introduce some duplication, but this is
to facilitate later changes to how AF_PACKET read works.
Switching from read() to recvmsg(), processing cmsg's, etc...

Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I8368d58d2cec88bafa688c38d63347fa898f3ad7
diff --git a/clatd.c b/clatd.c
index 307211f..be1a42c 100644
--- a/clatd.c
+++ b/clatd.c
@@ -76,35 +76,50 @@
   }
 }
 
-/* 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) {
-  uint8_t buf[PACKETLEN];
-  ssize_t readlen = read(read_fd, buf, PACKETLEN);
+// reads L3 IPv6 packet from AF_PACKET socket, translates to IPv4, writes to tun
+void process_packet_6_to_4(struct tun_data *tunnel) {
+  uint8_t buf[MAXMTU];
+  ssize_t readlen = read(tunnel->read_fd6, buf, MAXMTU);
 
   if (readlen < 0) {
     if (errno != EAGAIN) {
-      logmsg(ANDROID_LOG_WARN, "read_packet/read error: %s", strerror(errno));
+      logmsg(ANDROID_LOG_WARN, "%s: read error: %s", __func__, strerror(errno));
     }
     return;
   } else if (readlen == 0) {
-    logmsg(ANDROID_LOG_WARN, "read_packet/tun interface removed");
+    logmsg(ANDROID_LOG_WARN, "%s: packet socket removed?", __func__);
     running = 0;
     return;
+  } else if (readlen >= MAXMTU) {
+    logmsg(ANDROID_LOG_WARN, "%s: read truncation - ignoring pkt", __func__);
+    return;
   }
 
-  if (!to_ipv6) {
-    translate_packet(write_fd, 0 /* to_ipv6 */, buf, readlen);
+  translate_packet(tunnel->fd4, 0 /* to_ipv6 */, buf, readlen);
+}
+
+// reads TUN_PI + L3 IPv4 packet from tun, translates to IPv6, writes to AF_INET6/RAW socket
+void process_packet_4_to_6(struct tun_data *tunnel) {
+  uint8_t buf[PACKETLEN];
+  ssize_t readlen = read(tunnel->fd4, buf, PACKETLEN);
+
+  if (readlen < 0) {
+    if (errno != EAGAIN) {
+      logmsg(ANDROID_LOG_WARN, "%s: read error: %s", __func__, strerror(errno));
+    }
+    return;
+  } else if (readlen == 0) {
+    logmsg(ANDROID_LOG_WARN, "%s: tun interface removed", __func__);
+    running = 0;
+    return;
+  } else if (readlen >= PACKETLEN) {
+    logmsg(ANDROID_LOG_WARN, "%s: read truncation - ignoring pkt", __func__);
     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);
+    logmsg(ANDROID_LOG_WARN, "%s: short read: got %ld bytes", __func__, readlen);
     return;
   }
 
@@ -120,7 +135,7 @@
 
   uint8_t *packet = (uint8_t *)(tun_header + 1);
   readlen -= sizeof(*tun_header);
-  translate_packet(write_fd, 1 /* to_ipv6 */, packet, readlen);
+  translate_packet(tunnel->write_fd6, 1 /* to_ipv6 */, packet, readlen);
 }
 
 // IPv6 DAD packet format:
@@ -229,13 +244,13 @@
         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
+      // Call process_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) read_packet(tunnel->read_fd6, tunnel->fd4, 0 /* to_ipv6 */);
-      if (wait_fd[1].revents) read_packet(tunnel->fd4, tunnel->write_fd6, 1 /* to_ipv6 */);
+      if (wait_fd[0].revents) process_packet_6_to_4(tunnel);
+      if (wait_fd[1].revents) process_packet_4_to_6(tunnel);
     }
 
     time_t now = time(NULL);