/*
- * $Id: status.c,v 1.24 2009-10-13 22:55:37 didg Exp $
+ * $Id: status.c,v 1.30 2009-11-23 19:04:14 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/socket.h>
#include <atalk/logger.h>
#ifdef BSD4_4
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 );
hostid = 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 */
DSI *dsi;
char *status = NULL;
size_t statuslen;
- int c, sigoff;
+ int c, sigoff, ipok;
if (!(aspconfig || dsiconfig) || !options)
return;
} else
asp = NULL;
+ ipok = 0;
if (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;
+ 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->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);
status_machine(status);
- status_versions(status);
+ status_versions(status, asp, dsi);
status_uams(status, options->uamlist);
if (options->flags & OPTION_CUSTOMICON)
status_icon(status, icon, sizeof(icon), c);
}
/* this is the same as asp/dsi_getstatus */
-int afp_getsrvrinfo(AFPObj *obj, char *ibuf _U_, int ibuflen _U_, char *rbuf, int *rbuflen)
+int afp_getsrvrinfo(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
{
AFPConfig *config = obj->config;