[hipl-dev] [Merge] lp:~martin-lp/hipl/hipfwconf into lp:hipl

  • From: David Martin <david.martin.mailbox@xxxxxxxxxxxxxx>
  • To: mp+80830@xxxxxxxxxxxxxxxxxx
  • Date: Mon, 31 Oct 2011 18:22:27 -0000

David Martin has proposed merging lp:~martin-lp/hipl/hipfwconf into lp:hipl.

Requested reviews:
  Miika Komu (miika-iki)

For more details, see:
https://code.launchpad.net/~martin-lp/hipl/hipfwconf/+merge/80830

This branch introduces changes to get the currently active connection from the 
firewall.

This is a resubmitted merge proposal:
instead of using a separate binary option 1 of the previous discussion is 
implemented:
> 1) add an extra keyword to the hipconf command line: hipconf (daemon | 
> firewall) COMMAND

Summed up changes since the last proposal (revision 6116ff.):
Keywords to address hipd / hipfw are daemon and firewall and defined in 
lib/core/conf.h.
The hipconf help print has been updated.
Config file syntax does not have to be changed as only hipd parses configs via 
hipconf and the daemon
keyword is hardcoded.

>From what I've tested everything works as before. I do not know all hipconf 
>options or how to apply them
so I did not test them all. Please have a look if everything seems right.
-- 
https://code.launchpad.net/~martin-lp/hipl/hipfwconf/+merge/80830
Your team HIPL core team is subscribed to branch lp:hipl.
=== modified file 'Makefile.am'
--- Makefile.am 2011-10-17 18:14:10 +0000
+++ Makefile.am 2011-10-31 18:21:26 +0000
@@ -90,8 +90,8 @@
                                               firewall/port_bindings.c
 test_hc_performance_SOURCES                 = test/hc_performance.c
 
-tools_hipconf_SOURCES  = tools/hipconf.c
-tools_pisacert_SOURCES = tools/pisacert.c
+tools_hipconf_SOURCES   = tools/hipconf.c
+tools_pisacert_SOURCES  = tools/pisacert.c
 
 hipd_hipd_sources = hipd/accessor.c              \
                     hipd/cert.c                  \

=== modified file 'firewall/conntrack.c'
--- firewall/conntrack.c        2011-10-25 21:14:16 +0000
+++ firewall/conntrack.c        2011-10-31 18:21:26 +0000
@@ -2244,3 +2244,56 @@
         remove_connection(conn_list->data);
     }
 }
+
+/**
+ * Prepare given message with host association info from the tracked 
connections.
+ *
+ * @param msg The message where the info is written.
+ * @return  0 on success
+ *         -1 on error
+ */
+int hip_fw_handle_get_ha_info(struct hip_common *msg)
+{
+    struct hip_hadb_user_info_state hid = { { { { 0 } } } };
+    struct slist                   *iter_conn;
+    struct connection              *conn;
+    struct hip_data                *data;
+
+    if (!msg) {
+        HIP_ERROR("Missing message parameter.\n");
+        return -1;
+    }
+
+    if (conn_list == NULL) {
+        HIP_DEBUG("No tracked connections to return.\n");
+        return 0;
+    }
+
+    hip_msg_init(msg);
+    if (hip_build_user_hdr(msg, HIP_MSG_GET_HA_INFO, 0) < 0) {
+        HIP_ERROR("Failed to build GET_HA_INFO message header.\n");
+        return -1;
+    }
+
+    iter_conn = conn_list;
+    while (iter_conn) {
+        conn = iter_conn->data;
+        data = conn->original.hip_tuple->data;
+
+        // build HA_INFO with info from connection initiator
+        hid.state = conn->state;
+        ipv6_addr_copy(&hid.hit_our, &data->src_hit);
+        ipv6_addr_copy(&hid.hit_peer, &data->dst_hit);
+        hid.nat_udp_port_local = conn->original.src_port;
+        hid.nat_udp_port_peer  = conn->original.dst_port;
+
+        if (hip_build_param_contents(msg, &hid, HIP_PARAM_HA_INFO, 
sizeof(hid)) < 0) {
+            HIP_ERROR("Failed to build initiator HA_INFO parameter.\n");
+            return -1;
+        }
+
+        iter_conn = iter_conn->next;
+    }
+
+    return 0;
+}

