// RegisterService() is a simple wrapper function which takes C string
// parameters, converts them to domainname parameters, and calls mDNS_RegisterService()
mDNSlocal void RegisterService(mDNS *m, ServiceRecordSet *recordset,
                               const char name[], const char type[], const char domain[],
                               const domainname *host, mDNSu16 PortAsNumber, int argc, char **argv)
{
    domainlabel n;
    domainname t, d;
    unsigned char txtbuffer[1024], *bptr = txtbuffer;
    char buffer[MAX_ESCAPED_DOMAIN_NAME];

    MakeDomainLabelFromLiteralString(&n, name);
    MakeDomainNameFromDNSNameString(&t, type);
    MakeDomainNameFromDNSNameString(&d, domain);
    while (argc)
    {
        int len = strlen(argv[0]);
        if (len > 255 || bptr + 1 + len >= txtbuffer + sizeof(txtbuffer)) break;
        printf("STR: %s\n", argv[0]);
        bptr[0] = len;
        strcpy((char*)(bptr+1), argv[0]);
        bptr += 1 + len;
        argc--;
        argv++;
    }

    mDNS_RegisterService(m, recordset,
                         &n, &t, &d, // Name, type, domain
                         host, mDNSOpaque16fromIntVal(PortAsNumber),
                         txtbuffer, bptr-txtbuffer, // TXT data, length
                         mDNSNULL, 0, // Subtypes
                         mDNSInterface_Any, // Interface ID
                         ServiceCallback, mDNSNULL, 0); // Callback, context, flags

    ConvertDomainNameToCString(recordset->RR_SRV.resrec.name, buffer);
    printf("Made Service Records for %s\n", buffer);
}
// RegisterService() is a simple wrapper function which takes C string
// parameters, converts them to domainname parameters, and calls mDNS_RegisterService()
mDNSlocal void RegisterService(mDNS *m, ServiceRecordSet *recordset,
	UInt16 PortAsNumber, const char txtinfo[],
	const domainlabel *const n, const char type[], const char domain[])
	{
	domainname t;
	domainname d;
	char buffer[MAX_ESCAPED_DOMAIN_NAME];
	UInt8 txtbuffer[512];

	MakeDomainNameFromDNSNameString(&t, type);
	MakeDomainNameFromDNSNameString(&d, domain);
	
	if (txtinfo)
		{
		strncpy((char*)txtbuffer+1, txtinfo, sizeof(txtbuffer)-1);
		txtbuffer[0] = (UInt8)strlen(txtinfo);
		}
	else
		txtbuffer[0] = 0;

	mDNS_RegisterService(m, recordset,
		n, &t, &d,									// Name, type, domain
		mDNSNULL, mDNSOpaque16fromIntVal(PortAsNumber),
		txtbuffer, (mDNSu16)(1+txtbuffer[0]),		// TXT data, length
		mDNSNULL, 0,								// Subtypes (none)
		mDNSInterface_Any,							// Interface ID
		Callback, mDNSNULL);						// Callback and context

	ConvertDomainNameToCString(recordset->RR_SRV.resrec.name, buffer);
	printf("Made Service Records for %s\n", buffer);
	}
