changing type
[oweals/gnunet.git] / src / transport / gnunet-helper-transport-wlan.c
index 0169a2da116d5acf7f378889cf30a49f104d52cc..2edd171f48c2f3e72131e650966be0848af98e44 100644 (file)
  * interface.  It will force traffic to be in 'ad-hoc' mode, use the
  * proper MAC address of the WLAN interface and use a GNUnet-specific
  * SSID (and a GNUnet-specific SNAP header).  It only takes a single
- * argument, which is the name of the interface to use.  Since it uses
- * RAW sockets, it must be installed SUID or run as 'root'.  In order
- * to keep the security risk of the resulting SUID binary minimal, the
- * program ONLY opens the RAW socket with root privileges, then drops
- * them and only then starts to process command line arguments.  The
- * code also does not link against any shared libraries (except libc)
- * and is strictly minimal (except for checking for errors).  The
- * following list of people have reviewed this code and considered it
- * safe since the last modification (if you reviewed it, please have
- * your name added to the list):
+ * argument, which is the name of the WLAN interface to use.  The
+ * program detects if the interface is not a WLAN interface and exits
+ * with an error in that case.
  *
- * - Christian Grothoff (Mar 16th 2012)
+ * Once initialized, the program will first send a 'struct
+ * GNUNET_TRANSPORT_WLAN_HelperControlMessage' to 'stdout'.  That
+ * message contains the MAC address of the WLAN interface.  It will
+ * then read messages from the WLAN interface and send them together
+ * with performance information as 'struct
+ * GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage' messages to 'stdout'.
+ * Furthermore, it will read a stream of messages from 'stdin' that
+ * have the format from 'struct
+ * GNUNET_TRANSPORT_WLAN_RadiotapSendMessage'.  Those messages will
+ * then be sent via the WLAN interface; however, the sender MAC
+ * address will be forced to be the correct address from our WLAN
+ * card.  If 'stdin' closes, receiving from the WLAN interface will
+ * continue.  If 'stdout' causes a SIGPIPE, the process dies from the
+ * signal.  Errors cause an error message to be reported to 'stderr',
+ * in most cases the process also exits (with status code '1').  The
+ * program never terminates normally; it is safe to kill the
+ * process with SIGTERM or SIGKILL at any time.
+ *
+ * Since it uses RAW sockets, the binary must be installed SUID or run
+ * as 'root'.  In order to keep the security risk of the resulting
+ * SUID binary minimal, the program ONLY opens the RAW socket with
+ * root privileges, then drops them and only then starts to process
+ * command line arguments.  The code also does not link against any
+ * shared libraries (except libc) and is strictly minimal (except for
+ * checking for errors).  The following list of people have reviewed
+ * this code and considered it safe since the last modification (if
+ * you reviewed it, please have your name added to the list):
+ *
+ * - Christian Grothoff (Apr 3rd 2012)
  */
 
 /*-
@@ -1795,7 +1816,7 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
   sendsize = ntohs (hdr->size);
   if ( (sendsize <
        sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
-       (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) ) 
+       (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) 
   {
     fprintf (stderr, "Received malformed message\n");
     exit (1);
@@ -1803,7 +1824,7 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
   sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
   if (MAXLINE < sendsize)
   {
-    fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
+    fprintf (stderr, "Packet too big for buffer\n");
     exit (1);
   }
   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
@@ -1847,32 +1868,11 @@ main (int argc, char *argv[])
   struct MessageStreamTokenizer *stdin_mst;
   int raw_eno;
 
+  /* make use of SGID capabilities on POSIX */
   memset (&dev, 0, sizeof (dev));
   dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
   raw_eno = errno; /* remember for later */
 
-  /* drop privs */
-  {
-    uid_t uid = getuid ();
-#ifdef HAVE_SETRESUID
-    if (0 != setresuid (uid, uid, uid))
-    {
-      fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
-      if (-1 != dev.fd_raw)
-       (void) close (dev.fd_raw);
-      return 1;
-    }
-#else
-    if (0 != (setuid (uid) | seteuid (uid)))
-    {
-      fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
-      if (-1 != dev.fd_raw)
-       (void) close (dev.fd_raw);
-      return 1;
-    }
-  }
-#endif
-
   /* now that we've dropped root rights, we can do error checking */
   if (2 != argc)
   {
@@ -1907,6 +1907,29 @@ main (int argc, char *argv[])
     return 1;
   }
 
+  /* drop privs */
+  {
+    uid_t uid = getuid ();
+#ifdef HAVE_SETRESUID
+    if (0 != setresuid (uid, uid, uid))
+    {
+      fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
+      if (-1 != dev.fd_raw)
+       (void) close (dev.fd_raw);
+      return 1;
+    }
+#else
+    if (0 != (setuid (uid) | seteuid (uid)))
+    {
+      fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
+      if (-1 != dev.fd_raw)
+       (void) close (dev.fd_raw);
+      return 1;
+    }
+  }
+#endif
+
+
   /* send MAC address of the WLAN interface to STDOUT first */
   {
     struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
@@ -2039,7 +2062,7 @@ main (int argc, char *argv[])
          + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
          - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
         rrm->header.size = htons (write_std.size);
-        rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
+        rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
       }
     }
   }