Module: monitoring-plugins
 Branch: master
 Commit: 0453d6d1e206c1f4c156bf73c473608a8c0da4f5
 Author: Lorenz Kästle <12514511+rincewinds...@users.noreply.github.com>
   Date: Tue Apr  1 00:44:26 2025 +0200
    URL: 
https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=0453d6d1

Refactor check_dhcp

---

 plugins-root/check_dhcp.c          | 741 ++++++++++++++++++++-----------------
 plugins-root/check_dhcp.d/config.h |  50 +++
 2 files changed, 448 insertions(+), 343 deletions(-)

diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c
index 70809956..3732d970 100644
--- a/plugins-root/check_dhcp.c
+++ b/plugins-root/check_dhcp.c
@@ -4,7 +4,7 @@
  *
  * License: GPL
  * Copyright (c) 2001-2004 Ethan Galstad (nag...@nagios.org)
- * Copyright (c) 2001-2023 Monitoring Plugins Development Team
+ * Copyright (c) 2001-2025 Monitoring Plugins Development Team
  *
  * Description:
  *
@@ -34,13 +34,17 @@
  *****************************************************************************/
 
 const char *progname = "check_dhcp";
-const char *copyright = "2001-2024";
+const char *copyright = "2001-2025";
 const char *email = "devel@monitoring-plugins.org";
 
-#include "common.h"
-#include "netutils.h"
-#include "utils.h"
+#include "../plugins/common.h"
+#include "../plugins/utils.h"
+#include "./check_dhcp.d/config.h"
+#include "../lib/output.h"
+#include "../lib/utils_base.h"
 
+#include "states.h"
+#include <stdint.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -111,8 +115,9 @@ static long mac_addr_dlpi(const char *, int, u_char *);
 
 /**** Common definitions ****/
 
-#define OK    0
-#define ERROR -1
+#define OK           0
+#define ERROR        -1
+#define MAC_ADDR_LEN 6
 
 /**** DHCP definitions ****/
 
@@ -149,12 +154,6 @@ typedef struct dhcp_offer_struct {
        struct dhcp_offer_struct *next;
 } dhcp_offer;
 
-typedef struct requested_server_struct {
-       struct in_addr server_address;
-       bool answered;
-       struct requested_server_struct *next;
-} requested_server;
-
 #define BOOTREQUEST 1
 #define BOOTREPLY   2
 
@@ -186,65 +185,60 @@ typedef struct requested_server_struct {
 #define ETHERNET_HARDWARE_ADDRESS        1 /* used in htype field of dhcp 
packet */
 #define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware 
addresses */
 
-static bool unicast = false;   /* unicast mode: mimic a DHCP relay */
-static bool exclusive = false; /* exclusive mode aka "rogue DHCP server 
detection" */
-static struct in_addr my_ip;   /* our address (required for relay) */
-static struct in_addr dhcp_ip; /* server to query (if in unicast mode) */
-static unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH] = "";
-static unsigned char *user_specified_mac = NULL;
-
-static char network_interface_name[IFNAMSIZ] = "eth0";
-
-static uint32_t packet_xid = 0;
-
-static uint32_t dhcp_lease_time = 0;
-static uint32_t dhcp_renewal_time = 0;
-static uint32_t dhcp_rebinding_time = 0;
-
-static int dhcpoffer_timeout = 2;
-
-static dhcp_offer *dhcp_offer_list = NULL;
-static requested_server *requested_server_list = NULL;
-
-static int valid_responses = 0; /* number of valid DHCPOFFERs we received */
-static int requested_servers = 0;
-static int requested_responses = 0;
-
-static bool request_specific_address = false;
-static bool received_requested_address = false;
 static int verbose = 0;
-static struct in_addr requested_address;
 
-static int process_arguments(int, char **);
-static int call_getopt(int, char **);
-static int validate_arguments(int);
+typedef struct process_arguments_wrapper {
+       int error;
+       check_dhcp_config config;
+} process_arguments_wrapper;
+
+static process_arguments_wrapper process_arguments(int /*argc*/, char ** 
/*argv*/);
 void print_usage(void);
 static void print_help(void);
 
-static void resolve_host(const char *in, struct in_addr *out);
-static unsigned char *mac_aton(const char *);
-static void print_hardware_address(const unsigned char *);
-static int get_hardware_address(int, char *);
-static int get_ip_address(int, char *);
-
-static int send_dhcp_discover(int);
-static int get_dhcp_offer(int);
-
-static int get_results(void);
-
-static int add_dhcp_offer(struct in_addr, dhcp_packet *);
-static int free_dhcp_offer_list(void);
-static int free_requested_server_list(void);
-
-static int create_dhcp_socket(void);
-static int close_dhcp_socket(int);
-static int send_dhcp_packet(void *, int, int, struct sockaddr_in *);
-static int receive_dhcp_packet(void *, int, int, int, struct sockaddr_in *);
+static void resolve_host(const char * /*in*/, struct in_addr * /*out*/);
+static unsigned char *mac_aton(const char * /*string*/);
+static void print_hardware_address(const unsigned char * /*address*/);
+static int get_hardware_address(int /*sock*/, char * /*interface_name*/, 
unsigned char *client_hardware_address);
+
+typedef struct get_ip_address_wrapper {
+       int error;
+       struct in_addr my_ip;
+} get_ip_address_wrapper;
+static get_ip_address_wrapper get_ip_address(int /*sock*/, char * 
/*interface_name*/);
+
+typedef struct send_dhcp_discover_wrapper {
+       int error;
+       uint32_t packet_xid;
+} send_dhcp_discover_wrapper;
+static send_dhcp_discover_wrapper send_dhcp_discover(int socket, bool unicast, 
struct in_addr dhcp_ip, struct in_addr requested_address,
+                                                                               
                         bool request_specific_address, struct in_addr my_ip,
+                                                                               
                         unsigned char *client_hardware_address);
+typedef struct get_dhcp_offer_wrapper {
+       int error;
+       int valid_responses;
+       dhcp_offer *dhcp_offer_list;
+} get_dhcp_offer_wrapper;
+static get_dhcp_offer_wrapper get_dhcp_offer(int /*sock*/, int 
dhcpoffer_timeout, uint32_t packet_xid, dhcp_offer *dhcp_offer_list,
+                                                                               
         const unsigned char *client_hardware_address);
