Annotation of embedaddon/dnsmasq/src/dbus.c, revision 1.1.1.2

1.1.1.2 ! misho       1: /* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
1.1       misho       2: 
                      3:    This program is free software; you can redistribute it and/or modify
                      4:    it under the terms of the GNU General Public License as published by
                      5:    the Free Software Foundation; version 2 dated June, 1991, or
                      6:    (at your option) version 3 dated 29 June, 2007.
                      7:  
                      8:    This program is distributed in the hope that it will be useful,
                      9:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     10:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     11:    GNU General Public License for more details.
                     12:      
                     13:    You should have received a copy of the GNU General Public License
                     14:    along with this program.  If not, see <http://www.gnu.org/licenses/>.
                     15: */
                     16: 
                     17: #include "dnsmasq.h"
                     18: 
                     19: #ifdef HAVE_DBUS
                     20: 
                     21: #include <dbus/dbus.h>
                     22: 
                     23: const char* introspection_xml_template =
                     24: "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
                     25: "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
                     26: "<node name=\"" DNSMASQ_PATH "\">\n"
                     27: "  <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
                     28: "    <method name=\"Introspect\">\n"
                     29: "      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
                     30: "    </method>\n"
                     31: "  </interface>\n"
                     32: "  <interface name=\"%s\">\n"
                     33: "    <method name=\"ClearCache\">\n"
                     34: "    </method>\n"
                     35: "    <method name=\"GetVersion\">\n"
                     36: "      <arg name=\"version\" direction=\"out\" type=\"s\"/>\n"
                     37: "    </method>\n"
                     38: "    <method name=\"SetServers\">\n"
                     39: "      <arg name=\"servers\" direction=\"in\" type=\"av\"/>\n"
                     40: "    </method>\n"
                     41: "    <method name=\"SetDomainServers\">\n"
                     42: "      <arg name=\"servers\" direction=\"in\" type=\"as\"/>\n"
                     43: "    </method>\n"
                     44: "    <method name=\"SetServersEx\">\n"
                     45: "      <arg name=\"servers\" direction=\"in\" type=\"aas\"/>\n"
                     46: "    </method>\n"
                     47: "    <signal name=\"DhcpLeaseAdded\">\n"
                     48: "      <arg name=\"ipaddr\" type=\"s\"/>\n"
                     49: "      <arg name=\"hwaddr\" type=\"s\"/>\n"
                     50: "      <arg name=\"hostname\" type=\"s\"/>\n"
                     51: "    </signal>\n"
                     52: "    <signal name=\"DhcpLeaseDeleted\">\n"
                     53: "      <arg name=\"ipaddr\" type=\"s\"/>\n"
                     54: "      <arg name=\"hwaddr\" type=\"s\"/>\n"
                     55: "      <arg name=\"hostname\" type=\"s\"/>\n"
                     56: "    </signal>\n"
                     57: "    <signal name=\"DhcpLeaseUpdated\">\n"
                     58: "      <arg name=\"ipaddr\" type=\"s\"/>\n"
                     59: "      <arg name=\"hwaddr\" type=\"s\"/>\n"
                     60: "      <arg name=\"hostname\" type=\"s\"/>\n"
                     61: "    </signal>\n"
                     62: "  </interface>\n"
                     63: "</node>\n";
                     64: 
                     65: static char *introspection_xml = NULL;
                     66: 
                     67: struct watch {
                     68:   DBusWatch *watch;      
                     69:   struct watch *next;
                     70: };
                     71: 
                     72: 
                     73: static dbus_bool_t add_watch(DBusWatch *watch, void *data)
                     74: {
                     75:   struct watch *w;
                     76: 
                     77:   for (w = daemon->watches; w; w = w->next)
                     78:     if (w->watch == watch)
                     79:       return TRUE;
                     80: 
                     81:   if (!(w = whine_malloc(sizeof(struct watch))))
                     82:     return FALSE;
                     83: 
                     84:   w->watch = watch;
                     85:   w->next = daemon->watches;
                     86:   daemon->watches = w;
                     87: 
                     88:   w = data; /* no warning */
                     89:   return TRUE;
                     90: }
                     91: 
                     92: static void remove_watch(DBusWatch *watch, void *data)
                     93: {
                     94:   struct watch **up, *w, *tmp;  
                     95:   
                     96:   for (up = &(daemon->watches), w = daemon->watches; w; w = tmp)
                     97:     {
                     98:       tmp = w->next;
                     99:       if (w->watch == watch)
                    100:        {
                    101:          *up = tmp;
                    102:          free(w);
                    103:        }
                    104:       else
                    105:        up = &(w->next);
                    106:     }
                    107: 
                    108:   w = data; /* no warning */
                    109: }
                    110: 
                    111: static void dbus_read_servers(DBusMessage *message)
                    112: {
                    113:   DBusMessageIter iter;
                    114:   union  mysockaddr addr, source_addr;
                    115:   char *domain;
                    116:   
                    117:   dbus_message_iter_init(message, &iter);
                    118: 
1.1.1.2 ! misho     119:   mark_servers(SERV_FROM_DBUS);
        !           120:   
1.1       misho     121:   while (1)
                    122:     {
                    123:       int skip = 0;
                    124: 
                    125:       if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32)
                    126:        {
                    127:          u32 a;
                    128:          
                    129:          dbus_message_iter_get_basic(&iter, &a);
                    130:          dbus_message_iter_next (&iter);
                    131:          
                    132: #ifdef HAVE_SOCKADDR_SA_LEN
                    133:          source_addr.in.sin_len = addr.in.sin_len = sizeof(struct sockaddr_in);
                    134: #endif
                    135:          addr.in.sin_addr.s_addr = ntohl(a);
                    136:          source_addr.in.sin_family = addr.in.sin_family = AF_INET;
                    137:          addr.in.sin_port = htons(NAMESERVER_PORT);
                    138:          source_addr.in.sin_addr.s_addr = INADDR_ANY;
                    139:          source_addr.in.sin_port = htons(daemon->query_port);
                    140:        }
                    141:       else if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_BYTE)
                    142:        {
                    143:          unsigned char p[sizeof(struct in6_addr)];
                    144:          unsigned int i;
                    145: 
                    146:          skip = 1;
                    147: 
                    148:          for(i = 0; i < sizeof(struct in6_addr); i++)
                    149:            {
                    150:              dbus_message_iter_get_basic(&iter, &p[i]);
                    151:              dbus_message_iter_next (&iter);
                    152:              if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BYTE)
                    153:                break;
                    154:            }
                    155: 
                    156: #ifndef HAVE_IPV6
                    157:          my_syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
                    158: #else
                    159:          if (i == sizeof(struct in6_addr)-1)
                    160:            {
                    161:              memcpy(&addr.in6.sin6_addr, p, sizeof(struct in6_addr));
                    162: #ifdef HAVE_SOCKADDR_SA_LEN
                    163:               source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(struct sockaddr_in6);
                    164: #endif
                    165:               source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
                    166:               addr.in6.sin6_port = htons(NAMESERVER_PORT);
                    167:               source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
                    168:              source_addr.in6.sin6_scope_id = addr.in6.sin6_scope_id = 0;
                    169:               source_addr.in6.sin6_addr = in6addr_any;
                    170:               source_addr.in6.sin6_port = htons(daemon->query_port);
                    171:              skip = 0;
                    172:            }
                    173: #endif
                    174:        }
                    175:       else
                    176:        /* At the end */
                    177:        break;
                    178:       
                    179:       /* process each domain */
                    180:       do {
                    181:        if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING)
                    182:          {
                    183:            dbus_message_iter_get_basic(&iter, &domain);
                    184:            dbus_message_iter_next (&iter);
                    185:          }
                    186:        else
                    187:          domain = NULL;
                    188:        
                    189:        if (!skip)
1.1.1.2 ! misho     190:          add_update_server(SERV_FROM_DBUS, &addr, &source_addr, NULL, domain);
1.1       misho     191:      
                    192:       } while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING); 
                    193:     }
                    194:    
                    195:   /* unlink and free anything still marked. */
1.1.1.2 ! misho     196:   cleanup_servers();
1.1       misho     197: }
                    198: 
                    199: static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
                    200: {
                    201:   DBusMessageIter iter, array_iter, string_iter;
                    202:   DBusMessage *error = NULL;
                    203:   const char *addr_err;
                    204:   char *dup = NULL;
                    205:   
                    206:   if (!dbus_message_iter_init(message, &iter))
                    207:     {
                    208:       return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                    209:                                     "Failed to initialize dbus message iter");
                    210:     }
                    211: 
                    212:   /* check that the message contains an array of arrays */
                    213:   if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
                    214:       (dbus_message_iter_get_element_type(&iter) != (strings ? DBUS_TYPE_STRING : DBUS_TYPE_ARRAY)))
                    215:     {
                    216:       return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                    217:                                     strings ? "Expected array of string" : "Expected array of string arrays");
                    218:      }
                    219:  
1.1.1.2 ! misho     220:   mark_servers(SERV_FROM_DBUS);
1.1       misho     221: 
                    222:   /* array_iter points to each "as" element in the outer array */
                    223:   dbus_message_iter_recurse(&iter, &array_iter);
                    224:   while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID)
                    225:     {
                    226:       const char *str = NULL;
                    227:       union  mysockaddr addr, source_addr;
1.1.1.2 ! misho     228:       int flags = 0;
1.1       misho     229:       char interface[IF_NAMESIZE];
                    230:       char *str_addr, *str_domain = NULL;
                    231: 
                    232:       if (strings)
                    233:        {
                    234:          dbus_message_iter_get_basic(&array_iter, &str);
                    235:          if (!str || !strlen (str))
                    236:            {
                    237:              error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                    238:                                             "Empty string");
                    239:              break;
                    240:            }
                    241:          
                    242:          /* dup the string because it gets modified during parsing */
                    243:          if (dup)
                    244:            free(dup);
                    245:          if (!(dup = str_domain = whine_malloc(strlen(str)+1)))
                    246:            break;
                    247:          
                    248:          strcpy(str_domain, str);
                    249: 
                    250:          /* point to address part of old string for error message */
                    251:          if ((str_addr = strrchr(str, '/')))
                    252:            str = str_addr+1;
                    253:          
                    254:          if ((str_addr = strrchr(str_domain, '/')))
                    255:            {
                    256:              if (*str_domain != '/' || str_addr == str_domain)
                    257:                {
                    258:                  error = dbus_message_new_error_printf(message,
                    259:                                                        DBUS_ERROR_INVALID_ARGS,
                    260:                                                        "No domain terminator '%s'",
                    261:                                                        str);
                    262:                  break;
                    263:                }
                    264:              *str_addr++ = 0;
                    265:              str_domain++;
                    266:            }
                    267:          else
                    268:            {
                    269:              str_addr = str_domain;
                    270:              str_domain = NULL;
                    271:            }
                    272: 
                    273:          
                    274:        }
                    275:       else
                    276:        {
                    277:          /* check the types of the struct and its elements */
                    278:          if ((dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY) ||
                    279:              (dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_STRING))
                    280:            {
                    281:              error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                    282:                                             "Expected inner array of strings");
                    283:              break;
                    284:            }
                    285:          
                    286:          /* string_iter points to each "s" element in the inner array */
                    287:          dbus_message_iter_recurse(&array_iter, &string_iter);
                    288:          if (dbus_message_iter_get_arg_type(&string_iter) != DBUS_TYPE_STRING)
                    289:            {
                    290:              /* no IP address given */
                    291:              error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                    292:                                             "Expected IP address");
                    293:              break;
                    294:            }
                    295:          
                    296:          dbus_message_iter_get_basic(&string_iter, &str);
                    297:          if (!str || !strlen (str))
                    298:            {
                    299:              error = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                    300:                                             "Empty IP address");
                    301:              break;
                    302:            }
                    303:          
                    304:          /* dup the string because it gets modified during parsing */
                    305:          if (dup)
                    306:            free(dup);
                    307:          if (!(dup = str_addr = whine_malloc(strlen(str)+1)))
                    308:            break;
                    309:          
                    310:          strcpy(str_addr, str);
                    311:        }
                    312: 
                    313:       memset(&addr, 0, sizeof(addr));
                    314:       memset(&source_addr, 0, sizeof(source_addr));
                    315:       memset(&interface, 0, sizeof(interface));
                    316: 
                    317:       /* parse the IP address */
