On Friday 13 June 2008 23:05:00 Mark McLoughlin wrote:
> Allow assigning a MAC address to the network interface with
> e.g.
>
>   --tunnet=bridge:eth0:00:FF:95:6B:DA:3D
>
> or:
>
>   --tunnet=192.168.121.1:00:FF:95:6B:DA:3D
>
> which is pretty unintelligable, but ...

Agreed... ugly but clear.

Not sure about tossing around the ifr just to hold the interface name
across configure_device and get_mac though.  If we put it in a nice var,
we can have a cleaner interface and a better verbose() message.

Oh, and I'm trying to hang with the cool kids and use bool :)

Here's the patch I put on top (testing now)...
Rusty.

diff -r 8416df781ce4 Documentation/lguest/lguest.c
--- a/Documentation/lguest/lguest.c     Sat Jun 14 15:11:24 2008 +1000
+++ b/Documentation/lguest/lguest.c     Sat Jun 14 19:17:47 2008 +1000
@@ -1265,17 +1265,19 @@ static void setup_console(void)
 
 static u32 str2ip(const char *ipaddr)
 {
-       unsigned int byte[4];
+       unsigned int b[4];
 
-       sscanf(ipaddr, "%u.%u.%u.%u", &byte[0], &byte[1], &byte[2], &byte[3]);
-       return (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];
+       if (sscanf(ipaddr, "%u.%u.%u.%u", &b[0], &b[1], &b[2], &b[3]) != 4)
+               errx(1, "Failed to parse IP address '%s'", ipaddr);
+       return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
 }
 
 static void str2mac(const char *macaddr, unsigned char mac[6])
 {
        unsigned int m[6];
-       sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
-               &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]);
+       if (sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
+                  &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) != 6)
+               errx(1, "Failed to parse mac address '%s'", mac);
        mac[0] = m[0];
        mac[1] = m[1];
        mac[2] = m[2];
@@ -1311,58 +1313,79 @@ static void add_to_bridge(int fd, const 
 /* This sets up the Host end of the network device with an IP address, brings
  * it up so packets will flow, the copies the MAC address into the hwaddr
  * pointer. */
-static void configure_device(int fd, struct ifreq *ifr, u32 ipaddr)
+static void configure_device(int fd, const char *tapif, u32 ipaddr)
 {
-       struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr;
+       struct ifreq ifr;
+       struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
+
+       memset(&ifr, 0, sizeof(ifr));
+       strcpy(ifr.ifr_name, tapif);
 
        /* Don't read these incantations.  Just cut & paste them like I did! */
        sin->sin_family = AF_INET;
        sin->sin_addr.s_addr = htonl(ipaddr);
-       if (ioctl(fd, SIOCSIFADDR, ifr) != 0)
-               err(1, "Setting %s interface address", ifr->ifr_name);
-       ifr->ifr_flags = IFF_UP;
-       if (ioctl(fd, SIOCSIFFLAGS, ifr) != 0)
-               err(1, "Bringing interface %s up", ifr->ifr_name);
+       if (ioctl(fd, SIOCSIFADDR, &ifr) != 0)
+               err(1, "Setting %s interface address", tapif);
+       ifr.ifr_flags = IFF_UP;
+       if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0)
+               err(1, "Bringing interface %s up", tapif);
 }
 
-static void get_mac(int fd, struct ifreq *ifr, unsigned char hwaddr[6])
+static void get_mac(int fd, const char *tapif, unsigned char hwaddr[6])
 {
+       struct ifreq ifr;
+
+       memset(&ifr, 0, sizeof(ifr));
+       strcpy(ifr.ifr_name, tapif);
+
        /* SIOC stands for Socket I/O Control.  G means Get (vs S for Set
         * above).  IF means Interface, and HWADDR is hardware address.
         * Simple! */
-       if (ioctl(fd, SIOCGIFHWADDR, ifr) != 0)
-               err(1, "getting hw address for %s", ifr->ifr_name);
-       memcpy(hwaddr, ifr->ifr_hwaddr.sa_data, 6);
+       if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0)
+               err(1, "getting hw address for %s", tapif);
+       memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
+}
+
+static int get_tun_device(char tapif[IFNAMSIZ])
+{
+       struct ifreq ifr;
+       int netfd;
+
+       /* Start with this zeroed.  Messy but sure. */
+       memset(&ifr, 0, sizeof(ifr));
+
+       /* We open the /dev/net/tun device and tell it we want a tap device.  A
+        * tap device is like a tun device, only somehow different.  To tell
+        * the truth, I completely blundered my way through this code, but it
+        * works now! */
+       netfd = open_or_die("/dev/net/tun", O_RDWR);
+       ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+       strcpy(ifr.ifr_name, "tap%d");
+       if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
+               err(1, "configuring /dev/net/tun");
+
+       /* We don't need checksums calculated for packets coming in this
+        * device: trust us! */
+       ioctl(netfd, TUNSETNOCSUM, 1);
+
+       memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
+       return netfd;
 }
 
 /*L:195 Our network is a Host<->Guest network.  This can either use bridging or
  * routing, but the principle is the same: it uses the "tun" device to inject
  * packets into the Host as if they came in from a normal network card.  We
  * just shunt packets between the Guest and the tun device. */
