/*
- * $Id: status.c,v 1.17 2005-05-03 14:55:10 didg 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.
#ifdef BSD4_4
#include <sys/param.h>
-#ifndef USE_GETHOSTID
+#ifndef HAVE_GETHOSTID
#include <sys/sysctl.h>
-#endif /* USE_GETHOSTID */
+#endif /* HAVE_GETHOSTID */
#endif /* BSD4_4 */
#include <netatalk/at.h>
static size_t maxstatuslen = 0;
static void status_flags(char *data, const int notif, const int ipok,
- const unsigned char passwdbits, const int dirsrvcs _U_)
+ const unsigned char passwdbits, const int dirsrvcs _U_, int flags)
{
u_int16_t status;
status |= AFPSRVRINFO_SRVRDIR; /* AFP 3.1 specs says we need to specify this, but may set the count to 0 */
/* We don't set the UTF8 name flag here, we don't know whether we have enough space ... */
+ if (flags & OPTION_UUID) /* 05122008 FIXME: can we set AFPSRVRINFO_UUID here ? see AFPSRVRINFO_SRVRDIR*/
+ status |= AFPSRVRINFO_UUID;
+
status = htons(status);
memcpy(data + AFPSTATUS_FLAGOFF, &status, sizeof(status));
}
nbp_name(server, &Obj, &Type, &Zone);
if ((size_t)-1 == (len = convert_string(
options->unixcharset, options->maccharset,
- Obj, strlen(Obj), buf, 31)) ) {
+ Obj, -1, buf, sizeof(buf))) ) {
len = MIN(strlen(Obj), 31);
*data++ = len;
memcpy( data, Obj, len );
/* 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)))
/* 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;
+ }
+
}
}
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 */
/* ---------------------
*/
-void status_reset()
+void status_reset(void)
{
Id = 0;
}
DSI *dsi;
char *status = NULL;
size_t statuslen;
- int c, sigoff;
+ int c, sigoff, ipok;
if (!(aspconfig || dsiconfig) || !options)
return;
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;
* (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->k5service && options->k5realm && options->fqdn),
+ options->flags);
/* returns offset to signature offset */
c = status_server(status, options->server ? options->server :
options->hostname, options);
}
/* 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;