1.1.1.2 ! misho     318:       if ((addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, &flags)))
        !           319:        {
1.1       misho     320:           error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
                    321:                                                 "Invalid IP address '%s': %s",
                    322:                                                 str, addr_err);
                    323:           break;
                    324:         }
1.1.1.2 ! misho     325:       
        !           326:       /* 0.0.0.0 for server address == NULL, for Dbus */
        !           327:       if (addr.in.sin_family == AF_INET &&
        !           328:           addr.in.sin_addr.s_addr == 0)
        !           329:         flags |= SERV_NO_ADDR;
        !           330:       
1.1       misho     331:       if (strings)
                    332:        {
                    333:          char *p;
                    334:          
                    335:          do {
                    336:            if (str_domain)
                    337:              {
                    338:                if ((p = strchr(str_domain, '/')))
                    339:                  *p++ = 0;
                    340:              }
                    341:            else 
                    342:              p = NULL;
                    343:            
1.1.1.2 ! misho     344:            add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain);
1.1       misho     345:          } while ((str_domain = p));
                    346:        }
                    347:       else
                    348:        {
                    349:          /* jump past the address to the domain list (if any) */
                    350:          dbus_message_iter_next (&string_iter);
                    351:          
                    352:          /* parse domains and add each server/domain pair to the list */
                    353:          do {
                    354:            str = NULL;
                    355:            if (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING)
                    356:              dbus_message_iter_get_basic(&string_iter, &str);
                    357:            dbus_message_iter_next (&string_iter);
                    358:            
1.1.1.2 ! misho     359:            add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str);
1.1       misho     360:          } while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
                    361:        }
                    362:         
                    363:       /* jump to next element in outer array */
                    364:       dbus_message_iter_next(&array_iter);
                    365:     }
                    366: 