-static void setup_tun_net(const char *arg)
+static void setup_tun_net(char *arg)
 {
        struct device *dev;
-       struct ifreq ifr;
        int netfd, ipfd;
        u32 ip = INADDR_ANY;
-       int bridging = 0;
-       char name_or_ip[IFNAMSIZ];
-       const char *p;
+       bool bridging = false;
+       char tapif[IFNAMSIZ], *p;
        struct virtio_net_config conf;
 
-       /* We open the /dev/net/tun device and tell it we want a tap device.  A
-        * tap device is like a tun device, only somehow different.  To tell
-        * the truth, I completely blundered my way through this code, but it
-        * works now! */
-       netfd = open_or_die("/dev/net/tun", O_RDWR);
-       memset(&ifr, 0, sizeof(ifr));
-       ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-       strcpy(ifr.ifr_name, "tap%d");
-       if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
-               err(1, "configuring /dev/net/tun");
-       /* We don't need checksums calculated for packets coming in this
-        * device: trust us! */
-       ioctl(netfd, TUNSETNOCSUM, 1);
+       netfd = get_tun_device(tapif);
 
        /* First we create a new network device. */
        dev = new_device("net", VIRTIO_ID_NET, netfd, handle_tun_input);
@@ -1381,29 +1404,28 @@ static void setup_tun_net(const char *ar
        /* If the command line was --tunnet=bridge:<name> do bridging. */
        if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) {
                arg += strlen(BRIDGE_PFX);
-               bridging = 1;
+               bridging = true;
        }
 
        /* A mac address may follow the bridge name or IP address */
-       if ((p = strchr(arg, ':')))
+       p = strchr(arg, ':');
+       if (p) {
                str2mac(p+1, conf.mac);
-       else {
+               *p = '\0';
+       } else {
                p = arg + strlen(arg);
                /* None supplied; query the randomly assigned mac. */
-               get_mac(ipfd, &ifr, conf.mac);
+               get_mac(ipfd, tapif, conf.mac);
        }
 
        /* arg is now either an IP address or a bridge name */
-       strncpy(name_or_ip, arg, p-arg);
-       name_or_ip[p-arg] = '\0';
-
        if (bridging)
-               add_to_bridge(ipfd, ifr.ifr_name, name_or_ip);
+               add_to_bridge(ipfd, tapif, arg);
        else
-               ip = str2ip(name_or_ip);
+               ip = str2ip(arg);
 
        /* Set up the tun device. */
-       configure_device(ipfd, &ifr, ip);
+       configure_device(ipfd, tapif, ip);
 
        /* Tell Guest what MAC address to use. */
        add_feature(dev, VIRTIO_NET_F_MAC);
@@ -1416,11 +1438,11 @@ static void setup_tun_net(const char *ar
        devices.device_num++;
 
        if (bridging)
-               verbose("device %u: tun net attached to bridge: %s\n",
-                       devices.device_num, name_or_ip);
+               verbose("device %u: tun %s attached to bridge: %s\n",
+                       devices.device_num, tapif, arg);
        else
-               verbose("device %u: tun net: %s\n",
-                       devices.device_num, name_or_ip);
+               verbose("device %u: tun %s: %s\n",
+                       devices.device_num, tapif, arg);
 }
 
 /* Our block (disk) device should be really simple: the Guest asks for a block
_______________________________________________
Lguest mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/lguest

Reply via email to