예제 #3
0
static mStatus RegisterOneService(const char *  richTextHostName, 
                                  const char *  serviceType, 
				  const char *  serviceDomain,
                                  const mDNSu8  text[],
                                  mDNSu16       textLen,
                                  long          portNumber)
{
    mStatus             status;
    PosixService *      thisServ;
    mDNSOpaque16        port;
    domainlabel         name;
    domainname          type;
    domainname          domain;
    
    status = mStatus_NoError;
    thisServ = (PosixService *) malloc(sizeof(*thisServ));
    if (thisServ == NULL) {
        status = mStatus_NoMemoryErr;
    }
    if (status == mStatus_NoError) {
        MakeDomainLabelFromLiteralString(&name,  richTextHostName);
        MakeDomainNameFromDNSNameString(&type, serviceType);
        MakeDomainNameFromDNSNameString(&domain, serviceDomain);

        port.b[0] = (portNumber >> 8) & 0x0FF;
        port.b[1] = (portNumber >> 0) & 0x0FF;;
        status = mDNS_RegisterService(&mDNSStorage, &thisServ->coreServ,
				      &name, &type, &domain,
				      NULL,
				      port, 
				      text, textLen,
				      NULL, 0,
				      mDNSInterface_Any,
				      RegistrationCallback, thisServ);
    }
예제 #4
0
static mStatus RegisterOneService(const char *  richTextName, 
                                  const char *  serviceType, 
                                  const char *  serviceDomain, 
                                  const mDNSu8  text[],
                                  mDNSu16       textLen,
                                  long          portNumber)
{
    mStatus             status;
    PosixService *      thisServ;
    domainlabel         name;
    domainname          type;
    domainname          domain;
    
    status = mStatus_NoError;
    thisServ = (PosixService *) malloc(sizeof(*thisServ));
    if (thisServ == NULL) {
        status = mStatus_NoMemoryErr;
    }
    if (status == mStatus_NoError) {
        MakeDomainLabelFromLiteralString(&name,  richTextName);
        MakeDomainNameFromDNSNameString(&type, serviceType);
        MakeDomainNameFromDNSNameString(&domain, serviceDomain);
        status = mDNS_RegisterService(&mDNSStorage, &thisServ->coreServ,
                &name, &type, &domain,				// Name, type, domain
                NULL, mDNSOpaque16fromIntVal(portNumber),
                text, textLen,						// TXT data, length
                NULL, 0,							// Subtypes
                mDNSInterface_Any,					// Interface ID
                RegistrationCallback, thisServ);	// Callback and context
    }
    if (status == mStatus_NoError) {
        thisServ->serviceID = gServiceID;
        gServiceID += 1;

        thisServ->next = gServiceList;
        gServiceList = thisServ;

        if (gMDNSPlatformPosixVerboseLevel > 0) {
            fprintf(stderr, 
                    "%s: Registered service %d, name '%s', type '%s', port %ld\n", 
                    gProgramName, 
                    thisServ->serviceID, 
                    richTextName,
                    serviceType,
                    portNumber);
        }
    } else {
        if (thisServ != NULL) {
            free(thisServ);
        }
    }
    return status;
}
mDNSlocal void RegisterNoSuchService(mDNS *m, AuthRecord *const rr, domainname *proxyhostname,
                                     const char name[], const char type[], const char domain[])
{
    domainlabel n;
    domainname t, d;
    char buffer[MAX_ESCAPED_DOMAIN_NAME];
    MakeDomainLabelFromLiteralString(&n, name);
    MakeDomainNameFromDNSNameString(&t, type);
    MakeDomainNameFromDNSNameString(&d, domain);
    mDNS_RegisterNoSuchService(m, rr, &n, &t, &d, proxyhostname, mDNSInterface_Any, NoSuchServiceCallback, proxyhostname, 0);
    ConvertDomainNameToCString(rr->resrec.name, buffer);
    printf("Made Non-existence Record for %s\n", buffer);
}
mDNSexport void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled)
	{
	char buf[MAX_ESCAPED_DOMAIN_NAME] = "";
	char knn[MAX_ESCAPED_DOMAIN_NAME] = "";
   domainname keyName;
   mDNSIPPort port;
   keyName.c[0] = knn[0] = 0;
	mStatus err;
	FILE *f = fopen(filename, "r");

    if (hostname)                 hostname->c[0] = 0;
    if (domain)                   domain->c[0] = 0;
	if (DomainDiscoveryDisabled) *DomainDiscoveryDisabled = mDNSfalse;
	
   port = UnicastDNSPort;

	if (f)
		{
		if (DomainDiscoveryDisabled && GetConfigOption(buf, "DomainDiscoveryDisabled", f) && !strcasecmp(buf, "true")) *DomainDiscoveryDisabled = mDNStrue;
		if (hostname && GetConfigOption(buf, "hostname", f) && !MakeDomainNameFromDNSNameString(hostname, buf)) goto badf;
		if (domain && GetConfigOption(buf, "zone", f) && !MakeDomainNameFromDNSNameString(domain, buf)) goto badf;
		if (GetConfigOption(buf, "port", f)) {
         port = mDNSOpaque16fromIntVal(strtol(buf, (char **)NULL, 10));
		}
		buf[0] = 0;
		GetConfigOption(buf, "secret-64", f);  // failure means no authentication
		if (GetConfigOption(knn, "secret-name", f))
         MakeDomainNameFromDNSNameString(&keyName, knn);
		fclose(f);
		f = NULL;
		}
	else
		{
		if (errno != ENOENT) LogMsg("ERROR: Config file exists, but cannot be opened.");
		return;
		}

	if (domain && domain->c[0] && buf[0])
		{
		DomainAuthInfo *info = (DomainAuthInfo*)mDNSPlatformMemAllocate(sizeof(*info));
		// for now we assume keyname = service reg domain and we use same key for service and hostname registration
		err = mDNS_SetSecretForDomain(m, info, domain, (keyName.c[0] ? &keyName : domain), buf, hostname, &port, NULL);
		if (err) LogMsg("ERROR: mDNS_SetSecretForDomain returned %d for domain %##s", err, domain->c);
		}

	return;

	badf:
	LogMsg("ERROR: malformatted config file");
	if (f) fclose(f);
	}
