dhcpc: let server know we don't like oversized packets.
add TODO comment
This commit is contained in:
		| @@ -104,3 +104,4 @@ config UDHCPC_SLACK_FOR_BUGGY_SERVERS | ||||
| 	    seems to confuse maximum allowed UDP packet size with | ||||
| 	    maximum size of entire IP packet, and sends packets which are | ||||
| 	    28 bytes too large. | ||||
|           Seednet (ISP) VDSL: sends packets 2 bytes too big. | ||||
|   | ||||
| @@ -96,6 +96,9 @@ int send_discover(uint32_t xid, uint32_t requested) | ||||
| 	if (requested) | ||||
| 		add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); | ||||
|  | ||||
| 	/* Explicitly saying that we want RFC-compliant packets helps | ||||
| 	 * some buggy DHCP servers to NOT send bigger packets */ | ||||
| 	add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576)); | ||||
| 	add_requests(&packet); | ||||
| 	bb_info_msg("Sending discover..."); | ||||
| 	return udhcp_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, | ||||
|   | ||||
| @@ -90,7 +90,7 @@ static void attach_option(struct option_set **opt_list, | ||||
|  | ||||
| 	existing = find_option(*opt_list, option->code); | ||||
| 	if (!existing) { | ||||
| 		DEBUG("Attaching option %s to list", option->name); | ||||
| 		DEBUG("Attaching option %02x to list", option->code); | ||||
|  | ||||
| #if ENABLE_FEATURE_RFC3397 | ||||
| 		if ((option->flags & TYPE_MASK) == OPTION_STR1035) | ||||
| @@ -119,7 +119,7 @@ static void attach_option(struct option_set **opt_list, | ||||
| 	} | ||||
|  | ||||
| 	/* add it to an existing option */ | ||||
| 	DEBUG("Attaching option %s to existing member of list", option->name); | ||||
| 	DEBUG("Attaching option %02x to existing member of list", option->code); | ||||
| 	if (option->flags & OPTION_LIST) { | ||||
| #if ENABLE_FEATURE_RFC3397 | ||||
| 		if ((option->flags & TYPE_MASK) == OPTION_STR1035) | ||||
| @@ -170,7 +170,7 @@ static int read_opt(const char *const_line, void *arg) | ||||
| 	while (1) { | ||||
| 		if (!option->code) | ||||
| 			return 0; | ||||
| 		if (!strcasecmp(option->name, opt)) | ||||
| 		if (!strcasecmp(option->opt_name, opt)) | ||||
| 			break; | ||||
| 		option++; | ||||
| 	} | ||||
|   | ||||
| @@ -9,37 +9,42 @@ | ||||
| #include "options.h" | ||||
|  | ||||
|  | ||||
| /* supported options are easily added here */ | ||||
| /* Supported options are easily added here */ | ||||
| const struct dhcp_option dhcp_options[] = { | ||||
| 	/* name[12]     flags                                   code */ | ||||
| 	{"subnet",      OPTION_IP | OPTION_REQ,                 0x01}, | ||||
| 	{"timezone",    OPTION_S32,                             0x02}, | ||||
| 	{"router",      OPTION_IP | OPTION_LIST | OPTION_REQ,   0x03}, | ||||
| 	{"timesvr",     OPTION_IP | OPTION_LIST,                0x04}, | ||||
| 	{"namesvr",     OPTION_IP | OPTION_LIST,                0x05}, | ||||
| 	{"dns",         OPTION_IP | OPTION_LIST | OPTION_REQ,   0x06}, | ||||
| 	{"logsvr",      OPTION_IP | OPTION_LIST,                0x07}, | ||||
| 	{"cookiesvr",   OPTION_IP | OPTION_LIST,                0x08}, | ||||
| 	{"lprsvr",      OPTION_IP | OPTION_LIST,                0x09}, | ||||
| 	{"hostname",    OPTION_STRING | OPTION_REQ,             0x0c}, | ||||
| 	{"bootsize",    OPTION_U16,                             0x0d}, | ||||
| 	{"domain",      OPTION_STRING | OPTION_LIST | OPTION_REQ, 0x0f}, | ||||
| 	{"swapsvr",     OPTION_IP,                              0x10}, | ||||
| 	{"rootpath",    OPTION_STRING,                          0x11}, | ||||
| 	{"ipttl",       OPTION_U8,                              0x17}, | ||||
| 	{"mtu",         OPTION_U16,                             0x1a}, | ||||
| 	{"broadcast",   OPTION_IP | OPTION_REQ,                 0x1c}, | ||||
| 	{"nisdomain",   OPTION_STRING | OPTION_REQ,             0x28}, | ||||
| 	{"nissrv",      OPTION_IP | OPTION_LIST | OPTION_REQ,   0x29}, | ||||
| 	{"ntpsrv",      OPTION_IP | OPTION_LIST | OPTION_REQ,   0x2a}, | ||||
| 	{"wins",        OPTION_IP | OPTION_LIST,                0x2c}, | ||||
| 	{"requestip",   OPTION_IP,                              0x32}, | ||||
| 	{"lease",       OPTION_U32,                             0x33}, | ||||
| 	{"dhcptype",    OPTION_U8,                              0x35}, | ||||
| 	{"serverid",    OPTION_IP,                              0x36}, | ||||
| 	{"message",     OPTION_STRING,                          0x38}, | ||||
| 	{"vendorclass", OPTION_STRING,                          0x3C}, | ||||
| 	{"clientid",    OPTION_STRING,                          0x3D}, | ||||
| 	/* opt_name[12] flags                                   code */ | ||||
| 	{"subnet",      OPTION_IP | OPTION_REQ,                 0x01},   /* DHCP_SUBNET         */ | ||||
| 	{"timezone",    OPTION_S32,                             0x02},   /* DHCP_TIME_OFFSET    */ | ||||
| 	{"router",      OPTION_IP | OPTION_LIST | OPTION_REQ,   0x03},   /* DHCP_ROUTER         */ | ||||
| 	{"timesvr",     OPTION_IP | OPTION_LIST,                0x04},   /* DHCP_TIME_SERVER    */ | ||||
| 	{"namesvr",     OPTION_IP | OPTION_LIST,                0x05},   /* DHCP_NAME_SERVER    */ | ||||
| 	{"dns",         OPTION_IP | OPTION_LIST | OPTION_REQ,   0x06},   /* DHCP_DNS_SERVER     */ | ||||
| 	{"logsvr",      OPTION_IP | OPTION_LIST,                0x07},   /* DHCP_LOG_SERVER     */ | ||||
| 	{"cookiesvr",   OPTION_IP | OPTION_LIST,                0x08},   /* DHCP_COOKIE_SERVER  */ | ||||
| 	{"lprsvr",      OPTION_IP | OPTION_LIST,                0x09},   /* DHCP_LPR_SERVER     */ | ||||
| 	{"hostname",    OPTION_STRING | OPTION_REQ,             0x0c},   /* DHCP_HOST_NAME      */ | ||||
| 	{"bootsize",    OPTION_U16,                             0x0d},   /* DHCP_BOOT_SIZE      */ | ||||
| 	{"domain",      OPTION_STRING | OPTION_LIST | OPTION_REQ, 0x0f}, /* DHCP_DOMAIN_NAME    */ | ||||
| 	{"swapsvr",     OPTION_IP,                              0x10},   /* DHCP_SWAP_SERVER    */ | ||||
| 	{"rootpath",    OPTION_STRING,                          0x11},   /* DHCP_ROOT_PATH      */ | ||||
| 	{"ipttl",       OPTION_U8,                              0x17},   /* DHCP_IP_TTL         */ | ||||
| 	{"mtu",         OPTION_U16,                             0x1a},   /* DHCP_MTU            */ | ||||
| 	{"broadcast",   OPTION_IP | OPTION_REQ,                 0x1c},   /* DHCP_BROADCAST      */ | ||||
| 	{"nisdomain",   OPTION_STRING | OPTION_REQ,             0x28},   /* DHCP_NTP_SERVER     */ | ||||
| 	{"nissrv",      OPTION_IP | OPTION_LIST | OPTION_REQ,   0x29},   /* DHCP_WINS_SERVER    */ | ||||
| 	{"ntpsrv",      OPTION_IP | OPTION_LIST | OPTION_REQ,   0x2a},   /* DHCP_REQUESTED_IP   */ | ||||
| 	{"wins",        OPTION_IP | OPTION_LIST,                0x2c},   /* DHCP_LEASE_TIME     */ | ||||
| 	{"requestip",   OPTION_IP,                              0x32},   /* DHCP_OPTION_OVER    */ | ||||
| 	{"lease",       OPTION_U32,                             0x33},   /* DHCP_MESSAGE_TYPE   */ | ||||
| 	{"dhcptype",    OPTION_U8,                              0x35},   /* DHCP_SERVER_ID      */ | ||||
| 	{"serverid",    OPTION_IP,                              0x36},   /* DHCP_PARAM_REQ      */ | ||||
| 	{"message",     OPTION_STRING,                          0x38},   /* DHCP_MESSAGE        */ | ||||
| // TODO: 1) some options should not be parsed & passed to script - | ||||
| // maxsize sure should not, since it cannot appear in server responses! | ||||
| // grep for opt_name is fix the mess. | ||||
| // 2) Using fixed-sized char[] vector wastes space. | ||||
| 	{"maxsize",     OPTION_U16,                             0x39},   /* DHCP_MAX_SIZE       */ | ||||
| 	{"vendorclass", OPTION_STRING,                          0x3C},   /* DHCP_VENDOR         */ | ||||
| 	{"clientid",    OPTION_STRING,                          0x3D},   /* DHCP_CLIENT_ID      */ | ||||
| 	{"tftp",        OPTION_STRING,                          0x42}, | ||||
| 	{"bootfile",    OPTION_STRING,                          0x43}, | ||||
| 	{"userclass",   OPTION_STRING,                          0x4D}, | ||||
| @@ -48,9 +53,10 @@ const struct dhcp_option dhcp_options[] = { | ||||
| #endif | ||||
| 	/* MSIE's "Web Proxy Autodiscovery Protocol" support */ | ||||
| 	{"wpad",        OPTION_STRING,                          0xfc}, | ||||
| 	{"",            0x00,                                   0x00} | ||||
| 	{} /* zero-padded terminating entry */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Lengths of the different option types */ | ||||
| const unsigned char option_lengths[] ALIGN1 = { | ||||
| 	[OPTION_IP] =      4, | ||||
|   | ||||
| @@ -33,6 +33,7 @@ enum { | ||||
|  | ||||
| #define DHCP_MAGIC		0x63825363 | ||||
|  | ||||
|  | ||||
| /* DHCP option codes (partial list) */ | ||||
| #define DHCP_PADDING		0x00 | ||||
| #define DHCP_SUBNET		0x01 | ||||
| @@ -67,7 +68,6 @@ enum { | ||||
| #define DHCP_VENDOR		0x3c | ||||
| #define DHCP_CLIENT_ID		0x3d | ||||
| #define DHCP_FQDN		0x51 | ||||
|  | ||||
| #define DHCP_END		0xFF | ||||
|  | ||||
|  | ||||
| @@ -98,7 +98,7 @@ enum { | ||||
| #define OPT_DATA 2 | ||||
|  | ||||
| struct dhcp_option { | ||||
| 	char name[12]; | ||||
| 	char opt_name[12]; | ||||
| 	char flags; | ||||
| 	uint8_t code; | ||||
| }; | ||||
|   | ||||
| @@ -44,14 +44,15 @@ static int sprintip(char *dest, const char *pre, const uint8_t *ip) | ||||
|  | ||||
|  | ||||
| /* really simple implementation, just count the bits */ | ||||
| static int mton(struct in_addr *mask) | ||||
| static int mton(uint32_t mask) | ||||
| { | ||||
| 	int i; | ||||
| 	unsigned long bits = ntohl(mask->s_addr); | ||||
| 	/* too bad one can't check the carry bit, etc in c bit | ||||
| 	 * shifting */ | ||||
| 	for (i = 0; i < 32 && !((bits >> i) & 1); i++); | ||||
| 	return 32 - i; | ||||
| 	int i = 0; | ||||
| 	mask = ntohl(mask); /* 111110000-like bit pattern */ | ||||
| 	while (mask) { | ||||
| 		i++; | ||||
| 		mask <<= 1; | ||||
| 	} | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -69,8 +70,8 @@ static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p) | ||||
| 	type = type_p->flags & TYPE_MASK; | ||||
| 	optlen = option_lengths[type]; | ||||
|  | ||||
| 	dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->name) + 2); | ||||
| 	dest += sprintf(ret, "%s=", type_p->name); | ||||
| 	dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->opt_name) + 2); | ||||
| 	dest += sprintf(ret, "%s=", type_p->opt_name); | ||||
|  | ||||
| 	for (;;) { | ||||
| 		switch (type) { | ||||
| @@ -133,7 +134,6 @@ static char **fill_envp(struct dhcpMessage *packet) | ||||
| 	char **envp; | ||||
| 	char *var; | ||||
| 	uint8_t *temp; | ||||
| 	struct in_addr subnet; | ||||
| 	char over = 0; | ||||
|  | ||||
| 	if (packet) { | ||||
| @@ -179,8 +179,9 @@ static char **fill_envp(struct dhcpMessage *packet) | ||||
|  | ||||
| 		/* Fill in a subnet bits option for things like /24 */ | ||||
| 		if (dhcp_options[i].code == DHCP_SUBNET) { | ||||
| 			uint32_t subnet; | ||||
| 			memcpy(&subnet, temp, 4); | ||||
| 			envp[j++] = xasprintf("mask=%d", mton(&subnet)); | ||||
| 			envp[j++] = xasprintf("mask=%d", mton(subnet)); | ||||
| 		} | ||||
| 	} | ||||
| 	if (packet->siaddr) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user