=== modified file 'firewall/conntrack.h'
--- firewall/conntrack.h        2011-07-18 16:31:37 +0000
+++ firewall/conntrack.h        2011-10-31 18:21:26 +0000
@@ -63,4 +63,6 @@
 void hip_fw_conntrack_periodic_cleanup(void);
 void hip_fw_uninit_conntrack(void);
 
+int hip_fw_handle_get_ha_info(struct hip_common *msg);
+
 #endif /* HIP_FIREWALL_CONNTRACK_H */

=== modified file 'firewall/firewall.c'
--- firewall/firewall.c 2011-10-30 11:41:51 +0000
+++ firewall/firewall.c 2011-10-31 18:21:26 +0000
@@ -1672,7 +1672,7 @@
     n    = recvfrom(hip_fw_async_sock, msg, sizeof(struct hip_common),
                     MSG_PEEK, (struct sockaddr *) &sock_addr, &alen);
     if (n < 0) {
-        HIP_ERROR("Error receiving message header from daemon.\n");
+        HIP_ERROR("Error receiving message header.\n");
         return -1;
     }
 
@@ -1701,24 +1701,13 @@
                  (struct sockaddr *) &sock_addr, &alen);
 
     if (n < 0) {
-        HIP_ERROR("Error receiving message parameters from daemon.\n");
+        HIP_ERROR("Error receiving message parameters.\n");
         return -1;
     }
 
     HIP_ASSERT(n == len);
 
-    if (ntohs(sock_addr.sin6_port) != HIP_DAEMON_LOCAL_PORT) {
-        int type = hip_get_msg_type(msg);
-        if (type == HIP_MSG_FW_BEX_DONE) {
-            HIP_DEBUG("HIP_MSG_FW_BEX_DONE\n");
-            HIP_DEBUG("%d == %d\n", ntohs(sock_addr.sin6_port),
-                      HIP_DAEMON_LOCAL_PORT);
-        }
-        HIP_DEBUG("Drop, message not from hipd\n");
-        return -1;
-    }
-
-    if (hip_handle_msg(msg) < 0) {
+    if (hip_handle_msg(msg, (struct sockaddr *) &sock_addr) < 0) {
         HIP_ERROR("Error handling message\n");
         return -1;
     }
@@ -1847,8 +1836,6 @@
     sock_addr.sin6_addr   = in6addr_loopback;
     HIP_IFEL(bind(hip_fw_async_sock, (struct sockaddr *) &sock_addr, 
sizeof(sock_addr)), -1,
              "Bind on firewall socket addr failed. Give -k option to kill old 
hipfw\n");
-    HIP_IFEL(hip_daemon_connect(hip_fw_async_sock), -1,
-             "connecting socket failed\n");
 
     /* Starting hipfw does not always work when hipfw starts first -miika */
     if (hip_userspace_ipsec || hip_lsi_support) {
@@ -1944,7 +1931,7 @@
         }
 
         if (FD_ISSET(hip_fw_async_sock, &read_fdset)) {
-            HIP_DEBUG("****** Received HIPD message ******\n");
+            HIP_DEBUG("****** Received user message ******\n");
             err = fw_handle_hipd_message(msg);
         }
 
@@ -2009,3 +1996,31 @@
 
     return &default_lsi;
 }
+
+/**
+ * Send a message via the firewall socket for asynchronous messages.
+ * Caller is responsible for setting up the message.
+ *
+ * @param msg  The message to be sent.
+ * @param addr The destination address.
+ *
+ * @return  0 on success
+ *         -1 on error
+ */
+int hip_fw_send_message(const struct hip_common *const msg,
+                        const struct sockaddr *const addr)
+{
+    uint16_t len;
+
+    if (msg == NULL || addr == NULL) {
+        HIP_ERROR("Empty message or address.\n");
+        return -1;
+    }
+
+    len = hip_get_msg_total_len(msg);
+    if (sendto(hip_fw_async_sock, msg, len, 0, addr, hip_sockaddr_len(addr)) 
!= len) {
+        return -1;
+    }
+
+    return 0;
+}

=== modified file 'firewall/firewall.h'
--- firewall/firewall.h 2011-04-05 16:44:22 +0000
+++ firewall/firewall.h 2011-10-31 18:21:26 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -55,5 +55,7 @@
 void hip_fw_uninit_esp_relay(void);
 hip_hit_t *hip_fw_get_default_hit(void);
 hip_lsi_t *hip_fw_get_default_lsi(void);
+int hip_fw_send_message(const struct hip_common *const msg,
+                        const struct sockaddr *const addr);
 
 #endif /* HIP_FIREWALL_FIREWALL_H */

=== modified file 'firewall/firewall_control.c'
--- firewall/firewall_control.c 2011-10-25 21:14:16 +0000
+++ firewall/firewall_control.c 2011-10-31 18:21:26 +0000
@@ -38,10 +38,12 @@
 #include <string.h>
 #include <netinet/in.h>
 
+#include "conntrack.h"
 #include "lib/core/builder.h"
 #include "lib/core/debug.h"
 #include "lib/core/ife.h"
 #include "lib/core/message.h"
+#include "lib/core/prefix.h"
 #include "lib/core/protodefs.h"
 #include "cache.h"
 #include "firewall.h"
@@ -91,12 +93,12 @@
 }
 
 /**
- * distribute a message from hipd to the respective extension handler
+ * distribute a user message to the respective extension handler
  *
  * @param   msg pointer to the received user message
  * @return  0 on success, else -1
  */