예제 #7
0
int main(int argc, char **argv)
// The program's main entry point.  The program does a trivial
// mDNS query, looking for all AFP servers in the local domain.
{
    int     result;
    mStatus     status;
    DNSQuestion question;
    domainname  type;
    domainname  domain;

    // Parse our command line arguments.  This won't come back if there's an error.
    ParseArguments(argc, argv);

    // Initialise the mDNS core.
    status = mDNS_Init(&mDNSStorage, &PlatformStorage,
                       gRRCache, RR_CACHE_SIZE,
                       mDNS_Init_DontAdvertiseLocalAddresses,
                       mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
    if (status == mStatus_NoError) {

        // Construct and start the query.

        MakeDomainNameFromDNSNameString(&type, gServiceType);
        MakeDomainNameFromDNSNameString(&domain, gServiceDomain);

        status = mDNS_StartBrowse(&mDNSStorage, &question, &type, &domain, mDNSInterface_Any, mDNSfalse, BrowseCallback, NULL);

        // Run the platform main event loop until the user types ^C.
        // The BrowseCallback routine is responsible for printing
        // any results that we find.

        if (status == mStatus_NoError) {
            fprintf(stderr, "Hit ^C when you're bored waiting for responses.\n");
            ExampleClientEventLoop(&mDNSStorage);
            mDNS_StopQuery(&mDNSStorage, &question);
            mDNS_Close(&mDNSStorage);
        }
    }

    if (status == mStatus_NoError) {
        result = 0;
    } else {
        result = 2;
    }
    if ( (result != 0) || (gMDNSPlatformPosixVerboseLevel > 0) ) {
        fprintf(stderr, "%s: Finished with status %d, result %d\n", gProgramName, (int)status, result);
    }

    return 0;
}
예제 #8
0
static void
foobar_register(DNSQuestion *question)
{
	mStatus status;
	domainname type;
	domainname domain;

	MakeDomainNameFromDNSNameString(&type, "_foobar._tcp");
	MakeDomainNameFromDNSNameString(&domain, "local.");

	status = mDNS_StartBrowse(&mDNSStorage, question, &type, &domain,
	    mDNSNULL, mDNSInterface_Any, 0, mDNSfalse, mDNSfalse,
	    foobar_browse, NULL);
	assert(status == mStatus_NoError);
}
mDNSlocal mStatus mDNS_RegisterProxyHost(mDNS *m, ProxyHost *p)
{
    char buffer[32];

    mDNS_SetupResourceRecord(&p->RR_A,   mDNSNULL, mDNSInterface_Any, kDNSType_A,   60, kDNSRecordTypeUnique,      AuthRecordAny, HostNameCallback, p);
    mDNS_SetupResourceRecord(&p->RR_PTR, mDNSNULL, mDNSInterface_Any, kDNSType_PTR, 60, kDNSRecordTypeKnownUnique, AuthRecordAny, HostNameCallback, p);

    p->RR_A.namestorage.c[0] = 0;
    AppendDomainLabel(&p->RR_A.namestorage, &p->hostlabel);
    AppendLiteralLabelString(&p->RR_A.namestorage, "local");

    // Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code
    mDNS_snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.in-addr.arpa.", p->ip.b[3], p->ip.b[2], p->ip.b[1], p->ip.b[0]);
    MakeDomainNameFromDNSNameString(&p->RR_PTR.namestorage, buffer);
    p->RR_PTR.ForceMCast = mDNStrue; // This PTR points to our dot-local name, so don't ever try to write it into a uDNS server

    p->RR_A.resrec.rdata->u.ipv4 = p->ip;
    AssignDomainName(&p->RR_PTR.resrec.rdata->u.name, p->RR_A.resrec.name);

    mDNS_Register(m, &p->RR_A);
    mDNS_Register(m, &p->RR_PTR);

    debugf("Made Proxy Host Records for %##s", p->RR_A.resrec.name->c);

    return(mStatus_NoError);
}
예제 #10
0
mDNSlocal mStatus StartQuery(DNSQuestion *q, char *qname, mDNSu16 qtype, const mDNSAddr *target, mDNSQuestionCallback callback)
{
    lastsrc = zeroAddr;
    if (qname) MakeDomainNameFromDNSNameString(&q->qname, qname);
    q->InterfaceID      = mDNSInterface_Any;
    q->flags            = 0;
    q->Target           = target ? *target : zeroAddr;
    q->TargetPort       = MulticastDNSPort;
    q->TargetQID        = zeroID;
    q->qtype            = qtype;
    q->qclass           = kDNSClass_IN;
    q->LongLived        = mDNSfalse;
    q->ExpectUnique     = mDNSfalse;    // Don't want to stop after the first response packet
    q->ForceMCast       = mDNStrue;     // Query via multicast, even for apparently uDNS names like 1.1.1.17.in-addr.arpa.
    q->ReturnIntermed   = mDNStrue;
    q->SuppressUnusable = mDNSfalse;
    q->SearchListIndex  = 0;
    q->AppendSearchDomains = 0;
    q->RetryWithSearchDomains = mDNSfalse;
    q->TimeoutQuestion  = 0;
    q->ValidationRequired = 0;
    q->ValidatingResponse = 0;
    q->WakeOnResolve    = 0;
    q->UseBackgroundTrafficClass = mDNSfalse;
    q->ProxyQuestion    = 0;
    q->qnameOrig        = mDNSNULL;
    q->AnonInfo         = mDNSNULL;
    q->pid              = mDNSPlatformGetPID();
    q->QuestionCallback = callback;
    q->QuestionContext  = NULL;

    //mprintf("%##s %s ?\n", q->qname.c, DNSTypeName(qtype));
    return(mDNS_StartQuery(&mDNSStorage, q));
}
예제 #11
0
DNSServiceErrorType DNSServiceBrowse
	(
	DNSServiceRef                       *sdRef,
	DNSServiceFlags                     flags,
	uint32_t                            interfaceIndex,
	const char                          *regtype,
	const char                          *domain,    /* may be NULL */
	DNSServiceBrowseReply               callback,
	void                                *context    /* may be NULL */
	)
	{
	mStatus err = mStatus_NoError;
	const char *errormsg = "Unknown";
	domainname t, d;
	mDNS_DirectOP_Browse *x;
	(void)flags;			// Unused
	(void)interfaceIndex;	// Unused

	// Check parameters
	if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype))      { errormsg = "Illegal regtype"; goto badparam; }
	if (!MakeDomainNameFromDNSNameString(&d, *domain ? domain : "local.")) { errormsg = "Illegal domain";  goto badparam; }

	// Allocate memory, and handle failure
	x = (mDNS_DirectOP_Browse *)mDNSPlatformMemAllocate(sizeof(*x));
	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }

	// Set up object
	x->disposefn = DNSServiceBrowseDispose;
	x->callback  = callback;
	x->context   = context;
	x->q.QuestionContext = x;

	// Do the operation
	err = mDNS_StartBrowse(&mDNSStorage, &x->q, &t, &d, mDNSInterface_Any, (flags & kDNSServiceFlagsForceMulticast) != 0, FoundInstance, x);
	if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_StartBrowse"; goto fail; }

	// Succeeded: Wrap up and return
	*sdRef = (DNSServiceRef)x;
	return(mStatus_NoError);

badparam:
	err = mStatus_BadParamErr;
fail:
	LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err);
	return(err);
	}
