Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
        int r = 0;
        char err[128];
        struct mdns_ctx *ctx;

        signal(SIGINT, sighandler);
        signal(SIGTERM, sighandler);

        if ((r = mdns_init(&ctx, MDNS_ADDR_IPV4, MDNS_PORT)) < 0)
                goto err;

        // test with `ping mdnshost.local`
        mdns_announce(ctx, "mdnshost.local", RR_A, callback, ctx);

        if ((r = mdns_serve(ctx, stop, NULL)) < 0)
                goto err;
err:
        if (r < 0) {
                mdns_strerror(r, err, sizeof(err));
                fprintf(stderr, "fatal: %s\n", err);
        }
        mdns_destroy(ctx);
        return (0);
}
Ejemplo n.º 2
0
int
mdns_init(struct mdns_ctx **p_ctx, const char *addr, unsigned short port)
{
        const uint32_t on_off = 1;
        const uint32_t ttl = 255;
        const uint8_t loop = 1;
#ifdef _WIN32
        union {
                struct sockaddr_storage ss;
                struct sockaddr_in      sin;
                struct sockaddr_in6     sin6;
        } dumb;
#endif /* _WIN32 */
        struct mdns_ctx *ctx;

        if (p_ctx == NULL)
            return (MDNS_STDERR);
        *p_ctx = NULL;

        ctx = malloc(sizeof(struct mdns_ctx));
        if (ctx == NULL)
            return (MDNS_STDERR);

        ctx->services = NULL;
        ctx->sock = INVALID_SOCKET;
        errno = os_init("2.2");
        if (errno != 0)
                return mdns_destroy(ctx), (MDNS_NETERR);
        if (mdns_resolve(&ctx->addr, addr, port) < 0)
                return mdns_destroy(ctx), (MDNS_LKPERR);

        if ((ctx->sock = socket(ss_family(&ctx->addr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
                return mdns_destroy(ctx), (MDNS_NETERR);
        if (setsockopt(ctx->sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &on_off, sizeof(on_off)) < 0)
                return mdns_destroy(ctx), (MDNS_NETERR);
#ifdef _WIN32
        /* bind the receiver on any local address */
        memset(&dumb, 0, sizeof(dumb));
        dumb.ss.ss_family = ss_family(&ctx->addr);
        if (dumb.ss.ss_family == AF_INET) {
            dumb.sin.sin_port = htons(port);
            dumb.sin.sin_addr.s_addr = INADDR_ANY;
        } else {
            dumb.sin6.sin6_port = htons(port);
            dumb.sin6.sin6_addr = in6addr_any;
        }

        if (bind(ctx->sock, (const struct sockaddr *) &dumb, ss_len(&dumb.ss)) < 0)
                return mdns_destroy(ctx), (MDNS_NETERR);
#else /* _WIN32 */
        if (bind(ctx->sock, (const struct sockaddr *) &ctx->addr, ss_len(&ctx->addr)) < 0)
                return mdns_destroy(ctx), (MDNS_NETERR);
#endif /* _WIN32 */

        if (os_mcast_join(ctx->sock, &ctx->addr) < 0)
                return mdns_destroy(ctx), (MDNS_NETERR);
        if (setsockopt(ctx->sock, ss_level(&ctx->addr), ss_family(&ctx->addr)==AF_INET ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS, (const void *) &ttl, sizeof(ttl)) < 0)
                return mdns_destroy(ctx), (MDNS_NETERR);
        if (setsockopt(ctx->sock, ss_level(&ctx->addr), IP_MULTICAST_LOOP, (const void *) &loop, sizeof(loop)) < 0)
                return mdns_destroy(ctx), (MDNS_NETERR);

        *p_ctx = ctx;
        return (0);
}