From: Roy Marples Date: Wed, 18 Jul 2007 14:22:02 +0000 (+0000) Subject: Support RFC 3361 SIP Servers. X-Git-Tag: v3.2.3~232 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc3617fbf184a486647b068c0f2ae150ae11c268;p=thirdparty%2Fdhcpcd.git Support RFC 3361 SIP Servers. --- diff --git a/ChangeLog b/ChangeLog index 12bedab6..62fbfa6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +Support RFC 3361 SIP Servers. We now do ARP checking by default as recommended by RFC 2131. Add RFC 3927 (aka IPV4LL aka APIPA) support by default. Suport DHCP option (52) overload. diff --git a/Makefile b/Makefile index 8323d5b1..56e1efa9 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION = 3.1.0_pre5 +VERSION = 3.1.0_pre6 CFLAGS ?= -O2 -pipe # Should work for both GNU make and BSD make diff --git a/client.c b/client.c index 9ba63314..4d55e6c5 100644 --- a/client.c +++ b/client.c @@ -410,7 +410,9 @@ int dhcp_run (const options_t *options, int *pidfd) free_dhcp (dhcp); memset (dhcp, 0, sizeof (dhcp_t)); #ifdef ENABLE_INFO - if (! get_old_lease (options, iface, dhcp, &timeout)) { + if (! options->test && + ! get_old_lease (options, iface, dhcp, &timeout)) + { if (options->dolastlease) { retval = EXIT_FAILURE; goto eexit; @@ -422,9 +424,10 @@ int dhcp_run (const options_t *options, int *pidfd) #endif #ifdef ENABLE_IPV4LL - if (! dhcp->address.s_addr || - (! IN_LINKLOCAL (dhcp->address.s_addr) && - ! options->dolastlease)) + if (! options->test && + (! dhcp->address.s_addr || + (! IN_LINKLOCAL (dhcp->address.s_addr) && + ! options->dolastlease))) { logger (LOG_INFO, "probing for an IPV4LL address"); free_dhcp (dhcp); diff --git a/dhcp.c b/dhcp.c index b095d2f2..bbdc1c8d 100644 --- a/dhcp.c +++ b/dhcp.c @@ -26,9 +26,12 @@ #include #include +#include + #include #include #include +#include #include #include #include @@ -171,7 +174,7 @@ size_t send_message (const interface_t *iface, const dhcp_t *dhcp, RFC2131 Section 3.5 states that the REQUEST must include the list from the DISCOVER message, so I think we can safely do this. */ - if (type == DHCP_DISCOVER) + if (type == DHCP_DISCOVER && ! options->test) *p++ = DHCP_DNSSERVER; else { if (type != DHCP_INFORM) { @@ -194,11 +197,7 @@ size_t send_message (const interface_t *iface, const dhcp_t *dhcp, *p++ = DHCP_NTPSERVER; *p++ = DHCP_MTU; *p++ = DHCP_ROOTPATH; - /* These parameters were requested by dhcpcd-2.0 and earlier - but we never did anything with them */ - /* *p++ = DHCP_DEFAULTIPTTL; - *p++ = DHCP_MASKDISCOVERY; - *p++ = DHCP_ROUTERDISCOVERY; */ + *p++ = DHCP_SIPSERVER; } *n_params = p - n_params - 1; @@ -356,7 +355,7 @@ static unsigned int decode_search (const unsigned char *p, int len, char *out) /* Add our classless static routes to the routes variable * and return the last route set */ -static route_t *decodeCSR(const unsigned char *p, int len) +static route_t *decode_CSR(const unsigned char *p, int len) { const unsigned char *q = p; int cidr; @@ -459,6 +458,48 @@ static bool dhcp_add_address(address_t **address, const unsigned char *data, int return (true); } +static char *decode_sipservers (const unsigned char *data, int length) +{ + char *sip = NULL; + char *p; + const char encoding = *data++; + struct in_addr addr; + int len; + + length--; + + switch (encoding) { + case 0: + if ((len = decode_search (data, length, NULL)) > 0) { + sip = xmalloc (len); + decode_search (data, length, sip); + } + break; + + case 1: + if (length % 4 != 0) { + logger (LOG_ERR, "invalid length %d for option 120", length + 1); + break; + } + len = ((length / 4) * (4 * 4)) + 1; + sip = p = xmalloc (len); + while (length != 0) { + memcpy (&addr.s_addr, data, 4); + data += 4; + p += snprintf (p, len - (p - sip), "%s ", inet_ntoa (addr)); + length -= 4; + } + *--p = '\0'; + break; + + default: + logger (LOG_ERR, "unknown sip encoding %d", *data); + break; + } + + return (sip); +} + int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message) { const unsigned char *p = message->options; @@ -510,6 +551,12 @@ parse_start: length = *p++; + if (option != DHCP_PAD && length == 0) { + logger (LOG_ERR, "option %d has zero length", option); + retval = -1; + goto eexit; + } + if (p + length >= end) { logger (LOG_ERR, "dhcp option exceeds message length"); retval = -1; @@ -646,7 +693,12 @@ parse_start: case DHCP_CSR: MIN_LENGTH (5); free_route (csr); - csr = decodeCSR (p, length); + csr = decode_CSR (p, length); + break; + + case DHCP_SIPSERVER: + free (dhcp->sipservers); + dhcp->sipservers = decode_sipservers (p, length); break; case DHCP_STATICROUTE: diff --git a/dhcp.h b/dhcp.h index 3f5b9cda..e47113be 100644 --- a/dhcp.h +++ b/dhcp.h @@ -96,6 +96,7 @@ enum DHCP_OPTIONS DHCP_USERCLASS = 77, /* RFC 3004 */ DHCP_FQDN = 81, DHCP_DNSSEARCH = 119, /* RFC 3397 */ + DHCP_SIPSERVER = 120, /* RFC 3361 */ DHCP_CSR = 121, /* RFC 3442 */ DHCP_END = 255 }; @@ -151,6 +152,8 @@ typedef struct dhcp_t address_t *nisservers; char *nisdomain; + char *sipservers; + char *message; char *rootpath; diff --git a/info.c b/info.c index 6726a289..316a1362 100644 --- a/info.c +++ b/info.c @@ -173,6 +173,9 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp, if (dhcp->rootpath) fprintf (f, "ROOTPATH='%s'\n", cleanmetas (dhcp->rootpath)); + if (dhcp->sipservers) + fprintf (f, "SIPSERVERS='%s'\n", cleanmetas (dhcp->sipservers)); + if (dhcp->serveraddress.s_addr) fprintf (f, "DHCPSID='%s'\n", inet_ntoa (dhcp->serveraddress)); if (dhcp->servername[0])