Support the subnet attribute in the attr plugin
authorMartin Willi <martin@revosec.ch>
Thu, 24 Jun 2010 13:44:28 +0000 (15:44 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 24 Jun 2010 13:46:28 +0000 (15:46 +0200)
src/libhydra/plugins/attr/attr_provider.c

index 9d6daa8..cd504e0 100644 (file)
@@ -148,6 +148,7 @@ static struct {
        {"dhcp",                INTERNAL_IP4_DHCP,              INTERNAL_IP6_DHCP},
        {"netmask",             INTERNAL_IP4_NETMASK,   INTERNAL_IP6_NETMASK},
        {"server",              INTERNAL_IP4_SERVER,    INTERNAL_IP6_SERVER},
+       {"subnet",              INTERNAL_IP4_SUBNET,    INTERNAL_IP6_SUBNET},
 };
 
 /**
@@ -165,12 +166,19 @@ static void load_entries(private_attr_provider_t *this)
                configuration_attribute_type_t type;
                attribute_entry_t *entry;
                host_t *host;
-               int i;
+               char *pos;
+               int i, mask = -1;
 
                type = atoi(key);
                tokens = enumerator_create_token(value, ",", " ");
                while (tokens->enumerate(tokens, &token))
                {
+                       pos = strchr(token, '/');
+                       if (pos)
+                       {
+                               *(pos++) = '\0';
+                               mask = atoi(pos);
+                       }
                        host = host_create_from_string(token, 0);
                        if (!host)
                        {
@@ -201,7 +209,27 @@ static void load_entries(private_attr_provider_t *this)
                        }
                        entry = malloc_thing(attribute_entry_t);
                        entry->type = type;
-                       entry->value = chunk_clone(host->get_address(host));
+                       if (mask == -1)
+                       {
+                               entry->value = chunk_clone(host->get_address(host));
+                       }
+                       else
+                       {
+                               if (host->get_family(host) == AF_INET)
+                               {       /* IPv4 attributes contain a subnet mask */
+                                       u_int32_t netmask;
+
+                                       mask = 32 - mask;
+                                       netmask = htonl((0xFFFFFFFF >> mask) << mask);
+                                       entry->value = chunk_cat("cc", host->get_address(host),
+                                                                                        chunk_from_thing(netmask));
+                               }
+                               else
+                               {       /* IPv6 addresses the prefix only */
+                                       entry->value = chunk_cat("cc", host->get_address(host),
+                                                                                        chunk_from_chars(mask));
+                               }
+                       }
                        host->destroy(host);
                        this->attributes->insert_last(this->attributes, entry);
                }