From: Roy Marples Date: Thu, 25 Jul 2013 15:10:16 +0000 (+0000) Subject: Add the option hostname_short, which will force the sending of the X-Git-Tag: v6.0.4~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d6a186547664756fd51ca511b4bf821b279068e8;p=thirdparty%2Fdhcpcd.git Add the option hostname_short, which will force the sending of the short hostname so DDNS will always work, even if the hostname domain is different from the DHCP servers. Change hostname_fqdn to true/false/unset value. unset means use what the DHCP server supplies (DHCPv4/DHCPv6 maybe inconsistent depending on server setup) true/false force the hostname to be either a FQDN or a short name. --- diff --git a/common.c b/common.c index 1740e29e..4bf52bad 100644 --- a/common.c +++ b/common.c @@ -136,8 +136,9 @@ set_nonblock(int fd) } const char * -get_hostname(void) +get_hostname(int short_hostname) { + char *p; gethostname(hostname_buffer, sizeof(hostname_buffer)); hostname_buffer[sizeof(hostname_buffer) - 1] = '\0'; @@ -146,6 +147,13 @@ get_hostname(void) strncmp(hostname_buffer, "localhost.", strlen("localhost.")) == 0 || hostname_buffer[0] == '.') return NULL; + + if (short_hostname) { + p = strchr(hostname_buffer, '.'); + if (p) + *p = '\0'; + } + return hostname_buffer; } diff --git a/common.h b/common.h index b7851cb4..392125a2 100644 --- a/common.h +++ b/common.h @@ -100,7 +100,7 @@ int set_cloexec(int); int set_nonblock(int); char *get_line(FILE * __restrict); -const char *get_hostname(void); +const char *get_hostname(int); extern int clock_monotonic; int get_monotonic(struct timeval *); ssize_t setvar(char ***, const char *, const char *, const char *); diff --git a/dhcp.c b/dhcp.c index 06ed6111..30c1ecd6 100644 --- a/dhcp.c +++ b/dhcp.c @@ -845,7 +845,6 @@ make_message(struct dhcp_message **message, uint32_t ul; uint16_t sz; size_t len; - const char *hp; const struct dhcp_opt *opt; const struct if_options *ifo = iface->options; const struct dhcp_state *state = D_CSTATE(iface); @@ -987,7 +986,8 @@ make_message(struct dhcp_message **message, } if (ifo->hostname[0] == '\0') - hostname = get_hostname(); + hostname = get_hostname(ifo->options & + DHCPCD_HOSTNAME_SHORT ? 1 : 0); else hostname = ifo->hostname; if (ifo->fqdn != FQDN_DISABLE) { @@ -1018,17 +1018,7 @@ make_message(struct dhcp_message **message, } } else if (ifo->options & DHCPCD_HOSTNAME && hostname) { *p++ = DHO_HOSTNAME; - /* - * Regardless of RFC2132, we should always send a - * hostname upto the first dot (the short hostname) as - * a FQDN confuses some DHCP servers when updating DNS. - * The FQDN option should be used if a FQDN is wanted. - */ - hp = strchr(hostname, '.'); - if (hp) - len = hp - hostname; - else - len = strlen(hostname); + len = strlen(hostname); *p++ = len; memcpy(p, hostname, len); p += len; diff --git a/dhcp6.c b/dhcp6.c index 9e95b279..3cf69f39 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -398,7 +398,8 @@ dhcp6_makemessage(struct interface *ifp) if (fqdn == FQDN_DISABLE) fqdn = FQDN_BOTH; if (ifo->hostname[0] == '\0') - hostname = get_hostname(); + hostname = get_hostname(ifo->options & + DHCPCD_HOSTNAME_SHORT ? 1 : 0); else hostname = ifo->hostname; } diff --git a/dhcpcd-hooks/30-hostname b/dhcpcd-hooks/30-hostname index 42120ceb..6098f620 100644 --- a/dhcpcd-hooks/30-hostname +++ b/dhcpcd-hooks/30-hostname @@ -1,7 +1,9 @@ # Set the hostname from DHCP data if required -# Generally we should not set the system hostname to be fully qualified -: ${hostname_fqdn:=false} +# Set one of the below to override the DHCP supplied hostname information +# to be either a short hostname or a FQDN. +#hostname_fqdn=false +#hostname_fqdn=true # Some systems don't have hostname(1) _hostname() @@ -41,7 +43,7 @@ _hostname() need_hostname() { - local hostname hfqdn + local hostname hfqdn=false hshort=false case "$force_hostname" in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) return 0;; @@ -54,13 +56,14 @@ need_hostname() case "$hostname_fqdn" in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1) hfqdn=true;; - *) hfqdn=false;; + "") ;; + *) hshort=true;; esac if [ -n "$old_fqdn" ]; then - if ${hfqdn}; then + if ${hfqdn} || ! ${hsort}; then [ "$hostname" = "$old_fqdn" ] - else + else [ "$hostname" = "${old_fqdn%%.*}" ] fi elif [ -n "$old_host_name" ]; then @@ -73,8 +76,10 @@ need_hostname() else [ "$hostname" = "$old_host_name" ] fi - else + elif ${hshort}; then [ "$hostname" = "${old_host_name%%.*}" ] + else + [ "$hostname" = "$old_host_name" ] fi fi } @@ -101,7 +106,7 @@ set_hostname() esac if [ -n "$new_fqdn" ]; then - if ${hfqdn}; then + if ${hfqdn} || ! ${hsort}; then try_hostname "$new_fqdn" else try_hostname "${new_fqdn%%.*}" @@ -115,8 +120,10 @@ set_hostname() else try_hostname "$new_host_name" fi - else + elif ${hshort}; then try_hostname "${new_host_name%%.*}" + else + try_hostname "$new_host_name" fi fi } diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index f2f7fe58..cd14d3d9 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 19, 2013 +.Dd July 25, 2013 .Dt DHCPCD.CONF 5 SMM .Os .Sh NAME @@ -133,6 +133,10 @@ is an empty string then the current system hostname is sent. If .Ar hostname is a FQDN (ie, contains a .) then it will be encoded as such. +.It Ic hostname_short +Sends the short hostname to the DHCP server instead of the FQDN. +This is useful because DHCP servers will not register the FQDN in their +DNS if the domain part does not match theirs. .It Ic ia_na Op Ar iaid Request a DHCPv6 Normal Address for .Ar iaid . diff --git a/if-options.c b/if-options.c index d22af1be..9f359954 100644 --- a/if-options.c +++ b/if-options.c @@ -67,6 +67,7 @@ unsigned long long options = 0; #define O_IA_NA O_BASE + 10 #define O_IA_TA O_BASE + 11 #define O_IA_PD O_BASE + 12 +#define O_HOSTNAME_SHORT O_BASE + 13 const struct option cf_options[] = { {"background", no_argument, NULL, 'b'}, @@ -128,6 +129,7 @@ const struct option cf_options[] = { {"ia_na", no_argument, NULL, O_IA_NA}, {"ia_ta", no_argument, NULL, O_IA_TA}, {"ia_pd", no_argument, NULL, O_IA_PD}, + {"hostname_short", no_argument, NULL, O_HOSTNAME_SHORT}, {NULL, 0, NULL, '\0'} }; @@ -1079,6 +1081,9 @@ got_iaid: } } break; + case O_HOSTNAME_SHORT: + ifo->options |= DHCPCD_HOSTNAME_SHORT; + break; #endif default: return 0; diff --git a/if-options.h b/if-options.h index 06cccdf0..a00dd769 100644 --- a/if-options.h +++ b/if-options.h @@ -94,6 +94,7 @@ #define DHCPCD_IA_FORCED (1ULL << 40) #define DHCPCD_STOPPING (1ULL << 41) #define DHCPCD_DEPARTED (1ULL << 42) +#define DHCPCD_HOSTNAME_SHORT (1ULL << 43) extern const struct option cf_options[];