From dc4ca6861fc0becc11be1e1749e4b451817fb389 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 21 May 2015 12:21:26 +1000 Subject: [PATCH] Remove udhcp (DHCP server support) as it's a GPL violation :( --- FreeRTOS/Source/portable/esp8266/sdk_compat.c | 4 + common.mk | 2 +- include/udhcp/common.h | 434 ------------------ include/udhcp/dhcpc.h | 42 -- include/udhcp/dhcpd.h | 146 ------ lib/libudhcp.a | Bin 42930 -> 0 bytes 6 files changed, 5 insertions(+), 623 deletions(-) delete mode 100644 include/udhcp/common.h delete mode 100644 include/udhcp/dhcpc.h delete mode 100644 include/udhcp/dhcpd.h delete mode 100644 lib/libudhcp.a diff --git a/FreeRTOS/Source/portable/esp8266/sdk_compat.c b/FreeRTOS/Source/portable/esp8266/sdk_compat.c index 36b6f7c..9af3b4b 100644 --- a/FreeRTOS/Source/portable/esp8266/sdk_compat.c +++ b/FreeRTOS/Source/portable/esp8266/sdk_compat.c @@ -4,6 +4,10 @@ #include #include "FreeRTOS.h" +/* SDK uses this and so does lwip, it was defined in libudhcp.a + but that library has been removed. */ +int errno; + /* libc memory management functions. Many of these are linked from the RTOS SDK blob libraries. diff --git a/common.mk b/common.mk index 9bdf63e..afeaa0e 100644 --- a/common.mk +++ b/common.mk @@ -56,7 +56,7 @@ OBJCOPY = $(CROSS)objcopy COMPONENTS ?= FreeRTOS lwip # libraries to link, mainly blobs provided by the esp-iot-rtos SDK -LIBS ?= gcc json main net80211 phy pp ssl udhcp wpa hal +LIBS ?= gcc json main net80211 phy pp ssl wpa hal CFLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -std=gnu99 LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(ROOT)lib -u call_user_start -Wl,-static -Wl,-Map=build/${TARGET}.map diff --git a/include/udhcp/common.h b/include/udhcp/common.h deleted file mode 100644 index 332cf76..0000000 --- a/include/udhcp/common.h +++ /dev/null @@ -1,434 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Russ Dill September 2001 - * Rewritten by Vladimir Oleynik (C) 2003 - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ -#ifndef UDHCP_COMMON_H -#define UDHCP_COMMON_H 1 - -#include "esp_common.h" - -#include "lwip/sockets.h" - -//PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN - -extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */ - -#ifndef BUFSIZ -# define BUFSIZ 1024 -#endif - -typedef int smallint; -typedef unsigned smalluint; - -/* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */ -enum { COMMON_BUFSIZE = (BUFSIZ >= 256*sizeof(void*) ? BUFSIZ+1 : 256*sizeof(void*)) }; -extern char bb_common_bufsiz1[COMMON_BUFSIZE]; - -/* In this form code with pipes is much more readable */ -struct fd_pair { int rd; int wr; }; - -/* Having next pointer as a first member allows easy creation - * of "llist-compatible" structs, and using llist_FOO functions - * on them. - */ -typedef struct llist_t { - struct llist_t *link; - char *data; -} llist_t; - -void llist_add_to(llist_t **old_head, void *data); -void llist_add_to_end(llist_t **list_head, void *data); -void *llist_pop(llist_t **elm); -void llist_unlink(llist_t **head, llist_t *elm); -void llist_free(llist_t *elm, void (*freeit)(void *data)); -llist_t *llist_rev(llist_t *list); -llist_t *llist_find_str(llist_t *first, const char *str); - -//unsigned long long monotonic_ns(void); -//unsigned long long monotonic_us(void); -//unsigned long long monotonic_ms(void); -unsigned monotonic_sec(void); - -/* performs reasonably well (gcc usually inlines memcpy here) */ -# define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) -# define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long))) -# define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) -# define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) -# define move_to_unaligned16(u16p, v) do { \ - uint16_t __t = (v); \ - memcpy((u16p), &__t, 2); \ -} while (0) -# define move_to_unaligned32(u32p, v) do { \ - uint32_t __t = (v); \ - memcpy((u32p), &__t, 4); \ -} while (0) - -enum { wrote_pidfile = 0 }; -#define write_pidfile(path) ((void)0) -#define remove_pidfile(path) ((void)0) - -#ifndef ENABLE_FEATURE_UDHCP_8021Q -#define ENABLE_FEATURE_UDHCP_8021Q 0 -#endif - -#ifndef ENABLE_FEATURE_UDHCP_RFC3397 -#define ENABLE_FEATURE_UDHCP_RFC3397 0 -#endif - -#ifndef ENABLE_LONG_OPTS -#define ENABLE_LONG_OPTS 0 -#endif - -#ifndef ENABLE_FEATURE_UDHCPC_ARPING -#define ENABLE_FEATURE_UDHCPC_ARPING 0 -#endif - -#ifndef ENABLE_FEATURE_UDHCP_PORT -#define ENABLE_FEATURE_UDHCP_PORT 0 -#endif - -#ifndef ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC -#define ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC 0 -#endif - -#ifndef ENABLE_NOMMU -#define ENABLE_NOMMU 0 -#endif - -#ifndef ENABLE_FEATURE_IPV6 -#define ENABLE_FEATURE_IPV6 0 -#endif - -#ifndef ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY -#define ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY 0 -#endif - -/* - * For 0.9.29 and svn, __ARCH_USE_MMU__ indicates no-mmu reliably. - * For earlier versions there is no reliable way to check if we are building - * for a mmu-less system. - */ -#if ENABLE_NOMMU -# define BB_MMU 0 -# define USE_FOR_NOMMU(...) __VA_ARGS__ -# define USE_FOR_MMU(...) -#else -# define BB_MMU 1 -# define USE_FOR_NOMMU(...) -# define USE_FOR_MMU(...) __VA_ARGS__ -#endif - -#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0]))) - -/*** DHCP packet ***/ - -/* DHCP protocol. See RFC 2131 */ -#define DHCP_MAGIC 0x63825363 -#define DHCP_OPTIONS_BUFSIZE 308 -#define BOOTREQUEST 1 -#define BOOTREPLY 2 - -//TODO: rename ciaddr/yiaddr/chaddr -struct dhcp_packet { - uint8_t op; /* BOOTREQUEST or BOOTREPLY */ - uint8_t htype; /* hardware address type. 1 = 10mb ethernet */ - uint8_t hlen; /* hardware address length */ - uint8_t hops; /* used by relay agents only */ - uint32_t xid; /* unique id */ - uint16_t secs; /* elapsed since client began acquisition/renewal */ - uint16_t flags; /* only one flag so far: */ -#define BROADCAST_FLAG 0x8000 /* "I need broadcast replies" */ - uint32_t ciaddr; /* client IP (if client is in BOUND, RENEW or REBINDING state) */ - uint32_t yiaddr; /* 'your' (client) IP address */ - /* IP address of next server to use in bootstrap, returned in DHCPOFFER, DHCPACK by server */ - uint32_t siaddr_nip; - uint32_t gateway_nip; /* relay agent IP address */ - uint8_t chaddr[16]; /* link-layer client hardware address (MAC) */ - uint8_t sname[64]; /* server host name (ASCIZ) */ - uint8_t file[128]; /* boot file name (ASCIZ) */ - uint32_t cookie; /* fixed first four option bytes (99,130,83,99 dec) */ - uint8_t options[DHCP_OPTIONS_BUFSIZE];// + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS]; -}; - -#define DHCP_PKT_SNAME_LEN 64 -#define DHCP_PKT_FILE_LEN 128 -#define DHCP_PKT_SNAME_LEN_STR "64" -#define DHCP_PKT_FILE_LEN_STR "128" - -//struct ip_udp_dhcp_packet { -// struct ip_hdr ip; -// struct udp_hdr udp; -// struct dhcp_packet data; -//}; -// -//struct udp_dhcp_packet { -// struct udp_hdr udp; -// struct dhcp_packet data; -//}; - -enum { -// IP_UDP_DHCP_SIZE = sizeof(struct ip_udp_dhcp_packet),// - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, -// UDP_DHCP_SIZE = sizeof(struct udp_dhcp_packet),// - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, - DHCP_SIZE = sizeof(struct dhcp_packet),// - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS, -}; - -/* Let's see whether compiler understood us right */ -//struct BUG_bad_sizeof_struct_ip_udp_dhcp_packet { -// char c[IP_UDP_DHCP_SIZE == 576 ? 1 : -1]; -//}; - - -/*** Options ***/ - -enum { - OPTION_IP = 1, - OPTION_IP_PAIR, - OPTION_STRING, - /* Opts of STRING_HOST type will be sanitized before they are passed - * to udhcpc script's environment: */ - OPTION_STRING_HOST, -// OPTION_BOOLEAN, - OPTION_U8, - OPTION_U16, -// OPTION_S16, - OPTION_U32, - OPTION_S32, - OPTION_BIN, - OPTION_STATIC_ROUTES, - OPTION_6RD, -#if ENABLE_FEATURE_UDHCP_RFC3397 - OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ - OPTION_SIP_SERVERS, -#endif - - OPTION_TYPE_MASK = 0x0f, - /* Client requests this option by default */ - OPTION_REQ = 0x10, - /* There can be a list of 1 or more of these */ - OPTION_LIST = 0x20, -}; - -/* DHCP option codes (partial list). See RFC 2132 and - * http://www.iana.org/assignments/bootp-dhcp-parameters/ - * Commented out options are handled by common option machinery, - * uncommented ones have special cases (grep for them to see). - */ -#define DHCP_PADDING 0x00 -#define DHCP_SUBNET 0x01 -//#define DHCP_TIME_OFFSET 0x02 /* (localtime - UTC_time) in seconds. signed */ -//#define DHCP_ROUTER 0x03 -//#define DHCP_TIME_SERVER 0x04 /* RFC 868 time server (32-bit, 0 = 1.1.1900) */ -//#define DHCP_NAME_SERVER 0x05 /* IEN 116 _really_ ancient kind of NS */ -//#define DHCP_DNS_SERVER 0x06 -//#define DHCP_LOG_SERVER 0x07 /* port 704 UDP log (not syslog) -//#define DHCP_COOKIE_SERVER 0x08 /* "quote of the day" server */ -//#define DHCP_LPR_SERVER 0x09 -#define DHCP_HOST_NAME 0x0c /* either client informs server or server gives name to client */ -//#define DHCP_BOOT_SIZE 0x0d -//#define DHCP_DOMAIN_NAME 0x0f /* server gives domain suffix */ -//#define DHCP_SWAP_SERVER 0x10 -//#define DHCP_ROOT_PATH 0x11 -//#define DHCP_IP_TTL 0x17 -//#define DHCP_MTU 0x1a -//#define DHCP_BROADCAST 0x1c -//#define DHCP_ROUTES 0x21 -//#define DHCP_NIS_DOMAIN 0x28 -//#define DHCP_NIS_SERVER 0x29 -//#define DHCP_NTP_SERVER 0x2a -//#define DHCP_WINS_SERVER 0x2c -#define DHCP_REQUESTED_IP 0x32 /* sent by client if specific IP is wanted */ -#define DHCP_LEASE_TIME 0x33 -#define DHCP_OPTION_OVERLOAD 0x34 -#define DHCP_MESSAGE_TYPE 0x35 -#define DHCP_SERVER_ID 0x36 /* by default server's IP */ -#define DHCP_PARAM_REQ 0x37 /* list of options client wants */ -//#define DHCP_ERR_MESSAGE 0x38 /* error message when sending NAK etc */ -#define DHCP_MAX_SIZE 0x39 -#define DHCP_VENDOR 0x3c /* client's vendor (a string) */ -#define DHCP_CLIENT_ID 0x3d /* by default client's MAC addr, but may be arbitrarily long */ -//#define DHCP_TFTP_SERVER_NAME 0x42 /* same as 'sname' field */ -//#define DHCP_BOOT_FILE 0x43 /* same as 'file' field */ -//#define DHCP_USER_CLASS 0x4d /* RFC 3004. set of LASCII strings. "I am a printer" etc */ -#define DHCP_FQDN 0x51 /* client asks to update DNS to map its FQDN to its new IP */ -//#define DHCP_DOMAIN_SEARCH 0x77 /* RFC 3397. set of ASCIZ string, DNS-style compressed */ -//#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ -//#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ -//#define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ -//#define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ -//#define DHCP_PXE_CONF_FILE 0xd1 /* RFC 5071 Configuration File */ -//#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ -//#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ -#define DHCP_END 0xff - -/* Offsets in option byte sequence */ -#define OPT_CODE 0 -#define OPT_LEN 1 -#define OPT_DATA 2 -/* Bits in "overload" option */ -#define OPTION_FIELD 0 -#define FILE_FIELD 1 -#define SNAME_FIELD 2 - -/* DHCP_MESSAGE_TYPE values */ -#define DHCPDISCOVER 1 /* client -> server */ -#define DHCPOFFER 2 /* client <- server */ -#define DHCPREQUEST 3 /* client -> server */ -#define DHCPDECLINE 4 /* client -> server */ -#define DHCPACK 5 /* client <- server */ -#define DHCPNAK 6 /* client <- server */ -#define DHCPRELEASE 7 /* client -> server */ -#define DHCPINFORM 8 /* client -> server */ -#define DHCP_MINTYPE DHCPDISCOVER -#define DHCP_MAXTYPE DHCPINFORM - -struct dhcp_optflag { - uint8_t flags; - uint8_t code; -}; - -struct option_set { - uint8_t *data; - struct option_set *next; -}; - -extern const struct dhcp_optflag dhcp_optflags[]; -extern const char dhcp_option_strings[]; -extern const uint8_t dhcp_option_lengths[]; - -unsigned udhcp_option_idx(const char *name); - -uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code); -int udhcp_end_option(uint8_t *optionptr); -void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt); -void udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data); -#if ENABLE_FEATURE_UDHCP_RFC3397 -char *dname_dec(const uint8_t *cstr, int clen, const char *pre); -uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen); -#endif -struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code); - - -// RFC 2131 Table 5: Fields and options used by DHCP clients -// -// Fields 'hops', 'yiaddr', 'siaddr', 'giaddr' are always zero -// -// Field DHCPDISCOVER DHCPINFORM DHCPREQUEST DHCPDECLINE DHCPRELEASE -// ----- ------------ ------------ ----------- ----------- ----------- -// 'xid' selected by client selected by client 'xid' from server selected by client selected by client -// DHCPOFFER message -// 'secs' 0 or seconds since 0 or seconds since 0 or seconds since 0 0 -// DHCP process started DHCP process started DHCP process started -// 'flags' Set 'BROADCAST' Set 'BROADCAST' Set 'BROADCAST' 0 0 -// flag if client flag if client flag if client -// requires broadcast requires broadcast requires broadcast -// reply reply reply -// 'ciaddr' 0 client's IP 0 or client's IP 0 client's IP -// (BOUND/RENEW/REBIND) -// 'chaddr' client's MAC client's MAC client's MAC client's MAC client's MAC -// 'sname' options or sname options or sname options or sname (unused) (unused) -// 'file' options or file options or file options or file (unused) (unused) -// 'options' options options options message type opt message type opt -// -// Option DHCPDISCOVER DHCPINFORM DHCPREQUEST DHCPDECLINE DHCPRELEASE -// ------ ------------ ---------- ----------- ----------- ----------- -// Requested IP address MAY MUST NOT MUST (in MUST MUST NOT -// SELECTING or -// INIT-REBOOT) -// MUST NOT (in -// BOUND or -// RENEWING) -// IP address lease time MAY MUST NOT MAY MUST NOT MUST NOT -// Use 'file'/'sname' fields MAY MAY MAY MAY MAY -// Client identifier MAY MAY MAY MAY MAY -// Vendor class identifier MAY MAY MAY MUST NOT MUST NOT -// Server identifier MUST NOT MUST NOT MUST (after MUST MUST -// SELECTING) -// MUST NOT (after -// INIT-REBOOT, -// BOUND, RENEWING -// or REBINDING) -// Parameter request list MAY MAY MAY MUST NOT MUST NOT -// Maximum message size MAY MAY MAY MUST NOT MUST NOT -// Message SHOULD NOT SHOULD NOT SHOULD NOT SHOULD SHOULD -// Site-specific MAY MAY MAY MUST NOT MUST NOT -// All others MAY MAY MAY MUST NOT MUST NOT - - -/*** Logging ***/ - -#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 -# define IF_UDHCP_VERBOSE(...) __VA_ARGS__ -extern unsigned dhcp_verbose; -# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) -# if CONFIG_UDHCP_DEBUG >= 2 -void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; -# define log2(...) do { if (dhcp_verbose >= 2) bb_info_msg(__VA_ARGS__); } while (0) -# else -# define udhcp_dump_packet(...) ((void)0) -# define log2(...) ((void)0) -# endif -# if CONFIG_UDHCP_DEBUG >= 3 -# define log3(...) do { if (dhcp_verbose >= 3) bb_info_msg(__VA_ARGS__); } while (0) -# else -# define log3(...) ((void)0) -# endif -#else -# define IF_UDHCP_VERBOSE(...) -# define udhcp_dump_packet(...) ((void)0) -# define log1(...) ((void)0) -# define log2(...) ((void)0) -# define log3(...) ((void)0) -#endif - -//#define UDHCP_DBG - -#ifdef UDHCP_DBG -#define UDHCP_DEBUG os_printf -#else -#define UDHCP_DEBUG(...) -#endif - -/*** Other shared functions ***/ - -/* 2nd param is "uint32_t*" */ -int udhcp_str2nip(const char *str, void *arg); -/* 2nd param is "struct option_set**" */ -int udhcp_str2optset(const char *str, void *arg); - -void udhcp_init_header(struct dhcp_packet *packet, char type); - -int udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd); - -//int udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, -// uint32_t source_nip, int source_port, -// uint32_t dest_nip, int dest_port, const uint8_t *dest_arp, -// int ifindex); - -int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, - uint32_t source_nip, int source_port, - uint32_t dest_nip, int dest_port); - -void udhcp_sp_setup(void); -int udhcp_sp_fd_set(fd_set *rfds, int extra_fd); -int udhcp_sp_read(const fd_set *rfds); - -int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac); - -int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf); - -/* Returns 1 if no reply received */ -int arpping(uint32_t test_nip, - const uint8_t *safe_mac, - uint32_t from_ip, - uint8_t *from_mac, - const char *interface); - -/* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ -int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip); - -//POP_SAVED_FUNCTION_VISIBILITY - -#endif diff --git a/include/udhcp/dhcpc.h b/include/udhcp/dhcpc.h deleted file mode 100644 index 1896d40..0000000 --- a/include/udhcp/dhcpc.h +++ /dev/null @@ -1,42 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Licensed under GPLv2, see file LICENSE in this source tree. - */ -#ifndef UDHCP_DHCPC_H -#define UDHCP_DHCPC_H 1 - -//PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN - -struct client_config_t { - uint8_t client_mac[6]; /* Our mac address */ -// IF_FEATURE_UDHCP_PORT(uint16_t port;) - int ifindex; /* Index number of the interface to use */ - uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ - const char *interface; /* The name of the interface to use */ - char *pidfile; /* Optionally store the process ID */ - const char *script; /* User script to run at dhcp events */ - struct option_set *options; /* list of DHCP options to send to server */ - uint8_t *clientid; /* Optional client id to use */ - uint8_t *vendorclass; /* Optional vendor class-id to use */ - uint8_t *hostname; /* Optional hostname to use */ - uint8_t *fqdn; /* Optional fully qualified domain name to use */ - - uint16_t first_secs; - uint16_t last_secs; -}; - -/* server_config sits in 1st half of bb_common_bufsiz1 */ -#define client_config (*(struct client_config_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE / 2])) - -#if ENABLE_FEATURE_UDHCP_PORT -#define CLIENT_PORT (client_config.port) -#define CLIENT_PORT6 (client_config.port) -#else -#define CLIENT_PORT 68 -#define CLIENT_PORT6 546 -#endif - -//POP_SAVED_FUNCTION_VISIBILITY - -#endif - diff --git a/include/udhcp/dhcpd.h b/include/udhcp/dhcpd.h deleted file mode 100644 index bc5e883..0000000 --- a/include/udhcp/dhcpd.h +++ /dev/null @@ -1,146 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Licensed under GPLv2, see file LICENSE in this source tree. - */ -#ifndef UDHCP_DHCPD_H -#define UDHCP_DHCPD_H 1 - -//PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN - -/* Defaults you may want to tweak */ -/* Default max_lease_sec */ -#define DEFAULT_LEASE_TIME (60*60*24 * 10) -#define LEASES_FILE CONFIG_DHCPD_LEASES_FILE -/* Where to find the DHCP server configuration file */ -#define DHCPD_CONF_FILE "/etc/udhcpd.conf" - -#ifndef ENABLE_FEATURE_UDHCP_PORT -#define ENABLE_FEATURE_UDHCP_PORT 0 -#endif - -struct static_lease { - struct static_lease *next; - uint32_t nip; - uint8_t mac[6]; -}; - -struct server_config_t { - char *interface; /* interface to use */ -//TODO: ifindex, server_nip, server_mac -// are obtained from interface name. -// Instead of querying them *once*, create update_server_network_data_cache() -// and call it before any usage of these fields. -// update_server_network_data_cache() must re-query data -// if more than N seconds have passed after last use. - int ifindex; - uint32_t server_nip; -#if ENABLE_FEATURE_UDHCP_PORT - uint16_t port; -#endif - uint8_t server_mac[6]; /* our MAC address (used only for ARP probing) */ - struct option_set *options; /* list of DHCP options loaded from the config file */ - /* start,end are in host order: we need to compare start <= ip <= end */ - uint32_t start_ip; /* start address of leases, in host order */ - uint32_t end_ip; /* end of leases, in host order */ - uint32_t max_lease_sec; /* maximum lease time (host order) */ - uint32_t min_lease_sec; /* minimum lease time a client can request */ - uint32_t max_leases; /* maximum number of leases (including reserved addresses) */ - uint32_t auto_time; /* how long should udhcpd wait before writing a config file. - * if this is zero, it will only write one on SIGUSR1 */ - uint32_t decline_time; /* how long an address is reserved if a client returns a - * decline message */ - uint32_t conflict_time; /* how long an arp conflict offender is leased for */ - uint32_t offer_time; /* how long an offered address is reserved */ - uint32_t siaddr_nip; /* "next server" bootp option */ - char *lease_file; - char *pidfile; - char *notify_file; /* what to run whenever leases are written */ - char *sname; /* bootp server name */ - char *boot_file; /* bootp boot file option */ - struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */ -}; - -#define server_config (*(struct server_config_t*)&bb_common_bufsiz1) -/* client_config sits in 2nd half of bb_common_bufsiz1 */ - -#if ENABLE_FEATURE_UDHCP_PORT -#define SERVER_PORT (server_config.port) -#define SERVER_PORT6 (server_config.port) -#else -#define SERVER_PORT 67 -#define SERVER_PORT6 547 -#endif - - -typedef uint32_t leasetime_t; -typedef int32_t signed_leasetime_t; - -struct dyn_lease { - /* Unix time when lease expires. Kept in memory in host order. - * When written to file, converted to network order - * and adjusted (current time subtracted) */ - leasetime_t expires; - /* "nip": IP in network order */ - uint32_t lease_nip; - /* We use lease_mac[6], since e.g. ARP probing uses - * only 6 first bytes anyway. We check received dhcp packets - * that their hlen == 6 and thus chaddr has only 6 significant bytes - * (dhcp packet has chaddr[16], not [6]) - */ - uint8_t lease_mac[6]; - char hostname[20]; - uint8_t pad[2]; - /* total size is a multiply of 4 */ -}; - -extern struct dyn_lease *g_leases; - -struct dyn_lease *add_lease( - const uint8_t *chaddr, uint32_t yiaddr, - leasetime_t leasetime, - const char *hostname, int hostname_len - ); -int is_expired_lease(struct dyn_lease *lease); -struct dyn_lease *find_lease_by_mac(const uint8_t *mac); -struct dyn_lease *find_lease_by_nip(uint32_t nip); -uint32_t find_free_or_expired_nip(const uint8_t *safe_mac); - - -/* Config file parser will pass static lease info to this function - * which will add it to a data structure that can be searched later */ -void add_static_lease(struct static_lease **st_lease_pp, uint8_t *mac, uint32_t nip); -/* Find static lease IP by mac */ -uint32_t get_static_nip_by_mac(struct static_lease *st_lease, void *arg); -/* Check to see if an IP is reserved as a static IP */ -int is_nip_reserved(struct static_lease *st_lease, uint32_t nip); -/* Print out static leases just to check what's going on (debug code) */ -#ifdef UDHCP_DBG -void log_static_leases(struct static_lease **st_lease_pp); -#else -# define log_static_leases(st_lease_pp) ((void)0) -#endif - -struct dhcp_info{ - /* start,end are in host order: we need to compare start <= ip <= end */ - uint32_t start_ip; /* start address of leases, in host order */ - uint32_t end_ip; /* end of leases, in host order */ - - uint32_t max_leases; /* maximum number of leases (including reserved addresses) */ - uint32_t auto_time; /* how long should udhcpd wait before writing a config file. - * if this is zero, it will only write one on SIGUSR1 */ - uint32_t decline_time; /* how long an address is reserved if a client returns a - * decline message */ - uint32_t conflict_time; /* how long an arp conflict offender is leased for */ - uint32_t offer_time; /* how long an offered address is reserved */ - uint32_t max_lease_sec; /* maximum lease time (host order) */ - uint32_t min_lease_sec; /* minimum lease time a client can request */ -}; - -void read_config(const char *file); -void write_leases(void); -void read_leases(const char *file); - -void udhcpd_start(void); -//POP_SAVED_FUNCTION_VISIBILITY - -#endif diff --git a/lib/libudhcp.a b/lib/libudhcp.a deleted file mode 100644 index d3cd28daef8227e63b7357f32ddf84f98bd80bb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42930 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 F{{WP~5CQ-I