-int hip_handle_msg(struct hip_common *msg)
+int hip_handle_msg(struct hip_common *msg, struct sockaddr *addr)
 {
     int                type, err = 0;
     struct hip_common *msg_out = NULL;
@@ -150,12 +152,36 @@
         HIP_IFEL(hip_send_recv_daemon_info(msg_out, 1, hip_fw_sock), -1,
                  "Couldn't notify daemon of firewall presence\n");
         break;
+    case HIP_MSG_GET_HA_INFO:
+        HIP_IFEL(hip_fw_handle_get_ha_info(msg), -1,
+                 "Could not handle GET_HA message.\n");
+        HIP_IFEL(hip_fw_send_message(msg, addr), -1,
+                 "Could not send HA reply.\n");
+        break;
     default:
         HIP_ERROR("Unhandled message type %d\n", type);
         err = -1;
         break;
     }
+
 out_err:
+    if (hip_get_msg_response(msg)) {
+        HIP_DEBUG("Send response\n");
+        if (err) {
+            hip_hdr msg_type = hip_get_msg_type(msg);
+            hip_msg_init(msg);
+            hip_build_user_hdr(msg, msg_type, 0);
+            hip_set_msg_err(msg, 1);
+        }
+        HIP_DEBUG("Sending message (type=%d) response\n",
+                  hip_get_msg_type(msg));
+        if (hip_fw_send_message(msg, addr) == -1) {
+            err = -1;
+        } else {
+            HIP_DEBUG("Response sent ok\n");
+        }
+    }
+
     free(msg_out);
     return err;
 }

=== modified file 'firewall/firewall_control.h'
--- firewall/firewall_control.h 2010-10-15 15:29:14 +0000
+++ firewall/firewall_control.h 2011-10-31 18:21:26 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -28,6 +28,6 @@
 
 #include "lib/core/protodefs.h"
 
-int hip_handle_msg(struct hip_common *msg);
+int hip_handle_msg(struct hip_common *msg, struct sockaddr *addr);
 
 #endif /* HIP_FIREWALL_FIREWALL_CONTROL_H */