예제 #12
0
DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
	(
	DNSServiceRef                       *sdRef,
	DNSServiceFlags                     flags,
	uint32_t                            interfaceIndex,
	const char                          *fullname,
	uint16_t                            rrtype,
	uint16_t                            rrclass,
	DNSServiceQueryRecordReply          callback,
	void                                *context  /* may be NULL */
	)
	{
	mStatus err = mStatus_NoError;
	const char *errormsg = "Unknown";
	mDNS_DirectOP_QueryRecord *x;

	(void)flags;			// Unused
	(void)interfaceIndex;	// Unused

	// Allocate memory, and handle failure
	x = (mDNS_DirectOP_QueryRecord *)mDNSPlatformMemAllocate(sizeof(*x));
	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }

	// Set up object
	x->disposefn = DNSServiceQueryRecordDispose;
	x->callback  = callback;
	x->context   = context;

	x->q.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
	x->q.InterfaceID         = mDNSInterface_Any;
	x->q.Target              = zeroAddr;
	MakeDomainNameFromDNSNameString(&x->q.qname, fullname);
	x->q.qtype               = rrtype;
	x->q.qclass              = rrclass;
	x->q.LongLived           = (flags & kDNSServiceFlagsLongLivedQuery) != 0;
	x->q.ExpectUnique        = mDNSfalse;
	x->q.ForceMCast          = (flags & kDNSServiceFlagsForceMulticast) != 0;
	x->q.ReturnIntermed      = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
    x->q.SuppressUnusable    = (flags & kDNSServiceFlagsSuppressUnusable) != 0;
	x->q.SearchListIndex     = 0;
	x->q.AppendSearchDomains = 0;
	x->q.RetryWithSearchDomains = mDNSfalse;
	x->q.WakeOnResolve       = 0;
	x->q.qnameOrig           = mDNSNULL;
	x->q.QuestionCallback    = DNSServiceQueryRecordResponse;
	x->q.QuestionContext     = x;

	err = mDNS_StartQuery(&mDNSStorage, &x->q);
	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery"; goto fail; }

	// Succeeded: Wrap up and return
	*sdRef = (DNSServiceRef)x;
	return(mStatus_NoError);

fail:
	LogMsg("DNSServiceQueryRecord(\"%s\", %d, %d) failed: %s (%ld)", fullname, rrtype, rrclass, errormsg, err);
	return(err);
	}
예제 #13
0
mDNSlocal OSStatus mDNSResponderSetAvail(mDNS *m, AuthRecord *rr, ServiceRecordSet *sr)
	{
	// 1. Initialize required fields of AuthRecord
	// 2. Set name of subtype PTR record to our special subtype name denoting "available" instances
	// 3. Set target of subtype PTR record to point to our SRV record (exactly the same as the main service PTR record)
	// 4. And register it
	mDNS_SetupResourceRecord(rr, mDNSNULL, mDNSInterface_Any, kDNSType_PTR, 2*3600, kDNSRecordTypeShared, AvailCallback, &availRec2Active);
	MakeDomainNameFromDNSNameString(rr->resrec.name, "a._sub._raop._tcp.local.");
	AssignDomainName(&rr->resrec.rdata->u.name, sr->RR_SRV.resrec.name);
	return(mDNS_Register(m, rr));
	}
예제 #14
0
static ServiceRecordSet *
foobar_register(mDNSu16 port)
{
	ServiceRecordSet *srs;
	mStatus status;
	domainlabel name;
	domainname type;
	domainname domain;

	srs = calloc(1, sizeof(*srs));
	assert(srs != NULL);

	MakeDomainLabelFromLiteralString(&name, "foobar");
	MakeDomainNameFromDNSNameString(&type, "_foobar._tcp");
	MakeDomainNameFromDNSNameString(&domain, "local.");

	status = mDNS_RegisterService(&mDNSStorage, srs, &name, &type, &domain,
	    NULL, mDNSOpaque16fromIntVal(port), NULL, 0, NULL, 0,
	    mDNSInterface_Any, foobar_callback, srs, 0);
	assert(status == mStatus_NoError);

	return srs;
}
예제 #15
0
mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p)
    {
    AuthRecord *st = mDNSNULL;
    if (NumSubTypes)
        {
        mDNSs32 i;
        st = mDNSPlatformMemAllocate(NumSubTypes * sizeof(AuthRecord));
        if (!st) return(mDNSNULL);
        for (i = 0; i < NumSubTypes; i++)
            {
            mDNS_SetupResourceRecord(&st[i], mDNSNULL, mDNSInterface_Any, kDNSQType_ANY, kStandardTTL, 0, AuthRecordAny, mDNSNULL, mDNSNULL);
            while (*p) p++;
            p++;
            if (!MakeDomainNameFromDNSNameString(&st[i].namestorage, p))
                { mDNSPlatformMemFree(st); return(mDNSNULL); }
            }
        }
    return(st);
    }