+
+static mp_subcheck get_results(bool exclusive, int requested_servers, struct 
in_addr requested_address, bool request_specific_address,
+                                                          requested_server 
*requested_server_list, int valid_responses, dhcp_offer *dhcp_offer_list);
+
+typedef struct add_dhcp_offer_wrapper {
+       int error;
+       dhcp_offer *dhcp_offer_list;
+} add_dhcp_offer_wrapper;
+static add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr /*source*/, 
dhcp_packet * /*offer_packet*/, dhcp_offer *dhcp_offer_list);
+static int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list);
+static int free_requested_server_list(requested_server *requested_server_list);
+
+static int create_dhcp_socket(bool /*unicast*/, char *network_interface_name);
+static int close_dhcp_socket(int /*sock*/);
+static int send_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int 
/*sock*/, struct sockaddr_in * /*dest*/);
+static int receive_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int 
/*sock*/, int /*timeout*/, struct sockaddr_in * /*address*/);
 
 int main(int argc, char **argv) {
-       int dhcp_socket;
-       int result = STATE_UNKNOWN;
-
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
@@ -252,45 +246,80 @@ int main(int argc, char **argv) {
        /* Parse extra opts if any */
        argv = np_extra_opts(&argc, argv, progname);
 
-       if (process_arguments(argc, argv) != OK) {
+       process_arguments_wrapper tmp = process_arguments(argc, argv);
+
+       if (tmp.error != OK) {
                usage4(_("Could not parse arguments"));
        }
 
+       check_dhcp_config config = tmp.config;
+       if (config.output_format_is_set) {
+               mp_set_format(config.output_format);
+       }
+
        /* create socket for DHCP communications */
-       dhcp_socket = create_dhcp_socket();
+       int dhcp_socket = create_dhcp_socket(config.unicast_mode, 
config.network_interface_name);
 
        /* get hardware address of client machine */
-       if (user_specified_mac != NULL) {
-               memcpy(client_hardware_address, user_specified_mac, 6);
+       unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH] = "";
+       if (config.user_specified_mac != NULL) {
+               memcpy(client_hardware_address, config.user_specified_mac, 
MAC_ADDR_LEN);
        } else {
-               get_hardware_address(dhcp_socket, network_interface_name);
+               get_hardware_address(dhcp_socket, 
config.network_interface_name, client_hardware_address);
        }
 
-       if (unicast) { /* get IP address of client machine */
-               get_ip_address(dhcp_socket, network_interface_name);
+       struct in_addr my_ip = {0};
+
+       if (config.unicast_mode) { /* get IP address of client machine */
+               get_ip_address_wrapper tmp_get_ip = get_ip_address(dhcp_socket, 
config.network_interface_name);
+               if (tmp_get_ip.error == OK) {
+                       my_ip = tmp_get_ip.my_ip;
+               } else {
+                       // TODO failed to get own IP
+                       die(STATE_UNKNOWN, "Failed to retrieve my own IP 
address in unicast mode");
+               }
        }
 
        /* send DHCPDISCOVER packet */
-       send_dhcp_discover(dhcp_socket);
+       send_dhcp_discover_wrapper disco_res = send_dhcp_discover(dhcp_socket, 
config.unicast_mode, config.dhcp_ip, config.requested_address,
+                                                                               
                                          config.request_specific_address, 
my_ip, client_hardware_address);
+
+       if (disco_res.error != OK) {
+               // DO something?
+               die(STATE_UNKNOWN, "Failed to send DHCP discover");
+       }
 
        /* wait for a DHCPOFFER packet */
-       get_dhcp_offer(dhcp_socket);
+       get_dhcp_offer_wrapper offer_res =
+               get_dhcp_offer(dhcp_socket, config.dhcpoffer_timeout, 
disco_res.packet_xid, NULL, client_hardware_address);
+
+       int valid_responses = 0;
+       dhcp_offer *dhcp_offer_list = NULL;
+       if (offer_res.error == OK) {
+               valid_responses = offer_res.valid_responses;
+               dhcp_offer_list = offer_res.dhcp_offer_list;
+       } else {
+               die(STATE_UNKNOWN, "Failed to get DHCP offers");
+       }
 
        /* close socket we created */
        close_dhcp_socket(dhcp_socket);
 
-       /* determine state/plugin output to return */
-       result = get_results();
+       mp_check overall = mp_check_init();
 
+       /* determine state/plugin output to return */
+       mp_subcheck sc_res = get_results(config.exclusive_mode, 
config.num_of_requested_servers, config.requested_address,
+                                                                        
config.request_specific_address, config.requested_server_list, valid_responses, 
dhcp_offer_list);
+       mp_add_subcheck_to_check(&overall, sc_res);
        /* free allocated memory */
-       free_dhcp_offer_list();
-       free_requested_server_list();
+       free_dhcp_offer_list(dhcp_offer_list);
+       free_requested_server_list(config.requested_server_list);
 
-       return result;
+       mp_exit(overall);
 }
 
 /* determines hardware address on client machine */
-static int get_hardware_address(int sock, char *interface_name) {
+int get_hardware_address(int sock, char *interface_name, unsigned char 
*client_hardware_address) {
 
 #if defined(__linux__)
        struct ifreq ifr;
@@ -304,7 +333,7 @@ static int get_hardware_address(int sock, char 
*interface_name) {
                exit(STATE_UNKNOWN);
        }
 
-       memcpy(&client_hardware_address[0], &ifr.ifr_hwaddr.sa_data, 6);
+       memcpy(&client_hardware_address[0], &ifr.ifr_hwaddr.sa_data, 
MAC_ADDR_LEN);
 
 #elif defined(__bsd__)
        /* King 2004    see ACKNOWLEDGEMENTS */
@@ -404,7 +433,7 @@ static int get_hardware_address(int sock, char 
*interface_name) {
 }
 
 /* determines IP address of the client interface */
-static int get_ip_address(int sock, char *interface_name) {
+get_ip_address_wrapper get_ip_address(int sock, char *interface_name) {
 #if defined(SIOCGIFADDR)
        struct ifreq ifr;
 
@@ -416,29 +445,28 @@ static int get_ip_address(int sock, char *interface_name) 
{
                exit(STATE_UNKNOWN);
        }
 
-       my_ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
-
 #else
        printf(_("Error: Cannot get interface IP address on this platform.\n"));
        exit(STATE_UNKNOWN);
 #endif
 
+       get_ip_address_wrapper result = {
+               .error = OK,
+               .my_ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr,
+       };
+
        if (verbose) {
-               printf(_("Pretending to be relay client %s\n"), 
inet_ntoa(my_ip));
+               printf(_("Pretending to be relay client %s\n"), 
inet_ntoa(result.my_ip));
        }
 
-       return OK;
+       return result;
 }
 
 /* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */
-static int send_dhcp_discover(int sock) {
-       dhcp_packet discover_packet;
-       struct sockaddr_in sockaddr_broadcast;
-       unsigned short opts;
-
-       /* clear the packet data structure */
-       bzero(&discover_packet, sizeof(discover_packet));
-
+static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, 
struct in_addr dhcp_ip, struct in_addr requested_address,
+                                                                               
                         bool request_specific_address, struct in_addr my_ip,
+                                                                               
                         unsigned char *client_hardware_address) {
+       dhcp_packet discover_packet = {0};
        /* boot request flag (backward compatible with BOOTP servers) */
        discover_packet.op = BOOTREQUEST;
 
@@ -448,12 +476,15 @@ static int send_dhcp_discover(int sock) {
        /* length of our hardware address */
        discover_packet.hlen = ETHERNET_HARDWARE_ADDRESS_LENGTH;
 
+       send_dhcp_discover_wrapper result = {
+               .error = OK,
+       };
        /*
         * transaction ID is supposed to be random.
         */
        srand(time(NULL) ^ getpid());
-       packet_xid = random();
-       discover_packet.xid = htonl(packet_xid);
+       result.packet_xid = random();
+       discover_packet.xid = htonl(result.packet_xid);
 
        /*discover_packet.secs=htons(65535);*/
        discover_packet.secs = 0xFF;
@@ -473,7 +504,7 @@ static int send_dhcp_discover(int sock) {
        discover_packet.options[2] = '\x53';
        discover_packet.options[3] = '\x63';
 
-       opts = 4;
+       unsigned short opts = 4;
        /* DHCP message type is embedded in options field */
        discover_packet.options[opts++] = DHCP_OPTION_MESSAGE_TYPE; /* DHCP 
message type option identifier */
        discover_packet.options[opts++] = '\x01';                   /* DHCP 
message option length in bytes */
@@ -497,10 +528,11 @@ static int send_dhcp_discover(int sock) {
        discover_packet.hops = unicast ? 1 : 0;
 
        /* send the DHCPDISCOVER packet to broadcast address */
-       sockaddr_broadcast.sin_family = AF_INET;
-       sockaddr_broadcast.sin_port = htons(DHCP_SERVER_PORT);
-       sockaddr_broadcast.sin_addr.s_addr = unicast ? dhcp_ip.s_addr : 
INADDR_BROADCAST;
-       bzero(&sockaddr_broadcast.sin_zero, 
sizeof(sockaddr_broadcast.sin_zero));
+       struct sockaddr_in sockaddr_broadcast = {
+               .sin_family = AF_INET,
+               .sin_port = htons(DHCP_SERVER_PORT),
+               .sin_addr.s_addr = unicast ? dhcp_ip.s_addr : INADDR_BROADCAST,
+       };
 
        if (verbose) {
                printf(_("DHCPDISCOVER to %s port %d\n"), 
inet_ntoa(sockaddr_broadcast.sin_addr), ntohs(sockaddr_broadcast.sin_port));
@@ -518,25 +550,21 @@ static int send_dhcp_discover(int sock) {
                printf("\n\n");
        }
 
-       return OK;
+       return result;
 }
 
 /* waits for a DHCPOFFER message from one or more DHCP servers */
-static int get_dhcp_offer(int sock) {
-       dhcp_packet offer_packet;
-       struct sockaddr_in source;
-       struct sockaddr_in via;
-       int result = OK;
-       int responses = 0;
-       int x;
+get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, 
uint32_t packet_xid, dhcp_offer *dhcp_offer_list,
+                                                                         const 
unsigned char *client_hardware_address) {
        time_t start_time;
-       time_t current_time;
-
        time(&start_time);
 
+       int result = OK;
+       int responses = 0;
+       int valid_responses = 0;
        /* receive as many responses as we can */
-       for (responses = 0, valid_responses = 0;;) {
-
+       for (;;) {
+               time_t current_time;
                time(&current_time);
                if ((current_time - start_time) >= dhcpoffer_timeout) {
                        break;
@@ -546,9 +574,8 @@ static int get_dhcp_offer(int sock) {
                        printf("\n\n");
                }
 
-               bzero(&source, sizeof(source));
-               bzero(&via, sizeof(via));
-               bzero(&offer_packet, sizeof(offer_packet));
+               struct sockaddr_in source = {0};
+               dhcp_packet offer_packet = {0};
 
                result = OK;
                result = receive_dhcp_packet(&offer_packet, 
sizeof(offer_packet), sock, dhcpoffer_timeout, &source);
@@ -559,16 +586,16 @@ static int get_dhcp_offer(int sock) {
                        }
 
                        continue;
-               } else {
-                       if (verbose) {
-                               printf(_("Result=OK\n"));
-                       }
-
-                       responses++;
                }
+               if (verbose) {
+                       printf(_("Result=OK\n"));
+               }
+
+               responses++;
 
                /* The "source" is either a server or a relay. */
                /* Save a copy of "source" into "via" even if it's via itself */
+               struct sockaddr_in via = {0};
                memcpy(&via, &source, sizeof(source));
 
                if (verbose) {
@@ -593,12 +620,12 @@ static int get_dhcp_offer(int sock) {
                        printf("DHCPOFFER chaddr: ");
                }
 
-               for (x = 0; x < ETHERNET_HARDWARE_ADDRESS_LENGTH; x++) {
+               for (int i = 0; i < ETHERNET_HARDWARE_ADDRESS_LENGTH; i++) {
                        if (verbose) {
-                               printf("%02X", (unsigned 
char)offer_packet.chaddr[x]);
+                               printf("%02X", offer_packet.chaddr[i]);
                        }
 
-                       if (offer_packet.chaddr[x] != 
client_hardware_address[x]) {
+                       if (offer_packet.chaddr[i] != 
client_hardware_address[i]) {
                                result = ERROR;
                        }
                }
@@ -621,7 +648,12 @@ static int get_dhcp_offer(int sock) {
                        printf("DHCPOFFER giaddr: %s\n", 
inet_ntoa(offer_packet.giaddr));
                }
 
-               add_dhcp_offer(source.sin_addr, &offer_packet);
+               add_dhcp_offer_wrapper add_res = 
add_dhcp_offer(source.sin_addr, &offer_packet, dhcp_offer_list);
+               if (add_res.error != OK) {
+                       // TODO
+               } else {
+                       dhcp_offer_list = add_res.dhcp_offer_list;
+               }
 
                valid_responses++;
        }
@@ -631,14 +663,17 @@ static int get_dhcp_offer(int sock) {
                printf(_("Valid responses for this machine: %d\n"), 
valid_responses);
        }
 
-       return OK;
+       get_dhcp_offer_wrapper ret_val = {
+               .error = OK,
+               .valid_responses = valid_responses,
+               .dhcp_offer_list = dhcp_offer_list,
+       };
+       return ret_val;
 }
 
 /* sends a DHCP packet */
-static int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct 
sockaddr_in *dest) {
-       int result;
-
-       result = sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr 
*)dest, sizeof(*dest));
+int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct 
sockaddr_in *dest) {
+       int result = sendto(sock, (char *)buffer, buffer_size, 0, (struct 
sockaddr *)dest, sizeof(*dest));
 
        if (verbose) {
                printf(_("send_dhcp_packet result: %d\n"), result);
@@ -652,23 +687,19 @@ static int send_dhcp_packet(void *buffer, int 
buffer_size, int sock, struct sock
 }
 
 /* receives a DHCP packet */
-static int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int 
timeout, struct sockaddr_in *address) {
-       struct timeval tv;
-       fd_set readfds;
-       fd_set oobfds;
-       int recv_result;
-       socklen_t address_size;
-       struct sockaddr_in source_address;
-       int nfound;
-
+int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, 
struct sockaddr_in *address) {
        /* wait for data to arrive (up time timeout) */
-       tv.tv_sec = timeout;
-       tv.tv_usec = 0;
+       struct timeval timeout_val = {
+               .tv_sec = timeout,
+               .tv_usec = 0,
+       };
+       fd_set readfds;
        FD_ZERO(&readfds);
+       fd_set oobfds;
        FD_ZERO(&oobfds);
        FD_SET(sock, &readfds);
        FD_SET(sock, &oobfds);
-       nfound = select(sock + 1, &readfds, NULL, &oobfds, &tv);
+       int nfound = select(sock + 1, &readfds, NULL, &oobfds, &timeout_val);
 
        /* make sure some data has arrived */
        if (!FD_ISSET(sock, &readfds)) {
@@ -678,51 +709,44 @@ static int receive_dhcp_packet(void *buffer, int 
buffer_size, int sock, int time
                return ERROR;
        }
 
-       else {
-               bzero(&source_address, sizeof(source_address));
-               address_size = sizeof(source_address);
-               recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, 
(struct sockaddr *)&source_address, &address_size);
-               if (verbose) {
-                       printf("recv_result: %d\n", recv_result);
-               }
-
-               if (recv_result == -1) {
-                       if (verbose) {
-                               printf(_("recvfrom() failed, "));
-                               printf("errno: (%d) -> %s\n", errno, 
strerror(errno));
-                       }
-                       return ERROR;
-               } else {
-                       if (verbose) {
-                               printf(_("receive_dhcp_packet() result: %d\n"), 
recv_result);
-                               printf(_("receive_dhcp_packet() source: %s\n"), 
inet_ntoa(source_address.sin_addr));
-                       }
+       struct sockaddr_in source_address = {0};
+       socklen_t address_size = sizeof(source_address);
+       int recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, 
(struct sockaddr *)&source_address, &address_size);
+       if (verbose) {
+               printf("recv_result: %d\n", recv_result);
+       }
 
-                       memcpy(address, &source_address, 
sizeof(source_address));
-                       return OK;
+       if (recv_result == -1) {
+               if (verbose) {
+                       printf(_("recvfrom() failed, "));
+                       printf("errno: (%d) -> %s\n", errno, strerror(errno));
                }
+               return ERROR;
+       }
+       if (verbose) {
+               printf(_("receive_dhcp_packet() result: %d\n"), recv_result);
+               printf(_("receive_dhcp_packet() source: %s\n"), 
inet_ntoa(source_address.sin_addr));
        }
 
+       memcpy(address, &source_address, sizeof(source_address));
        return OK;
 }
 
 /* creates a socket for DHCP communication */
-static int create_dhcp_socket(void) {
-       struct sockaddr_in myname;
-       struct ifreq interface;
-       int sock;
-       int flag = 1;
-
+int create_dhcp_socket(bool unicast, char *network_interface_name) {
        /* Set up the address we're going to bind to. */
-       bzero(&myname, sizeof(myname));
-       myname.sin_family = AF_INET;
        /* listen to DHCP server port if we're in unicast mode */
-       myname.sin_port = htons(unicast ? DHCP_SERVER_PORT : DHCP_CLIENT_PORT);
-       myname.sin_addr.s_addr = unicast ? my_ip.s_addr : INADDR_ANY;
-       bzero(&myname.sin_zero, sizeof(myname.sin_zero));
+       struct sockaddr_in myname = {
+               .sin_family = AF_INET,
+               .sin_port = htons(unicast ? DHCP_SERVER_PORT : 
DHCP_CLIENT_PORT),
+               // TODO previously the next line was trying to use our own IP, 
we was not set
+               // until some point later, so it was removed. Recheck whether 
it is actually
+               // necessary/useful
+               .sin_addr.s_addr = INADDR_ANY,
+       };
 
        /* create a socket for DHCP communications */
-       sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (sock < 0) {
                printf(_("Error: Could not create socket!\n"));
                exit(STATE_UNKNOWN);
@@ -733,7 +757,7 @@ static int create_dhcp_socket(void) {
        }
 
        /* set the reuse address flag so we don't get errors when restarting */
-       flag = 1;
+       int flag = 1;
        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, 
sizeof(flag)) < 0) {
                printf(_("Error: Could not set reuse address option on DHCP 
socket!\n"));
                exit(STATE_UNKNOWN);
@@ -745,6 +769,7 @@ static int create_dhcp_socket(void) {
                exit(STATE_UNKNOWN);
        }
 
+       struct ifreq interface;
        /* bind socket to interface */
 #if defined(__linux__)
        strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ 
- 1);
@@ -769,18 +794,14 @@ static int create_dhcp_socket(void) {
 }
 
 /* closes DHCP socket */
-static int close_dhcp_socket(int sock) {
-
+int close_dhcp_socket(int sock) {
        close(sock);
-
        return OK;
 }
 
 /* adds a requested server address to list in memory */
-static int add_requested_server(struct in_addr server_address) {
-       requested_server *new_server;
-
-       new_server = (requested_server *)malloc(sizeof(requested_server));
+int add_requested_server(struct in_addr server_address, int 
*requested_servers, requested_server **requested_server_list) {
+       requested_server *new_server = (requested_server 
*)malloc(sizeof(requested_server));
        if (new_server == NULL) {
                return ERROR;
        }
@@ -788,10 +809,10 @@ static int add_requested_server(struct in_addr 
server_address) {
        new_server->server_address = server_address;
        new_server->answered = false;
 
-       new_server->next = requested_server_list;
-       requested_server_list = new_server;
+       new_server->next = *requested_server_list;
+       *requested_server_list = new_server;
 
-       requested_servers++;
+       *requested_servers += 1;
 
        if (verbose) {
                printf(_("Requested server address: %s\n"), 
inet_ntoa(new_server->server_address));
@@ -801,29 +822,31 @@ static int add_requested_server(struct in_addr 
server_address) {
 }
 
 /* adds a DHCP OFFER to list in memory */
-static int add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet) {
-       dhcp_offer *new_offer;
-       int x;
-       unsigned option_type;
-       unsigned option_length;
-       struct in_addr serv_ident = {0};
-
+add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr source, dhcp_packet 
*offer_packet, dhcp_offer *dhcp_offer_list) {
        if (offer_packet == NULL) {
-               return ERROR;
+               add_dhcp_offer_wrapper tmp = {
+                       .error = ERROR,
+               };
+               return tmp;
        }
 
+       uint32_t dhcp_lease_time = 0;
+       uint32_t dhcp_renewal_time = 0;
+       uint32_t dhcp_rebinding_time = 0;
+       dhcp_offer *new_offer;
+       struct in_addr serv_ident = {0};
        /* process all DHCP options present in the packet */
-       for (x = 4; x < MAX_DHCP_OPTIONS_LENGTH - 1;) {
+       for (int dchp_opt_idx = 4; dchp_opt_idx < MAX_DHCP_OPTIONS_LENGTH - 1;) 
{
 
-               if ((int)offer_packet->options[x] == -1) {
+               if ((int)offer_packet->options[dchp_opt_idx] == -1) {
                        break;
                }
 
                /* get option type */
-               option_type = offer_packet->options[x++];
+               unsigned option_type = offer_packet->options[dchp_opt_idx++];
 
                /* get option length */
-               option_length = offer_packet->options[x++];
+               unsigned option_length = offer_packet->options[dchp_opt_idx++];
 
                if (verbose) {
                        printf("Option: %d (0x%02X)\n", option_type, 
option_length);
@@ -832,27 +855,27 @@ static int add_dhcp_offer(struct in_addr source, 
dhcp_packet *offer_packet) {
                /* get option data */
                switch (option_type) {
                case DHCP_OPTION_LEASE_TIME:
-                       memcpy(&dhcp_lease_time, &offer_packet->options[x], 
sizeof(dhcp_lease_time));
+                       memcpy(&dhcp_lease_time, 
&offer_packet->options[dchp_opt_idx], sizeof(dhcp_lease_time));
                        dhcp_lease_time = ntohl(dhcp_lease_time);
                        break;
                case DHCP_OPTION_RENEWAL_TIME:
-                       memcpy(&dhcp_renewal_time, &offer_packet->options[x], 
sizeof(dhcp_renewal_time));
+                       memcpy(&dhcp_renewal_time, 
&offer_packet->options[dchp_opt_idx], sizeof(dhcp_renewal_time));
                        dhcp_renewal_time = ntohl(dhcp_renewal_time);
                        break;
                case DHCP_OPTION_REBINDING_TIME:
-                       memcpy(&dhcp_rebinding_time, &offer_packet->options[x], 
sizeof(dhcp_rebinding_time));
+                       memcpy(&dhcp_rebinding_time, 
&offer_packet->options[dchp_opt_idx], sizeof(dhcp_rebinding_time));
                        dhcp_rebinding_time = ntohl(dhcp_rebinding_time);
                        break;
                case DHCP_OPTION_SERVER_IDENTIFIER:
-                       memcpy(&serv_ident.s_addr, &offer_packet->options[x], 
sizeof(serv_ident.s_addr));
+                       memcpy(&serv_ident.s_addr, 
&offer_packet->options[dchp_opt_idx], sizeof(serv_ident.s_addr));
                        break;
                }
 
                /* skip option data we're ignoring */
                if (option_type == 0) { /* "pad" option, see RFC 2132 (3.1) */
-                       x += 1;
+                       dchp_opt_idx += 1;
                } else {
-                       x += option_length;
+                       dchp_opt_idx += option_length;
                }
        }
 
@@ -876,7 +899,10 @@ static int add_dhcp_offer(struct in_addr source, 
dhcp_packet *offer_packet) {
        new_offer = (dhcp_offer *)malloc(sizeof(dhcp_offer));
 
        if (new_offer == NULL) {
-               return ERROR;
+               add_dhcp_offer_wrapper tmp = {
+                       .error = ERROR,
+               };
+               return tmp;
        }
 
        /*
@@ -907,15 +933,18 @@ static int add_dhcp_offer(struct in_addr source, 
dhcp_packet *offer_packet) {
        new_offer->next = dhcp_offer_list;
        dhcp_offer_list = new_offer;
 
-       return OK;
+       add_dhcp_offer_wrapper result = {
+               .error = OK,
+               .dhcp_offer_list = dhcp_offer_list,
+       };
+
+       return result;
 }
 
 /* frees memory allocated to DHCP OFFER list */
-static int free_dhcp_offer_list(void) {
-       dhcp_offer *this_offer;
+int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list) {
        dhcp_offer *next_offer;
-
-       for (this_offer = dhcp_offer_list; this_offer != NULL; this_offer = 
next_offer) {
+       for (dhcp_offer *this_offer = dhcp_offer_list; this_offer != NULL; 
this_offer = next_offer) {
                next_offer = this_offer->next;
                free(this_offer);
        }
@@ -924,11 +953,9 @@ static int free_dhcp_offer_list(void) {
 }
 
 /* frees memory allocated to requested server list */
-static int free_requested_server_list(void) {
-       requested_server *this_server;
+int free_requested_server_list(requested_server *requested_server_list) {
        requested_server *next_server;
-
-       for (this_server = requested_server_list; this_server != NULL; 
this_server = next_server) {
+       for (requested_server *this_server = requested_server_list; this_server 
!= NULL; this_server = next_server) {
                next_server = this_server->next;
                free(this_server);
        }
@@ -937,22 +964,39 @@ static int free_requested_server_list(void) {
 }
 
 /* gets state and plugin output to return */
-static int get_results(void) {
-       dhcp_offer *temp_offer, *undesired_offer = NULL;
-       requested_server *temp_server;
-       int result;
-       uint32_t max_lease_time = 0;
-
-       received_requested_address = false;
+mp_subcheck get_results(bool exclusive, const int requested_servers, const 
struct in_addr requested_address, bool request_specific_address,
+                                               requested_server 
*requested_server_list, int valid_responses, dhcp_offer *dhcp_offer_list) {
+       mp_subcheck sc_dhcp_results = mp_subcheck_init();
+       sc_dhcp_results = mp_set_subcheck_default_state(sc_dhcp_results, 
STATE_OK);
 
-       /* checks responses from requested servers */
-       requested_responses = 0;
-       if (requested_servers > 0) {
+       /* we didn't receive any DHCPOFFERs */
+       if (dhcp_offer_list == NULL) {
+               sc_dhcp_results = mp_set_subcheck_state(sc_dhcp_results, 
STATE_CRITICAL);
+               xasprintf(&sc_dhcp_results.output, "%s", "No DHCP offers were 
received");
+               return sc_dhcp_results;
+       }
 
-               for (temp_server = requested_server_list; temp_server != NULL; 
temp_server = temp_server->next) {
+       if (valid_responses == 0) {
+               // No valid responses at all, so early exit here
+               sc_dhcp_results = mp_set_subcheck_state(sc_dhcp_results, 
STATE_CRITICAL);
+               xasprintf(&sc_dhcp_results.output, "No valid responses 
received");
+               return sc_dhcp_results;
+       }
 
-                       for (temp_offer = dhcp_offer_list; temp_offer != NULL; 
temp_offer = temp_offer->next) {
+       if (valid_responses == 1) {
+               xasprintf(&sc_dhcp_results.output, "Received %d DHCPOFFER", 
valid_responses);
+       } else {
+               xasprintf(&sc_dhcp_results.output, "Received %d DHCPOFFERs", 
valid_responses);
+       }
 
+       bool received_requested_address = false;
+       dhcp_offer *undesired_offer = NULL;
+       uint32_t max_lease_time = 0;
+       /* checks responses from requested servers */
+       int requested_responses = 0;
+       if (requested_servers > 0) {
+               for (requested_server *temp_server = requested_server_list; 
temp_server != NULL; temp_server = temp_server->next) {
+                       for (dhcp_offer *temp_offer = dhcp_offer_list; 
temp_offer != NULL; temp_offer = temp_offer->next) {
                                /* get max lease time we were offered */
                                if (temp_offer->lease_time > max_lease_time || 
temp_offer->lease_time == DHCP_INFINITE_TIME) {
                                        max_lease_time = temp_offer->lease_time;
@@ -963,7 +1007,7 @@ static int get_results(void) {
                                        received_requested_address = true;
                                }
 
-                               /* see if the servers we wanted a response from 
talked to us or not */
+                               /* see if the servers we wanted a response 
from, talked to us or not */
                                if (!memcmp(&temp_offer->server_address, 
&temp_server->server_address, sizeof(temp_server->server_address))) {
                                        if (verbose) {
                                                printf(_("DHCP Server Match: 
Offerer=%s"), inet_ntoa(temp_offer->server_address));
@@ -973,6 +1017,7 @@ static int get_results(void) {
                                                }
                                                printf(_("\n"));
                                        }
+
                                        if (!temp_server->answered) {
                                                requested_responses++;
                                                temp_server->answered = true;
@@ -983,19 +1028,32 @@ static int get_results(void) {
                }
 
                /* exclusive mode: check for undesired offers */
-               for (temp_offer = dhcp_offer_list; temp_offer != NULL; 
temp_offer = temp_offer->next) {
+               for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != 
NULL; temp_offer = temp_offer->next) {
                        if (!temp_offer->desired) {
                                undesired_offer = temp_offer; /* Checks only 
for the first undesired offer */
                                break;                        /* no further 
checks needed */
                        }
                }
-       }
 
-       /* else check and see if we got our requested address from any server */
-       else {
+               mp_subcheck sc_rqust_srvs = mp_subcheck_init();
+               xasprintf(&sc_rqust_srvs.output, "%d of %d requested servers 
responded", requested_responses, requested_servers);
 
-               for (temp_offer = dhcp_offer_list; temp_offer != NULL; 
temp_offer = temp_offer->next) {
+               if (requested_responses == requested_servers) {
+                       sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, 
STATE_OK);
+               } else if (requested_responses == 0) {
+                       sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, 
STATE_CRITICAL);
+               } else if (requested_responses < requested_servers) {
+                       sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, 
STATE_WARNING);
+               } else {
+                       // We received more(!) responses than we asked for?
+                       // This case shouldn't happen, but is here for 
completion
+                       sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, 
STATE_WARNING);
+               }
+               mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rqust_srvs);
 
+       } else {
+               /* else check and see if we got our requested address from any 
server */
+               for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != 
NULL; temp_offer = temp_offer->next) {
                        /* get max lease time we were offered */
                        if (temp_offer->lease_time > max_lease_time || 
temp_offer->lease_time == DHCP_INFINITE_TIME) {
                                max_lease_time = temp_offer->lease_time;
@@ -1008,79 +1066,77 @@ static int get_results(void) {
                }
        }
 
-       result = STATE_OK;
-       if (valid_responses == 0) {
-               result = STATE_CRITICAL;
-       } else if (requested_servers > 0 && requested_responses == 0) {
-               result = STATE_CRITICAL;
-       } else if (requested_responses < requested_servers) {
-               result = STATE_WARNING;
-       } else if (request_specific_address && !received_requested_address) {
-               result = STATE_WARNING;
+       if (max_lease_time == DHCP_INFINITE_TIME) {
+               xasprintf(&sc_dhcp_results.output, "%s, max lease time = 
Infinity", sc_dhcp_results.output);
+       } else {
+               xasprintf(&sc_dhcp_results.output, "%s, max lease time = %" 
PRIu32 " seconds", sc_dhcp_results.output, max_lease_time);
        }
 
-       if (exclusive && undesired_offer) {
-               result = STATE_CRITICAL;
-       }
+       if (exclusive) {
+               mp_subcheck sc_rogue_server = mp_subcheck_init();
 
-       if (result == 0) { /* garrett honeycutt 2005 */
-               printf("OK: ");
-       } else if (result == 1) {
-               printf("WARNING: ");
-       } else if (result == 2) {
-               printf("CRITICAL: ");
-       } else if (result == 3) {
-               printf("UNKNOWN: ");
-       }
+               if (undesired_offer != NULL) {
+                       // We wanted to get a DHCPOFFER exclusively from one 
machine, but another one
+                       // sent one (too)
+                       sc_rogue_server = 
mp_set_subcheck_state(sc_rogue_server, STATE_CRITICAL);
 
-       /* we didn't receive any DHCPOFFERs */
-       if (dhcp_offer_list == NULL) {
-               printf(_("No DHCPOFFERs were received.\n"));
-               return result;
-       }
+                       // Get the addresses for printout
+                       // 1.address of the sending server
+                       char server_address[INET_ADDRSTRLEN];
+                       const char *server_address_transformed =
+                               inet_ntop(AF_INET, 
&undesired_offer->server_address, server_address, sizeof(server_address));
+
+                       if (server_address != server_address_transformed) {
+                               die(STATE_UNKNOWN, "inet_ntop failed");
+                       }
 
-       printf(_("Received %d DHCPOFFER(s)"), valid_responses);
+                       // 2.address offered
+                       char offered_address[INET_ADDRSTRLEN];
+                       const char *offered_address_transformed =
+                               inet_ntop(AF_INET, 
&undesired_offer->offered_address, offered_address, sizeof(offered_address));
 
-       if (exclusive && undesired_offer) {
-               printf(_(", Rogue DHCP Server detected! Server %s"), 
inet_ntoa(undesired_offer->server_address));
-               printf(_(" offered %s \n"), 
inet_ntoa(undesired_offer->offered_address));
-               return result;
-       }
+                       if (offered_address != offered_address_transformed) {
+                               die(STATE_UNKNOWN, "inet_ntop failed");
+                       }
 
-       if (requested_servers > 0) {
-               printf(_(", %s%d of %d requested servers responded"),
-                          ((requested_responses < requested_servers) && 
requested_responses > 0) ? "only " : "", requested_responses,
-                          requested_servers);
+                       xasprintf(&sc_rogue_server.output, "Rogue DHCP Server 
detected! Server %s offered %s", server_address, offered_address);
+               } else {
+                       sc_rogue_server = 
mp_set_subcheck_state(sc_rogue_server, STATE_OK);
+                       xasprintf(&sc_rogue_server.output, "No Rogue DHCP 
Server detected");
+               }
+               mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rogue_server);
        }
 
        if (request_specific_address) {
-               printf(_(", requested address (%s) was %soffered"), 
inet_ntoa(requested_address), (received_requested_address) ? "" : _("not "));
-       }
+               mp_subcheck sc_rqustd_addr = mp_subcheck_init();
 
-       printf(_(", max lease time = "));
-       if (max_lease_time == DHCP_INFINITE_TIME) {
-               printf(_("Infinity"));
-       } else {
-               printf("%lu sec", (unsigned long)max_lease_time);
-       }
+               if (received_requested_address) {
+                       sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, 
STATE_OK);
+                       xasprintf(&sc_rqustd_addr.output, "Requested address 
(%s) was offered", inet_ntoa(requested_address));
+               } else {
+                       sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, 
STATE_WARNING);
+                       xasprintf(&sc_rqustd_addr.output, "Requested address 
(%s) was NOT offered", inet_ntoa(requested_address));
+               }
 
-       printf(".\n");
+               mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rqustd_addr);
+       }
 
-       return result;
+       return sc_dhcp_results;
 }
 
 /* process command-line arguments */
-static int process_arguments(int argc, char **argv) {
+process_arguments_wrapper process_arguments(int argc, char **argv) {
        if (argc < 1) {
-               return ERROR;
+               process_arguments_wrapper tmp = {
+                       .error = ERROR,
+               };
+               return tmp;
        }
 
-       call_getopt(argc, argv);
-       return validate_arguments(argc);
-}
+       enum {
+               output_format_index = CHAR_MAX + 1,
+       };
 
-static int call_getopt(int argc, char **argv) {
-       extern int optind;
        int option_index = 0;
        static struct option long_options[] = {{"serverip", required_argument, 
0, 's'},
                                                                                
   {"requestedip", required_argument, 0, 'r'},
@@ -1092,65 +1148,55 @@ static int call_getopt(int argc, char **argv) {
                                                                                
   {"verbose", no_argument, 0, 'v'},
                                                                                
   {"version", no_argument, 0, 'V'},
                                                                                
   {"help", no_argument, 0, 'h'},
+                                                                               
   {"output-format", required_argument, 0, output_format_index},
                                                                                
   {0, 0, 0, 0}};
 
-       int c = 0;
+       check_dhcp_config config = check_dhcp_config_init();
+       int option_char = 0;
        while (true) {
-               c = getopt_long(argc, argv, "+hVvxt:s:r:t:i:m:u", long_options, 
&option_index);
+               option_char = getopt_long(argc, argv, "+hVvxt:s:r:t:i:m:u", 
long_options, &option_index);
 
-               if (c == -1 || c == EOF || c == 1) {
+               if (option_char == -1 || option_char == EOF || option_char == 
1) {
                        break;
                }
 
-               switch (c) {
-
+               switch (option_char) {
                case 's': /* DHCP server address */
-                       resolve_host(optarg, &dhcp_ip);
-                       add_requested_server(dhcp_ip);
+                       resolve_host(optarg, &config.dhcp_ip);
+                       add_requested_server(config.dhcp_ip, 
&config.num_of_requested_servers, &config.requested_server_list);
                        break;
 
                case 'r': /* address we are requested from DHCP servers */
-                       resolve_host(optarg, &requested_address);
-                       request_specific_address = true;
+                       resolve_host(optarg, &config.requested_address);
+                       config.request_specific_address = true;
                        break;
 
                case 't': /* timeout */
-
-                       /*
-                                if(is_intnonneg(optarg))
-                                */
                        if (atoi(optarg) > 0) {
-                               dhcpoffer_timeout = atoi(optarg);
+                               config.dhcpoffer_timeout = atoi(optarg);
                        }
-                       /*
-                                else
-                                usage("Time interval must be a nonnegative 
integer\n");
-                                */
                        break;
 
                case 'm': /* MAC address */
-
-                       if ((user_specified_mac = mac_aton(optarg)) == NULL) {
+                       if ((config.user_specified_mac = mac_aton(optarg)) == 
NULL) {
                                usage("Cannot parse MAC address.\n");
                        }
                        if (verbose) {
-                               print_hardware_address(user_specified_mac);
+                               
print_hardware_address(config.user_specified_mac);
                        }
-
                        break;
 
                case 'i': /* interface name */
-
-                       strncpy(network_interface_name, optarg, 
sizeof(network_interface_name) - 1);
-                       network_interface_name[sizeof(network_interface_name) - 
1] = '\x0';
-
+                       strncpy(config.network_interface_name, optarg, 
sizeof(config.network_interface_name) - 1);
+                       
config.network_interface_name[sizeof(config.network_interface_name) - 1] = 
'\x0';
                        break;
 
                case 'u': /* unicast testing */
-                       unicast = true;
+                       config.unicast_mode = true;
                        break;
+
                case 'x': /* exclusive testing aka "rogue DHCP server 
detection" */
-                       exclusive = true;
+                       config.exclusive_mode = true;
                        break;
 
                case 'V': /* version */
@@ -1164,6 +1210,18 @@ static int call_getopt(int argc, char **argv) {
                case 'v': /* verbose */
                        verbose = 1;
                        break;
+               case output_format_index: {
+                       parsed_output_format parser = 
mp_parse_output_format(optarg);
+                       if (!parser.parsing_success) {
+                               // TODO List all available formats here, maybe 
add anothoer usage function
+                               printf("Invalid output format: %s\n", optarg);
+                               exit(STATE_UNKNOWN);
+                       }
+
+                       config.output_format_is_set = true;
+                       config.output_format = parser.output_format;
+                       break;
+               }
                case '?': /* help */
                        usage5();
                        break;
@@ -1172,16 +1230,16 @@ static int call_getopt(int argc, char **argv) {
                        break;
                }
        }
-       return optind;
-}
-
-static int validate_arguments(int argc) {
 
        if (argc - optind > 0) {
                usage(_("Got unexpected non-option argument"));
        }
 
-       return OK;
+       process_arguments_wrapper result = {
+               .config = config,
+               .error = OK,
+       };
+       return result;
 }
 
 #if defined(__sun__) || defined(__solaris__) || defined(__hpux__)
@@ -1300,7 +1358,7 @@ static int dl_bind(int fd, int sap, u_char *addr) {
  *
  ***********************************************************************/
 
-static long mac_addr_dlpi(const char *dev, int unit, u_char *addr) {
+long mac_addr_dlpi(const char *dev, int unit, u_char *addr) {
        int fd;
        u_char mac_addr[25];
 
@@ -1319,26 +1377,27 @@ static long mac_addr_dlpi(const char *dev, int unit, 
u_char *addr) {
 #endif
 
 /* resolve host name or die (TODO: move this to netutils.c!) */
-static void resolve_host(const char *in, struct in_addr *out) {
-       struct addrinfo hints, *ai;
+void resolve_host(const char *name, struct in_addr *out) {
+       struct addrinfo hints = {
+               .ai_family = PF_INET,
+       };
+       struct addrinfo *addr_info;
 
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = PF_INET;
-       if (getaddrinfo(in, NULL, &hints, &ai) != 0) {
+       if (getaddrinfo(name, NULL, &hints, &addr_info) != 0) {
                usage_va(_("Invalid hostname/address - %s"), optarg);
        }
 
-       memcpy(out, &((struct sockaddr_in *)ai->ai_addr)->sin_addr, 
sizeof(*out));
-       freeaddrinfo(ai);
+       memcpy(out, &((struct sockaddr_in *)addr_info->ai_addr)->sin_addr, 
sizeof(*out));
+       freeaddrinfo(addr_info);
 }
 
 /* parse MAC address string, return 6 bytes (unterminated) or NULL */
-static unsigned char *mac_aton(const char *string) {
-       static unsigned char result[6];
+unsigned char *mac_aton(const char *string) {
+       static unsigned char result[MAC_ADDR_LEN];
        char tmp[3];
-       unsigned i, j;
+       unsigned byte_counter = 0;
 
-       for (i = 0, j = 0; string[i] != '\0' && j < sizeof(result); i++) {
+       for (int i = 0; string[i] != '\0' && byte_counter < sizeof(result); 
i++) {
                /* ignore ':' and any other non-hex character */
                if (!isxdigit(string[i]) || !isxdigit(string[i + 1])) {
                        continue;
@@ -1346,27 +1405,25 @@ static unsigned char *mac_aton(const char *string) {
                tmp[0] = string[i];
                tmp[1] = string[i + 1];
                tmp[2] = '\0';
-               result[j] = strtol(tmp, (char **)NULL, 16);
+               result[byte_counter] = strtol(tmp, (char **)NULL, 16);
                i++;
-               j++;
+               byte_counter++;
        }
 
-       return (j == 6) ? result : NULL;
+       return (byte_counter == MAC_ADDR_LEN) ? result : NULL;
 }
 
-static void print_hardware_address(const unsigned char *address) {
-       int i;
+void print_hardware_address(const unsigned char *address) {
 
        printf(_("Hardware address: "));
-       for (i = 0; i < 5; i++) {
-               printf("%2.2x:", address[i]);
+       for (int addr_idx = 0; addr_idx < MAC_ADDR_LEN; addr_idx++) {
+               printf("%2.2x:", address[addr_idx]);
        }
-       printf("%2.2x", address[i]);
        putchar('\n');
 }
 
 /* print usage help */
-static void print_help(void) {
+void print_help(void) {
 
        print_revision(progname, NP_VERSION);
 
@@ -1382,6 +1439,7 @@ static void print_help(void) {
        printf(UT_HELP_VRSN);
        printf(UT_EXTRA_OPTS);
 
+       printf(UT_OUTPUT_FORMAT);
        printf(UT_VERBOSE);
 
        printf(" %s\n", "-s, --serverip=IPADDRESS");
@@ -1400,7 +1458,6 @@ static void print_help(void) {
        printf("    %s\n", _("Only requested DHCP server may response (rogue 
DHCP server detection), requires -s"));
 
        printf(UT_SUPPORT);
-       return;
 }
 
 void print_usage(void) {
@@ -1408,6 +1465,4 @@ void print_usage(void) {
        printf("%s\n", _("Usage:"));
        printf(" %s [-v] [-u] [-x] [-s serverip] [-r requestedip] [-t 
timeout]\n", progname);
        printf("                  [-i interface] [-m mac]\n");
-
-       return;
 }
diff --git a/plugins-root/check_dhcp.d/config.h 
b/plugins-root/check_dhcp.d/config.h
new file mode 100644
index 00000000..f189068b
--- /dev/null
+++ b/plugins-root/check_dhcp.d/config.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "../../config.h"
+#include "../lib/states.h"
+#include <stdbool.h>
+#include <netinet/in.h>
+#include "net/if.h"
+#include "output.h"
+
+typedef struct requested_server_struct {
+       struct in_addr server_address;
+       bool answered;
+       struct requested_server_struct *next;
+} requested_server;
+
+typedef struct check_dhcp_config {
+       bool unicast_mode;   /* unicast mode: mimic a DHCP relay */
+       bool exclusive_mode; /* exclusive mode aka "rogue DHCP server 
detection" */
+       int num_of_requested_servers;
+       struct in_addr dhcp_ip; /* server to query (if in unicast mode) */
+       struct in_addr requested_address;
+       bool request_specific_address;
+
+       int dhcpoffer_timeout;
+       unsigned char *user_specified_mac;
+       char network_interface_name[IFNAMSIZ];
+       requested_server *requested_server_list;
+
+       mp_output_format output_format;
+       bool output_format_is_set;
+} check_dhcp_config;
+
+check_dhcp_config check_dhcp_config_init(void) {
+       check_dhcp_config tmp = {
+               .unicast_mode = false,
+               .exclusive_mode = false,
+               .num_of_requested_servers = 0,
+               .dhcp_ip = {0},
+               .requested_address = {0},
+               .request_specific_address = false,
+
+               .dhcpoffer_timeout = 2,
+               .user_specified_mac = NULL,
+               .network_interface_name = "eth0",
+               .requested_server_list = NULL,
+
+               .output_format_is_set = false,
+       };
+       return tmp;
+}


Reply via email to