=== modified file 'lib/core/conf.c'
--- lib/core/conf.c     2011-10-31 17:38:04 +0000
+++ lib/core/conf.c     2011-10-31 18:21:26 +0000
@@ -181,6 +181,11 @@
 /* #define TYPE_RELAY         22 */
 
 /**
+ * The daemon process to be configured by the conf command.
+ */
+enum daemon_name daemon_name;
+
+/**
  * A help string containing the usage of @c hipconf and also
  * @c HIPL_SYSCONFDIR/hipd_config.
  *
@@ -226,6 +231,47 @@
 ;
 
 /**
+ * A help string containing the usage of @c hipfwconf.
+ *
+ * @note If you added a new action, do not forget to add a brief usage below
+ *       for the action.
+ */
+const char *hipfwconf_usage = "get ha <hit> | all\n";
+
+/**
+ * Send a message to hipd or hipfw and optionally receive an answer.
+ *
+ * @param msg       The message to be sent. The respective answer will be 
stored
+ *                  here as well.
+ * @param send_only 1 if no response from hipd should be requested.
+ *                  0 if it should block until a response from hipd is 
received.
+ *                  This option has no effect when sending messages to hipfw.
+ *
+ * @return  0 on success
+ *         -1 on error
+ */
+static int send_receive_message(struct hip_common *msg,
+                                const int send_only)
+{
+    if (daemon_name == HIP_DAEMON) {
+        if (hip_send_recv_daemon_info(msg, send_only, 0)) {
+            HIP_ERROR("Failed to send user message to the HIP daemon.\n");
+            return -1;
+        }
+    } else if (daemon_name == HIP_FIREWALL) {
+        if (hip_send_recv_firewall_info(msg)) {
+            HIP_ERROR("Failed to send user message to the HIP firewall.\n");
+            return -1;
+        }
+    } else {
+        HIP_ERROR("Destination daemon process unknown.\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
  * Query hipd for the HITs of the local host
  *
  * @param msg input/output message for the query/response for hipd
@@ -510,6 +556,25 @@
 /* Non-static functions -> global scope */
 
 /**
+ * Map daemon / firewall keyboard to its respective enum.
+ *
+ * @param argv an array of strings (command line args to hipconf)
+ * @return HIP_DAEMON in case of hipd keyword
+ *         HIP_FIREWALL in case of hipfw keyword
+ *         -1 else
+ */
+static int conf_get_process(const char *argv[])
+{
+    if (!strcmp(HIPCONF_HIPD_KEYWORD, argv[1])) {
+        return HIP_DAEMON;
+    } else if (!strcmp(HIPCONF_HIPFW_KEYWORD, argv[1])) {
+        return HIP_FIREWALL;
+    }
+
+    return -1;
+}
+
+/**
  * Map a symbolic hipconf action (=add/del) into a number
  *
  * @param argv an array of strings (command line args to hipconf)
@@ -526,61 +591,61 @@
 {
     int ret = -1;
 
-    if (!strcmp("add", argv[1])) {
+    if (!strcmp("add", argv[2])) {
         ret = ACTION_ADD;
-    } else if (!strcmp("del", argv[1])) {
+    } else if (!strcmp("del", argv[2])) {
         ret = ACTION_DEL;
-    } else if (!strcmp("new", argv[1])) {
+    } else if (!strcmp("new", argv[2])) {
         ret = ACTION_NEW;
-    } else if (!strcmp("get", argv[1])) {
+    } else if (!strcmp("get", argv[2])) {
         ret = ACTION_GET;
-    } else if (!strcmp("set", argv[1])) {
+    } else if (!strcmp("set", argv[2])) {
         ret = ACTION_SET;
-    } else if (!strcmp("inc", argv[1])) {
+    } else if (!strcmp("inc", argv[2])) {
         ret = ACTION_INC;
-    } else if (!strcmp("dec", argv[1])) {
+    } else if (!strcmp("dec", argv[2])) {
         ret = ACTION_DEC;
-    } else if (!strcmp("rst", argv[1])) {
+    } else if (!strcmp("rst", argv[2])) {
         ret = ACTION_RST;
-    } else if (!strcmp("run", argv[1])) {
+    } else if (!strcmp("run", argv[2])) {
         ret = ACTION_RUN;
-    } else if (!strcmp("load", argv[1])) {
+    } else if (!strcmp("load", argv[2])) {
         ret = ACTION_LOAD;
-    } else if (!strcmp("heartbeat", argv[1])) {
+    } else if (!strcmp("heartbeat", argv[2])) {
         ret = ACTION_HEARTBEAT;
-    } else if (!strcmp("locator", argv[1])) {
+    } else if (!strcmp("locator", argv[2])) {
         ret = ACTION_LOCATOR;
-    } else if (!strcmp("debug", argv[1])) {
+    } else if (!strcmp("debug", argv[2])) {
         ret = ACTION_DEBUG;
-    } else if (!strcmp("transform", argv[1])) {
+    } else if (!strcmp("transform", argv[2])) {
         ret = ACTION_TRANSORDER;
-    } else if (!strcmp("reinit", argv[1])) {
+    } else if (!strcmp("reinit", argv[2])) {
         ret = ACTION_REINIT;
-    } else if (!strcmp("manual-update", argv[1])) {
+    } else if (!strcmp("manual-update", argv[2])) {
         ret = ACTION_MANUAL_UPDATE;
-    } else if (!strcmp("hit-to-lsi", argv[1])) {
+    } else if (!strcmp("hit-to-lsi", argv[2])) {
         ret = ACTION_HIT_TO_LSI;
-    } else if (!strcmp("nsupdate", argv[1])) {
+    } else if (!strcmp("nsupdate", argv[2])) {
         ret = ACTION_NSUPDATE;
-    } else if (!strcmp("hit-to-ip-set", argv[1])) {
+    } else if (!strcmp("hit-to-ip-set", argv[2])) {
         ret = ACTION_HIT_TO_IP_SET;
-    } else if (!strcmp("hit-to-ip", argv[1])) {
+    } else if (!strcmp("hit-to-ip", argv[2])) {
         ret = ACTION_HIT_TO_IP;
-    } else if (!strcmp("shotgun", argv[1])) {
+    } else if (!strcmp("shotgun", argv[2])) {
         ret = ACTION_SHOTGUN;
-    } else if (!strcmp("lsi-to-hit", argv[1])) {
+    } else if (!strcmp("lsi-to-hit", argv[2])) {
         ret = ACTION_LSI_TO_HIT;
-    } else if (!strcmp("nat", argv[1])) {
-        if (!strcmp("port", argv[2])) {
-            if (!strcmp("local", argv[3])) {
+    } else if (!strcmp("nat", argv[2])) {
+        if (!strcmp("port", argv[3])) {
+            if (!strcmp("local", argv[4])) {
                 ret = ACTION_NAT_LOCAL_PORT;
-            } else if (!strcmp("peer", argv[3])) {
+            } else if (!strcmp("peer", argv[4])) {
                 ret = ACTION_NAT_PEER_PORT;
             }
         } else {
             ret = ACTION_NAT;
         }
-    } else if (!strcmp("broadcast", argv[1])) {
+    } else if (!strcmp("broadcast", argv[2])) {
         ret = ACTION_BROADCAST;
     }
 
@@ -670,45 +735,45 @@
         ret = TYPE_HA;
     } else if (!strcmp("shotgun", text)) {
         ret = TYPE_SHOTGUN;
-    } else if ((!strcmp("all", text)) && (strcmp("rst", argv[1]) == 0)) {
-        ret = TYPE_RST;
-    } else if ((!strcmp("peer_hit", text)) && (strcmp("rst", argv[1]) == 0)) {
-        ret = TYPE_RST;
-    } else if (strcmp("nat", argv[1]) == 0) {
-        if (argv[2] && strcmp("port", argv[2]) == 0) {
-            if (argv[3] && strcmp("local", argv[3]) == 0) {
+    } else if ((!strcmp("all", text)) && (strcmp("rst", argv[2]) == 0)) {
+        ret = TYPE_RST;
+    } else if ((!strcmp("peer_hit", text)) && (strcmp("rst", argv[2]) == 0)) {
+        ret = TYPE_RST;
+    } else if (strcmp("nat", argv[2]) == 0) {
+        if (argv[3] && strcmp("port", argv[3]) == 0) {
+            if (argv[4] && strcmp("local", argv[4]) == 0) {
                 ret = TYPE_NAT_LOCAL_PORT;
-            } else if (argv[3] && strcmp("peer", argv[3]) == 0) {
+            } else if (argv[4] && strcmp("peer", argv[4]) == 0) {
                 ret = TYPE_NAT_PEER_PORT;
             }
         } else {
             ret = TYPE_NAT;
         }
-    } else if (strcmp("locator", argv[1]) == 0) {
+    } else if (strcmp("locator", argv[2]) == 0) {
         ret = TYPE_LOCATOR;
     } else if (!strcmp("debug", text)) {
         ret = TYPE_DEBUG;
     } else if (!strcmp("order", text)) {
         ret = TYPE_ORDER;
-    } else if (strcmp("heartbeat", argv[1]) == 0) {
+    } else if (strcmp("heartbeat", argv[2]) == 0) {
         ret = TYPE_HEARTBEAT;
     } else if (!strcmp("ttl", text)) {
         ret = TYPE_TTL;
     } else if (!strcmp("config", text)) {
         ret = TYPE_CONFIG;
-    } else if (strcmp("manual-update", argv[1]) == 0) {
+    } else if (strcmp("manual-update", argv[2]) == 0) {
         ret = TYPE_MANUAL_UPDATE;
-    } else if (strcmp("hit-to-lsi", argv[1]) == 0) {
+    } else if (strcmp("hit-to-lsi", argv[2]) == 0) {
         ret = TYPE_HIT_TO_LSI;
-    } else if (strcmp("nsupdate", argv[1]) == 0) {
+    } else if (strcmp("nsupdate", argv[2]) == 0) {
         ret = TYPE_NSUPDATE;
-    } else if (strcmp("hit-to-ip-set", argv[1]) == 0) {
+    } else if (strcmp("hit-to-ip-set", argv[2]) == 0) {
         ret = TYPE_HIT_TO_IP_SET;
-    } else if (strcmp("hit-to-ip", argv[1]) == 0) {
+    } else if (strcmp("hit-to-ip", argv[2]) == 0) {
         ret = TYPE_HIT_TO_IP;
-    } else if (strcmp("lsi-to-hit", argv[1]) == 0) {
+    } else if (strcmp("lsi-to-hit", argv[2]) == 0) {
         ret = TYPE_LSI_TO_HIT;
-    } else if (strcmp("broadcast", argv[1]) == 0) {
+    } else if (strcmp("broadcast", argv[2]) == 0) {
         ret = TYPE_BROADCAST;
     } else {
         HIP_DEBUG("ERROR: NO MATCHES FOUND \n");
@@ -725,7 +790,7 @@
  *       here in the switch(action) block.
  * @param action integer value for an action
  * @return an index for argv[], which indicates the type argument.
- *         Usually either 1 or 2.
+ *         Usually either 2 or 3.
  */
 static int conf_get_type_arg(int action)
 {
@@ -753,15 +818,15 @@
     case ACTION_HIT_TO_IP:
     case ACTION_HIT_TO_IP_SET:
     case ACTION_BROADCAST:
+        type_arg = 3;
+        break;
+    case ACTION_MANUAL_UPDATE:
+    case ACTION_HIT_TO_LSI:
+    case ACTION_LSI_TO_HIT:
+    case ACTION_DEBUG:
+    case ACTION_SHOTGUN:
         type_arg = 2;
         break;
-    case ACTION_MANUAL_UPDATE:
-    case ACTION_HIT_TO_LSI:
-    case ACTION_LSI_TO_HIT:
-    case ACTION_DEBUG:
-    case ACTION_SHOTGUN:
-        type_arg = 1;
-        break;
     default:
         break;
     }
@@ -2042,10 +2107,10 @@
     HIP_IFEL(optc > 1, -1, "Too many arguments\n");
 
     HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_GET_HA_INFO, 0), -1,
-             "Building of daemon header failed\n");
+             "Building of user msg header failed\n");
 