예제 #16
0
// All the children are in a linked list
//
// <TrustAnchor> has two children: <Zone> and <KeyDigest>
// <KeyDigest> has four children <KeyTag> <Algorithm> <DigestType> <Digest>
//
// Returns false if failed to parse the element i.e., malformed xml document.
// Validity of the actual values itself is done outside the function.
mDNSlocal mDNSBool ParseElementChildren(xmlDocPtr tadoc, xmlNode *node, TrustAnchor *ta)
{
    xmlNode *cur_node;
    xmlChar *val1, *val2, *val;
    char *invalid = NULL;

    val = val1 = val2 = NULL;

    for (cur_node = node; cur_node; cur_node = cur_node->next)
    {
        invalid = NULL;
        val1 = val2 = NULL;
        
        val = xmlNodeListGetString(tadoc, cur_node->xmlChildrenNode, 1);
        if (!val)
        {
           LogInfo("ParseElementChildren: NULL value for %s", cur_node->name);
           continue; 
        }
        if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Zone"))
        {
            // MaeDomainNameFromDNSNameString does not work for "."
            if (!xmlStrcmp(val, (const xmlChar *)"."))
            {
                ta->zone.c[0] = 0;
            }
            else if (!MakeDomainNameFromDNSNameString(&ta->zone, (char *)val))
            {
                LogMsg("ParseElementChildren: Cannot parse Zone %s", val);
                goto error;
            }
            else
            {
                LogInfo("ParseElementChildren: Element %s, value %##s", cur_node->name, ta->zone.c);
            }
        }
        else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"KeyTag"))
        {
            ta->rds.keyTag = strtol((const char *)val, &invalid, 10);
            if (*invalid != '\0')
            {
                LogMsg("ParseElementChildren: KeyTag invalid character %d", *invalid);
                goto error;
            }
            else
            {
                LogInfo("ParseElementChildren: Element %s, value %d", cur_node->name, ta->rds.keyTag);
            }
        }
        else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Algorithm"))
        {
            ta->rds.alg = strtol((const char *)val, &invalid, 10);
            if (*invalid != '\0')
            {
                LogMsg("ParseElementChildren: Algorithm invalid character %c", *invalid);
                goto error;
            }
            else
            {
                LogInfo("ParseElementChildren: Element %s, value %d", cur_node->name, ta->rds.alg);
            }
        }
        else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"DigestType"))
        {
            ta->rds.digestType = strtol((const char *)val, &invalid, 10);
            if (*invalid != '\0')
            {
                LogMsg("ParseElementChildren: Algorithm invalid character %c", *invalid);
                goto error;
            }
            else
            {
                LogInfo("ParseElementChildren: Element %s, value %d", cur_node->name, ta->rds.digestType);
            }
        }
        else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Digest"))
        {
            int diglen;
            mDNSu8 *dig = ConvertDigest((char *)val, ta->rds.digestType, &diglen);
            if (dig)
            { 
                LogInfo("ParseElementChildren: Element %s, digest %s", cur_node->name, val);
                ta->digestLen = diglen;
                ta->rds.digest = dig;
            }
            else
            {
                LogMsg("ParseElementChildren: Element %s, NULL digest", cur_node->name);
                goto error;
            }
        }
        else if (!xmlStrcmp(cur_node->name, (const xmlChar *)"KeyDigest"))
        {
            struct tm tm;
            val1 = xmlGetProp(cur_node, (const xmlChar *)"validFrom");
            if (val1)
            {
                char *s = strptime((const char *)val1, "%Y-%m-%dT%H:%M:%S", &tm);
                if (!s)
                {
                    LogMsg("ParseElementChildren: Parsing ValidFrom failed %s", val1);
                    goto error;
                }
                else
                {
                    ta->validFrom = (mDNSu32)timegm(&tm);
                }
            }
            val2 = xmlGetProp(cur_node, (const xmlChar *)"validUntil");
            if (val2)
            {
                char *s = strptime((const char *)val2, "%Y-%m-%dT%H:%M:%S", &tm);
                if (!s)
                {
                    LogMsg("ParseElementChildren: Parsing ValidFrom failed %s", val2);
                    goto error;
                }
                else
                {
                    ta->validUntil = (mDNSu32)timegm(&tm);
                }
            }
            else
            {
                // If there is no validUntil, set it to the next probing interval
                mDNSu32 t = (mDNSu32) time(NULL); 
                ta->validUntil = t + ROOT_TA_UPDATE_INTERVAL;
            }
            LogInfo("ParseElementChildren: ValidFrom time %u, validUntil %u", (unsigned)ta->validFrom, (unsigned)ta->validUntil);
        }
        if (val1)
            xmlFree(val1);
        if (val2)
            xmlFree(val2);
        if (val)
            xmlFree(val);
    }
    return mDNStrue;