1.1.1.2 ! misho     367:   cleanup_servers();
1.1       misho     368: 
                    369:   if (dup)
                    370:     free(dup);
                    371: 
                    372:   return error;
                    373: }
                    374: 
                    375: DBusHandlerResult message_handler(DBusConnection *connection, 
                    376:                                  DBusMessage *message, 
                    377:                                  void *user_data)
                    378: {
                    379:   char *method = (char *)dbus_message_get_member(message);
                    380:   DBusMessage *reply = NULL;
1.1.1.2 ! misho     381:   int clear_cache = 0, new_servers = 0;
1.1       misho     382:     
                    383:   if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
                    384:     {
                    385:       /* string length: "%s" provides space for termination zero */
                    386:       if (!introspection_xml && 
                    387:          (introspection_xml = whine_malloc(strlen(introspection_xml_template) + strlen(daemon->dbus_name))))
                    388:        sprintf(introspection_xml, introspection_xml_template, daemon->dbus_name);
                    389:     
                    390:       if (introspection_xml)
                    391:        {
                    392:          reply = dbus_message_new_method_return(message);
                    393:          dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection_xml, DBUS_TYPE_INVALID);
                    394:        }
                    395:     }
                    396:   else if (strcmp(method, "GetVersion") == 0)
                    397:     {
                    398:       char *v = VERSION;
                    399:       reply = dbus_message_new_method_return(message);
                    400:       
                    401:       dbus_message_append_args(reply, DBUS_TYPE_STRING, &v, DBUS_TYPE_INVALID);
                    402:     }
                    403:   else if (strcmp(method, "SetServers") == 0)
                    404:     {
                    405:       dbus_read_servers(message);
1.1.1.2 ! misho     406:       new_servers = 1;
1.1       misho     407:     }
                    408:   else if (strcmp(method, "SetServersEx") == 0)
                    409:     {
                    410:       reply = dbus_read_servers_ex(message, 0);
1.1.1.2 ! misho     411:       new_servers = 1;
1.1       misho     412:     }
                    413:   else if (strcmp(method, "SetDomainServers") == 0)
                    414:     {
                    415:       reply = dbus_read_servers_ex(message, 1);
1.1.1.2 ! misho     416:       new_servers = 1;
1.1       misho     417:     }
                    418:   else if (strcmp(method, "ClearCache") == 0)