-    HIP_IFEL(hip_send_recv_daemon_info(msg, send_only, 0), -1,
-             "send recv daemon info\n");
+    HIP_IFEL(send_receive_message(msg, send_only), -1,
+             "send recv info\n");
 
     while ((current_param = hip_get_next_param(msg, current_param))) {
         ha = hip_get_param_contents_direct(current_param);
@@ -2313,8 +2378,9 @@
             *comment = '\0';
         }
 
-        /* prefix the contents of the line with" hipconf"  */
-        res_len = sprintf(str, "hipconf %s", c);
+        /* prefix the contents of the line with" hipconf HIPCONF_HIPD_KEYWORD"
+         * Only hipd parses config files as hipconf commands, hardcode it as 
target */
+        res_len = sprintf(str, "hipconf %s %s", HIPCONF_HIPD_KEYWORD, c);
         if (str[res_len] == '\n') {
             str[res_len] = '\0';
         }
@@ -2327,7 +2393,6 @@
             args[i++] = token;
             token     = strtok(NULL, " \t");
         }
-
         err = hip_do_hipconf(i, args, 1);
         if (err) {
             HIP_ERROR("Error on the following line: %s\n", line);
@@ -2440,6 +2505,7 @@
  *
  * @param argc the number of arguments
  * @param argv the arguments
+ * @param daemon_process HIP_DAEMON for messages to hipd, HIP_FIREWALL for 
hipfw
  * @param send_only 1 if no response from hipd should be requrested, or 0 if
  *                  should block for a response from hipd
  * @return zero for success and negative on error
@@ -2451,24 +2517,29 @@
     struct hip_common *msg    = NULL;
 
     /* Check that we have at least one command line argument. */
-    if (argc < 2) {
-        HIP_ERROR("Invalid arguments.\n\n%s usage:\n%s\n",
-                  argv[0], hipconf_usage);
+    if (argc < 3) {
+        HIP_ERROR("Invalid arguments.\nUsage: %s %s | %s <command>\n\n"
+                  "HIP daemon commands:\n%s\n\nHIP firewall commands:\n%s\n",
+                  argv[0], HIPCONF_HIPD_KEYWORD, HIPCONF_HIPFW_KEYWORD,
+                  hipconf_usage, hipfwconf_usage);
         return -1;
     }
 
+    /* set context for this conf command */
+    daemon_name = conf_get_process(argv);
+
     /* Get a numeric value representing the action. */
     action = conf_get_action(argv);
 
     if (action == -1) {
-        HIP_ERROR("Invalid action argument '%s'\n", argv[1]);
+        HIP_ERROR("Invalid action argument '%s'\n", argv[2]);
         return -1;
     }
 
     /* Check that we have at least the minimum number of arguments
      * for the given action. */
-    if (argc < conf_check_action_argc(action) + 2) {
-        HIP_ERROR("Not enough arguments given for the action '%s'\n", argv[1]);
+    if (argc < conf_check_action_argc(action) + 3) {
+        HIP_ERROR("Not enough arguments given for the action '%s'\n", argv[2]);
         return -1;
     }
 
@@ -2496,14 +2567,14 @@
     /* Call handler function from the handler function pointer
      * array at index "type" with given commandline arguments.
      * The functions build a hip_common message. */
-    if (argc == 3) {
-        err = (*action_handler[type])(msg, action, &argv[2], argc - 3, 
send_only);
+    if (argc == 4) {
+        err = (*action_handler[type])(msg, action, &argv[3], argc - 4, 
send_only);
     } else {
-        err = (*action_handler[type])(msg, action, &argv[3], argc - 3, 
send_only);
+        err = (*action_handler[type])(msg, action, &argv[4], argc - 4, 
send_only);
     }
 
     if (err != 0) {
-        HIP_ERROR("Failed to send a message to the HIP daemon.\n");
+        HIP_ERROR("Failed to send user message.\n");
         goto out_err;
     }
 
@@ -2512,9 +2583,7 @@
         goto out_err;
     }
 
-    /* Send message to hipd */
-    HIP_IFEL(hip_send_recv_daemon_info(msg, send_only, 0), -1,
-             "Failed to send user message to the HIP daemon.\n");
+    send_receive_message(msg, send_only);
 
     HIP_INFO("User message was sent successfully to the HIP daemon.\n");
 

=== modified file 'lib/core/conf.h'
--- lib/core/conf.h     2011-08-15 14:11:56 +0000
+++ lib/core/conf.h     2011-10-31 18:21:26 +0000
@@ -54,6 +54,11 @@
 #define ACTION_ADD 1
 #define ACTION_NEW 3
 
+enum daemon_name { HIP_DAEMON, HIP_FIREWALL };
+/* keywords used to identify hipd / hipfw as target of hipconf command */
+#define HIPCONF_HIPD_KEYWORD  "daemon"
+#define HIPCONF_HIPFW_KEYWORD "firewall"
+
 int hip_handle_exec_app(int fork, int type, int argc,
                         const char *const argv[]);
 int hip_do_hipconf(int argc, const char *argv[], int send_only);

=== modified file 'lib/core/message.c'
--- lib/core/message.c  2011-10-25 21:44:47 +0000
+++ lib/core/message.c  2011-10-31 18:21:26 +0000
@@ -178,6 +178,30 @@
 }
 
 /**
+ * Connect a socket to the loopback address of hipd or hipfw.
+ *
+ * @param  hip_user_sock The socket to connect.
+ * @param  port          The port to connect.
+ * @return zero on success and negative on failure
+ * @note   currently only SOCK_DGRAM and AF_INET6 are supported
+ */
+static int hip_connect(int hip_user_sock, int port)
+{
+    struct sockaddr_in6 addr = { 0 };
+
+    addr.sin6_family = AF_INET6;
+    addr.sin6_port   = htons(port);
+    addr.sin6_addr   = in6addr_loopback;
+
+    if (connect(hip_user_sock, (struct sockaddr *) &addr, sizeof(addr))) {
+        HIP_ERROR("connection failed: %s\n", strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
  * Connect a socket to the loop back address of hipd
  *
  * @param hip_user_sock The socket to connect. Currently only SOCK_DGRAM
@@ -187,21 +211,7 @@
  */
 int hip_daemon_connect(int hip_user_sock)
 {
-    int                 err         = 0;
-    struct sockaddr_in6 daemon_addr = { 0 };
-    // We're using system call here add thus resetting errno.
-    errno = 0;
-
-    daemon_addr.sin6_family = AF_INET6;
-    daemon_addr.sin6_port   = htons(HIP_DAEMON_LOCAL_PORT);
-    daemon_addr.sin6_addr   = in6addr_loopback;
-
-    HIP_IFEL(connect(hip_user_sock, (struct sockaddr *) &daemon_addr,
-                     sizeof(daemon_addr)), -1, "connection to daemon 
failed\n");
-
-out_err:
-
-    return err;
+    return hip_connect(hip_user_sock, HIP_DAEMON_LOCAL_PORT);
 }
 
 /**
@@ -479,6 +489,83 @@
 }
 
 /**
+ * A generic function to send messages to hipfw with subsequent reply. This 
will
+ * block the process until the hipfw sends the response or a predefined timeout
+ * is exceeded.
+ *
+ * @param msg An input/output parameter. As input, contains the
+ *            message to be sent to hipfw. As output, hipfw response
+ *            will be written here.
+ * @return zero on success and negative on failure.
+ * @note currently the only SOCK_DGRAM and AF_INET6 are supported
+ */
+int hip_send_recv_firewall_info(struct hip_common *const msg)
+{
+    int                 tmp_sock = 0, len = 0,  n = 0, err = 0;
+    uint8_t             msg_type_old, msg_type_new;
+    struct sockaddr_in6 dst_addr = { 0 };
+
+    HIP_ASSERT(msg);
+    const uint16_t msg_length = hip_get_msg_total_len(msg);
+
+    if ((tmp_sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+        HIP_ERROR("failed to open new socket: %s\n", strerror(errno));
+        return -1;
+    }
+
+    dst_addr.sin6_family = AF_INET6;
+    dst_addr.sin6_addr   = in6addr_loopback;
+
+    HIP_IFEL(daemon_bind_socket(tmp_sock, (struct sockaddr *) &dst_addr),
+             -1, "bind failed\n");
+    HIP_IFEL(hip_connect(tmp_sock, HIP_FIREWALL_PORT), -1, "connect failed\n");
+
+    /* Require a response from hipd */
+    hip_set_msg_response(msg, 1);
+
+    msg_type_old = hip_get_msg_type(msg);
+
+    HIP_DEBUG("Sending msg type %d\n", msg_type_old);
+    HIP_IFEL(send(tmp_sock, msg, msg_length, 0) < msg_length, -1,
+             "sending of user message failed: %s\n", strerror(errno));
+
+    HIP_DEBUG("sending of user message successful. Waiting for reply...\n");
+
+    HIP_IFEL((len = peek_recv_total_len(tmp_sock, 0,
+                                            HIP_DEFAULT_MSG_TIMEOUT)) < 0,
+             -1, "failed to receive firewall reply\n");
+
+    n = recv(tmp_sock, msg, len, 0);
+
+    HIP_DEBUG("%d bytes received from HIP daemon\n", n);
+
+    if (n == 0) {
+        HIP_INFO("The HIP firewall has performed an " \
+                 "orderly shutdown.\n");
+        // Note. This is not an error condition, thus we return zero.
+        goto out_err;
+    } else if (n < (int) sizeof(struct hip_common)) {
+        HIP_ERROR("Could not receive message from firewall.\n");
+        goto out_err;
+    }
+
+    /* You have a message synchronization problem if you see this error. */
+    msg_type_new = hip_get_msg_type(msg);
+    HIP_IFEL(msg_type_new != msg_type_old, -1,
+             "Message sync problem. Expected %d, got %d\n",
+             msg_type_old, msg_type_new);
+
+    if (hip_get_msg_err(msg)) {
+        HIP_ERROR("HIP message contained an error.\n");
+        err = -EHIP;
+    }
+
+out_err:
+    close(tmp_sock);
+    return err;
+}
+
+/**
  * Read an interprocess (user) message
  *
  * @param  sockfd   a socket from where to read

=== modified file 'lib/core/message.h'
--- lib/core/message.h  2011-08-15 14:11:56 +0000
+++ lib/core/message.h  2011-10-31 18:21:26 +0000
@@ -46,5 +46,6 @@
 int hip_send_recv_daemon_info(struct hip_common *msg,
                               int send_only,
                               int opt_socket);
+int hip_send_recv_firewall_info(struct hip_common *const msg);
 
 #endif /* HIP_LIB_CORE_MESSAGE_H */

Other related posts: