-static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
- AvahiInterfaceMonitor *m = userdata;
-
- g_assert(m);
- g_assert(n);
- g_assert(m->netlink == nl);
-
- if (n->nlmsg_type == RTM_NEWLINK) {
- struct ifinfomsg *ifinfomsg = NLMSG_DATA(n);
- AvahiHwInterface *hw;
- struct rtattr *a = NULL;
- size_t l;
-
- if (ifinfomsg->ifi_family != AF_UNSPEC)
- return;
-
- if (!(hw = g_hash_table_lookup(m->hash_table, &ifinfomsg->ifi_index))) {
- hw = g_new(AvahiHwInterface, 1);
- hw->monitor = m;
- hw->name = NULL;
- hw->flags = 0;
- hw->mtu = 1500;
- hw->index = ifinfomsg->ifi_index;
- hw->mac_address_size = 0;
- hw->entry_group = NULL;
-
- AVAHI_LLIST_HEAD_INIT(AvahiInterface, hw->interfaces);
- AVAHI_LLIST_PREPEND(AvahiHwInterface, hardware, m->hw_interfaces, hw);
-
- g_hash_table_insert(m->hash_table, &hw->index, hw);
-
- if (m->server->fd_ipv4 >= 0)
- new_interface(m, hw, AVAHI_PROTO_INET);
- if (m->server->fd_ipv6 >= 0)
- new_interface(m, hw, AVAHI_PROTO_INET6);
- }
-
- hw->flags = ifinfomsg->ifi_flags;
-
- l = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg));
- a = IFLA_RTA(ifinfomsg);
-
- while (RTA_OK(a, l)) {
- switch(a->rta_type) {
- case IFLA_IFNAME:
- g_free(hw->name);
- hw->name = g_strndup(RTA_DATA(a), RTA_PAYLOAD(a));
- break;
-
- case IFLA_MTU:
- g_assert(RTA_PAYLOAD(a) == sizeof(unsigned int));
- hw->mtu = *((unsigned int*) RTA_DATA(a));
- break;
-
- case IFLA_ADDRESS: {
- hw->mac_address_size = RTA_PAYLOAD(a);
- if (hw->mac_address_size > AVAHI_MAX_MAC_ADDRESS)
- hw->mac_address_size = AVAHI_MAX_MAC_ADDRESS;
-
- memcpy(hw->mac_address, RTA_DATA(a), hw->mac_address_size);
- break;
- }
-
- default:
- ;
- }
-
- a = RTA_NEXT(a, l);
- }
-
- update_hw_interface_rr(m, hw, FALSE);
- check_hw_interface_relevant(m, hw);
-
- } else if (n->nlmsg_type == RTM_DELLINK) {
- struct ifinfomsg *ifinfomsg = NLMSG_DATA(n);
- AvahiHwInterface *hw;
-
- if (ifinfomsg->ifi_family != AF_UNSPEC)
- return;
-
- if (!(hw = avahi_interface_monitor_get_hw_interface(m, ifinfomsg->ifi_index)))
- return;
-
- update_hw_interface_rr(m, hw, TRUE);
- free_hw_interface(m, hw, FALSE);
-
- } else if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
-
- struct ifaddrmsg *ifaddrmsg = NLMSG_DATA(n);
- AvahiInterface *i;
- struct rtattr *a = NULL;
- size_t l;
- AvahiAddress raddr;
- gboolean raddr_valid = FALSE;
-
- if (ifaddrmsg->ifa_family != AVAHI_PROTO_INET && ifaddrmsg->ifa_family != AVAHI_PROTO_INET6)
- return;
-
- if (!(i = (AvahiInterface*) avahi_interface_monitor_get_interface(m, ifaddrmsg->ifa_index, ifaddrmsg->ifa_family)))
- return;
-
- raddr.family = ifaddrmsg->ifa_family;
-
- l = NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg));
- a = IFA_RTA(ifaddrmsg);
-
- while (RTA_OK(a, l)) {
-
- switch(a->rta_type) {
- case IFA_ADDRESS:
- if ((raddr.family == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) ||
- (raddr.family == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4))
- return;
-
- memcpy(raddr.data.data, RTA_DATA(a), RTA_PAYLOAD(a));
- raddr_valid = TRUE;
-
- break;
-
- default:
- ;
- }
-
- a = RTA_NEXT(a, l);
- }
-
- if (!raddr_valid)
- return;
-
- if (n->nlmsg_type == RTM_NEWADDR) {
- AvahiInterfaceAddress *addr;
-
- if (!(addr = get_address(m, i, &raddr))) {
- addr = g_new(AvahiInterfaceAddress, 1);
- addr->monitor = m;
- addr->address = raddr;
- addr->interface = i;
- addr->entry_group = NULL;
-
- AVAHI_LLIST_PREPEND(AvahiInterfaceAddress, address, i->addresses, addr);
- }
-
- addr->flags = ifaddrmsg->ifa_flags;
- addr->scope = ifaddrmsg->ifa_scope;
- addr->prefix_len = ifaddrmsg->ifa_prefixlen;
-
- update_address_rr(m, addr, FALSE);
- } else {
- AvahiInterfaceAddress *addr;
-
- if (!(addr = get_address(m, i, &raddr)))
- return;