4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs/*
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs *
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * Licensed under the Academic Free License version 2.1
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <stdio.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <stdlib.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <unistd.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <signal.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <string.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <sys/types.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <sys/socket.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <sys/ioctl.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <sys/sockio.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <net/if.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <net/if_arp.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <netinet/in.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <arpa/inet.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <netdb.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <libhal.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <logger.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <glib.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include "network-discovery.h"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#define NP(x) (x?x:"NULL")
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsextern int snmp_printer_info(char *hostname, char *community,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char **manufacturer, char **model, char **description,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char **serial_no, char ***command_set, char **uri);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsvoid
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnetwork_device_name_to_udi(char *udi, size_t size, ...)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs va_list ap;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *element;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int i;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs udi[0] = '\0';
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs va_start(ap, size);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs while ((element = va_arg(ap, char *)) != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (element[0] != '/')
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs strlcat(udi, "/", size);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs strlcat(udi, element, size);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs va_end(ap);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs for (i = 0; udi[i] != NULL; i++)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (udi[i] == '.')
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs udi[i] = '_';
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic void nop(int sig) {}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic int
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobstest_socket_access(struct in6_addr *addr, int port)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int sd, rc;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct sockaddr_in6 sin6;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs void (*hndlr)(int);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs memset(&sin6, 0, sizeof (sin6));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs sin6.sin6_family = AF_INET6;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs memcpy(&sin6.sin6_addr, addr, sizeof (*addr));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs sin6.sin6_port = htons(port);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs sd = socket(AF_INET6, SOCK_STREAM, 0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs hndlr = signal(SIGALRM, nop);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs alarm(1);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs rc = connect(sd, (struct sockaddr *)&sin6, sizeof (sin6));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs alarm(0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (hndlr != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs signal(SIGALRM, hndlr);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs close(sd);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return ((rc < 0) ? 1 : 0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsint
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsis_listening(char *hostname, int port)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *uri = NULL, addr_string[INET6_ADDRSTRLEN];
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct in6_addr ipv6addr[1];
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int errnum;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct hostent *hp;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs hp = getipnodebyname(hostname, AF_INET6,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &errnum);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (hp != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (void) memcpy(&ipv6addr, hp->h_addr_list[0], hp->h_length);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs } else
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (-1);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (test_socket_access(ipv6addr, port));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic char *
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsaddr_to_string(char *prefix, uchar_t *mac, int mac_len, char *buf, int buf_len)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int i, n = 0;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs buf[0] = '\0';
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (prefix != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs n = sprintf(buf, prefix);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs for (i = 0; ((i < (mac_len)) && (n < buf_len)); i++)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs n += sprintf(buf + n, "%2.2X", *mac++);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (buf);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic char *
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobspseudo_serialno_from_addr(char *name)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int sd, rc, errnum;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char buf[128];
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct hostent *hp;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct xarpreq ar;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (name == NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (NULL);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs memset(&ar, 0, sizeof (ar));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs hp = getipnodebyname(name, AF_INET6, AI_ADDRCONFIG, &errnum);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (hp != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ar.xarp_pa;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs sin6->sin6_family = AF_INET6;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (void) memcpy(&sin6->sin6_addr, hp->h_addr_list[0],
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs hp->h_length);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs } else {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct sockaddr_in *sin = (struct sockaddr_in *)&ar.xarp_pa;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs sin->sin_family = AF_INET;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs sin->sin_addr.s_addr = inet_addr(name);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs sd = socket(AF_INET, SOCK_DGRAM, 0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ar.xarp_ha.sdl_family = AF_LINK;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs rc = ioctl(sd, SIOCGXARP, (caddr_t)&ar);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs close(sd);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (ar.xarp_flags & ATF_COM) { /* use the MAC address */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs uchar_t *ea = (uchar_t *)LLADDR(&ar.xarp_ha);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs addr_to_string("LLADDR-", ea, ar.xarp_ha.sdl_alen,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs buf, sizeof (buf));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs } else if (hp != NULL) { /* use the IPv6 address */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs addr_to_string("IPV6ADDR-", (uchar_t *)&hp->h_addr_list[0],
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs hp->h_length, buf, sizeof (buf));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs } else { /* use the IPv4 address */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct sockaddr_in *sin = (struct sockaddr_in *)&ar.xarp_pa;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs addr_to_string("IPV4ADDR-", (uchar_t *)&sin->sin_addr.s_addr, 4,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs buf, sizeof (buf));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (strdup(buf));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsint
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsadd_network_printer(LibHalContext *ctx, char *base, char *hostaddr,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *device, char *community)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBusError error;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int rc = -1;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char udi[128];
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *tmp_udi = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs static char *parent = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *manufacturer = NULL, *model = NULL, *description = NULL,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs *uri = NULL, *sn, *serial;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs sn = serial = pseudo_serialno_from_addr(hostaddr);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (parent == NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs parent = getenv("UDI");
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_init(&error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs network_device_name_to_udi(udi, sizeof (udi), base, serial, NULL);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (libhal_device_exists(ctx, udi, &error) == TRUE)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs goto out;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((tmp_udi = libhal_new_device(ctx, &error)) == NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs goto out;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_printer_info(hostaddr, community, &manufacturer, &model,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs &description, &serial, NULL, &uri);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "info.parent", parent, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "info.category", "printer", &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_property_strlist_append(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "info.capabilities", "printer", &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_property_strlist_append(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "info.capabilities", "network_device", &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "network_device.address", hostaddr, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((community != NULL) && (strcasecmp(community, "public") != 0))
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "network_device.snmp_community", community, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((uri != NULL) || (device != NULL))
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "printer.device", (uri ? uri : device), &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (serial != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "printer.serial", serial, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (manufacturer != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "printer.vendor", manufacturer, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (model != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "printer.product", model, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (description != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_device_set_property_string(ctx, tmp_udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "printer.description", description, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* commit the changes to the new UDI */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs rc = libhal_device_commit_to_gdl(ctx, tmp_udi, udi, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsout:
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("result: %s (%s): %s, %s, %s, %s, %s", hostaddr, udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs NP(manufacturer), NP(model), NP(description), NP(serial),
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs NP(uri)));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (tmp_udi != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(tmp_udi);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (manufacturer != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(manufacturer);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (model != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(model);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (description != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(description);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (uri != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(uri);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (sn != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(sn);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (dbus_error_is_set(&error)) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_WARNING(("%s: %s", error.name, error.message));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_free(&error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("add: %s (%s)", hostaddr, udi));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (rc);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic int
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnumber_of_interfaces(int s)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int rc = -1;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct lifnum n;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs memset(&n, 0 , sizeof (n));
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems n.lifn_family = AF_INET;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (ioctl(s, SIOCGLIFNUM, (char *)&n) == 0)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs rc = n.lifn_count;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (rc);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic char *
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsbroadcast_address(int s, char *ifname)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *result = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct lifreq r;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs memset(&r, 0, sizeof (r));
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems strlcpy(r.lifr_name, ifname, sizeof (r.lifr_name));
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&r) < 0) {
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems HAL_DEBUG(("broadcast_address: ioctl(SIOCGLIFFLAGS) failed."));
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems return (NULL);
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems }
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems if ((r.lifr_flags & (IFF_UP | IFF_LOOPBACK)) != IFF_UP) {
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems return (NULL);
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems }
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems if (ioctl(s, SIOCGLIFBRDADDR, (char *)&r) >= 0) {
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems char buf[INET_ADDRSTRLEN];
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems struct sockaddr_in *s =
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems (struct sockaddr_in *)&r.lifr_broadaddr;
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems result = (char *)inet_ntop(AF_INET,
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems &s->sin_addr, buf, sizeof (buf));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (result != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs result = strdup(result);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (result);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsGList *
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsbroadcast_addresses()
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs GList *result = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int s;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct lifconf c;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int count;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (NULL);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs count = number_of_interfaces(s);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs memset(&c, 0, sizeof (c));
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems c.lifc_family = AF_INET;
18c4e255539c8eac2a18c73be8729ec1f6fa818aLin Guo - Sun Microsystems c.lifc_flags = 0;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs c.lifc_buf = calloc(count, sizeof (struct lifreq));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs c.lifc_len = (count * sizeof (struct lifreq));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (ioctl(s, SIOCGLIFCONF, (char *)&c) == 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs struct lifreq *r = c.lifc_req;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs for (count = c.lifc_len / sizeof (struct lifreq);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs count > 0; count--, r++) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *address = broadcast_address(s, r->lifr_name);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (address != NULL) /* add it to the list */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs result = g_list_append(result, address);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(c.lifc_buf);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs close(s);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (result);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}