From b37705b24ed13a3a7aaa73b6026b7c48eb334a21 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 23 Mar 2006 03:05:05 +0000 Subject: [PATCH] sync busybox and udhcp trees --- arpping.c | 6 ++-- arpping.h | 2 +- clientpacket.c | 4 +-- common.h | 3 +- dhcpc.c | 67 ++++++++++++++++++----------------- dhcpc.h | 6 ++-- dhcpd.c | 4 +-- dhcpd.h | 22 ++++++------ dumpleases.c | 6 +++- files.c | 53 ++++++++++++++++++++++++++-- files.h | 2 ++ leases.c | 2 +- libbb_udhcp.h | 52 +++++++++++++++++++++++---- options.c | 96 ++++++++++---------------------------------------- options.h | 2 -- packet.c | 27 ++++++++------ script.c | 5 +-- script.h | 2 +- serverpacket.c | 10 +++--- socket.c | 3 ++ 20 files changed, 208 insertions(+), 166 deletions(-) diff --git a/arpping.c b/arpping.c index 7cc2be4..4831d43 100644 --- a/arpping.c +++ b/arpping.c @@ -23,7 +23,7 @@ * ip - our ip * mac - our arp address * interface - interface to use - * retn: 1 addr free + * retn: 1 addr free * 0 addr used * -1 error */ @@ -33,7 +33,7 @@ int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *mac, char *interface) { int timeout = 2; - int optval = 1; + int optval = 1; int s; /* socket */ int rv = 1; /* return value */ struct sockaddr addr; /* for interface name */ @@ -101,6 +101,6 @@ int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *mac, char *interface) prevTime = uptime(); } close(s); - DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V"); + DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V"); return rv; } diff --git a/arpping.h b/arpping.h index 6f27d9f..30959ca 100644 --- a/arpping.h +++ b/arpping.h @@ -27,7 +27,7 @@ struct arpMsg { uint8_t tHaddr[6]; /* target's hardware address */ uint8_t tInaddr[4]; /* target's IP address */ uint8_t pad[18]; /* pad for min. Ethernet payload (60 bytes) */ -} __attribute__ ((packed)); +} ATTRIBUTE_PACKED; /* function prototypes */ int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface); diff --git a/clientpacket.c b/clientpacket.c index 528befd..e377bd2 100644 --- a/clientpacket.c +++ b/clientpacket.c @@ -205,8 +205,8 @@ int get_raw_packet(struct dhcpMessage *payload, int fd) packet.ip.ihl != sizeof(packet.ip) >> 2 || packet.udp.dest != htons(CLIENT_PORT) || bytes > (int) sizeof(struct udp_dhcp_packet) || ntohs(packet.udp.len) != (uint16_t) (bytes - sizeof(packet.ip))) { - DEBUG(LOG_INFO, "unrelated/bogus packet"); - return -2; + DEBUG(LOG_INFO, "unrelated/bogus packet"); + return -2; } /* check IP checksum */ diff --git a/common.h b/common.h index ca19a24..071a5c4 100644 --- a/common.h +++ b/common.h @@ -42,9 +42,8 @@ enum syslog_levels { long uptime(void); void background(const char *pidfile); void start_log_and_pid(const char *client_server, const char *pidfile); -void background(const char *pidfile); void udhcp_logging(int level, const char *fmt, ...); - + #define LOG(level, str, args...) udhcp_logging(level, str, ## args) #ifdef UDHCP_DEBUG diff --git a/dhcpc.c b/dhcpc.c index 179f9a3..fe2225a 100644 --- a/dhcpc.c +++ b/dhcpc.c @@ -4,19 +4,7 @@ * * Russ Dill July 2001 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */ #include @@ -34,6 +22,7 @@ #include #include +#include "common.h" #include "dhcpd.h" #include "dhcpc.h" #include "options.h" @@ -41,7 +30,6 @@ #include "clientsocket.h" #include "script.h" #include "socket.h" -#include "common.h" #include "signalpipe.h" static int state; @@ -70,11 +58,13 @@ struct client_config_t client_config = { .hostname = NULL, .fqdn = NULL, .ifindex = 0, + .retries = 3, + .timeout = 3, .arp = "\0\0\0\0\0\0", /* appease gcc-3.0 */ }; #ifndef IN_BUSYBOX -static void __attribute__ ((noreturn)) show_usage(void) +static void ATTRIBUTE_NORETURN show_usage(void) { printf( "Usage: udhcpc [OPTIONS]\n\n" @@ -95,13 +85,15 @@ static void __attribute__ ((noreturn)) show_usage(void) " -r, --request=IP IP address to request (default: none)\n" " -s, --script=file Run file at dhcp events (default:\n" " " DEFAULT_SCRIPT ")\n" +" -T, --timeout=seconds Try to get the lease for the amount of\n" +" seconds (default: 3)\n" " -v, --version Display version\n" ); exit(0); } #else #define show_usage bb_show_usage -extern void show_usage(void) __attribute__ ((noreturn)); +extern void show_usage(void) ATTRIBUTE_NORETURN; #endif @@ -208,31 +200,33 @@ int main(int argc, char *argv[]) {"hostname", required_argument, 0, 'h'}, {"fqdn", required_argument, 0, 'F'}, {"interface", required_argument, 0, 'i'}, - {"now", no_argument, 0, 'n'}, + {"now", no_argument, 0, 'n'}, {"pidfile", required_argument, 0, 'p'}, {"quit", no_argument, 0, 'q'}, {"request", required_argument, 0, 'r'}, {"script", required_argument, 0, 's'}, + {"timeout", required_argument, 0, 'T'}, {"version", no_argument, 0, 'v'}, + {"retries", required_argument, 0, 't'}, {0, 0, 0, 0} }; /* get options */ while (1) { int option_index = 0; - c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:v", arg_options, &option_index); + c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:T:t:v", arg_options, &option_index); if (c == -1) break; switch (c) { case 'c': if (no_clientid) show_usage(); len = strlen(optarg) > 255 ? 255 : strlen(optarg); - if (client_config.clientid) free(client_config.clientid); + free(client_config.clientid); client_config.clientid = xmalloc(len + 2); client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID; client_config.clientid[OPT_LEN] = len; client_config.clientid[OPT_DATA] = '\0'; - strncpy(client_config.clientid + OPT_DATA, optarg, len); + strncpy((char*)client_config.clientid + OPT_DATA, optarg, len); break; case 'C': if (client_config.clientid) show_usage(); @@ -240,11 +234,11 @@ int main(int argc, char *argv[]) break; case 'V': len = strlen(optarg) > 255 ? 255 : strlen(optarg); - if (client_config.vendorclass) free(client_config.vendorclass); + free(client_config.vendorclass); client_config.vendorclass = xmalloc(len + 2); client_config.vendorclass[OPT_CODE] = DHCP_VENDOR; client_config.vendorclass[OPT_LEN] = len; - strncpy(client_config.vendorclass + OPT_DATA, optarg, len); + strncpy((char*)client_config.vendorclass + OPT_DATA, optarg, len); break; case 'f': client_config.foreground = 1; @@ -255,15 +249,15 @@ int main(int argc, char *argv[]) case 'h': case 'H': len = strlen(optarg) > 255 ? 255 : strlen(optarg); - if (client_config.hostname) free(client_config.hostname); + free(client_config.hostname); client_config.hostname = xmalloc(len + 2); client_config.hostname[OPT_CODE] = DHCP_HOST_NAME; client_config.hostname[OPT_LEN] = len; - strncpy(client_config.hostname + 2, optarg, len); + strncpy((char*)client_config.hostname + 2, optarg, len); break; case 'F': len = strlen(optarg) > 255 ? 255 : strlen(optarg); - if (client_config.fqdn) free(client_config.fqdn); + free(client_config.fqdn); client_config.fqdn = xmalloc(len + 5); client_config.fqdn[OPT_CODE] = DHCP_FQDN; client_config.fqdn[OPT_LEN] = len + 3; @@ -276,7 +270,7 @@ int main(int argc, char *argv[]) client_config.fqdn[OPT_LEN + 1] = 0x1; client_config.fqdn[OPT_LEN + 2] = 0; client_config.fqdn[OPT_LEN + 3] = 0; - strncpy(client_config.fqdn + 5, optarg, len); + strncpy((char*)client_config.fqdn + 5, optarg, len); break; case 'i': client_config.interface = optarg; @@ -296,6 +290,12 @@ int main(int argc, char *argv[]) case 's': client_config.script = optarg; break; + case 'T': + client_config.timeout = atoi(optarg); + break; + case 't': + client_config.retries = atoi(optarg); + break; case 'v': printf("udhcpcd, version %s\n\n", VERSION); return 0; @@ -326,7 +326,7 @@ int main(int argc, char *argv[]) client_config.vendorclass[OPT_CODE] = DHCP_VENDOR; client_config.vendorclass[OPT_LEN] = sizeof("udhcp "VERSION) - 1; client_config.vendorclass[OPT_DATA] = 1; - memcpy(&client_config.vendorclass[OPT_DATA], + memcpy(&client_config.vendorclass[OPT_DATA], "udhcp "VERSION, sizeof("udhcp "VERSION) - 1); } @@ -365,14 +365,14 @@ int main(int argc, char *argv[]) /* timeout dropped to zero */ switch (state) { case INIT_SELECTING: - if (packet_num < 3) { + if (packet_num < client_config.retries) { if (packet_num == 0) xid = random_xid(); /* send discover packet */ send_discover(xid, requested_ip); /* broadcast */ - timeout = now + ((packet_num == 2) ? 4 : 2); + timeout = now + client_config.timeout; packet_num++; } else { run_script(NULL, "leasefail"); @@ -382,7 +382,7 @@ int main(int argc, char *argv[]) } else if (client_config.abort_if_no_lease) { LOG(LOG_INFO, "No lease, failing."); return 1; - } + } /* wait to try again */ packet_num = 0; timeout = now + 60; @@ -390,7 +390,7 @@ int main(int argc, char *argv[]) break; case RENEW_REQUESTED: case REQUESTING: - if (packet_num < 3) { + if (packet_num < client_config.retries) { /* send request packet */ if (state == RENEW_REQUESTED) send_renew(xid, server_addr, requested_ip); /* unicast */ @@ -469,9 +469,12 @@ int main(int argc, char *argv[]) (unsigned long) packet.xid, xid); continue; } + /* Ignore packets that aren't for us */ - if (memcmp(client_config.arp,packet.chaddr,6)) + if (memcmp(packet.chaddr, client_config.arp, 6)) { + DEBUG(LOG_INFO, "packet does not have our chaddr -- ignoring"); continue; + } if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) { DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring"); diff --git a/dhcpc.h b/dhcpc.h index 4cc1c4c..7c93f42 100644 --- a/dhcpc.h +++ b/dhcpc.h @@ -2,9 +2,7 @@ #ifndef _DHCPC_H #define _DHCPC_H -#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" - -/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */ +/* grab define DEFAULT_SCRIPT */ #include "libbb_udhcp.h" #define INIT_SELECTING 0 @@ -30,6 +28,8 @@ struct client_config_t { uint8_t *hostname; /* Optional hostname to use */ uint8_t *fqdn; /* Optional fully qualified domain name to use */ int ifindex; /* Index number of the interface to use */ + int retries; /* Max number of request packets */ + int timeout; /* Number of seconds to try to get a lease */ uint8_t arp[6]; /* Our arp address */ }; diff --git a/dhcpd.c b/dhcpd.c index ab3ddfe..0dfc0b5 100644 --- a/dhcpd.c +++ b/dhcpd.c @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) else server_config.lease = LEASE_TIME; /* Sanity check */ - num_ips = ntohl(server_config.end) - ntohl(server_config.start); + num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1; if (server_config.max_leases > num_ips) { LOG(LOG_ERR, "max_leases value (%lu) not sane, " "setting to %lu instead", @@ -193,7 +193,7 @@ int main(int argc, char *argv[]) LOG(LOG_ERR, "send OFFER failed"); } break; - case DHCPREQUEST: + case DHCPREQUEST: DEBUG(LOG_INFO, "received REQUEST"); requested = get_option(&packet, DHCP_REQUESTED_IP); diff --git a/dhcpd.h b/dhcpd.h index 65c8348..a060002 100644 --- a/dhcpd.h +++ b/dhcpd.h @@ -108,23 +108,23 @@ struct static_lease { struct server_config_t { uint32_t server; /* Our IP, in network order */ - uint32_t start; /* Start address of leases, network order */ + uint32_t start; /* Start address of leases, network order */ uint32_t end; /* End of leases, network order */ struct option_set *options; /* List of DHCP options loaded from the config file */ char *interface; /* The name of the interface to use */ int ifindex; /* Index number of the interface to use */ - uint8_t arp[6]; /* Our arp address */ + uint8_t arp[6]; /* Our arp address */ unsigned long lease; /* lease time in seconds (host order) */ - unsigned long max_leases; /* maximum number of leases (including reserved address) */ - char remaining; /* should the lease file be interpreted as lease time remaining, or - * as the time the lease expires */ - unsigned long auto_time; /* how long should udhcpd wait before writing a config file. + unsigned long max_leases; /* maximum number of leases (including reserved address) */ + char remaining; /* should the lease file be interpreted as lease time remaining, or + * as the time the lease expires */ + unsigned long auto_time; /* how long should udhcpd wait before writing a config file. * if this is zero, it will only write one on SIGUSR1 */ - unsigned long decline_time; /* how long an address is reserved if a client returns a - * decline message */ - unsigned long conflict_time; /* how long an arp conflict offender is leased for */ - unsigned long offer_time; /* how long an offered address is reserved */ - unsigned long min_lease; /* minimum lease a client can request*/ + unsigned long decline_time; /* how long an address is reserved if a client returns a + * decline message */ + unsigned long conflict_time; /* how long an arp conflict offender is leased for */ + unsigned long offer_time; /* how long an offered address is reserved */ + unsigned long min_lease; /* minimum lease a client can request*/ char *lease_file; char *pidfile; char *notify_file; /* What to run whenever leases are written */ diff --git a/dumpleases.c b/dumpleases.c index a9036df..c0c58ee 100644 --- a/dumpleases.c +++ b/dumpleases.c @@ -1,3 +1,7 @@ +/* vi: set sw=4 ts=4: */ +/* + * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. + */ #include #include #include @@ -21,7 +25,7 @@ #ifndef IN_BUSYBOX -static void __attribute__ ((noreturn)) show_usage(void) +static void ATTRIBUTE_NORETURN show_usage(void) { printf( "Usage: dumpleases -f -[r|a]\n\n" diff --git a/files.c b/files.c index 73a3bbc..fe853c7 100644 --- a/files.c +++ b/files.c @@ -15,8 +15,8 @@ #include "static_leases.h" #include "dhcpd.h" -#include "files.h" #include "options.h" +#include "files.h" #include "common.h" /* @@ -62,7 +62,7 @@ static int read_str(const char *line, void *arg) { char **dest = arg; - if (*dest) free(*dest); + free(*dest); *dest = strdup(line); return 1; @@ -93,6 +93,53 @@ static int read_yn(const char *line, void *arg) } +/* find option 'code' in opt_list */ +struct option_set *find_option(struct option_set *opt_list, char code) +{ + while (opt_list && opt_list->data[OPT_CODE] < code) + opt_list = opt_list->next; + + if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list; + else return NULL; +} + + +/* add an option to the opt_list */ +static void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length) +{ + struct option_set *existing, *new, **curr; + + /* add it to an existing option */ + if ((existing = find_option(*opt_list, option->code))) { + DEBUG(LOG_INFO, "Attaching option %s to existing member of list", option->name); + if (option->flags & OPTION_LIST) { + if (existing->data[OPT_LEN] + length <= 255) { + existing->data = realloc(existing->data, + existing->data[OPT_LEN] + length + 2); + memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length); + existing->data[OPT_LEN] += length; + } /* else, ignore the data, we could put this in a second option in the future */ + } /* else, ignore the new data */ + } else { + DEBUG(LOG_INFO, "Attaching option %s to list", option->name); + + /* make a new option */ + new = xmalloc(sizeof(struct option_set)); + new->data = xmalloc(length + 2); + new->data[OPT_CODE] = option->code; + new->data[OPT_LEN] = length; + memcpy(new->data + 2, buffer, length); + + curr = opt_list; + while (*curr && (*curr)->data[OPT_CODE] < option->code) + curr = &(*curr)->next; + + new->next = *curr; + *curr = new; + } +} + + /* read a dhcp option and add it to opt_list */ static int read_opt(const char *const_line, void *arg) { @@ -225,7 +272,7 @@ static const struct config_keyword keywords[] = { {"boot_file", read_str, &(server_config.boot_file), ""}, {"static_lease",read_staticlease, &(server_config.static_leases), ""}, /*ADDME: static lease */ - {"", NULL, NULL, ""} + {"", NULL, NULL, ""} }; diff --git a/files.h b/files.h index 279738a..03acee2 100644 --- a/files.h +++ b/files.h @@ -14,4 +14,6 @@ int read_config(const char *file); void write_leases(void); void read_leases(const char *file); +struct option_set *find_option(struct option_set *opt_list, char code); + #endif diff --git a/leases.c b/leases.c index 4da21a2..bb08c3a 100644 --- a/leases.c +++ b/leases.c @@ -148,7 +148,7 @@ uint32_t find_address(int check_expired) (check_expired && lease_expired(lease))) && /* and it isn't on the network */ - !check_ip(ret)) { + !check_ip(ret)) { return ret; break; } diff --git a/libbb_udhcp.h b/libbb_udhcp.h index 51e1571..dd58f1b 100644 --- a/libbb_udhcp.h +++ b/libbb_udhcp.h @@ -3,14 +3,15 @@ /* bit of a hack, do this no matter what the order of the includes. * (for busybox) */ -#ifdef CONFIG_INSTALL_NO_USR -#undef DEFAULT_SCRIPT -#define DEFAULT_SCRIPT "/share/udhcpc/default.script" -#endif - #ifndef _LIBBB_UDHCP_H #define _LIBBB_UDHCP_H +#ifdef CONFIG_INSTALL_NO_USR +# define DEFAULT_SCRIPT "/share/udhcpc/default.script" +#else +# define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" +#endif + #ifdef IN_BUSYBOX #include "busybox.h" @@ -27,12 +28,49 @@ #define xfopen bb_xfopen -#else /* ! BB_VER */ +/* make safe the exported namespace */ +/* from common.h */ +#define background udhcp_background +#define start_log_and_pid udhcp_start_log_and_pid +/* from script.h */ +#define run_script udhcp_run_script +/* from packet.h */ +#define init_header udhcp_init_header +#define get_packet udhcp_get_packet +#define checksum udhcp_checksum +#define raw_packet udhcp_raw_packet +#define kernel_packet udhcp_kernel_packet +/* from pidfile.h */ +#define pidfile_acquire udhcp_pidfile_acquire +#define pidfile_write_release udhcp_pidfile_write_release +/* from options.h */ +#define get_option udhcp_get_option +#define end_option udhcp_end_option +#define add_option_string udhcp_add_option_string +#define add_simple_option udhcp_add_simple_option +#define option_lengths udhcp_option_lengths +/* from socket.h */ +#define listen_socket udhcp_listen_socket +#define read_interface udhcp_read_interface +/* from dhcpc.h */ +#define client_config udhcp_client_config +/* from dhcpd.h */ +#define server_config udhcp_server_config + +#else /* ! IN_BUSYBOX */ #include #include #include +#ifndef ATTRIBUTE_NORETURN +#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) +#endif /* ATTRIBUTE_NORETURN */ + +#ifndef ATTRIBUTE_PACKED +#define ATTRIBUTE_PACKED __attribute__ ((__packed__)) +#endif /* ATTRIBUTE_PACKED */ + #define TRUE 1 #define FALSE 0 @@ -49,6 +87,6 @@ static inline FILE *xfopen(const char *file, const char *mode) return fp; } -#endif /* BB_VER */ +#endif /* IN_BUSYBOX */ #endif /* _LIBBB_UDHCP_H */ diff --git a/options.c b/options.c index ae98194..d394b4c 100644 --- a/options.c +++ b/options.c @@ -6,10 +6,10 @@ #include #include -#include "dhcpd.h" -#include "files.h" -#include "options.h" #include "common.h" +#include "dhcpd.h" +#include "options.h" +#include "files.h" /* supported options are easily added here */ @@ -149,82 +149,24 @@ int add_option_string(uint8_t *optionptr, uint8_t *string) /* add a one to four byte option to a packet */ int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data) { - char length = 0; - int i; - uint8_t option[2 + 4]; - uint8_t *u8; - uint16_t *u16; - uint32_t *u32; - uint32_t aligned; - u8 = (uint8_t *) &aligned; - u16 = (uint16_t *) &aligned; - u32 = &aligned; + struct dhcp_option *dh; - for (i = 0; dhcp_options[i].code; i++) - if (dhcp_options[i].code == code) { - length = option_lengths[dhcp_options[i].flags & TYPE_MASK]; + for (dh=dhcp_options; dh->code; dh++) { + if (dh->code == code) { + uint8_t option[6], len; + + option[OPT_CODE] = code; + len = option_lengths[dh->flags & TYPE_MASK]; + option[OPT_LEN] = len; + if (__BYTE_ORDER == __BIG_ENDIAN) + data <<= 8 * (4 - len); + /* This memcpy is for broken processors which can't + * handle a simple unaligned 32-bit assignment */ + memcpy(&option[OPT_DATA], &data, 4); + return add_option_string(optionptr, option); } - - if (!length) { - DEBUG(LOG_ERR, "Could not add option 0x%02x", code); - return 0; } - option[OPT_CODE] = code; - option[OPT_LEN] = length; - - switch (length) { - case 1: *u8 = data; break; - case 2: *u16 = data; break; - case 4: *u32 = data; break; - } - memcpy(option + 2, &aligned, length); - return add_option_string(optionptr, option); -} - - -/* find option 'code' in opt_list */ -struct option_set *find_option(struct option_set *opt_list, char code) -{ - while (opt_list && opt_list->data[OPT_CODE] < code) - opt_list = opt_list->next; - - if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list; - else return NULL; -} - - -/* add an option to the opt_list */ -void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length) -{ - struct option_set *existing, *new, **curr; - - /* add it to an existing option */ - if ((existing = find_option(*opt_list, option->code))) { - DEBUG(LOG_INFO, "Attaching option %s to existing member of list", option->name); - if (option->flags & OPTION_LIST) { - if (existing->data[OPT_LEN] + length <= 255) { - existing->data = realloc(existing->data, - existing->data[OPT_LEN] + length + 2); - memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length); - existing->data[OPT_LEN] += length; - } /* else, ignore the data, we could put this in a second option in the future */ - } /* else, ignore the new data */ - } else { - DEBUG(LOG_INFO, "Attaching option %s to list", option->name); - - /* make a new option */ - new = xmalloc(sizeof(struct option_set)); - new->data = xmalloc(length + 2); - new->data[OPT_CODE] = option->code; - new->data[OPT_LEN] = length; - memcpy(new->data + 2, buffer, length); - - curr = opt_list; - while (*curr && (*curr)->data[OPT_CODE] < option->code) - curr = &(*curr)->next; - - new->next = *curr; - *curr = new; - } + DEBUG(LOG_ERR, "Could not add option 0x%02x", code); + return 0; } diff --git a/options.h b/options.h index fbe54c8..4948bac 100644 --- a/options.h +++ b/options.h @@ -34,7 +34,5 @@ uint8_t *get_option(struct dhcpMessage *packet, int code); int end_option(uint8_t *optionptr); int add_option_string(uint8_t *optionptr, uint8_t *string); int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data); -struct option_set *find_option(struct option_set *opt_list, char code); -void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length); #endif diff --git a/packet.c b/packet.c index 1c6bb0c..32fb8a7 100644 --- a/packet.c +++ b/packet.c @@ -46,12 +46,12 @@ void init_header(struct dhcpMessage *packet, char type) /* read a packet from socket fd, return -1 on read error, -2 on packet error */ int get_packet(struct dhcpMessage *packet, int fd) { - int bytes; - int i; - const char broken_vendors[][8] = { + static const char broken_vendors[][8] = { "MSFT 98", "" }; + int bytes; + int i; char unsigned *vendor; memset(packet, 0, sizeof(struct dhcpMessage)); @@ -70,14 +70,13 @@ int get_packet(struct dhcpMessage *packet, int fd) if (packet->op == BOOTREQUEST && (vendor = get_option(packet, DHCP_VENDOR))) { for (i = 0; broken_vendors[i][0]; i++) { if (vendor[OPT_LEN - 2] == (uint8_t) strlen(broken_vendors[i]) && - !strncmp(vendor, broken_vendors[i], vendor[OPT_LEN - 2])) { - DEBUG(LOG_INFO, "broken client (%s), forcing broadcast", - broken_vendors[i]); - packet->flags |= htons(BROADCAST_FLAG); + !strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - 2])) { + DEBUG(LOG_INFO, "broken client (%s), forcing broadcast", + broken_vendors[i]); + packet->flags |= htons(BROADCAST_FLAG); } } } - return bytes; } @@ -177,24 +176,30 @@ int kernel_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_po if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) return -1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) { + close(fd); return -1; + } memset(&client, 0, sizeof(client)); client.sin_family = AF_INET; client.sin_port = htons(source_port); client.sin_addr.s_addr = source_ip; - if (bind(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) + if (bind(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) { + close(fd); return -1; + } memset(&client, 0, sizeof(client)); client.sin_family = AF_INET; client.sin_port = htons(dest_port); client.sin_addr.s_addr = dest_ip; - if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) + if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) { + close(fd); return -1; + } result = write(fd, payload, sizeof(struct dhcpMessage)); close(fd); diff --git a/script.c b/script.c index 820fbb0..b6b0e0d 100644 --- a/script.c +++ b/script.c @@ -29,10 +29,11 @@ #include #include +#include "common.h" #include "options.h" #include "dhcpd.h" #include "dhcpc.h" -#include "common.h" +#include "script.h" /* get a rough idea of how long an option will be (rounding up...) */ static const int max_option_length[] = { @@ -96,7 +97,7 @@ static void fill_options(char *dest, uint8_t *option, struct dhcp_option *type_p optlen = 4; case OPTION_IP: /* Works regardless of host byte order. */ dest += sprintip(dest, "", option); - break; + break; case OPTION_BOOLEAN: dest += sprintf(dest, *option ? "yes" : "no"); break; diff --git a/script.h b/script.h index 87a20cc..7100331 100644 --- a/script.h +++ b/script.h @@ -1,6 +1,6 @@ #ifndef _SCRIPT_H #define _SCRIPT_H -void run_script(struct dhcpMessage *packet, const char *name); +extern void run_script(struct dhcpMessage *packet, const char *name); #endif diff --git a/serverpacket.c b/serverpacket.c index 75d55bd..fe880b4 100644 --- a/serverpacket.c +++ b/serverpacket.c @@ -25,10 +25,10 @@ #include #include +#include "common.h" #include "serverpacket.h" #include "dhcpd.h" #include "options.h" -#include "common.h" #include "static_leases.h" /* send a packet to giaddr using the kernel ip stack */ @@ -98,9 +98,9 @@ static void add_bootp_options(struct dhcpMessage *packet) { packet->siaddr = server_config.siaddr; if (server_config.sname) - strncpy(packet->sname, server_config.sname, sizeof(packet->sname) - 1); + strncpy((char*)packet->sname, server_config.sname, sizeof(packet->sname) - 1); if (server_config.boot_file) - strncpy(packet->file, server_config.boot_file, sizeof(packet->file) - 1); + strncpy((char*)packet->file, server_config.boot_file, sizeof(packet->file) - 1); } @@ -138,11 +138,11 @@ int sendOffer(struct dhcpMessage *oldpacket) /* and the ip is in the lease range */ ntohl(req_align) >= ntohl(server_config.start) && ntohl(req_align) <= ntohl(server_config.end) && - + !static_lease_ip && /* Check that its not a static lease */ /* and is not already taken/offered */ ((!(lease = find_lease_by_yiaddr(req_align)) || - + /* or its taken, but expired */ /* ADDME: or maybe in here */ lease_expired(lease)))) { packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */ diff --git a/socket.c b/socket.c index 7b05752..0368851 100644 --- a/socket.c +++ b/socket.c @@ -62,6 +62,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp) DEBUG(LOG_INFO, "%s (our ip) = %s", ifr.ifr_name, inet_ntoa(our_ip->sin_addr)); } else { LOG(LOG_ERR, "SIOCGIFADDR failed, is the interface up and configured?: %m"); + close(fd); return -1; } } @@ -71,6 +72,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp) *ifindex = ifr.ifr_ifindex; } else { LOG(LOG_ERR, "SIOCGIFINDEX failed!: %m"); + close(fd); return -1; } if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) { @@ -79,6 +81,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp) arp[0], arp[1], arp[2], arp[3], arp[4], arp[5]); } else { LOG(LOG_ERR, "SIOCGIFHWADDR failed!: %m"); + close(fd); return -1; } } else {