X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fstatus.c;h=745d349c5765768ce49960dfbd121312d55f97a0;hb=refs%2Ftags%2Fafter-ipv6;hp=a95c7fe33e7895318eb415020fec6cae94d0325b;hpb=320ff76a9709888aeea17dd9edb12b61548f3b35;p=netatalk.git diff --git a/etc/afpd/status.c b/etc/afpd/status.c index a95c7fe3..745d349c 100644 --- a/etc/afpd/status.c +++ b/etc/afpd/status.c @@ -1,5 +1,5 @@ /* - * $Id: status.c,v 1.22 2009-02-16 14:03:30 franklahm Exp $ + * $Id: status.c,v 1.27 2009-11-05 14:38:07 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -18,9 +18,9 @@ #ifdef BSD4_4 #include -#ifndef USE_GETHOSTID +#ifndef HAVE_GETHOSTID #include -#endif /* USE_GETHOSTID */ +#endif /* HAVE_GETHOSTID */ #endif /* BSD4_4 */ #include @@ -88,7 +88,7 @@ static int status_server(char *data, const char *server, const struct afp_option nbp_name(server, &Obj, &Type, &Zone); if ((size_t)-1 == (len = convert_string( options->unixcharset, options->maccharset, - Obj, strlen(Obj), buf, sizeof(buf))) ) { + Obj, -1, buf, sizeof(buf))) ) { len = MIN(strlen(Obj), 31); *data++ = len; memcpy( data, Obj, len ); @@ -194,18 +194,24 @@ static u_int16_t status_signature(char *data, int *servoffset, DSI *dsi, /* If signature type is a standard hostid... */ server_signature_hostid: /* 16-byte signature consists of copies of the hostid */ -#if defined(BSD4_4) && defined(USE_GETHOSTID) +#if defined(BSD4_4) && !defined(HAVE_GETHOSTID) mib[0] = CTL_KERN; mib[1] = KERN_HOSTID; len = sizeof(hostid); sysctl(mib, 2, &hostid, &len, NULL, 0); -#else /* BSD4_4 && USE_GETHOSTID */ +#else /* BSD4_4 && !HAVE_GETHOSTID */ hostid = gethostid(); -#endif /* BSD4_4 && USE_GETHOSTID */ +#endif /* BSD4_4 && !HAVE_GETHOSTID */ if (!hostid) { - if (dsi) - hostid = dsi->server.sin_addr.s_addr; - else { + if (dsi) { + if (dsi->server.ss_family == AF_INET) { /* IPv4 */ + hostid = ((struct sockaddr_in *)(&dsi->server))->sin_addr.s_addr; + } else { /* IPv6 */ + struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&dsi->server; + /* Use the last "sizeof(long) bytes of the IPv6 addr */ + memcpy(&hostid, sa6->sin6_addr.s6_addr + (16 - sizeof(long)), sizeof(long)); + } + } else { struct hostent *host; if ((host = gethostbyname(options->hostname))) @@ -261,25 +267,45 @@ static size_t status_netaddress(char *data, int *servoffset, /* ip address */ if (dsi) { - const struct sockaddr_in *inaddr = &dsi->server; - - if (inaddr->sin_port == htons(DSI_AFPOVERTCP_PORT)) { - *data++ = 6; /* length */ - *data++ = 0x01; /* basic ip address */ - memcpy(data, &inaddr->sin_addr.s_addr, - sizeof(inaddr->sin_addr.s_addr)); - data += sizeof(inaddr->sin_addr.s_addr); - addresses_len += 7; - } else { - /* ip address + port */ - *data++ = 8; - *data++ = 0x02; /* ip address with port */ - memcpy(data, &inaddr->sin_addr.s_addr, - sizeof(inaddr->sin_addr.s_addr)); - data += sizeof(inaddr->sin_addr.s_addr); - memcpy(data, &inaddr->sin_port, sizeof(inaddr->sin_port)); - data += sizeof(inaddr->sin_port); - addresses_len += 9; + if (dsi->server.ss_family == AF_INET) { /* IPv4 */ + const struct sockaddr_in *inaddr = (struct sockaddr_in *)&dsi->server; + if (inaddr->sin_port == htons(DSI_AFPOVERTCP_PORT)) { + *data++ = 6; /* length */ + *data++ = 0x01; /* basic ip address */ + memcpy(data, &inaddr->sin_addr.s_addr, + sizeof(inaddr->sin_addr.s_addr)); + data += sizeof(inaddr->sin_addr.s_addr); + addresses_len += 7; + } else { + /* ip address + port */ + *data++ = 8; + *data++ = 0x02; /* ip address with port */ + memcpy(data, &inaddr->sin_addr.s_addr, + sizeof(inaddr->sin_addr.s_addr)); + data += sizeof(inaddr->sin_addr.s_addr); + memcpy(data, &inaddr->sin_port, sizeof(inaddr->sin_port)); + data += sizeof(inaddr->sin_port); + addresses_len += 9; + } + } else { /* IPv6 */ + const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&dsi->server; + if (sa6->sin6_port == htons(DSI_AFPOVERTCP_PORT)) { + *data++ = 18; /* length */ + *data++ = 6; /* type */ + memcpy(data, &sa6->sin6_addr.s6_addr, sizeof(sa6->sin6_addr.s6_addr)); + data += sizeof(sa6->sin6_addr.s6_addr); + addresses_len += 19; + } else { + /* ip address + port */ + *data++ = 20; /* length */ + *data++ = 7; /* type*/ + memcpy(data, &sa6->sin6_addr.s6_addr, sizeof(sa6->sin6_addr.s6_addr)); + data += sizeof(sa6->sin6_addr.s6_addr); + memcpy(data, &sa6->sin6_port, sizeof(sa6->sin6_port)); + data += sizeof(sa6->sin6_port); + addresses_len += 21; + } + } } @@ -417,7 +443,7 @@ static size_t status_utf8servername(char *data, int *nameoffset, if ((size_t) -1 == (len = convert_string ( options->unixcharset, CH_UTF8_MAC, - Obj, strlen(Obj), data+sizeof(namelen), maxstatuslen-offset )) ) { + Obj, -1, data+sizeof(namelen), maxstatuslen-offset )) ) { LOG ( log_error, logtype_afpd, "Could not set utf8 servername"); /* set offset to 0 */ @@ -471,7 +497,7 @@ static void status_icon(char *data, const unsigned char *icondata, /* --------------------- */ -void status_reset() +void status_reset(void) { Id = 0; } @@ -486,7 +512,7 @@ void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig, DSI *dsi; char *status = NULL; size_t statuslen; - int c, sigoff; + int c, sigoff, ipok; if (!(aspconfig || dsiconfig) || !options) return; @@ -502,6 +528,19 @@ void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig, status = dsiconfig->status; maxstatuslen=sizeof(dsiconfig->status); dsi = dsiconfig->obj.handle; + if (dsi->server.ss_family == AF_INET) { /* IPv4 */ + const struct sockaddr_in *sa4 = (struct sockaddr_in *)&dsi->server; + ipok = sa4->sin_addr.s_addr ? 1 : 0; + } else { /* IPv6 */ + const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&dsi->server; + ipok = 0; + for (int i=0; i<16; i++) { + if (sa6->sin6_addr.s6_addr[i]) { + ipok = 1; + break; + } + } + } } else dsi = NULL; @@ -525,11 +564,12 @@ void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig, * (16-bytes), network addresses, volume icon/mask */ - status_flags(status, options->server_notif, options->fqdn || - (dsiconfig && dsi->server.sin_addr.s_addr), + status_flags(status, + options->server_notif, + (options->fqdn || ipok), options->passwdbits, - (options->k5service && options->k5realm && options->fqdn), - options->flags); + (options->k5service && options->k5realm && options->fqdn), + options->flags); /* returns offset to signature offset */ c = status_server(status, options->server ? options->server : options->hostname, options); @@ -574,10 +614,7 @@ void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig, } /* this is the same as asp/dsi_getstatus */ -int afp_getsrvrinfo(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf _U_, *rbuf; -int ibuflen _U_, *rbuflen; +int afp_getsrvrinfo(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { AFPConfig *config = obj->config;