int main(int argc, char *argv[]) { // create host entries char *hostname = "some-random-host.local"; struct mdnsd *svr = mdnsd_start(); if (svr == NULL) { printf("mdnsd_start() error\n"); return 1; } printf("mdnsd_start OK. press ENTER to add hostname & service\n"); getchar(); mdnsd_set_hostname(svr, hostname, inet_addr("192.168.0.29")); struct rr_entry *a2_e = NULL; a2_e = rr_create_a(create_nlabel(hostname), inet_addr("192.168.0.31")); mdnsd_add_rr(svr, a2_e); struct rr_entry *aaaa_e = NULL; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_flags = AI_NUMERICHOST; struct addrinfo* results; getaddrinfo( "fe80::e2f8:47ff:fe20:28e0", NULL, &hints, &results); struct sockaddr_in6* addr = (struct sockaddr_in6*)results->ai_addr; struct in6_addr v6addr = addr->sin6_addr; freeaddrinfo(results); aaaa_e = rr_create_aaaa(create_nlabel(hostname), &v6addr); mdnsd_add_rr(svr, aaaa_e); const char *txt[] = { "path=/mywebsite", NULL }; struct mdns_service *svc = mdnsd_register_svc(svr, "My Website", "_http._tcp.local", 8080, NULL, txt); mdns_service_destroy(svc); printf("added service and hostname. press ENTER to exit\n"); getchar(); mdnsd_stop(svr); return 0; }
static int mdns_tinysvcmdns_register(char *apname, int port) { struct ifaddrs *ifalist; struct ifaddrs *ifa; svr = mdnsd_start(); if (svr == NULL) { warn("tinysvcmdns: mdnsd_start() failed"); return -1; } // Thanks to Paul Lietar for this // room for name + .local + NULL char hostname[100 + 6]; gethostname(hostname, 99); // according to POSIX, this may be truncated without a final NULL ! hostname[99] = 0; // will not work if the hostname doesn't end in .local char *hostend = hostname + strlen(hostname); if ((strlen(hostname) < strlen(".local")) || (strcmp(hostend - 6, ".local") != 0)) { strcat(hostname, ".local"); } if (getifaddrs(&ifalist) < 0) { warn("tinysvcmdns: getifaddrs() failed"); return -1; } ifa = ifalist; // Look for an ipv4/ipv6 non-loopback interface to use as the main one. for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next) { if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { uint32_t main_ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; mdnsd_set_hostname(svr, hostname, main_ip); // TTL should be 120 seconds break; } else if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) { struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; mdnsd_set_hostname_v6(svr, hostname, addr); // TTL should be 120 seconds break; } } if (ifa == NULL) { warn("tinysvcmdns: no non-loopback ipv4 or ipv6 interface found"); return -1; } // Skip the first one, it was already added by set_hostname for (ifa = ifa->ifa_next; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_flags & IFF_LOOPBACK) // Skip loop-back interfaces continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: { // ipv4 uint32_t ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; struct rr_entry *a_e = rr_create_a(create_nlabel(hostname), ip); // TTL should be 120 seconds mdnsd_add_rr(svr, a_e); } break; case AF_INET6: { // ipv6 struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; struct rr_entry *aaaa_e = rr_create_aaaa(create_nlabel(hostname), addr); // TTL should be 120 seconds mdnsd_add_rr(svr, aaaa_e); } break; } } freeifaddrs(ifa); char *txtwithoutmetadata[] = {MDNS_RECORD_WITHOUT_METADATA, NULL}; #ifdef CONFIG_METADATA char *txtwithmetadata[] = {MDNS_RECORD_WITH_METADATA, NULL}; #endif char **txt; #ifdef CONFIG_METADATA if (config.metadata_enabled) txt = txtwithmetadata; else #endif txt = txtwithoutmetadata; struct mdns_service *svc = mdnsd_register_svc(svr, apname, "_raop._tcp.local", port, NULL, (const char **)txt); // TTL should be 75 minutes, i.e. 4500 seconds mdns_service_destroy(svc); return 0; }
static int mdns_tinysvcmdns_register(char *apname, int port) { struct ifaddrs *ifalist; struct ifaddrs *ifa; svr = mdnsd_start(); if (svr == NULL) { warn("tinysvcmdns: mdnsd_start() failed"); return -1; } // room for name + .local + NULL char hostname[100 + 6]; gethostname(hostname, 99); // according to POSIX, this may be truncated without a final NULL ! hostname[99] = 0; // will not work on iOS if the hostname doesn't end in .local strcat(hostname, ".local"); if (getifaddrs(&ifalist) < 0) { warn("tinysvcmdns: getifaddrs() failed"); return -1; } ifa = ifalist; // Look for an ipv4/ipv6 non-loopback interface to use as the main one. for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next) { if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { uint32_t main_ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; mdnsd_set_hostname(svr, hostname, main_ip); break; } else if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) { struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; mdnsd_set_hostname_v6(svr, hostname, addr); break; } } if (ifa == NULL) { warn("tinysvcmdns: no non-loopback ipv4 or ipv6 interface found"); return -1; } // Skip the first one, it was already added by set_hostname for (ifa = ifa->ifa_next; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_flags & IFF_LOOPBACK) // Skip loop-back interfaces continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: { // ipv4 uint32_t ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; struct rr_entry *a_e = rr_create_a(create_nlabel(hostname), ip); mdnsd_add_rr(svr, a_e); } break; case AF_INET6: { // ipv6 struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; struct rr_entry *aaaa_e = rr_create_aaaa(create_nlabel(hostname), addr); mdnsd_add_rr(svr, aaaa_e); } break; } } freeifaddrs(ifa); const char *txt[] = { MDNS_RECORD, NULL }; struct mdns_service *svc = mdnsd_register_svc(svr, apname, "_raop._tcp.local", port, NULL, txt); mdns_service_destroy(svc); return 0; }