error:
    if (val1)
        xmlFree(val1);
    if (val2)
        xmlFree(val2);
    if (val)
        xmlFree(val);
    return mDNSfalse;
}
int main()
	{
	mStatus err;
	Boolean DoneSetup = false;
	void *tempmem;

	SIOUXSettings.asktosaveonclose = false;
	SIOUXSettings.userwindowtitle  = "\pMulticast DNS Searcher";
	SIOUXSettings.rows             = 40;
	SIOUXSettings.columns          = 132;

	printf("Multicast DNS Searcher\n\n");
	printf("This software reports errors using MacsBug breaks,\n");
	printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
	printf("******************************************************************************\n");

	err = InitOpenTransport();
	if (err) { debugf("InitOpenTransport failed %d", err); return(err); }

	err = mDNS_Init(&mDNSStorage, &PlatformSupportStorage, rrcachestorage, RR_CACHE_SIZE,
		mDNS_Init_DontAdvertiseLocalAddresses, mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
	if (err) return(err);

	// Make sure OT has a large enough memory pool for us to draw from at OTNotifier (interrupt) time
	tempmem = OTAllocMem(0x10000);
	if (tempmem) OTFreeMem(tempmem);
	else printf("**** Warning: OTAllocMem couldn't pre-allocate 64K for us.\n");

	services.serviceinfolist.fHead = NULL;
	services.headerPrinted         = false;
	services.lostRecords           = false;

	while (!YieldSomeTime(35))
		{
#if MDNS_ONLYSYSTEMTASK
		// For debugging, use "#define MDNS_ONLYSYSTEMTASK 1" and call mDNSPlatformIdle() periodically.
		// For shipping code, don't define MDNS_ONLYSYSTEMTASK, and you don't need to call mDNSPlatformIdle()
		extern void mDNSPlatformIdle(mDNS *const m);
		mDNSPlatformIdle(&mDNSStorage);	// Only needed for debugging version
#endif
		if (mDNSStorage.mDNSPlatformStatus == mStatus_NoError && !DoneSetup)
			{
			domainname srvtype, srvdom;
			DoneSetup = true;
			printf("\nSending mDNS service lookup queries and waiting for responses...\n\n");
			MakeDomainNameFromDNSNameString(&srvtype, "_http._tcp.");
			MakeDomainNameFromDNSNameString(&srvdom, "local.");
			err = mDNS_StartBrowse(&mDNSStorage, &browsequestion, &srvtype, &srvdom, mDNSInterface_Any, mDNSfalse, FoundInstance, &services);
			if (err) break;
			err = mDNS_GetDomains(&mDNSStorage, &domainquestion, mDNS_DomainTypeBrowse, NULL, mDNSInterface_Any, FoundDomain, &services);
			if (err) break;
			}

		if (services.serviceinfolist.fHead)
			PrintServiceInfo(&services);

		if (services.lostRecords)
			{
			services.lostRecords = false;
			printf("**** Warning: Out of memory: Records have been missed.\n");
			}
		}

	mDNS_StopBrowse(&mDNSStorage, &browsequestion);
	mDNS_Close(&mDNSStorage);
	return(0);
	}
예제 #18
0
int main(void)
    // The program's main entry point.  The program does a trivial 
    // mDNS query, looking for mDNS service & device in the local domain.
{
    	int     result;
    	mStatus     status;
    	DNSQuestion question;
    	domainname  type;
    	domainname  domain;
	char DeviceName[64];

    	// Initialise the mDNS core.
	status = mDNS_Init(&mDNSStorage, &PlatformStorage,
    	gRRCache, RR_CACHE_SIZE,
    	mDNS_Init_DontAdvertiseLocalAddresses,
    	mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);

    if (status == mStatus_NoError) {
#if 1 /* Query service type */
        // Construct and start the query.
        MakeDomainNameFromDNSNameString(&type, gServiceType);
        MakeDomainNameFromDNSNameString(&domain, gServiceDomain);

        status = mDNS_StartBrowse(&mDNSStorage, &question, &type, &domain, mDNSInterface_Any, mDNSfalse, BrowseCallback, NULL);
    
	//return;
        // Run the platform main event loop. 
        // The BrowseCallback routine is responsible for printing 
        // any results that we find.
        
        if (status == mStatus_NoError) {
            	fprintf(stderr, "* Query: %s\n", gServiceType);
        	EventLoop(&mDNSStorage);
            	mDNS_StopQuery(&mDNSStorage, &question);
                //Parse all service type and query detail
                //fprintf(stderr, "===== Parse all service type and query detail...\n");
                callback = 0;
                event = 0;
		StopNow = 0;
	}
	return 0;
#endif

#if 0 /* Query device name */
		Service_tmp = Service_list;
		while(Service_tmp!=NULL) {
			printf("\n======= Queried Service: %s.%s\n", Service_tmp->service, Service_tmp->type);
			sprintf(Query_type, "%s.%s", Service_tmp->service, Service_tmp->type);
			//Device_found = Service_tmp->sup_device;
			gServiceType = Query_type;
			MakeDomainNameFromDNSNameString(&type, gServiceType);
			status = mDNS_StartBrowse(&mDNSStorage, &question, &type, &domain, mDNSInterface_Any, mDNSfalse, QueryCallback, NULL);
			if (status == mStatus_NoError) {
		                EventLoop(&mDNSStorage);
        		        mDNS_StopQuery(&mDNSStorage, &question);
			}
                        callback = 0;
                        event = 0;
                        StopNow = 0;
                        Service_tmp = Service_tmp->next;
                }
		printf("===============\n\n");
#endif

#if 0 /* Query IP of device */
		DeviceIP_cur = Device_list;
		printf("%d,%d,%d  ", callback, event, StopNow);
		printf("QUERY DEVICE: %s/%s\n", Device_cur->name, Device_cur->IPv4Addr);
		char *cc = Device_cur->IPv4Addr;
		int x =0;
		for(; x<16; x++) {
			printf("%",*cc);
			cc++;
		}
		printf("\n");
		//if(DeviceIP_cur->IPv4Addr == NULL)
		if(!strcmp(DeviceIP_cur->IPv4Addr, ""))
			printf("    DeviceIP_cur->IPv4Addr == NULL\n");

		while(DeviceIP_cur && (!strcmp(DeviceIP_cur->IPv4Addr, ""))) {
			memset(DeviceName, 0, 64);
			strcpy(DeviceName, DeviceIP_cur->name);
			HostnameParse(DeviceName);
			gServiceType = DeviceName;
        		printf("Query IP of %s\n", gServiceType);
		        // Construct and start the query.
		       	MakeDomainNameFromDNSNameString(&type, gServiceType);
		        status = mDNS_GetAddrInfo(&mDNSStorage, &question, &type, &domain, mDNSInterface_Any, mDNSfalse, IPInfoCallback, NULL);
		        if (status == mStatus_NoError) {
		       	        EventLoop(&mDNSStorage);
                		mDNS_StopQuery(&mDNSStorage, &question);
		        }
			else {
				printf("Error= %ld\n", status);
			}
			DeviceIP_cur = DeviceIP_cur->next;
        	               callback = 0;
                        event = 0;
                       	StopNow = 0;
		}

		printf("===============\n");
#endif
int nvram_size, i = 0;
char *nvram_info;
char device_name_ascii[256], service_type_list[512];
struct mDNS_service_handler *handler;

nvram_size = device_count*64 + service_count*4;
nvram_info = malloc(nvram_size);
memset(nvram_info, 0, nvram_size);
printf("nvram_size= %d\n", nvram_size);

    	//Print all info
    	Service_tmp = Service_list;
    	while(Service_tmp!=NULL) {
		printf("\n=== %s.%s ===\n", Service_tmp->service, Service_tmp->type);
		Service_tmp = Service_tmp->next;
    	}

printf("\n===== Print device ========\n");
        Device_tmp = Device_list;
        while(Device_tmp!=NULL) {
                //printf("    %s:%s->", Device_tmp->name, Device_tmp->IPv4Addr);
		memset(device_name_ascii, 0, 256);
		char_to_ascii(device_name_ascii, Device_tmp->name);
		strcat(nvram_info, "<");
		sprintf(nvram_info, "%s%s>%s>", nvram_info, Device_tmp->IPv4Addr, device_name_ascii);
printf("    %s\n", nvram_info);
		Sup_service_tmp = Device_tmp->sup_service;
		memset(service_type_list, 0, 512);
		while(Sup_service_tmp!=NULL) {
			for(handler = &service_handler[0], i=0; handler->service; handler++, i++) {
				if(strstr(Sup_service_tmp->name, handler->service)) {
					sprintf(service_type_list, "%s#%d", service_type_list, i);
					break;
				}	
			}

			printf("%s ", Sup_service_tmp->name);
			Sup_service_tmp = Sup_service_tmp->next;
		}
		printf("\n");
		printf("Service_type= %s\n", service_type_list);
		sprintf(nvram_info, "%s%s", nvram_info, service_type_list);
printf("-> %s\n", nvram_info);
                Device_tmp = Device_tmp->next;
        }
	printf("\n==> %s\n", nvram_info);

	free(nvram_info);
	mDNS_Close(&mDNSStorage);
    }//Endof Initialise the mDNS core.
    
    if (status == mStatus_NoError) {
        result = 0;
    } else {
        result = 2;
    }
    if ( (result != 0) || (gMDNSPlatformPosixVerboseLevel > 0) ) {
        fprintf(stderr, "%s: Finished with status %d, result %d\n", gProgramName, (int)status, result);
    }

    return 0;
}
예제 #19
0
DNSServiceErrorType DNSServiceResolve
	(
	DNSServiceRef                       *sdRef,
	DNSServiceFlags                     flags,
	uint32_t                            interfaceIndex,
	const char                          *name,
	const char                          *regtype,
	const char                          *domain,
	DNSServiceResolveReply              callback,
	void                                *context  /* may be NULL */
	)
	{
	mStatus err = mStatus_NoError;
	const char *errormsg = "Unknown";
	domainlabel n;
	domainname t, d, srv;
	mDNS_DirectOP_Resolve *x;

	(void)flags;			// Unused
	(void)interfaceIndex;	// Unused

	// Check parameters
	if (!name[0]    || !MakeDomainLabelFromLiteralString(&n, name  )) { errormsg = "Bad Instance Name"; goto badparam; }
	if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype)) { errormsg = "Bad Service Type";  goto badparam; }
	if (!domain[0]  || !MakeDomainNameFromDNSNameString(&d, domain )) { errormsg = "Bad Domain";        goto badparam; }
	if (!ConstructServiceName(&srv, &n, &t, &d))                      { errormsg = "Bad Name";          goto badparam; }

	// Allocate memory, and handle failure
	x = (mDNS_DirectOP_Resolve *)mDNSPlatformMemAllocate(sizeof(*x));
	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }

	// Set up object
	x->disposefn = DNSServiceResolveDispose;
	x->callback  = callback;
	x->context   = context;
	x->SRV       = mDNSNULL;
	x->TXT       = mDNSNULL;

	x->qSRV.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
	x->qSRV.InterfaceID         = mDNSInterface_Any;
	x->qSRV.Target              = zeroAddr;
	AssignDomainName(&x->qSRV.qname, &srv);
	x->qSRV.qtype               = kDNSType_SRV;
	x->qSRV.qclass              = kDNSClass_IN;
	x->qSRV.LongLived           = mDNSfalse;
	x->qSRV.ExpectUnique        = mDNStrue;
	x->qSRV.ForceMCast          = mDNSfalse;
	x->qSRV.QuestionCallback    = FoundServiceInfo;
	x->qSRV.QuestionContext     = x;

	x->qTXT.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
	x->qTXT.InterfaceID         = mDNSInterface_Any;
	x->qTXT.Target              = zeroAddr;
	AssignDomainName(&x->qTXT.qname, &srv);
	x->qTXT.qtype               = kDNSType_TXT;
	x->qTXT.qclass              = kDNSClass_IN;
	x->qTXT.LongLived           = mDNSfalse;
	x->qTXT.ExpectUnique        = mDNStrue;
	x->qTXT.ForceMCast          = mDNSfalse;
	x->qTXT.QuestionCallback    = FoundServiceInfo;
	x->qTXT.QuestionContext     = x;

	err = mDNS_StartQuery(&mDNSStorage, &x->qSRV);
	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qSRV"; goto fail; }
	err = mDNS_StartQuery(&mDNSStorage, &x->qTXT);
	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qTXT"; goto fail; }

	// Succeeded: Wrap up and return
	*sdRef = (DNSServiceRef)x;
	return(mStatus_NoError);