1.1.1.2 ! misho     419:     clear_cache = 1;
1.1       misho     420:   else
                    421:     return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
1.1.1.2 ! misho     422:    
        !           423:   if (new_servers)
        !           424:     {
        !           425:       my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
        !           426:       check_servers();
        !           427:       if (option_bool(OPT_RELOAD))
        !           428:        clear_cache = 1;
        !           429:     }
        !           430: 
        !           431:   if (clear_cache)
        !           432:     clear_cache_and_reload(dnsmasq_time());
1.1       misho     433:   
                    434:   method = user_data; /* no warning */
                    435: 
                    436:   /* If no reply or no error, return nothing */
                    437:   if (!reply)
                    438:     reply = dbus_message_new_method_return(message);
                    439: 
                    440:   if (reply)
                    441:     {
                    442:       dbus_connection_send (connection, reply, NULL);
                    443:       dbus_message_unref (reply);
                    444:     }
                    445: 
                    446:   return (DBUS_HANDLER_RESULT_HANDLED);
                    447: }
                    448:  
                    449: 
                    450: /* returns NULL or error message, may fail silently if dbus daemon not yet up. */
                    451: char *dbus_init(void)
                    452: {
                    453:   DBusConnection *connection = NULL;
                    454:   DBusObjectPathVTable dnsmasq_vtable = {NULL, &message_handler, NULL, NULL, NULL, NULL };
                    455:   DBusError dbus_error;
                    456:   DBusMessage *message;
                    457: 
                    458:   dbus_error_init (&dbus_error);
                    459:   if (!(connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error)))
                    460:     return NULL;
                    461:     
                    462:   dbus_connection_set_exit_on_disconnect(connection, FALSE);
                    463:   dbus_connection_set_watch_functions(connection, add_watch, remove_watch, 
                    464:                                      NULL, NULL, NULL);
                    465:   dbus_error_init (&dbus_error);
                    466:   dbus_bus_request_name (connection, daemon->dbus_name, 0, &dbus_error);
                    467:   if (dbus_error_is_set (&dbus_error))
                    468:     return (char *)dbus_error.message;
                    469:   
                    470:   if (!dbus_connection_register_object_path(connection,  DNSMASQ_PATH, 
                    471:                                            &dnsmasq_vtable, NULL))
                    472:     return _("could not register a DBus message handler");
                    473:   
                    474:   daemon->dbus = connection; 
                    475:   
                    476:   if ((message = dbus_message_new_signal(DNSMASQ_PATH, daemon->dbus_name, "Up")))
                    477:     {
                    478:       dbus_connection_send(connection, message, NULL);
                    479:       dbus_message_unref(message);
                    480:     }
                    481: 
                    482:   return NULL;
                    483: }
                    484:  
                    485: 
                    486: void set_dbus_listeners(int *maxfdp,
                    487:                        fd_set *rset, fd_set *wset, fd_set *eset)
                    488: {
                    489:   struct watch *w;
                    490:   
                    491:   for (w = daemon->watches; w; w = w->next)
                    492:     if (dbus_watch_get_enabled(w->watch))
                    493:       {
                    494:        unsigned int flags = dbus_watch_get_flags(w->watch);
                    495:        int fd = dbus_watch_get_unix_fd(w->watch);
                    496:        
                    497:        bump_maxfd(fd, maxfdp);
                    498:        
                    499:        if (flags & DBUS_WATCH_READABLE)
                    500:          FD_SET(fd, rset);
                    501:        
                    502:        if (flags & DBUS_WATCH_WRITABLE)
                    503:          FD_SET(fd, wset);
                    504:        
                    505:        FD_SET(fd, eset);
                    506:       }
                    507: }
                    508: 
                    509: void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset)
                    510: {
                    511:   DBusConnection *connection = (DBusConnection *)daemon->dbus;
                    512:   struct watch *w;
                    513: 
                    514:   for (w = daemon->watches; w; w = w->next)
                    515:     if (dbus_watch_get_enabled(w->watch))
                    516:       {
                    517:        unsigned int flags = 0;
                    518:        int fd = dbus_watch_get_unix_fd(w->watch);
                    519:        
                    520:        if (FD_ISSET(fd, rset))
                    521:          flags |= DBUS_WATCH_READABLE;
                    522:        
                    523:        if (FD_ISSET(fd, wset))
                    524:          flags |= DBUS_WATCH_WRITABLE;
                    525:        
                    526:        if (FD_ISSET(fd, eset))
                    527:          flags |= DBUS_WATCH_ERROR;
                    528: 
                    529:        if (flags != 0)
                    530:          dbus_watch_handle(w->watch, flags);
                    531:       }
                    532: 
                    533:   if (connection)
                    534:     {
                    535:       dbus_connection_ref (connection);
                    536:       while (dbus_connection_dispatch (connection) == DBUS_DISPATCH_DATA_REMAINS);
                    537:       dbus_connection_unref (connection);
                    538:     }
                    539: }
                    540: 
                    541: #ifdef HAVE_DHCP
                    542: void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname)
                    543: {
                    544:   DBusConnection *connection = (DBusConnection *)daemon->dbus;
                    545:   DBusMessage* message = NULL;
                    546:   DBusMessageIter args;
                    547:   char *action_str, *mac = daemon->namebuff;
                    548:   unsigned char *p;
                    549:   int i;
                    550: 
                    551:   if (!connection)
                    552:     return;
                    553:   
                    554:   if (!hostname)
                    555:     hostname = "";
                    556:   
                    557: #ifdef HAVE_DHCP6
                    558:    if (lease->flags & (LEASE_TA | LEASE_NA))
                    559:      {
                    560:        print_mac(mac, lease->clid, lease->clid_len);
                    561:        inet_ntop(AF_INET6, lease->hwaddr, daemon->addrbuff, ADDRSTRLEN);
                    562:      }
                    563:    else
                    564: #endif
                    565:      {
                    566:        p = extended_hwaddr(lease->hwaddr_type, lease->hwaddr_len,
                    567:                           lease->hwaddr, lease->clid_len, lease->clid, &i);
                    568:        print_mac(mac, p, i);
                    569:        inet_ntop(AF_INET, &lease->addr, daemon->addrbuff, ADDRSTRLEN);
                    570:      }
                    571: 
                    572:   if (action == ACTION_DEL)
                    573:     action_str = "DhcpLeaseDeleted";
                    574:   else if (action == ACTION_ADD)
                    575:     action_str = "DhcpLeaseAdded";
                    576:   else if (action == ACTION_OLD)
                    577:     action_str = "DhcpLeaseUpdated";
                    578:   else
                    579:     return;
                    580: 
                    581:   if (!(message = dbus_message_new_signal(DNSMASQ_PATH, daemon->dbus_name, action_str)))
                    582:     return;
                    583:   
                    584:   dbus_message_iter_init_append(message, &args);
                    585:   
                    586:   if (dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &daemon->addrbuff) &&
                    587:       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &mac) &&
                    588:       dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &hostname))
                    589:     dbus_connection_send(connection, message, NULL);
                    590:   
                    591:   dbus_message_unref(message);
                    592: }
                    593: #endif
                    594: 
                    595: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>