badparam:
	err = mStatus_BadParamErr;
fail:
	LogMsg("DNSServiceResolve(\"%s\", \"%s\", \"%s\") failed: %s (%ld)", name, regtype, domain, errormsg, err);
	return(err);
	}
예제 #20
0
DNSServiceErrorType DNSServiceRegister
	(
	DNSServiceRef                       *sdRef,
	DNSServiceFlags                     flags,
	uint32_t                            interfaceIndex,
	const char                          *name,         /* may be NULL */
	const char                          *regtype,
	const char                          *domain,       /* may be NULL */
	const char                          *host,         /* may be NULL */
	uint16_t                            notAnIntPort,
	uint16_t                            txtLen,
	const void                          *txtRecord,    /* may be NULL */
	DNSServiceRegisterReply             callback,      /* may be NULL */
	void                                *context       /* may be NULL */
	)
	{
	mStatus err = mStatus_NoError;
	const char *errormsg = "Unknown";
	domainlabel n;
	domainname t, d, h, srv;
	mDNSIPPort port;
	unsigned int size = sizeof(RDataBody);
	AuthRecord *SubTypes = mDNSNULL;
	mDNSu32 NumSubTypes = 0;
	mDNS_DirectOP_Register *x;
	(void)flags;			// Unused
	(void)interfaceIndex;	// Unused

	// Check parameters
	if (!name[0]) n = mDNSStorage.nicelabel;
	else if (!MakeDomainLabelFromLiteralString(&n, name))                              { errormsg = "Bad Instance Name"; goto badparam; }
	if (!regtype || !*regtype || !MakeDomainNameFromDNSNameString(&t, regtype))        { errormsg = "Bad Service Type";  goto badparam; }
	if (!MakeDomainNameFromDNSNameString(&d, (domain && *domain) ? domain : "local.")) { errormsg = "Bad Domain";        goto badparam; }
	if (!MakeDomainNameFromDNSNameString(&h, (host   && *host  ) ? host   : ""))       { errormsg = "Bad Target Host";   goto badparam; }
	if (!ConstructServiceName(&srv, &n, &t, &d))                                       { errormsg = "Bad Name";          goto badparam; }
	port.NotAnInteger = notAnIntPort;

	// Allocate memory, and handle failure
	if (size < txtLen)
		size = txtLen;
	x = (mDNS_DirectOP_Register *)mDNSPlatformMemAllocate(sizeof(*x) - sizeof(RDataBody) + size);
	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }

	// Set up object
	x->disposefn = DNSServiceRegisterDispose;
	x->callback  = callback;
	x->context   = context;
	x->autoname = (!name[0]);
	x->autorename = mDNSfalse;
	x->name = n;

	// Do the operation
	err = mDNS_RegisterService(&mDNSStorage, &x->s,
		&x->name, &t, &d,		// Name, type, domain
		&h, port,				// Host and port
		txtRecord, txtLen,		// TXT data, length
		SubTypes, NumSubTypes,	// Subtypes
		mDNSInterface_Any,		// Interface ID
		RegCallback, x);		// Callback and context
	if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_RegisterService"; goto fail; }

	// Succeeded: Wrap up and return
	*sdRef = (DNSServiceRef)x;
	return(mStatus_NoError);

badparam:
	err = mStatus_BadParamErr;
fail:
	LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err);
	return(err);
	}
예제 #21
0
DNSServiceErrorType DNSSD_API DNSServiceBrowse
	(
	DNSServiceRef                       *sdRef,
	DNSServiceFlags                     flags,
	uint32_t                            interfaceIndex,
	const char                          *regtype,
	const char                          *domain,    /* may be NULL */
	DNSServiceBrowseReply               callback,
	void                                *context    /* may be NULL */
	)
	{
	mStatus err = mStatus_NoError;
	const char *errormsg = "Unknown";
	domainname t, d;
	mDNS_DirectOP_Browse *x;
    mDNSs32 NumSubTypes;
    char regTypeBuf[MAX_ESCAPED_DOMAIN_NAME];
    (void)flags;			// Unused
	(void)interfaceIndex;	// Unused

    if (!regtype || !*regtype)                                         { goto badregtype; }
    mDNSPlatformStrCopy(regTypeBuf, regtype);

    // Check parameters
    t.c[0] = 0;
    NumSubTypes = ChopSubTypes(regTypeBuf);	// Note: Modifies regtype string to remove trailing subtypes
    if (NumSubTypes < 0 || NumSubTypes > 1)                            { goto badregtype; }
    if (NumSubTypes == 1 &&
       !AppendDNSNameString(&t, regTypeBuf + mDNSPlatformStrLen(regTypeBuf) + 1))
                                                                       { goto badregtype; }

    if (!regTypeBuf[0] || !AppendDNSNameString(&t, regTypeBuf))        { goto badregtype; }

    if (!MakeDomainNameFromDNSNameString(&d, (domain && *domain) ? domain : "local.")) { errormsg = "Illegal domain";  goto badparam; }

	// Allocate memory, and handle failure
	x = (mDNS_DirectOP_Browse *)mDNSPlatformMemAllocate(sizeof(*x));
	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }

	// Set up object
	x->disposefn = DNSServiceBrowseDispose;
	x->callback  = callback;
	x->context   = context;
	x->q.QuestionContext = x;

	// Do the operation
	err = mDNS_StartBrowse(&mDNSStorage, &x->q, &t, &d, mDNSInterface_Any, (flags & kDNSServiceFlagsForceMulticast) != 0, FoundInstance, x);
	if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_StartBrowse"; goto fail; }

	// Succeeded: Wrap up and return
	*sdRef = (DNSServiceRef)x;
	return(mStatus_NoError);

badregtype:
    errormsg = "Illegal regtype";
badparam:
	err = mStatus_BadParamErr;
fail:
	LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err);
	return(err);
	}