forked from qt-creator/qt-creator
Don't build mdnssd
This was enabled for Linux only, but Linux users should use Avahi,
which is present on most modern distributions, and implements mDNS
functionality.
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com>
(cherry picked from commit 272e9a37f3
)
Change-Id: I5e17ff9b8bff6eae9af2f8281937afdb687c371f
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
This commit is contained in:
committed by
Eike Ziller
parent
aed4d1058e
commit
d3849fd82e
File diff suppressed because it is too large
Load Diff
@@ -1,292 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __DNSCOMMON_H_
|
|
||||||
#define __DNSCOMMON_H_
|
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//*************************************************************************************************************
|
|
||||||
// Macros
|
|
||||||
|
|
||||||
// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
|
|
||||||
// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
|
|
||||||
// To expand "version" to its value before making the string, use STRINGIFY(version) instead
|
|
||||||
#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
|
|
||||||
#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
|
||||||
#pragma mark - DNS Protocol Constants
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
kDNSFlag0_QR_Mask = 0x80, // Query or response?
|
|
||||||
kDNSFlag0_QR_Query = 0x00,
|
|
||||||
kDNSFlag0_QR_Response = 0x80,
|
|
||||||
|
|
||||||
kDNSFlag0_OP_Mask = 0x78, // Operation type
|
|
||||||
kDNSFlag0_OP_StdQuery = 0x00,
|
|
||||||
kDNSFlag0_OP_Iquery = 0x08,
|
|
||||||
kDNSFlag0_OP_Status = 0x10,
|
|
||||||
kDNSFlag0_OP_Unused3 = 0x18,
|
|
||||||
kDNSFlag0_OP_Notify = 0x20,
|
|
||||||
kDNSFlag0_OP_Update = 0x28,
|
|
||||||
|
|
||||||
kDNSFlag0_QROP_Mask = kDNSFlag0_QR_Mask | kDNSFlag0_OP_Mask,
|
|
||||||
|
|
||||||
kDNSFlag0_AA = 0x04, // Authoritative Answer?
|
|
||||||
kDNSFlag0_TC = 0x02, // Truncated?
|
|
||||||
kDNSFlag0_RD = 0x01, // Recursion Desired?
|
|
||||||
kDNSFlag1_RA = 0x80, // Recursion Available?
|
|
||||||
|
|
||||||
kDNSFlag1_Zero = 0x40, // Reserved; must be zero
|
|
||||||
kDNSFlag1_AD = 0x20, // Authentic Data [RFC 2535]
|
|
||||||
kDNSFlag1_CD = 0x10, // Checking Disabled [RFC 2535]
|
|
||||||
|
|
||||||
kDNSFlag1_RC_Mask = 0x0F, // Response code
|
|
||||||
kDNSFlag1_RC_NoErr = 0x00,
|
|
||||||
kDNSFlag1_RC_FormErr = 0x01,
|
|
||||||
kDNSFlag1_RC_ServFail = 0x02,
|
|
||||||
kDNSFlag1_RC_NXDomain = 0x03,
|
|
||||||
kDNSFlag1_RC_NotImpl = 0x04,
|
|
||||||
kDNSFlag1_RC_Refused = 0x05,
|
|
||||||
kDNSFlag1_RC_YXDomain = 0x06,
|
|
||||||
kDNSFlag1_RC_YXRRSet = 0x07,
|
|
||||||
kDNSFlag1_RC_NXRRSet = 0x08,
|
|
||||||
kDNSFlag1_RC_NotAuth = 0x09,
|
|
||||||
kDNSFlag1_RC_NotZone = 0x0A
|
|
||||||
} DNS_Flags;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
TSIG_ErrBadSig = 16,
|
|
||||||
TSIG_ErrBadKey = 17,
|
|
||||||
TSIG_ErrBadTime = 18
|
|
||||||
} TSIG_ErrorCode;
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - General Utility Functions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern NetworkInterfaceInfo *GetFirstActiveInterface(NetworkInterfaceInfo *intf);
|
|
||||||
extern mDNSInterfaceID GetNextActiveInterfaceID(const NetworkInterfaceInfo *intf);
|
|
||||||
|
|
||||||
extern mDNSu32 mDNSRandom(mDNSu32 max); // Returns pseudo-random result from zero to max inclusive
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - Domain Name Utility Functions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define mDNSIsDigit(X) ((X) >= '0' && (X) <= '9')
|
|
||||||
#define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
|
|
||||||
#define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
|
|
||||||
#define mDNSIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
|
|
||||||
|
|
||||||
#define mDNSValidHostChar(X, notfirst, notlast) (mDNSIsLetter(X) || mDNSIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
|
|
||||||
|
|
||||||
extern mDNSu16 CompressedDomainNameLength(const domainname *const name, const domainname *parent);
|
|
||||||
extern int CountLabels(const domainname *d);
|
|
||||||
extern const domainname *SkipLeadingLabels(const domainname *d, int skip);
|
|
||||||
|
|
||||||
extern mDNSu32 TruncateUTF8ToLength(mDNSu8 *string, mDNSu32 length, mDNSu32 max);
|
|
||||||
extern mDNSBool LabelContainsSuffix(const domainlabel *const name, const mDNSBool RichText);
|
|
||||||
extern mDNSu32 RemoveLabelSuffix(domainlabel *name, mDNSBool RichText);
|
|
||||||
extern void AppendLabelSuffix(domainlabel *const name, mDNSu32 val, const mDNSBool RichText);
|
|
||||||
#define ValidateDomainName(N) (DomainNameLength(N) <= MAX_DOMAIN_NAME)
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - Resource Record Utility Functions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// IdenticalResourceRecord returns true if two resources records have
|
|
||||||
// the same name, type, class, and identical rdata (InterfaceID and TTL may differ)
|
|
||||||
|
|
||||||
// IdenticalSameNameRecord is the same, except it skips the expensive SameDomainName() check,
|
|
||||||
// which is at its most expensive and least useful in cases where we know in advance that the names match
|
|
||||||
|
|
||||||
// Note: The dominant use of IdenticalResourceRecord is from ProcessQuery(), handling known-answer lists. In this case
|
|
||||||
// it's common to have a whole bunch or records with exactly the same name (e.g. "_http._tcp.local") but different RDATA.
|
|
||||||
// The SameDomainName() check is expensive when the names match, and in this case *all* the names match, so we
|
|
||||||
// used to waste a lot of CPU time verifying that the names match, only then to find that the RDATA is different.
|
|
||||||
// We observed mDNSResponder spending 30% of its total CPU time on this single task alone.
|
|
||||||
// By swapping the checks so that we check the RDATA first, we can quickly detect when it's different
|
|
||||||
// (99% of the time) and then bail out before we waste time on the expensive SameDomainName() check.
|
|
||||||
|
|
||||||
#define IdenticalResourceRecord(r1,r2) ( \
|
|
||||||
(r1)->rrtype == (r2)->rrtype && \
|
|
||||||
(r1)->rrclass == (r2)->rrclass && \
|
|
||||||
(r1)->namehash == (r2)->namehash && \
|
|
||||||
(r1)->rdlength == (r2)->rdlength && \
|
|
||||||
(r1)->rdatahash == (r2)->rdatahash && \
|
|
||||||
SameRDataBody((r1), &(r2)->rdata->u, SameDomainName) && \
|
|
||||||
SameDomainName((r1)->name, (r2)->name))
|
|
||||||
|
|
||||||
#define IdenticalSameNameRecord(r1,r2) ( \
|
|
||||||
(r1)->rrtype == (r2)->rrtype && \
|
|
||||||
(r1)->rrclass == (r2)->rrclass && \
|
|
||||||
(r1)->rdlength == (r2)->rdlength && \
|
|
||||||
(r1)->rdatahash == (r2)->rdatahash && \
|
|
||||||
SameRDataBody((r1), &(r2)->rdata->u, SameDomainName))
|
|
||||||
|
|
||||||
// A given RRType answers a QuestionType if RRType is CNAME, or types match, or QuestionType is ANY,
|
|
||||||
// or the RRType is NSEC and positively asserts the nonexistence of the type being requested
|
|
||||||
#define RRTypeAnswersQuestionType(R,Q) ((R)->rrtype == kDNSType_CNAME || (R)->rrtype == (Q) || (Q) == kDNSQType_ANY || RRAssertsNonexistence((R),(Q)))
|
|
||||||
#define RRAssertsNonexistence(R,T) ((R)->rrtype == kDNSType_NSEC && (T) < kDNSQType_ANY && !((R)->rdata->u.nsec.bitmap[(T)>>3] & (128 >> ((T)&7))))
|
|
||||||
|
|
||||||
extern mDNSu32 RDataHashValue(const ResourceRecord *const rr);
|
|
||||||
extern mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *const r2, DomainNameComparisonFn *samename);
|
|
||||||
extern mDNSBool SameNameRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
|
|
||||||
extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
|
|
||||||
extern mDNSBool AnyTypeRecordAnswersQuestion (const ResourceRecord *const rr, const DNSQuestion *const q);
|
|
||||||
extern mDNSBool ResourceRecordAnswersUnicastResponse(const ResourceRecord *const rr, const DNSQuestion *const q);
|
|
||||||
extern mDNSBool LocalOnlyRecordAnswersQuestion(AuthRecord *const rr, const DNSQuestion *const q);
|
|
||||||
extern mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate);
|
|
||||||
extern mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd);
|
|
||||||
|
|
||||||
#define GetRRDomainNameTarget(RR) ( \
|
|
||||||
((RR)->rrtype == kDNSType_NS || (RR)->rrtype == kDNSType_CNAME || (RR)->rrtype == kDNSType_PTR || (RR)->rrtype == kDNSType_DNAME) ? &(RR)->rdata->u.name : \
|
|
||||||
((RR)->rrtype == kDNSType_MX || (RR)->rrtype == kDNSType_AFSDB || (RR)->rrtype == kDNSType_RT || (RR)->rrtype == kDNSType_KX ) ? &(RR)->rdata->u.mx.exchange : \
|
|
||||||
((RR)->rrtype == kDNSType_SRV ) ? &(RR)->rdata->u.srv.target : mDNSNULL )
|
|
||||||
|
|
||||||
#define LocalRecordReady(X) ((X)->resrec.RecordType != kDNSRecordTypeUnique)
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - DNS Message Creation Functions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void InitializeDNSMessage(DNSMessageHeader *h, mDNSOpaque16 id, mDNSOpaque16 flags);
|
|
||||||
extern const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const mDNSu8 *const end, const mDNSu8 *const domname);
|
|
||||||
extern mDNSu8 *putDomainNameAsLabels(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name);
|
|
||||||
extern mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const ResourceRecord *const rr);
|
|
||||||
|
|
||||||
// If we have a single large record to put in the packet, then we allow the packet to be up to 9K bytes,
|
|
||||||
// but in the normal case we try to keep the packets below 1500 to avoid IP fragmentation on standard Ethernet
|
|
||||||
|
|
||||||
#define AllowedRRSpace(msg) (((msg)->h.numAnswers || (msg)->h.numAuthorities || (msg)->h.numAdditionals) ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData)
|
|
||||||
|
|
||||||
extern mDNSu8 *PutResourceRecordTTLWithLimit(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 ttl, const mDNSu8 *limit);
|
|
||||||
|
|
||||||
#define PutResourceRecordTTL(msg, ptr, count, rr, ttl) \
|
|
||||||
PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), (msg)->data + AllowedRRSpace(msg))
|
|
||||||
|
|
||||||
#define PutResourceRecordTTLJumbo(msg, ptr, count, rr, ttl) \
|
|
||||||
PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), (msg)->data + AbsoluteMaxDNSMessageData)
|
|
||||||
|
|
||||||
#define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
|
|
||||||
|
|
||||||
// The PutRR_OS variants assume a local variable 'm', put build the packet at m->omsg,
|
|
||||||
// and assume a local variable 'OwnerRecordSpace' indicating how many bytes (if any) to reserve to add an OWNER option at the end
|
|
||||||
#define PutRR_OS_TTL(ptr, count, rr, ttl) \
|
|
||||||
PutResourceRecordTTLWithLimit(&m->omsg, (ptr), (count), (rr), (ttl), m->omsg.data + AllowedRRSpace(&m->omsg) - OwnerRecordSpace)
|
|
||||||
|
|
||||||
#define PutRR_OS(P, C, RR) PutRR_OS_TTL((P), (C), (RR), (RR)->rroriginalttl)
|
|
||||||
|
|
||||||
extern mDNSu8 *putQuestion(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name, mDNSu16 rrtype, mDNSu16 rrclass);
|
|
||||||
extern mDNSu8 *putZone(DNSMessage *const msg, mDNSu8 *ptr, mDNSu8 *limit, const domainname *zone, mDNSOpaque16 zoneClass);
|
|
||||||
extern mDNSu8 *putPrereqNameNotInUse(const domainname *const name, DNSMessage *const msg, mDNSu8 *const ptr, mDNSu8 *const end);
|
|
||||||
extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr);
|
|
||||||
extern mDNSu8 *putDeletionRecordWithLimit(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr, mDNSu8 *limit);
|
|
||||||
extern mDNSu8 *putDeleteRRSetWithLimit(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype, mDNSu8 *limit);
|
|
||||||
extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
|
|
||||||
extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
|
|
||||||
extern mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit);
|
|
||||||
|
|
||||||
extern mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *ptr, DomainAuthInfo *authInfo, mDNSu8 *limit);
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - DNS Message Parsing Functions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define AuthHashSlot(X) (DomainNameHashValue(X) % AUTH_HASH_SLOTS)
|
|
||||||
#define HashSlot(X) (DomainNameHashValue(X) % CACHE_HASH_SLOTS)
|
|
||||||
extern mDNSu32 DomainNameHashValue(const domainname *const name);
|
|
||||||
extern void SetNewRData(ResourceRecord *const rr, RData *NewRData, mDNSu16 rdlength);
|
|
||||||
extern const mDNSu8 *skipDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end);
|
|
||||||
extern const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end,
|
|
||||||
domainname *const name);
|
|
||||||
extern const mDNSu8 *skipResourceRecord(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
|
|
||||||
extern const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage * const msg, const mDNSu8 *ptr,
|
|
||||||
const mDNSu8 * end, const mDNSInterfaceID InterfaceID, mDNSu8 RecordType, LargeCacheRecord *const largecr);
|
|
||||||
extern const mDNSu8 *skipQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
|
|
||||||
extern const mDNSu8 *getQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end, const mDNSInterfaceID InterfaceID,
|
|
||||||
DNSQuestion *question);
|
|
||||||
extern const mDNSu8 *LocateAnswers(const DNSMessage *const msg, const mDNSu8 *const end);
|
|
||||||
extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8 *const end);
|
|
||||||
extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end);
|
|
||||||
extern const mDNSu8 *LocateOptRR(const DNSMessage *const msg, const mDNSu8 *const end, int minsize);
|
|
||||||
extern const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end);
|
|
||||||
extern mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end);
|
|
||||||
extern void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *transport,
|
|
||||||
const mDNSAddr *srcaddr, mDNSIPPort srcport,
|
|
||||||
const mDNSAddr *dstaddr, mDNSIPPort dstport, const DNSMessage *const msg, const mDNSu8 *const end);
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - Packet Sending Functions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNSu8 *end,
|
|
||||||
mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, mDNSIPPort dstport, TCPSocket *sock, DomainAuthInfo *authInfo);
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - RR List Management & Task Management
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void ShowTaskSchedulingError(mDNS *const m);
|
|
||||||
extern void mDNS_Lock_(mDNS *const m, const char * const functionname);
|
|
||||||
extern void mDNS_Unlock_(mDNS *const m, const char * const functionname);
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#define __func__ __FUNCTION__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define mDNS_Lock(X) mDNS_Lock_((X), __func__)
|
|
||||||
|
|
||||||
#define mDNS_Unlock(X) mDNS_Unlock_((X), __func__)
|
|
||||||
|
|
||||||
#define mDNS_DropLockBeforeCallback() do { m->mDNS_reentrancy++; \
|
|
||||||
if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Locking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define mDNS_ReclaimLockAfterCallback() do { \
|
|
||||||
if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Unlocking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
|
|
||||||
m->mDNS_reentrancy--; } while (0)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __DNSCOMMON_H_
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,319 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
|
|
||||||
File: GenLinkedList.c
|
|
||||||
|
|
||||||
Contains: implementation of generic linked lists.
|
|
||||||
|
|
||||||
Version: 1.0
|
|
||||||
Tabs: 4 spaces
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "GenLinkedList.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Return the link pointer contained within element e at offset o.
|
|
||||||
#define GETLINK( e, o) ( *(void**)((char*) (e) + (o)) )
|
|
||||||
|
|
||||||
// Assign the link pointer l to element e at offset o.
|
|
||||||
#define ASSIGNLINK( e, l, o) ( *((void**)((char*) (e) + (o))) = (l))
|
|
||||||
|
|
||||||
|
|
||||||
// GenLinkedList /////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void InitLinkedList( GenLinkedList *pList, size_t linkOffset)
|
|
||||||
/* Initialize the block of memory pointed to by pList as a linked list. */
|
|
||||||
{
|
|
||||||
pList->Head = NULL;
|
|
||||||
pList->Tail = NULL;
|
|
||||||
pList->LinkOffset = linkOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AddToTail( GenLinkedList *pList, void *elem)
|
|
||||||
/* Add a linked list element to the tail of the list. */
|
|
||||||
{
|
|
||||||
if ( pList->Tail) {
|
|
||||||
ASSIGNLINK( pList->Tail, elem, pList->LinkOffset);
|
|
||||||
} else
|
|
||||||
pList->Head = elem;
|
|
||||||
ASSIGNLINK( elem, NULL, pList->LinkOffset);
|
|
||||||
|
|
||||||
pList->Tail = elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AddToHead( GenLinkedList *pList, void *elem)
|
|
||||||
/* Add a linked list element to the head of the list. */
|
|
||||||
{
|
|
||||||
ASSIGNLINK( elem, pList->Head, pList->LinkOffset);
|
|
||||||
if ( pList->Tail == NULL)
|
|
||||||
pList->Tail = elem;
|
|
||||||
|
|
||||||
pList->Head = elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int RemoveFromList( GenLinkedList *pList, void *elem)
|
|
||||||
/* Remove a linked list element from the list. Return 0 if it was not found. */
|
|
||||||
/* If the element is removed, its link will be set to NULL. */
|
|
||||||
{
|
|
||||||
void *iElem, *lastElem;
|
|
||||||
|
|
||||||
for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset)) {
|
|
||||||
if ( iElem == elem) {
|
|
||||||
if ( lastElem) { // somewhere past the head
|
|
||||||
ASSIGNLINK( lastElem, GETLINK( elem, pList->LinkOffset), pList->LinkOffset);
|
|
||||||
} else { // at the head
|
|
||||||
pList->Head = GETLINK( elem, pList->LinkOffset);
|
|
||||||
}
|
|
||||||
if ( pList->Tail == elem)
|
|
||||||
pList->Tail = lastElem ? lastElem : NULL;
|
|
||||||
ASSIGNLINK( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
lastElem = iElem;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem)
|
|
||||||
/* Replace an element in the list with a new element, in the same position. */
|
|
||||||
{
|
|
||||||
void *iElem, *lastElem;
|
|
||||||
|
|
||||||
if ( elemInList == NULL || newElem == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset))
|
|
||||||
{
|
|
||||||
if ( iElem == elemInList)
|
|
||||||
{
|
|
||||||
ASSIGNLINK( newElem, GETLINK( elemInList, pList->LinkOffset), pList->LinkOffset);
|
|
||||||
if ( lastElem) // somewhere past the head
|
|
||||||
{
|
|
||||||
ASSIGNLINK( lastElem, newElem, pList->LinkOffset);
|
|
||||||
}
|
|
||||||
else // at the head
|
|
||||||
{
|
|
||||||
pList->Head = newElem;
|
|
||||||
}
|
|
||||||
if ( pList->Tail == elemInList)
|
|
||||||
pList->Tail = newElem;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
lastElem = iElem;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// GenDoubleLinkedList /////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
|
|
||||||
size_t backLinkOffset)
|
|
||||||
/* Initialize the block of memory pointed to by pList as a double linked list. */
|
|
||||||
{
|
|
||||||
pList->Head = NULL;
|
|
||||||
pList->Tail = NULL;
|
|
||||||
pList->FwdLinkOffset = fwdLinkOffset;
|
|
||||||
pList->BackLinkOffset = backLinkOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DLLAddToHead( GenDoubleLinkedList *pList, void *elem)
|
|
||||||
/* Add a linked list element to the head of the list. */
|
|
||||||
{
|
|
||||||
void *pNext;
|
|
||||||
|
|
||||||
pNext = pList->Head;
|
|
||||||
|
|
||||||
// fix up the forward links
|
|
||||||
ASSIGNLINK( elem, pList->Head, pList->FwdLinkOffset);
|
|
||||||
pList->Head = elem;
|
|
||||||
|
|
||||||
// fix up the backward links
|
|
||||||
if ( pNext) {
|
|
||||||
ASSIGNLINK( pNext, elem, pList->BackLinkOffset);
|
|
||||||
} else
|
|
||||||
pList->Tail = elem;
|
|
||||||
ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem)
|
|
||||||
/* Remove a linked list element from the list. */
|
|
||||||
/* When the element is removed, its link will be set to NULL. */
|
|
||||||
{
|
|
||||||
void *pNext, *pPrev;
|
|
||||||
|
|
||||||
pNext = GETLINK( elem, pList->FwdLinkOffset);
|
|
||||||
pPrev = GETLINK( elem, pList->BackLinkOffset);
|
|
||||||
|
|
||||||
// fix up the forward links
|
|
||||||
if ( pPrev)
|
|
||||||
ASSIGNLINK( pPrev, pNext, pList->FwdLinkOffset);
|
|
||||||
else
|
|
||||||
pList->Head = pNext;
|
|
||||||
|
|
||||||
// fix up the backward links
|
|
||||||
if ( pNext)
|
|
||||||
ASSIGNLINK( pNext, pPrev, pList->BackLinkOffset);
|
|
||||||
else
|
|
||||||
pList->Tail = pPrev;
|
|
||||||
|
|
||||||
ASSIGNLINK( elem, NULL, pList->FwdLinkOffset);
|
|
||||||
ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// GenLinkedOffsetList /////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Extract the Next offset from element
|
|
||||||
#define GETOFFSET( e, o) ( *(size_t*)((char*) (e) + (o)) )
|
|
||||||
|
|
||||||
static void AssignOffsetLink( void *elem, void *link, size_t linkOffset);
|
|
||||||
|
|
||||||
|
|
||||||
static void AssignOffsetLink( void *elem, void *link, size_t linkOffset)
|
|
||||||
// Assign link to elem as an offset from elem. Assign 0 to elem if link is NULL.
|
|
||||||
{
|
|
||||||
GETOFFSET( elem, linkOffset) = link ? (size_t) link - (size_t) elem : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *GetHeadPtr( GenLinkedOffsetList *pList)
|
|
||||||
/* Return a pointer to the head element of a list, or NULL if none. */
|
|
||||||
{
|
|
||||||
return pList->Head ? ( (char*) (pList) + pList->Head) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *GetTailPtr( GenLinkedOffsetList *pList)
|
|
||||||
/* Return a pointer to the tail element of a list, or NULL if none. */
|
|
||||||
{
|
|
||||||
return pList->Tail ? ( (char*) (pList) + pList->Tail) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem)
|
|
||||||
/* Return the link pointer contained within element e for pList, or NULL if it is 0. */
|
|
||||||
{
|
|
||||||
size_t nextOffset;
|
|
||||||
|
|
||||||
nextOffset = GETOFFSET( elem, pList->LinkOffset);
|
|
||||||
|
|
||||||
return nextOffset ? (char*) elem + nextOffset : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset)
|
|
||||||
/* Initialize the block of memory pointed to by pList as a linked list. */
|
|
||||||
{
|
|
||||||
pList->Head = 0;
|
|
||||||
pList->Tail = 0;
|
|
||||||
pList->LinkOffset = linkOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem)
|
|
||||||
/* Add a linked list element to the tail of the list. */
|
|
||||||
{
|
|
||||||
if ( pList->Tail) {
|
|
||||||
AssignOffsetLink( GetTailPtr( pList), elem, pList->LinkOffset);
|
|
||||||
} else
|
|
||||||
pList->Head = (size_t) elem - (size_t) pList;
|
|
||||||
AssignOffsetLink( elem, NULL, pList->LinkOffset);
|
|
||||||
|
|
||||||
pList->Tail = (size_t) elem - (size_t) pList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem)
|
|
||||||
/* Add a linked list element to the head of the list. */
|
|
||||||
{
|
|
||||||
AssignOffsetLink( elem, GetHeadPtr( pList), pList->LinkOffset);
|
|
||||||
if ( pList->Tail == 0)
|
|
||||||
pList->Tail = (size_t) elem - (size_t) pList;
|
|
||||||
|
|
||||||
pList->Head = (size_t) elem - (size_t) pList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem)
|
|
||||||
/* Remove a linked list element from the list. Return 0 if it was not found. */
|
|
||||||
/* If the element is removed, its link will be set to NULL. */
|
|
||||||
{
|
|
||||||
void *iElem, *lastElem;
|
|
||||||
|
|
||||||
for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
|
|
||||||
iElem = GetOffsetLink( pList, iElem))
|
|
||||||
{
|
|
||||||
if ( iElem == elem) {
|
|
||||||
if ( lastElem) { // somewhere past the head
|
|
||||||
AssignOffsetLink( lastElem, GetOffsetLink( pList, elem), pList->LinkOffset);
|
|
||||||
} else { // at the head
|
|
||||||
iElem = GetOffsetLink( pList, elem);
|
|
||||||
pList->Head = iElem ? (size_t) iElem - (size_t) pList : 0;
|
|
||||||
}
|
|
||||||
if ( GetTailPtr( pList) == elem)
|
|
||||||
pList->Tail = lastElem ? (size_t) lastElem - (size_t) pList : 0;
|
|
||||||
AssignOffsetLink( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
lastElem = iElem;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem)
|
|
||||||
/* Replace an element in the list with a new element, in the same position. */
|
|
||||||
{
|
|
||||||
void *iElem, *lastElem;
|
|
||||||
|
|
||||||
if ( elemInList == NULL || newElem == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
|
|
||||||
iElem = GetOffsetLink( pList, iElem))
|
|
||||||
{
|
|
||||||
if ( iElem == elemInList)
|
|
||||||
{
|
|
||||||
AssignOffsetLink( newElem, GetOffsetLink( pList, elemInList), pList->LinkOffset);
|
|
||||||
if ( lastElem) // somewhere past the head
|
|
||||||
{
|
|
||||||
AssignOffsetLink( lastElem, newElem, pList->LinkOffset);
|
|
||||||
}
|
|
||||||
else // at the head
|
|
||||||
{
|
|
||||||
pList->Head = (size_t) newElem - (size_t) pList;
|
|
||||||
}
|
|
||||||
if ( GetTailPtr( pList) == elemInList)
|
|
||||||
pList->Tail = (size_t) newElem - (size_t) pList;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
lastElem = iElem;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@@ -1,90 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GenLinkedList__
|
|
||||||
#define __GenLinkedList__
|
|
||||||
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct GenLinkedList
|
|
||||||
{
|
|
||||||
void *Head,
|
|
||||||
*Tail;
|
|
||||||
size_t LinkOffset;
|
|
||||||
};
|
|
||||||
typedef struct GenLinkedList GenLinkedList;
|
|
||||||
|
|
||||||
|
|
||||||
void InitLinkedList( GenLinkedList *pList, size_t linkOffset);
|
|
||||||
|
|
||||||
void AddToHead( GenLinkedList *pList, void *elem);
|
|
||||||
void AddToTail( GenLinkedList *pList, void *elem);
|
|
||||||
|
|
||||||
int RemoveFromList( GenLinkedList *pList, void *elem);
|
|
||||||
|
|
||||||
int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct GenDoubleLinkedList
|
|
||||||
{
|
|
||||||
void *Head,
|
|
||||||
*Tail;
|
|
||||||
size_t FwdLinkOffset,
|
|
||||||
BackLinkOffset;
|
|
||||||
};
|
|
||||||
typedef struct GenDoubleLinkedList GenDoubleLinkedList;
|
|
||||||
|
|
||||||
|
|
||||||
void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
|
|
||||||
size_t backLinkOffset);
|
|
||||||
|
|
||||||
void DLLAddToHead( GenDoubleLinkedList *pList, void *elem);
|
|
||||||
|
|
||||||
void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* A GenLinkedOffsetList is like a GenLinkedList that stores the *Next field as a signed */
|
|
||||||
/* offset from the address of the beginning of the element, rather than as a pointer. */
|
|
||||||
|
|
||||||
struct GenLinkedOffsetList
|
|
||||||
{
|
|
||||||
size_t Head,
|
|
||||||
Tail;
|
|
||||||
size_t LinkOffset;
|
|
||||||
};
|
|
||||||
typedef struct GenLinkedOffsetList GenLinkedOffsetList;
|
|
||||||
|
|
||||||
|
|
||||||
void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset);
|
|
||||||
|
|
||||||
void *GetHeadPtr( GenLinkedOffsetList *pList);
|
|
||||||
void *GetTailPtr( GenLinkedOffsetList *pList);
|
|
||||||
void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem);
|
|
||||||
|
|
||||||
void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem);
|
|
||||||
void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem);
|
|
||||||
|
|
||||||
int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem);
|
|
||||||
|
|
||||||
int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __GenLinkedList__
|
|
@@ -1,196 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h> // Needed for fopen() etc.
|
|
||||||
#include <unistd.h> // Needed for close()
|
|
||||||
#include <string.h> // Needed for strlen() etc.
|
|
||||||
#include <errno.h> // Needed for errno etc.
|
|
||||||
#include <sys/socket.h> // Needed for socket() etc.
|
|
||||||
#include <netinet/in.h> // Needed for sockaddr_in
|
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above
|
|
||||||
#include "DNSCommon.h"
|
|
||||||
#include "PlatformCommon.h"
|
|
||||||
|
|
||||||
#ifdef NOT_HAVE_SOCKLEN_T
|
|
||||||
typedef unsigned int socklen_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Bind a UDP socket to find the source address to a destination
|
|
||||||
mDNSexport void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst)
|
|
||||||
{
|
|
||||||
union { struct sockaddr s; struct sockaddr_in a4; struct sockaddr_in6 a6; } addr;
|
|
||||||
socklen_t len = sizeof(addr);
|
|
||||||
socklen_t inner_len = 0;
|
|
||||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
src->type = mDNSAddrType_None;
|
|
||||||
if (sock == -1) return;
|
|
||||||
if (dst->type == mDNSAddrType_IPv4)
|
|
||||||
{
|
|
||||||
inner_len = sizeof(addr.a4);
|
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
|
||||||
addr.a4.sin_len = inner_len;
|
|
||||||
#endif
|
|
||||||
addr.a4.sin_family = AF_INET;
|
|
||||||
addr.a4.sin_port = 1; // Not important, any port will do
|
|
||||||
addr.a4.sin_addr.s_addr = dst->ip.v4.NotAnInteger;
|
|
||||||
}
|
|
||||||
else if (dst->type == mDNSAddrType_IPv6)
|
|
||||||
{
|
|
||||||
inner_len = sizeof(addr.a6);
|
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
|
||||||
addr.a6.sin6_len = inner_len;
|
|
||||||
#endif
|
|
||||||
addr.a6.sin6_family = AF_INET6;
|
|
||||||
addr.a6.sin6_flowinfo = 0;
|
|
||||||
addr.a6.sin6_port = 1; // Not important, any port will do
|
|
||||||
addr.a6.sin6_addr = *(struct in6_addr*)&dst->ip.v6;
|
|
||||||
addr.a6.sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
else return;
|
|
||||||
|
|
||||||
if ((connect(sock, &addr.s, inner_len)) < 0)
|
|
||||||
{ LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d (%s)", dst, errno, strerror(errno)); goto exit; }
|
|
||||||
|
|
||||||
if ((getsockname(sock, &addr.s, &len)) < 0)
|
|
||||||
{ LogMsg("mDNSPlatformSourceAddrForDest: getsockname failed errno %d (%s)", errno, strerror(errno)); goto exit; }
|
|
||||||
|
|
||||||
src->type = dst->type;
|
|
||||||
if (dst->type == mDNSAddrType_IPv4) src->ip.v4.NotAnInteger = addr.a4.sin_addr.s_addr;
|
|
||||||
else src->ip.v6 = *(mDNSv6Addr*)&addr.a6.sin6_addr;
|
|
||||||
exit:
|
|
||||||
close(sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// dst must be at least MAX_ESCAPED_DOMAIN_NAME bytes, and option must be less than 32 bytes in length
|
|
||||||
mDNSlocal mDNSBool GetConfigOption(char *dst, const char *option, FILE *f)
|
|
||||||
{
|
|
||||||
char buf[32+1+MAX_ESCAPED_DOMAIN_NAME]; // Option name, one space, option value
|
|
||||||
unsigned int len = strlen(option);
|
|
||||||
if (len + 1 + MAX_ESCAPED_DOMAIN_NAME > sizeof(buf)-1) { LogMsg("GetConfigOption: option %s too long", option); return mDNSfalse; }
|
|
||||||
fseek(f, 0, SEEK_SET); // set position to beginning of stream
|
|
||||||
while (fgets(buf, sizeof(buf), f)) // Read at most sizeof(buf)-1 bytes from file, and append '\0' C-string terminator
|
|
||||||
{
|
|
||||||
if (!strncmp(buf, option, len))
|
|
||||||
{
|
|
||||||
strncpy(dst, buf + len + 1, MAX_ESCAPED_DOMAIN_NAME-1);
|
|
||||||
if (dst[MAX_ESCAPED_DOMAIN_NAME-1]) dst[MAX_ESCAPED_DOMAIN_NAME-1] = '\0';
|
|
||||||
len = strlen(dst);
|
|
||||||
if (len && dst[len-1] == '\n') dst[len-1] = '\0'; // chop newline
|
|
||||||
return mDNStrue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debugf("Option %s not set", option);
|
|
||||||
return mDNSfalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDNSexport void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled)
|
|
||||||
{
|
|
||||||
char buf[MAX_ESCAPED_DOMAIN_NAME] = "";
|
|
||||||
mStatus err;
|
|
||||||
FILE *f = fopen(filename, "r");
|
|
||||||
|
|
||||||
if (hostname) hostname->c[0] = 0;
|
|
||||||
if (domain) domain->c[0] = 0;
|
|
||||||
if (DomainDiscoveryDisabled) *DomainDiscoveryDisabled = mDNSfalse;
|
|
||||||
|
|
||||||
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;
|
|
||||||
buf[0] = 0;
|
|
||||||
GetConfigOption(buf, "secret-64", f); // failure means no authentication
|
|
||||||
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, domain, buf, NULL, 0, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS
|
|
||||||
mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"%s\n", msg);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, mDNSLogLevel_t loglevel)
|
|
||||||
{
|
|
||||||
#if APPLE_OSX_mDNSResponder && LogTimeStamps
|
|
||||||
extern mDNS mDNSStorage;
|
|
||||||
extern mDNSu32 mDNSPlatformClockDivisor;
|
|
||||||
mDNSs32 t = mDNSStorage.timenow ? mDNSStorage.timenow : mDNSPlatformClockDivisor ? mDNS_TimeNow_NoLock(&mDNSStorage) : 0;
|
|
||||||
int ms = ((t < 0) ? -t : t) % 1000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mDNS_DebugMode) // In debug mode we write to stderr
|
|
||||||
{
|
|
||||||
#if APPLE_OSX_mDNSResponder && LogTimeStamps
|
|
||||||
if (ident && ident[0] && mDNSPlatformClockDivisor)
|
|
||||||
fprintf(stderr,"%8d.%03d: %s\n", (int)(t/1000), ms, buffer);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
fprintf(stderr,"%s\n", buffer);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
else // else, in production mode, we write to syslog
|
|
||||||
{
|
|
||||||
static int log_inited = 0;
|
|
||||||
|
|
||||||
int syslog_level = LOG_ERR;
|
|
||||||
switch (loglevel)
|
|
||||||
{
|
|
||||||
case MDNS_LOG_MSG: syslog_level = LOG_ERR; break;
|
|
||||||
case MDNS_LOG_OPERATION: syslog_level = LOG_WARNING; break;
|
|
||||||
case MDNS_LOG_SPS: syslog_level = LOG_NOTICE; break;
|
|
||||||
case MDNS_LOG_INFO: syslog_level = LOG_INFO; break;
|
|
||||||
case MDNS_LOG_DEBUG: syslog_level = LOG_DEBUG; break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!log_inited) { openlog(ident, LOG_CONS, LOG_DAEMON); log_inited++; }
|
|
||||||
|
|
||||||
#if APPLE_OSX_mDNSResponder && LogTimeStamps
|
|
||||||
if (ident && ident[0] && mDNSPlatformClockDivisor)
|
|
||||||
syslog(syslog_level, "%8d.%03d: %s", (int)(t/1000), ms, buffer);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
syslog(syslog_level, "%s", buffer);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled);
|
|
@@ -1,258 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
|
|
||||||
File: daemon.c
|
|
||||||
|
|
||||||
Contains: main & associated Application layer for mDNSResponder on Linux.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if __APPLE__
|
|
||||||
// In Mac OS X 10.5 and later trying to use the daemon function gives a "'daemon' is deprecated"
|
|
||||||
// error, which prevents compilation because we build with "-Werror".
|
|
||||||
// Since this is supposed to be portable cross-platform code, we don't care that daemon is
|
|
||||||
// deprecated on Mac OS X 10.5, so we use this preprocessor trick to eliminate the error message.
|
|
||||||
#define daemon yes_we_know_that_daemon_is_deprecated_in_os_x_10_5_thankyou
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#if __APPLE__
|
|
||||||
#undef daemon
|
|
||||||
extern int daemon(int, int);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
|
||||||
#include "mDNSPosix.h"
|
|
||||||
#include "mDNSUNP.h" // For daemon()
|
|
||||||
#include "uds_daemon.h"
|
|
||||||
#include "PlatformCommon.h"
|
|
||||||
|
|
||||||
#define CONFIG_FILE "/etc/mdnsd.conf"
|
|
||||||
static domainname DynDNSZone; // Default wide-area zone for service registration
|
|
||||||
static domainname DynDNSHostname;
|
|
||||||
|
|
||||||
#define RR_CACHE_SIZE 500
|
|
||||||
static CacheEntity gRRCache[RR_CACHE_SIZE];
|
|
||||||
static mDNS_PlatformSupport PlatformStorage;
|
|
||||||
|
|
||||||
mDNSlocal void mDNS_StatusCallback(mDNS *const m, mStatus result)
|
|
||||||
{
|
|
||||||
(void)m; // Unused
|
|
||||||
if (result == mStatus_NoError)
|
|
||||||
{
|
|
||||||
// On successful registration of dot-local mDNS host name, daemon may want to check if
|
|
||||||
// any name conflict and automatic renaming took place, and if so, record the newly negotiated
|
|
||||||
// name in persistent storage for next time. It should also inform the user of the name change.
|
|
||||||
// On Mac OS X we store the current dot-local mDNS host name in the SCPreferences store,
|
|
||||||
// and notify the user with a CFUserNotification.
|
|
||||||
}
|
|
||||||
else if (result == mStatus_ConfigChanged)
|
|
||||||
{
|
|
||||||
udsserver_handle_configchange(m);
|
|
||||||
}
|
|
||||||
else if (result == mStatus_GrowCache)
|
|
||||||
{
|
|
||||||
// Allocate another chunk of cache storage
|
|
||||||
CacheEntity *storage = malloc(sizeof(CacheEntity) * RR_CACHE_SIZE);
|
|
||||||
if (storage) mDNS_GrowCache(m, storage, RR_CACHE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// %%% Reconfigure() probably belongs in the platform support layer (mDNSPosix.c), not the daemon cde
|
|
||||||
// -- all client layers running on top of mDNSPosix.c need to handle network configuration changes,
|
|
||||||
// not only the Unix Domain Socket Daemon
|
|
||||||
|
|
||||||
static void Reconfigure(mDNS *m)
|
|
||||||
{
|
|
||||||
mDNSAddr DynDNSIP;
|
|
||||||
const mDNSAddr dummy = { mDNSAddrType_IPv4, { { { 1, 1, 1, 1 } } } };;
|
|
||||||
mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL);
|
|
||||||
if (ParseDNSServers(m, uDNS_SERVERS_FILE) < 0)
|
|
||||||
LogMsg("Unable to parse DNS server list. Unicast DNS-SD unavailable");
|
|
||||||
ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &DynDNSHostname, &DynDNSZone, NULL);
|
|
||||||
mDNSPlatformSourceAddrForDest(&DynDNSIP, &dummy);
|
|
||||||
if (DynDNSHostname.c[0]) mDNS_AddDynDNSHostName(m, &DynDNSHostname, NULL, NULL);
|
|
||||||
if (DynDNSIP.type) mDNS_SetPrimaryInterfaceInfo(m, &DynDNSIP, NULL, NULL);
|
|
||||||
mDNS_ConfigChanged(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do appropriate things at startup with command line arguments. Calls exit() if unhappy.
|
|
||||||
mDNSlocal void ParseCmdLinArgs(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc > 1)
|
|
||||||
{
|
|
||||||
if (0 == strcmp(argv[1], "-debug")) mDNS_DebugMode = mDNStrue;
|
|
||||||
else printf("Usage: %s [-debug]\n", argv[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mDNS_DebugMode)
|
|
||||||
{
|
|
||||||
int result = daemon(0, 0);
|
|
||||||
if (result != 0) { LogMsg("Could not run as daemon - exiting"); exit(result); }
|
|
||||||
#if __APPLE__
|
|
||||||
LogMsg("The POSIX mdnsd should only be used on OS X for testing - exiting");
|
|
||||||
exit(-1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mDNSlocal void DumpStateLog(mDNS *const m)
|
|
||||||
// Dump a little log of what we've been up to.
|
|
||||||
{
|
|
||||||
LogMsg("---- BEGIN STATE LOG ----");
|
|
||||||
udsserver_info(m);
|
|
||||||
LogMsg("---- END STATE LOG ----");
|
|
||||||
}
|
|
||||||
|
|
||||||
mDNSlocal mStatus MainLoop(mDNS *m) // Loop until we quit.
|
|
||||||
{
|
|
||||||
sigset_t signals;
|
|
||||||
mDNSBool gotData = mDNSfalse;
|
|
||||||
|
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGINT);
|
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGTERM);
|
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGUSR1);
|
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGPIPE);
|
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGHUP) ;
|
|
||||||
|
|
||||||
for (; ;)
|
|
||||||
{
|
|
||||||
// Work out how long we expect to sleep before the next scheduled task
|
|
||||||
struct timeval timeout;
|
|
||||||
mDNSs32 ticks;
|
|
||||||
|
|
||||||
// Only idle if we didn't find any data the last time around
|
|
||||||
if (!gotData)
|
|
||||||
{
|
|
||||||
mDNSs32 nextTimerEvent = mDNS_Execute(m);
|
|
||||||
nextTimerEvent = udsserver_idle(nextTimerEvent);
|
|
||||||
ticks = nextTimerEvent - mDNS_TimeNow(m);
|
|
||||||
if (ticks < 1) ticks = 1;
|
|
||||||
}
|
|
||||||
else // otherwise call EventLoop again with 0 timemout
|
|
||||||
ticks = 0;
|
|
||||||
|
|
||||||
timeout.tv_sec = ticks / mDNSPlatformOneSecond;
|
|
||||||
timeout.tv_usec = (ticks % mDNSPlatformOneSecond) * 1000000 / mDNSPlatformOneSecond;
|
|
||||||
|
|
||||||
(void) mDNSPosixRunEventLoopOnce(m, &timeout, &signals, &gotData);
|
|
||||||
|
|
||||||
if (sigismember(&signals, SIGHUP )) Reconfigure(m);
|
|
||||||
if (sigismember(&signals, SIGUSR1)) DumpStateLog(m);
|
|
||||||
// SIGPIPE happens when we try to write to a dead client; death should be detected soon in request_callback() and cleaned up.
|
|
||||||
if (sigismember(&signals, SIGPIPE)) LogMsg("Received SIGPIPE - ignoring");
|
|
||||||
if (sigismember(&signals, SIGINT) || sigismember(&signals, SIGTERM)) break;
|
|
||||||
}
|
|
||||||
return EINTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
mStatus err;
|
|
||||||
|
|
||||||
ParseCmdLinArgs(argc, argv);
|
|
||||||
|
|
||||||
LogMsg("%s starting", mDNSResponderVersionString);
|
|
||||||
|
|
||||||
err = mDNS_Init(&mDNSStorage, &PlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses,
|
|
||||||
mDNS_StatusCallback, mDNS_Init_NoInitCallbackContext);
|
|
||||||
|
|
||||||
if (mStatus_NoError == err)
|
|
||||||
err = udsserver_init(mDNSNULL, 0);
|
|
||||||
|
|
||||||
Reconfigure(&mDNSStorage);
|
|
||||||
|
|
||||||
// Now that we're finished with anything privileged, switch over to running as "nobody"
|
|
||||||
if (mStatus_NoError == err)
|
|
||||||
{
|
|
||||||
const struct passwd *pw = getpwnam("nobody");
|
|
||||||
if (pw != NULL)
|
|
||||||
setuid(pw->pw_uid);
|
|
||||||
else
|
|
||||||
LogMsg("WARNING: mdnsd continuing as root because user \"nobody\" does not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mStatus_NoError == err)
|
|
||||||
err = MainLoop(&mDNSStorage);
|
|
||||||
|
|
||||||
LogMsg("%s stopping", mDNSResponderVersionString);
|
|
||||||
|
|
||||||
mDNS_Close(&mDNSStorage);
|
|
||||||
|
|
||||||
if (udsserver_exit() < 0)
|
|
||||||
LogMsg("ExitCallback: udsserver_exit failed");
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS > 0
|
|
||||||
printf("mDNSResponder exiting normally with %ld\n", err);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// uds_daemon support ////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
mStatus udsSupportAddFDToEventLoop(int fd, udsEventCallback callback, void *context, void **platform_data)
|
|
||||||
/* Support routine for uds_daemon.c */
|
|
||||||
{
|
|
||||||
// Depends on the fact that udsEventCallback == mDNSPosixEventCallback
|
|
||||||
(void) platform_data;
|
|
||||||
return mDNSPosixAddFDToEventLoop(fd, callback, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
int udsSupportReadFD(dnssd_sock_t fd, char *buf, int len, int flags, void *platform_data)
|
|
||||||
{
|
|
||||||
(void) platform_data;
|
|
||||||
return recv(fd, buf, len, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
mStatus udsSupportRemoveFDFromEventLoop(int fd, void *platform_data) // Note: This also CLOSES the file descriptor
|
|
||||||
{
|
|
||||||
mStatus err = mDNSPosixRemoveFDFromEventLoop(fd);
|
|
||||||
(void) platform_data;
|
|
||||||
close(fd);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
|
|
||||||
{
|
|
||||||
(void)m;
|
|
||||||
(void)delay;
|
|
||||||
// No-op, for now
|
|
||||||
}
|
|
||||||
|
|
||||||
#if _BUILDING_XCODE_PROJECT_
|
|
||||||
// If the process crashes, then this string will be magically included in the automatically-generated crash log
|
|
||||||
const char *__crashreporter_info__ = mDNSResponderVersionString_SCCS + 5;
|
|
||||||
asm(".desc ___crashreporter_info__, 0x10");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For convenience when using the "strings" command, this is the last thing in the file
|
|
||||||
#if mDNSResponderVersion > 1
|
|
||||||
mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder-" STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
|
|
||||||
#elif MDNS_VERSIONSTR_NODTS
|
|
||||||
mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build)";
|
|
||||||
#else
|
|
||||||
mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build) (" __DATE__ " " __TIME__ ")";
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@@ -1,161 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from this
|
|
||||||
* software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dnssd_ipc.h"
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
char *win32_strerror(int inErrorCode)
|
|
||||||
{
|
|
||||||
static char buffer[1024];
|
|
||||||
DWORD n;
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
n = FormatMessageA(
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL,
|
|
||||||
(DWORD) inErrorCode,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
buffer,
|
|
||||||
sizeof(buffer),
|
|
||||||
NULL);
|
|
||||||
if (n > 0)
|
|
||||||
{
|
|
||||||
// Remove any trailing CR's or LF's since some messages have them.
|
|
||||||
while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
|
|
||||||
buffer[--n] = '\0';
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void put_uint32(const uint32_t l, char **ptr)
|
|
||||||
{
|
|
||||||
(*ptr)[0] = (char)((l >> 24) & 0xFF);
|
|
||||||
(*ptr)[1] = (char)((l >> 16) & 0xFF);
|
|
||||||
(*ptr)[2] = (char)((l >> 8) & 0xFF);
|
|
||||||
(*ptr)[3] = (char)((l ) & 0xFF);
|
|
||||||
*ptr += sizeof(uint32_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t get_uint32(const char **ptr, const char *end)
|
|
||||||
{
|
|
||||||
if (!*ptr || *ptr + sizeof(uint32_t) > end)
|
|
||||||
{
|
|
||||||
*ptr = NULL;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint8_t *p = (uint8_t*) *ptr;
|
|
||||||
*ptr += sizeof(uint32_t);
|
|
||||||
return((uint32_t) ((uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void put_uint16(uint16_t s, char **ptr)
|
|
||||||
{
|
|
||||||
(*ptr)[0] = (char)((s >> 8) & 0xFF);
|
|
||||||
(*ptr)[1] = (char)((s ) & 0xFF);
|
|
||||||
*ptr += sizeof(uint16_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t get_uint16(const char **ptr, const char *end)
|
|
||||||
{
|
|
||||||
if (!*ptr || *ptr + sizeof(uint16_t) > end)
|
|
||||||
{
|
|
||||||
*ptr = NULL;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint8_t *p = (uint8_t*) *ptr;
|
|
||||||
*ptr += sizeof(uint16_t);
|
|
||||||
return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int put_string(const char *str, char **ptr)
|
|
||||||
{
|
|
||||||
if (!str) str = "";
|
|
||||||
strcpy(*ptr, str);
|
|
||||||
*ptr += strlen(str) + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_string(const char **ptr, const char *const end, char *buffer, int buflen)
|
|
||||||
{
|
|
||||||
if (!*ptr)
|
|
||||||
{
|
|
||||||
*buffer = 0;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *lim = buffer + buflen; // Calculate limit
|
|
||||||
while (*ptr < end && buffer < lim)
|
|
||||||
{
|
|
||||||
char c = *buffer++ = *(*ptr)++;
|
|
||||||
if (c == 0) return(0); // Success
|
|
||||||
}
|
|
||||||
if (buffer == lim) buffer--;
|
|
||||||
*buffer = 0; // Failed, so terminate string,
|
|
||||||
*ptr = NULL; // clear pointer,
|
|
||||||
return(-1); // and return failure indication
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr)
|
|
||||||
{
|
|
||||||
memcpy(*ptr, rdata, rdlen);
|
|
||||||
*ptr += rdlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *get_rdata(const char **ptr, const char *end, int rdlen)
|
|
||||||
{
|
|
||||||
if (!*ptr || *ptr + rdlen > end)
|
|
||||||
{
|
|
||||||
*ptr = NULL;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char *rd = *ptr;
|
|
||||||
*ptr += rdlen;
|
|
||||||
return rd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConvertHeaderBytes(ipc_msg_hdr *hdr)
|
|
||||||
{
|
|
||||||
hdr->version = htonl(hdr->version);
|
|
||||||
hdr->datalen = htonl(hdr->datalen);
|
|
||||||
hdr->ipc_flags = htonl(hdr->ipc_flags);
|
|
||||||
hdr->op = htonl(hdr->op );
|
|
||||||
hdr->reg_index = htonl(hdr->reg_index);
|
|
||||||
}
|
|
@@ -1,217 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from this
|
|
||||||
* software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DNSSD_IPC_H
|
|
||||||
#define DNSSD_IPC_H
|
|
||||||
|
|
||||||
#include "dns_sd.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Common cross platform services
|
|
||||||
//
|
|
||||||
#if defined(WIN32)
|
|
||||||
# include <winsock2.h>
|
|
||||||
# define dnssd_InvalidSocket INVALID_SOCKET
|
|
||||||
# define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
|
|
||||||
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
|
|
||||||
# define dnssd_EINTR WSAEINTR
|
|
||||||
# define dnssd_ECONNRESET WSAECONNRESET
|
|
||||||
# define dnssd_sock_t SOCKET
|
|
||||||
# define dnssd_socklen_t int
|
|
||||||
# define dnssd_close(sock) closesocket(sock)
|
|
||||||
# define dnssd_errno WSAGetLastError()
|
|
||||||
# define dnssd_strerror(X) win32_strerror(X)
|
|
||||||
# define ssize_t int
|
|
||||||
# define getpid _getpid
|
|
||||||
# define unlink _unlink
|
|
||||||
extern char *win32_strerror(int inErrorCode);
|
|
||||||
#else
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
# include <sys/un.h>
|
|
||||||
# include <string.h>
|
|
||||||
# include <stdio.h>
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <sys/stat.h>
|
|
||||||
# include <sys/socket.h>
|
|
||||||
# include <netinet/in.h>
|
|
||||||
# define dnssd_InvalidSocket -1
|
|
||||||
# define dnssd_SocketValid(s) ((s) >= 0)
|
|
||||||
# define dnssd_EWOULDBLOCK EWOULDBLOCK
|
|
||||||
# define dnssd_EINTR EINTR
|
|
||||||
# define dnssd_ECONNRESET ECONNRESET
|
|
||||||
# define dnssd_EPIPE EPIPE
|
|
||||||
# define dnssd_sock_t int
|
|
||||||
# define dnssd_socklen_t unsigned int
|
|
||||||
# define dnssd_close(sock) close(sock)
|
|
||||||
# define dnssd_errno errno
|
|
||||||
# define dnssd_strerror(X) strerror(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USE_TCP_LOOPBACK)
|
|
||||||
# define AF_DNSSD AF_INET
|
|
||||||
# define MDNS_TCP_SERVERADDR "127.0.0.1"
|
|
||||||
# define MDNS_TCP_SERVERPORT 5354
|
|
||||||
# define LISTENQ 5
|
|
||||||
# define dnssd_sockaddr_t struct sockaddr_in
|
|
||||||
#else
|
|
||||||
# define AF_DNSSD AF_LOCAL
|
|
||||||
# ifndef MDNS_UDS_SERVERPATH
|
|
||||||
# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
|
|
||||||
# endif
|
|
||||||
# define LISTENQ 100
|
|
||||||
// longest legal control path length
|
|
||||||
# define MAX_CTLPATH 256
|
|
||||||
# define dnssd_sockaddr_t struct sockaddr_un
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Compatibility workaround
|
|
||||||
#ifndef AF_LOCAL
|
|
||||||
#define AF_LOCAL AF_UNIX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// General UDS constants
|
|
||||||
#define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record
|
|
||||||
|
|
||||||
// IPC data encoding constants and types
|
|
||||||
#define VERSION 1
|
|
||||||
#define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client
|
|
||||||
|
|
||||||
// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
|
|
||||||
// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
|
|
||||||
// correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code.
|
|
||||||
#ifndef packedstruct
|
|
||||||
#if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
|
|
||||||
#define packedstruct struct __attribute__((__packed__))
|
|
||||||
#define packedunion union __attribute__((__packed__))
|
|
||||||
#else
|
|
||||||
#define packedstruct struct
|
|
||||||
#define packedunion union
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
request_op_none = 0, // No request yet received on this connection
|
|
||||||
connection_request = 1, // connected socket via DNSServiceConnect()
|
|
||||||
reg_record_request, // reg/remove record only valid for connected sockets
|
|
||||||
remove_record_request,
|
|
||||||
enumeration_request,
|
|
||||||
reg_service_request,
|
|
||||||
browse_request,
|
|
||||||
resolve_request,
|
|
||||||
query_request,
|
|
||||||
reconfirm_record_request,
|
|
||||||
add_record_request,
|
|
||||||
update_record_request,
|
|
||||||
setdomain_request, // Up to here is in Tiger and B4W 1.0.3
|
|
||||||
getproperty_request, // New in B4W 1.0.4
|
|
||||||
port_mapping_request, // New in Leopard and B4W 2.0
|
|
||||||
addrinfo_request,
|
|
||||||
send_bpf, // New in SL
|
|
||||||
|
|
||||||
cancel_request = 63
|
|
||||||
} request_op_t;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
enumeration_reply_op = 64,
|
|
||||||
reg_service_reply_op,
|
|
||||||
browse_reply_op,
|
|
||||||
resolve_reply_op,
|
|
||||||
query_reply_op,
|
|
||||||
reg_record_reply_op, // Up to here is in Tiger and B4W 1.0.3
|
|
||||||
getproperty_reply_op, // New in B4W 1.0.4
|
|
||||||
port_mapping_reply_op, // New in Leopard and B4W 2.0
|
|
||||||
addrinfo_reply_op
|
|
||||||
} reply_op_t;
|
|
||||||
|
|
||||||
#if defined(_WIN64)
|
|
||||||
# pragma pack(push,4)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Define context object big enough to hold a 64-bit pointer,
|
|
||||||
// to accomodate 64-bit clients communicating with 32-bit daemon.
|
|
||||||
// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
|
|
||||||
typedef packedunion
|
|
||||||
{
|
|
||||||
void *context;
|
|
||||||
uint32_t u32[2];
|
|
||||||
} client_context_t;
|
|
||||||
|
|
||||||
typedef packedstruct
|
|
||||||
{
|
|
||||||
uint32_t version;
|
|
||||||
uint32_t datalen;
|
|
||||||
uint32_t ipc_flags;
|
|
||||||
uint32_t op; // request_op_t or reply_op_t
|
|
||||||
client_context_t client_context; // context passed from client, returned by server in corresponding reply
|
|
||||||
uint32_t reg_index; // identifier for a record registered via DNSServiceRegisterRecord() on a
|
|
||||||
// socket connected by DNSServiceCreateConnection(). Must be unique in the scope of the connection, such that and
|
|
||||||
// index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord())
|
|
||||||
} ipc_msg_hdr;
|
|
||||||
|
|
||||||
#if defined(_WIN64)
|
|
||||||
# pragma pack(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// routines to write to and extract data from message buffers.
|
|
||||||
// caller responsible for bounds checking.
|
|
||||||
// ptr is the address of the pointer to the start of the field.
|
|
||||||
// it is advanced to point to the next field, or the end of the message
|
|
||||||
|
|
||||||
void put_uint32(const uint32_t l, char **ptr);
|
|
||||||
uint32_t get_uint32(const char **ptr, const char *end);
|
|
||||||
|
|
||||||
void put_uint16(uint16_t s, char **ptr);
|
|
||||||
uint16_t get_uint16(const char **ptr, const char *end);
|
|
||||||
|
|
||||||
#define put_flags put_uint32
|
|
||||||
#define get_flags get_uint32
|
|
||||||
|
|
||||||
#define put_error_code put_uint32
|
|
||||||
#define get_error_code get_uint32
|
|
||||||
|
|
||||||
int put_string(const char *str, char **ptr);
|
|
||||||
int get_string(const char **ptr, const char *const end, char *buffer, int buflen);
|
|
||||||
|
|
||||||
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
|
|
||||||
const char *get_rdata(const char **ptr, const char *end, int rdlen); // return value is rdata pointed to by *ptr -
|
|
||||||
// rdata is not copied from buffer.
|
|
||||||
|
|
||||||
void ConvertHeaderBytes(ipc_msg_hdr *hdr);
|
|
||||||
|
|
||||||
struct CompileTimeAssertionChecks_dnssd_ipc
|
|
||||||
{
|
|
||||||
// Check that the compiler generated our on-the-wire packet format structure definitions
|
|
||||||
// properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
|
|
||||||
char assert0[(sizeof(client_context_t) == 8) ? 1 : -1];
|
|
||||||
char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DNSSD_IPC_H
|
|
11521
src/tools/mdnssd/mDNS.c
11521
src/tools/mdnssd/mDNS.c
File diff suppressed because it is too large
Load Diff
@@ -1,93 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
|
|
||||||
File: mDNSDebug.c
|
|
||||||
|
|
||||||
Contains: Implementation of debugging utilities. Requires a POSIX environment.
|
|
||||||
|
|
||||||
Version: 1.0
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mDNSDebug.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#if defined(WIN32) || defined(EFI32) || defined(EFI64) || defined(EFIX64)
|
|
||||||
// Need to add Windows/EFI syslog support here
|
|
||||||
#define LOG_PID 0x01
|
|
||||||
#define LOG_CONS 0x02
|
|
||||||
#define LOG_PERROR 0x20
|
|
||||||
#else
|
|
||||||
#include <syslog.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
|
||||||
|
|
||||||
mDNSexport int mDNS_LoggingEnabled = 0;
|
|
||||||
mDNSexport int mDNS_PacketLoggingEnabled = 0;
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS
|
|
||||||
mDNSexport int mDNS_DebugMode = mDNStrue;
|
|
||||||
#else
|
|
||||||
mDNSexport int mDNS_DebugMode = mDNSfalse;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Note, this uses mDNS_vsnprintf instead of standard "vsnprintf", because mDNS_vsnprintf knows
|
|
||||||
// how to print special data types like IP addresses and length-prefixed domain names
|
|
||||||
#if MDNS_DEBUGMSGS > 1
|
|
||||||
mDNSexport void verbosedebugf_(const char *format, ...)
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
va_list ptr;
|
|
||||||
va_start(ptr,format);
|
|
||||||
buffer[mDNS_vsnprintf(buffer, sizeof(buffer), format, ptr)] = 0;
|
|
||||||
va_end(ptr);
|
|
||||||
mDNSPlatformWriteDebugMsg(buffer);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Log message with default "mDNSResponder" ident string at the start
|
|
||||||
mDNSlocal void LogMsgWithLevelv(mDNSLogLevel_t logLevel, const char *format, va_list ptr)
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
|
|
||||||
mDNSPlatformWriteLogMsg(ProgramName, buffer, logLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOG_HELPER_BODY(L) \
|
|
||||||
{ \
|
|
||||||
va_list ptr; \
|
|
||||||
va_start(ptr,format); \
|
|
||||||
LogMsgWithLevelv(L, format, ptr); \
|
|
||||||
va_end(ptr); \
|
|
||||||
}
|
|
||||||
|
|
||||||
// see mDNSDebug.h
|
|
||||||
#if !MDNS_HAS_VA_ARG_MACROS
|
|
||||||
void LogMsg_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_MSG)
|
|
||||||
void LogOperation_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_OPERATION)
|
|
||||||
void LogSPS_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_SPS)
|
|
||||||
void LogInfo_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_INFO)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS
|
|
||||||
void debugf_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_DEBUG)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Log message with default "mDNSResponder" ident string at the start
|
|
||||||
mDNSexport void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...)
|
|
||||||
LOG_HELPER_BODY(logLevel)
|
|
@@ -1,164 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __mDNSDebug_h
|
|
||||||
#define __mDNSDebug_h
|
|
||||||
|
|
||||||
// Set MDNS_DEBUGMSGS to 0 to optimize debugf() calls out of the compiled code
|
|
||||||
// Set MDNS_DEBUGMSGS to 1 to generate normal debugging messages
|
|
||||||
// Set MDNS_DEBUGMSGS to 2 to generate verbose debugging messages
|
|
||||||
// MDNS_DEBUGMSGS is normally set in the project options (or makefile) but can also be set here if desired
|
|
||||||
// (If you edit the file here to turn on MDNS_DEBUGMSGS while you're debugging some code, be careful
|
|
||||||
// not to accidentally check-in that change by mistake when you check in your other changes.)
|
|
||||||
|
|
||||||
//#undef MDNS_DEBUGMSGS
|
|
||||||
//#define MDNS_DEBUGMSGS 2
|
|
||||||
|
|
||||||
// Set MDNS_CHECK_PRINTF_STYLE_FUNCTIONS to 1 to enable extra GCC compiler warnings
|
|
||||||
// Note: You don't normally want to do this, because it generates a bunch of
|
|
||||||
// spurious warnings for the following custom extensions implemented by mDNS_vsnprintf:
|
|
||||||
// warning: `#' flag used with `%s' printf format (for %#s -- pascal string format)
|
|
||||||
// warning: repeated `#' flag in format (for %##s -- DNS name string format)
|
|
||||||
// warning: double format, pointer arg (arg 2) (for %.4a, %.16a, %#a -- IP address formats)
|
|
||||||
#define MDNS_CHECK_PRINTF_STYLE_FUNCTIONS 0
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
MDNS_LOG_MSG,
|
|
||||||
MDNS_LOG_OPERATION,
|
|
||||||
MDNS_LOG_SPS,
|
|
||||||
MDNS_LOG_INFO,
|
|
||||||
MDNS_LOG_DEBUG,
|
|
||||||
} mDNSLogLevel_t;
|
|
||||||
|
|
||||||
// Set this symbol to 1 to answer remote queries for our Address, reverse mapping PTR, and HINFO records
|
|
||||||
#define ANSWER_REMOTE_HOSTNAME_QUERIES 0
|
|
||||||
|
|
||||||
// Set this symbol to 1 to do extra debug checks on malloc() and free()
|
|
||||||
// Set this symbol to 2 to write a log message for every malloc() and free()
|
|
||||||
//#define MACOSX_MDNS_MALLOC_DEBUGGING 1
|
|
||||||
|
|
||||||
//#define ForceAlerts 1
|
|
||||||
//#define LogTimeStamps 1
|
|
||||||
|
|
||||||
// Developer-settings section ends here
|
|
||||||
|
|
||||||
#if MDNS_CHECK_PRINTF_STYLE_FUNCTIONS
|
|
||||||
#define IS_A_PRINTF_STYLE_FUNCTION(F,A) __attribute__ ((format(printf,F,A)))
|
|
||||||
#else
|
|
||||||
#define IS_A_PRINTF_STYLE_FUNCTION(F,A)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Variable argument macro support. Use ANSI C99 __VA_ARGS__ where possible. Otherwise, use the next best thing.
|
|
||||||
|
|
||||||
#if (defined(__GNUC__))
|
|
||||||
#if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
|
|
||||||
#define MDNS_C99_VA_ARGS 1
|
|
||||||
#define MDNS_GNU_VA_ARGS 0
|
|
||||||
#else
|
|
||||||
#define MDNS_C99_VA_ARGS 0
|
|
||||||
#define MDNS_GNU_VA_ARGS 1
|
|
||||||
#endif
|
|
||||||
#define MDNS_HAS_VA_ARG_MACROS 1
|
|
||||||
#elif (_MSC_VER >= 1400) // Visual Studio 2005 and later
|
|
||||||
#define MDNS_C99_VA_ARGS 1
|
|
||||||
#define MDNS_GNU_VA_ARGS 0
|
|
||||||
#define MDNS_HAS_VA_ARG_MACROS 1
|
|
||||||
#elif (defined(__MWERKS__))
|
|
||||||
#define MDNS_C99_VA_ARGS 1
|
|
||||||
#define MDNS_GNU_VA_ARGS 0
|
|
||||||
#define MDNS_HAS_VA_ARG_MACROS 1
|
|
||||||
#else
|
|
||||||
#define MDNS_C99_VA_ARGS 0
|
|
||||||
#define MDNS_GNU_VA_ARGS 0
|
|
||||||
#define MDNS_HAS_VA_ARG_MACROS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MDNS_HAS_VA_ARG_MACROS)
|
|
||||||
#if (MDNS_C99_VA_ARGS)
|
|
||||||
#define debug_noop( ... ) ((void)0)
|
|
||||||
#define LogMsg( ... ) LogMsgWithLevel(MDNS_LOG_MSG, __VA_ARGS__)
|
|
||||||
#define LogOperation( ... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_OPERATION, __VA_ARGS__); } while (0)
|
|
||||||
#define LogSPS( ... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_SPS, __VA_ARGS__); } while (0)
|
|
||||||
#define LogInfo( ... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_INFO, __VA_ARGS__); } while (0)
|
|
||||||
#elif (MDNS_GNU_VA_ARGS)
|
|
||||||
#define debug_noop( ARGS... ) ((void)0)
|
|
||||||
#define LogMsg( ARGS... ) LogMsgWithLevel(MDNS_LOG_MSG, ARGS)
|
|
||||||
#define LogOperation( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_OPERATION, ARGS); } while (0)
|
|
||||||
#define LogSPS( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_SPS, ARGS); } while (0)
|
|
||||||
#define LogInfo( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_INFO, ARGS); } while (0)
|
|
||||||
#else
|
|
||||||
#error Unknown variadic macros
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
// If your platform does not support variadic macros, you need to define the following variadic functions.
|
|
||||||
// See mDNSShared/mDNSDebug.c for sample implementation
|
|
||||||
#define debug_noop 1 ? (void)0 : (void)
|
|
||||||
#define LogMsg LogMsg_
|
|
||||||
#define LogOperation (mDNS_LoggingEnabled == 0) ? ((void)0) : LogOperation_
|
|
||||||
#define LogSPS (mDNS_LoggingEnabled == 0) ? ((void)0) : LogSPS_
|
|
||||||
#define LogInfo (mDNS_LoggingEnabled == 0) ? ((void)0) : LogInfo_
|
|
||||||
extern void LogMsg_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
extern void LogOperation_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
extern void LogSPS_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
extern void LogInfo_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS
|
|
||||||
#define debugf debugf_
|
|
||||||
extern void debugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
#else
|
|
||||||
#define debugf debug_noop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS > 1
|
|
||||||
#define verbosedebugf verbosedebugf_
|
|
||||||
extern void verbosedebugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
#else
|
|
||||||
#define verbosedebugf debug_noop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int mDNS_LoggingEnabled;
|
|
||||||
extern int mDNS_PacketLoggingEnabled;
|
|
||||||
extern int mDNS_DebugMode; // If non-zero, LogMsg() writes to stderr instead of syslog
|
|
||||||
extern const char ProgramName[];
|
|
||||||
|
|
||||||
extern void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(2,3);
|
|
||||||
// LogMsgNoIdent needs to be fixed so that it logs without the ident prefix like it used to
|
|
||||||
// (or completely overhauled to use the new "log to a separate file" facility)
|
|
||||||
#define LogMsgNoIdent LogMsg
|
|
||||||
|
|
||||||
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
|
|
||||||
extern void *mallocL(char *msg, unsigned int size);
|
|
||||||
extern void freeL(char *msg, void *x);
|
|
||||||
extern void LogMemCorruption(const char *format, ...);
|
|
||||||
extern void uds_validatelists(void);
|
|
||||||
extern void udns_validatelists(void *const v);
|
|
||||||
#else
|
|
||||||
#define mallocL(X,Y) malloc(Y)
|
|
||||||
#define freeL(X,Y) free(Y)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,85 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __mDNSPlatformPosix_h
|
|
||||||
#define __mDNSPlatformPosix_h
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PosixNetworkInterface is a record extension of the core NetworkInterfaceInfo
|
|
||||||
// type that supports extra fields needed by the Posix platform.
|
|
||||||
//
|
|
||||||
// IMPORTANT: coreIntf must be the first field in the structure because
|
|
||||||
// we cast between pointers to the two different types regularly.
|
|
||||||
|
|
||||||
typedef struct PosixNetworkInterface PosixNetworkInterface;
|
|
||||||
|
|
||||||
struct PosixNetworkInterface
|
|
||||||
{
|
|
||||||
NetworkInterfaceInfo coreIntf;
|
|
||||||
const char * intfName;
|
|
||||||
PosixNetworkInterface * aliasIntf;
|
|
||||||
int index;
|
|
||||||
int multicastSocket4;
|
|
||||||
#if HAVE_IPV6
|
|
||||||
int multicastSocket6;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is a global because debugf_() needs to be able to check its value
|
|
||||||
extern int gMDNSPlatformPosixVerboseLevel;
|
|
||||||
|
|
||||||
struct mDNS_PlatformSupport_struct
|
|
||||||
{
|
|
||||||
int unicastSocket4;
|
|
||||||
#if HAVE_IPV6
|
|
||||||
int unicastSocket6;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#define uDNS_SERVERS_FILE "/etc/resolv.conf"
|
|
||||||
extern int ParseDNSServers(mDNS *m, const char *filePath);
|
|
||||||
extern mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m);
|
|
||||||
// See comment in implementation.
|
|
||||||
|
|
||||||
// Call mDNSPosixGetFDSet before calling select(), to update the parameters
|
|
||||||
// as may be necessary to meet the needs of the mDNSCore code.
|
|
||||||
// The timeout pointer MUST NOT be NULL.
|
|
||||||
// Set timeout->tv_sec to 0x3FFFFFFF if you want to have effectively no timeout
|
|
||||||
// After calling mDNSPosixGetFDSet(), call select(nfds, &readfds, NULL, NULL, &timeout); as usual
|
|
||||||
// After select() returns, call mDNSPosixProcessFDSet() to let mDNSCore do its work
|
|
||||||
extern void mDNSPosixGetFDSet(mDNS *m, int *nfds, fd_set *readfds, struct timeval *timeout);
|
|
||||||
extern void mDNSPosixProcessFDSet(mDNS *const m, fd_set *readfds);
|
|
||||||
|
|
||||||
typedef void (*mDNSPosixEventCallback)(int fd, short filter, void *context);
|
|
||||||
|
|
||||||
extern mStatus mDNSPosixAddFDToEventLoop( int fd, mDNSPosixEventCallback callback, void *context);
|
|
||||||
extern mStatus mDNSPosixRemoveFDFromEventLoop( int fd);
|
|
||||||
extern mStatus mDNSPosixListenForSignalInEventLoop( int signum);
|
|
||||||
extern mStatus mDNSPosixIgnoreSignalInEventLoop( int signum);
|
|
||||||
extern mStatus mDNSPosixRunEventLoopOnce( mDNS *m, const struct timeval *pTimeout, sigset_t *pSignalsReceived, mDNSBool *pDataDispatched);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,719 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mDNSUNP.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* Some weird platforms derived from 4.4BSD Lite (e.g. EFI) need the ALIGN(P)
|
|
||||||
macro, usually defined in <sys/param.h> or someplace like that, to make sure the
|
|
||||||
CMSG_NXTHDR macro is well-formed. On such platforms, the symbol NEED_ALIGN_MACRO
|
|
||||||
should be set to the name of the header to include to get the ALIGN(P) macro.
|
|
||||||
*/
|
|
||||||
#ifdef NEED_ALIGN_MACRO
|
|
||||||
#include NEED_ALIGN_MACRO
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Solaris defined SIOCGIFCONF etc in <sys/sockio.h> but
|
|
||||||
other platforms don't even have that include file. So,
|
|
||||||
if we haven't yet got a definition, let's try to find
|
|
||||||
<sys/sockio.h>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SIOCGIFCONF
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* sockaddr_dl is only referenced if we're using IP_RECVIF,
|
|
||||||
so only include the header in that case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef IP_RECVIF
|
|
||||||
#include <net/if_dl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6 && !HAVE_LINUX
|
|
||||||
#include <net/if_var.h>
|
|
||||||
#include <netinet/in_var.h>
|
|
||||||
// Note: netinet/in_var.h implicitly includes netinet6/in6_var.h for us
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
/* Converts a prefix length to IPv6 network mask */
|
|
||||||
void plen_to_mask(int plen, char *addr) {
|
|
||||||
int i;
|
|
||||||
int colons=7; /* Number of colons in IPv6 address */
|
|
||||||
int bits_in_block=16; /* Bits per IPv6 block */
|
|
||||||
for(i=0;i<=colons;i++) {
|
|
||||||
int block, ones=0xffff, ones_in_block;
|
|
||||||
if (plen>bits_in_block) ones_in_block=bits_in_block;
|
|
||||||
else ones_in_block=plen;
|
|
||||||
block = ones & (ones << (bits_in_block-ones_in_block));
|
|
||||||
i==0 ? sprintf(addr, "%x", block) : sprintf(addr, "%s:%x", addr, block);
|
|
||||||
plen -= ones_in_block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Gets IPv6 interface information from the /proc filesystem in linux*/
|
|
||||||
struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
|
|
||||||
{
|
|
||||||
struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
|
|
||||||
FILE *fp;
|
|
||||||
char addr[8][5];
|
|
||||||
int flags, myflags, index, plen, scope;
|
|
||||||
char ifname[9], lastname[IFNAMSIZ];
|
|
||||||
char addr6[32+7+1]; /* don't forget the seven ':' */
|
|
||||||
struct addrinfo hints, *res0;
|
|
||||||
struct sockaddr_in6 *sin6;
|
|
||||||
struct in6_addr *addrptr;
|
|
||||||
int err;
|
|
||||||
int sockfd = -1;
|
|
||||||
struct ifreq ifr;
|
|
||||||
|
|
||||||
res0=NULL;
|
|
||||||
ifihead = NULL;
|
|
||||||
ifipnext = &ifihead;
|
|
||||||
lastname[0] = 0;
|
|
||||||
|
|
||||||
if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
|
|
||||||
sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
||||||
if (sockfd < 0) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
while (fscanf(fp,
|
|
||||||
"%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
|
|
||||||
addr[0],addr[1],addr[2],addr[3],
|
|
||||||
addr[4],addr[5],addr[6],addr[7],
|
|
||||||
&index, &plen, &scope, &flags, ifname) != EOF) {
|
|
||||||
|
|
||||||
myflags = 0;
|
|
||||||
if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
|
|
||||||
if (doaliases == 0)
|
|
||||||
continue; /* already processed this interface */
|
|
||||||
myflags = IFI_ALIAS;
|
|
||||||
}
|
|
||||||
memcpy(lastname, ifname, IFNAMSIZ);
|
|
||||||
ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
|
|
||||||
if (ifi == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
|
|
||||||
ifipold = *ifipnext; /* need this later */
|
|
||||||
ifiptr = ifipnext;
|
|
||||||
*ifipnext = ifi; /* prev points to this new one */
|
|
||||||
ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
|
|
||||||
|
|
||||||
sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
|
|
||||||
addr[0],addr[1],addr[2],addr[3],
|
|
||||||
addr[4],addr[5],addr[6],addr[7]);
|
|
||||||
|
|
||||||
/* Add address of the interface */
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = AF_INET6;
|
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
|
||||||
err = getaddrinfo(addr6, NULL, &hints, &res0);
|
|
||||||
if (err) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
|
|
||||||
if (ifi->ifi_addr == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6));
|
|
||||||
|
|
||||||
/* Add netmask of the interface */
|
|
||||||
char ipv6addr[INET6_ADDRSTRLEN];
|
|
||||||
plen_to_mask(plen, ipv6addr);
|
|
||||||
ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
|
|
||||||
if (ifi->ifi_addr == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
sin6=calloc(1, sizeof(struct sockaddr_in6));
|
|
||||||
addrptr=calloc(1, sizeof(struct in6_addr));
|
|
||||||
inet_pton(family, ipv6addr, addrptr);
|
|
||||||
sin6->sin6_family=family;
|
|
||||||
sin6->sin6_addr=*addrptr;
|
|
||||||
sin6->sin6_scope_id=scope;
|
|
||||||
memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
|
|
||||||
free(sin6);
|
|
||||||
|
|
||||||
|
|
||||||
/* Add interface name */
|
|
||||||
memcpy(ifi->ifi_name, ifname, IFI_NAME);
|
|
||||||
|
|
||||||
/* Add interface index */
|
|
||||||
ifi->ifi_index = index;
|
|
||||||
|
|
||||||
/* Add interface flags*/
|
|
||||||
memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
|
||||||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
|
||||||
if (errno == EADDRNOTAVAIL) {
|
|
||||||
/*
|
|
||||||
* If the main interface is configured with no IP address but
|
|
||||||
* an alias interface exists with an IP address, you get
|
|
||||||
* EADDRNOTAVAIL for the main interface
|
|
||||||
*/
|
|
||||||
free(ifi->ifi_addr);
|
|
||||||
free(ifi);
|
|
||||||
ifipnext = ifiptr;
|
|
||||||
*ifipnext = ifipold;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ifi->ifi_flags = ifr.ifr_flags;
|
|
||||||
freeaddrinfo(res0);
|
|
||||||
res0=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
gotError:
|
|
||||||
if (ifihead != NULL) {
|
|
||||||
free_ifi_info(ifihead);
|
|
||||||
ifihead = NULL;
|
|
||||||
}
|
|
||||||
if (res0 != NULL) {
|
|
||||||
freeaddrinfo(res0);
|
|
||||||
res0=NULL;
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
if (sockfd != -1) {
|
|
||||||
assert(close(sockfd) == 0);
|
|
||||||
}
|
|
||||||
return(ifihead); /* pointer to first structure in linked list */
|
|
||||||
}
|
|
||||||
#endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
|
||||||
|
|
||||||
struct ifi_info *get_ifi_info(int family, int doaliases)
|
|
||||||
{
|
|
||||||
int junk;
|
|
||||||
struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
|
|
||||||
int sockfd, sockf6, len, lastlen, flags, myflags;
|
|
||||||
#ifdef NOT_HAVE_IF_NAMETOINDEX
|
|
||||||
int index = 200;
|
|
||||||
#endif
|
|
||||||
char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
|
|
||||||
struct ifconf ifc;
|
|
||||||
struct ifreq *ifr, ifrcopy;
|
|
||||||
struct sockaddr_in *sinptr;
|
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6
|
|
||||||
struct sockaddr_in6 *sinptr6;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
|
||||||
if (family == AF_INET6) return get_ifi_info_linuxv6(family, doaliases);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sockfd = -1;
|
|
||||||
sockf6 = -1;
|
|
||||||
buf = NULL;
|
|
||||||
ifihead = NULL;
|
|
||||||
|
|
||||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (sockfd < 0) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastlen = 0;
|
|
||||||
len = 100 * sizeof(struct ifreq); /* initial buffer size guess */
|
|
||||||
for ( ; ; ) {
|
|
||||||
buf = (char*)malloc(len);
|
|
||||||
if (buf == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
ifc.ifc_len = len;
|
|
||||||
ifc.ifc_buf = buf;
|
|
||||||
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
|
|
||||||
if (errno != EINVAL || lastlen != 0) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ifc.ifc_len == lastlen)
|
|
||||||
break; /* success, len has not changed */
|
|
||||||
lastlen = ifc.ifc_len;
|
|
||||||
}
|
|
||||||
len += 10 * sizeof(struct ifreq); /* increment */
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
ifihead = NULL;
|
|
||||||
ifipnext = &ifihead;
|
|
||||||
lastname[0] = 0;
|
|
||||||
/* end get_ifi_info1 */
|
|
||||||
|
|
||||||
/* include get_ifi_info2 */
|
|
||||||
for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
|
|
||||||
ifr = (struct ifreq *) ptr;
|
|
||||||
|
|
||||||
/* Advance to next one in buffer */
|
|
||||||
if (sizeof(struct ifreq) > sizeof(ifr->ifr_name) + GET_SA_LEN(ifr->ifr_addr))
|
|
||||||
ptr += sizeof(struct ifreq);
|
|
||||||
else
|
|
||||||
ptr += sizeof(ifr->ifr_name) + GET_SA_LEN(ifr->ifr_addr);
|
|
||||||
|
|
||||||
// fprintf(stderr, "intf %p name=%s AF=%d\n", index, ifr->ifr_name, ifr->ifr_addr.sa_family);
|
|
||||||
|
|
||||||
if (ifr->ifr_addr.sa_family != family)
|
|
||||||
continue; /* ignore if not desired address family */
|
|
||||||
|
|
||||||
myflags = 0;
|
|
||||||
if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL)
|
|
||||||
*cptr = 0; /* replace colon will null */
|
|
||||||
if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
|
|
||||||
if (doaliases == 0)
|
|
||||||
continue; /* already processed this interface */
|
|
||||||
myflags = IFI_ALIAS;
|
|
||||||
}
|
|
||||||
memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
|
|
||||||
|
|
||||||
ifrcopy = *ifr;
|
|
||||||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
|
|
||||||
flags = ifrcopy.ifr_flags;
|
|
||||||
if ((flags & IFF_UP) == 0)
|
|
||||||
continue; /* ignore if interface not up */
|
|
||||||
|
|
||||||
ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
|
|
||||||
if (ifi == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
ifipold = *ifipnext; /* need this later */
|
|
||||||
ifiptr = ifipnext;
|
|
||||||
*ifipnext = ifi; /* prev points to this new one */
|
|
||||||
ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
|
|
||||||
|
|
||||||
ifi->ifi_flags = flags; /* IFF_xxx values */
|
|
||||||
ifi->ifi_myflags = myflags; /* IFI_xxx values */
|
|
||||||
#ifndef NOT_HAVE_IF_NAMETOINDEX
|
|
||||||
ifi->ifi_index = if_nametoindex(ifr->ifr_name);
|
|
||||||
#else
|
|
||||||
ifrcopy = *ifr;
|
|
||||||
#ifdef SIOCGIFINDEX
|
|
||||||
if ( 0 >= ioctl(sockfd, SIOCGIFINDEX, &ifrcopy))
|
|
||||||
ifi->ifi_index = ifrcopy.ifr_index;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
ifi->ifi_index = index++; /* SIOCGIFINDEX is broken on Solaris 2.5ish, so fake it */
|
|
||||||
#endif
|
|
||||||
memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
|
|
||||||
ifi->ifi_name[IFI_NAME-1] = '\0';
|
|
||||||
/* end get_ifi_info2 */
|
|
||||||
/* include get_ifi_info3 */
|
|
||||||
switch (ifr->ifr_addr.sa_family) {
|
|
||||||
case AF_INET:
|
|
||||||
sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
|
|
||||||
if (ifi->ifi_addr == NULL) {
|
|
||||||
ifi->ifi_addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
|
||||||
if (ifi->ifi_addr == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
|
|
||||||
|
|
||||||
#ifdef SIOCGIFNETMASK
|
|
||||||
if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) {
|
|
||||||
if (errno == EADDRNOTAVAIL) {
|
|
||||||
/*
|
|
||||||
* If the main interface is configured with no IP address but
|
|
||||||
* an alias interface exists with an IP address, you get
|
|
||||||
* EADDRNOTAVAIL for the main interface
|
|
||||||
*/
|
|
||||||
free(ifi->ifi_addr);
|
|
||||||
free(ifi);
|
|
||||||
ifipnext = ifiptr;
|
|
||||||
*ifipnext = ifipold;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
|
||||||
if (ifi->ifi_netmask == NULL) goto gotError;
|
|
||||||
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_addr;
|
|
||||||
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
|
||||||
sinptr->sin_len = sizeof(struct sockaddr_in);
|
|
||||||
#endif
|
|
||||||
sinptr->sin_family = AF_INET;
|
|
||||||
memcpy(ifi->ifi_netmask, sinptr, sizeof(struct sockaddr_in));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SIOCGIFBRDADDR
|
|
||||||
if (flags & IFF_BROADCAST) {
|
|
||||||
if (ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy) < 0) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;
|
|
||||||
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
|
||||||
sinptr->sin_len = sizeof( struct sockaddr_in );
|
|
||||||
#endif
|
|
||||||
sinptr->sin_family = AF_INET;
|
|
||||||
ifi->ifi_brdaddr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
|
||||||
if (ifi->ifi_brdaddr == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SIOCGIFDSTADDR
|
|
||||||
if (flags & IFF_POINTOPOINT) {
|
|
||||||
if (ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy) < 0) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;
|
|
||||||
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
|
||||||
sinptr->sin_len = sizeof( struct sockaddr_in );
|
|
||||||
#endif
|
|
||||||
sinptr->sin_family = AF_INET;
|
|
||||||
ifi->ifi_dstaddr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
|
||||||
if (ifi->ifi_dstaddr == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6
|
|
||||||
case AF_INET6:
|
|
||||||
sinptr6 = (struct sockaddr_in6 *) &ifr->ifr_addr;
|
|
||||||
if (ifi->ifi_addr == NULL) {
|
|
||||||
ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
|
|
||||||
if (ifi->ifi_addr == NULL) {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some platforms (*BSD) inject the prefix in IPv6LL addresses */
|
|
||||||
/* We need to strip that out */
|
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&sinptr6->sin6_addr))
|
|
||||||
sinptr6->sin6_addr.s6_addr[2] = sinptr6->sin6_addr.s6_addr[3] = 0;
|
|
||||||
memcpy(ifi->ifi_addr, sinptr6, sizeof(struct sockaddr_in6));
|
|
||||||
|
|
||||||
#ifdef SIOCGIFNETMASK_IN6
|
|
||||||
{
|
|
||||||
struct in6_ifreq ifr6;
|
|
||||||
if (sockf6 == -1)
|
|
||||||
sockf6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
||||||
memset(&ifr6, 0, sizeof(ifr6));
|
|
||||||
memcpy(&ifr6.ifr_name, &ifr->ifr_name, sizeof(ifr6.ifr_name ));
|
|
||||||
memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, sizeof(ifr6.ifr_ifru.ifru_addr));
|
|
||||||
if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) {
|
|
||||||
if (errno == EADDRNOTAVAIL) {
|
|
||||||
/*
|
|
||||||
* If the main interface is configured with no IP address but
|
|
||||||
* an alias interface exists with an IP address, you get
|
|
||||||
* EADDRNOTAVAIL for the main interface
|
|
||||||
*/
|
|
||||||
free(ifi->ifi_addr);
|
|
||||||
free(ifi);
|
|
||||||
ifipnext = ifiptr;
|
|
||||||
*ifipnext = ifipold;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
goto gotError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in6));
|
|
||||||
if (ifi->ifi_netmask == NULL) goto gotError;
|
|
||||||
sinptr6 = (struct sockaddr_in6 *) &ifr6.ifr_ifru.ifru_addr;
|
|
||||||
memcpy(ifi->ifi_netmask, sinptr6, sizeof(struct sockaddr_in6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
gotError:
|
|
||||||
if (ifihead != NULL) {
|
|
||||||
free_ifi_info(ifihead);
|
|
||||||
ifihead = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (buf != NULL) {
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
if (sockfd != -1) {
|
|
||||||
junk = close(sockfd);
|
|
||||||
assert(junk == 0);
|
|
||||||
}
|
|
||||||
if (sockf6 != -1) {
|
|
||||||
junk = close(sockf6);
|
|
||||||
assert(junk == 0);
|
|
||||||
}
|
|
||||||
return(ifihead); /* pointer to first structure in linked list */
|
|
||||||
}
|
|
||||||
/* end get_ifi_info3 */
|
|
||||||
|
|
||||||
/* include free_ifi_info */
|
|
||||||
void
|
|
||||||
free_ifi_info(struct ifi_info *ifihead)
|
|
||||||
{
|
|
||||||
struct ifi_info *ifi, *ifinext;
|
|
||||||
|
|
||||||
for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
|
|
||||||
if (ifi->ifi_addr != NULL)
|
|
||||||
free(ifi->ifi_addr);
|
|
||||||
if (ifi->ifi_netmask != NULL)
|
|
||||||
free(ifi->ifi_netmask);
|
|
||||||
if (ifi->ifi_brdaddr != NULL)
|
|
||||||
free(ifi->ifi_brdaddr);
|
|
||||||
if (ifi->ifi_dstaddr != NULL)
|
|
||||||
free(ifi->ifi_dstaddr);
|
|
||||||
ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */
|
|
||||||
free(ifi); /* the ifi_info{} itself */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* end free_ifi_info */
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
|
||||||
struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp, u_char *ttl)
|
|
||||||
{
|
|
||||||
struct msghdr msg;
|
|
||||||
struct iovec iov[1];
|
|
||||||
ssize_t n;
|
|
||||||
|
|
||||||
#ifdef CMSG_FIRSTHDR
|
|
||||||
struct cmsghdr *cmptr;
|
|
||||||
union {
|
|
||||||
struct cmsghdr cm;
|
|
||||||
char control[1024];
|
|
||||||
} control_un;
|
|
||||||
|
|
||||||
*ttl = 255; // If kernel fails to provide TTL data then assume the TTL was 255 as it should be
|
|
||||||
|
|
||||||
msg.msg_control = control_un.control;
|
|
||||||
msg.msg_controllen = sizeof(control_un.control);
|
|
||||||
msg.msg_flags = 0;
|
|
||||||
#else
|
|
||||||
memset(&msg, 0, sizeof(msg)); /* make certain msg_accrightslen = 0 */
|
|
||||||
#endif /* CMSG_FIRSTHDR */
|
|
||||||
|
|
||||||
msg.msg_name = (char *) sa;
|
|
||||||
msg.msg_namelen = *salenptr;
|
|
||||||
iov[0].iov_base = (char *)ptr;
|
|
||||||
iov[0].iov_len = nbytes;
|
|
||||||
msg.msg_iov = iov;
|
|
||||||
msg.msg_iovlen = 1;
|
|
||||||
|
|
||||||
if ( (n = recvmsg(fd, &msg, *flagsp)) < 0)
|
|
||||||
return(n);
|
|
||||||
|
|
||||||
*salenptr = msg.msg_namelen; /* pass back results */
|
|
||||||
if (pktp) {
|
|
||||||
/* 0.0.0.0, i/f = -1 */
|
|
||||||
/* We set the interface to -1 so that the caller can
|
|
||||||
tell whether we returned a meaningful value or
|
|
||||||
just some default. Previously this code just
|
|
||||||
set the value to 0, but I'm concerned that 0
|
|
||||||
might be a valid interface value.
|
|
||||||
*/
|
|
||||||
memset(pktp, 0, sizeof(struct my_in_pktinfo));
|
|
||||||
pktp->ipi_ifindex = -1;
|
|
||||||
}
|
|
||||||
/* end recvfrom_flags1 */
|
|
||||||
|
|
||||||
/* include recvfrom_flags2 */
|
|
||||||
#ifndef CMSG_FIRSTHDR
|
|
||||||
#warning CMSG_FIRSTHDR not defined. Will not be able to determine destination address, received interface, etc.
|
|
||||||
*flagsp = 0; /* pass back results */
|
|
||||||
return(n);
|
|
||||||
#else
|
|
||||||
|
|
||||||
*flagsp = msg.msg_flags; /* pass back results */
|
|
||||||
if (msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr) ||
|
|
||||||
(msg.msg_flags & MSG_CTRUNC) || pktp == NULL)
|
|
||||||
return(n);
|
|
||||||
|
|
||||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
|
|
||||||
cmptr = CMSG_NXTHDR(&msg, cmptr)) {
|
|
||||||
|
|
||||||
#ifdef IP_PKTINFO
|
|
||||||
#if in_pktinfo_definition_is_missing
|
|
||||||
struct in_pktinfo
|
|
||||||
{
|
|
||||||
int ipi_ifindex;
|
|
||||||
struct in_addr ipi_spec_dst;
|
|
||||||
struct in_addr ipi_addr;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
|
||||||
cmptr->cmsg_type == IP_PKTINFO) {
|
|
||||||
struct in_pktinfo *tmp;
|
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
|
|
||||||
|
|
||||||
tmp = (struct in_pktinfo *) CMSG_DATA(cmptr);
|
|
||||||
sin->sin_family = AF_INET;
|
|
||||||
sin->sin_addr = tmp->ipi_addr;
|
|
||||||
sin->sin_port = 0;
|
|
||||||
pktp->ipi_ifindex = tmp->ipi_ifindex;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IP_RECVDSTADDR
|
|
||||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
|
||||||
cmptr->cmsg_type == IP_RECVDSTADDR) {
|
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
|
|
||||||
|
|
||||||
sin->sin_family = AF_INET;
|
|
||||||
sin->sin_addr = *(struct in_addr*)CMSG_DATA(cmptr);
|
|
||||||
sin->sin_port = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IP_RECVIF
|
|
||||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
|
||||||
cmptr->cmsg_type == IP_RECVIF) {
|
|
||||||
struct sockaddr_dl *sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);
|
|
||||||
#ifndef HAVE_BROKEN_RECVIF_NAME
|
|
||||||
int nameLen = (sdl->sdl_nlen < IFI_NAME - 1) ? sdl->sdl_nlen : (IFI_NAME - 1);
|
|
||||||
strncpy(pktp->ipi_ifname, sdl->sdl_data, nameLen);
|
|
||||||
#endif
|
|
||||||
pktp->ipi_ifindex = sdl->sdl_index;
|
|
||||||
#ifdef HAVE_BROKEN_RECVIF_NAME
|
|
||||||
if (sdl->sdl_index == 0) {
|
|
||||||
pktp->ipi_ifindex = *(uint_t*)sdl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
assert(pktp->ipi_ifname[IFI_NAME - 1] == 0);
|
|
||||||
// null terminated because of memset above
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IP_RECVTTL
|
|
||||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
|
||||||
cmptr->cmsg_type == IP_RECVTTL) {
|
|
||||||
*ttl = *(u_char*)CMSG_DATA(cmptr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (cmptr->cmsg_level == IPPROTO_IP &&
|
|
||||||
cmptr->cmsg_type == IP_TTL) { // some implementations seem to send IP_TTL instead of IP_RECVTTL
|
|
||||||
*ttl = *(int*)CMSG_DATA(cmptr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(IPV6_PKTINFO) && HAVE_IPV6
|
|
||||||
if (cmptr->cmsg_level == IPPROTO_IPV6 &&
|
|
||||||
cmptr->cmsg_type == IPV6_2292_PKTINFO) {
|
|
||||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&pktp->ipi_addr;
|
|
||||||
struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmptr);
|
|
||||||
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
|
||||||
sin6->sin6_len = sizeof(*sin6);
|
|
||||||
#endif
|
|
||||||
sin6->sin6_addr = ip6_info->ipi6_addr;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
pktp->ipi_ifindex = ip6_info->ipi6_ifindex;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(IPV6_HOPLIMIT) && HAVE_IPV6
|
|
||||||
if (cmptr->cmsg_level == IPPROTO_IPV6 &&
|
|
||||||
cmptr->cmsg_type == IPV6_2292_HOPLIMIT) {
|
|
||||||
*ttl = *(int*)CMSG_DATA(cmptr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
assert(0); // unknown ancillary data
|
|
||||||
}
|
|
||||||
return(n);
|
|
||||||
#endif /* CMSG_FIRSTHDR */
|
|
||||||
}
|
|
||||||
|
|
||||||
// **********************************************************************************************
|
|
||||||
|
|
||||||
// daemonize the process. Adapted from "Unix Network Programming" vol 1 by Stevens, section 12.4.
|
|
||||||
// Returns 0 on success, -1 on failure.
|
|
||||||
|
|
||||||
#ifdef NOT_HAVE_DAEMON
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/signal.h>
|
|
||||||
|
|
||||||
int daemon(int nochdir, int noclose)
|
|
||||||
{
|
|
||||||
switch (fork())
|
|
||||||
{
|
|
||||||
case -1: return (-1); // Fork failed
|
|
||||||
case 0: break; // Child -- continue
|
|
||||||
default: _exit(0); // Parent -- exit
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setsid() == -1) return(-1);
|
|
||||||
|
|
||||||
signal(SIGHUP, SIG_IGN);
|
|
||||||
|
|
||||||
switch (fork()) // Fork again, primarily for reasons of Unix trivia
|
|
||||||
{
|
|
||||||
case -1: return (-1); // Fork failed
|
|
||||||
case 0: break; // Child -- continue
|
|
||||||
default: _exit(0); // Parent -- exit
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nochdir) (void)chdir("/");
|
|
||||||
umask(0);
|
|
||||||
|
|
||||||
if (!noclose)
|
|
||||||
{
|
|
||||||
int fd = open("/dev/null", O_RDWR, 0);
|
|
||||||
if (fd != -1)
|
|
||||||
{
|
|
||||||
// Avoid unnecessarily duplicating a file descriptor to itself
|
|
||||||
if (fd != STDIN_FILENO) (void)dup2(fd, STDIN_FILENO);
|
|
||||||
if (fd != STDOUT_FILENO) (void)dup2(fd, STDOUT_FILENO);
|
|
||||||
if (fd != STDERR_FILENO) (void)dup2(fd, STDERR_FILENO);
|
|
||||||
if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO)
|
|
||||||
(void)close (fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif /* NOT_HAVE_DAEMON */
|
|
@@ -1,130 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __mDNSUNP_h
|
|
||||||
#define __mDNSUNP_h
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_LINUX
|
|
||||||
#include <linux/socket.h>
|
|
||||||
#define IPV6_2292_PKTINFO IPV6_2292PKTINFO
|
|
||||||
#define IPV6_2292_HOPLIMIT IPV6_2292HOPLIMIT
|
|
||||||
#else
|
|
||||||
// The following are the supported non-linux posix OSes -
|
|
||||||
// netbsd, freebsd and openbsd.
|
|
||||||
#if HAVE_IPV6
|
|
||||||
#define IPV6_2292_PKTINFO 19
|
|
||||||
#define IPV6_2292_HOPLIMIT 20
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NOT_HAVE_SOCKLEN_T
|
|
||||||
typedef unsigned int socklen_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(_SS_MAXSIZE)
|
|
||||||
#if HAVE_IPV6
|
|
||||||
#define sockaddr_storage sockaddr_in6
|
|
||||||
#else
|
|
||||||
#define sockaddr_storage sockaddr
|
|
||||||
#endif // HAVE_IPV6
|
|
||||||
#endif // !defined(_SS_MAXSIZE)
|
|
||||||
|
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
|
||||||
#define GET_SA_LEN(X) (sizeof(struct sockaddr) > ((struct sockaddr*)&(X))->sa_len ? \
|
|
||||||
sizeof(struct sockaddr) : ((struct sockaddr*)&(X))->sa_len )
|
|
||||||
#elif HAVE_IPV6
|
|
||||||
#define GET_SA_LEN(X) (((struct sockaddr*)&(X))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : \
|
|
||||||
((struct sockaddr*)&(X))->sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr))
|
|
||||||
#else
|
|
||||||
#define GET_SA_LEN(X) (((struct sockaddr*)&(X))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IFI_NAME 16 /* same as IFNAMSIZ in <net/if.h> */
|
|
||||||
#define IFI_HADDR 8 /* allow for 64-bit EUI-64 in future */
|
|
||||||
|
|
||||||
// Renamed from my_in_pktinfo because in_pktinfo is used by Linux.
|
|
||||||
|
|
||||||
struct my_in_pktinfo {
|
|
||||||
struct sockaddr_storage ipi_addr;
|
|
||||||
int ipi_ifindex; /* received interface index */
|
|
||||||
char ipi_ifname[IFI_NAME]; /* received interface name */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* From the text (Stevens, section 20.2): */
|
|
||||||
/* 'As an example of recvmsg we will write a function named recvfrom_flags that */
|
|
||||||
/* is similar to recvfrom but also returns: */
|
|
||||||
/* 1. the returned msg_flags value, */
|
|
||||||
/* 2. the destination addres of the received datagram (from the IP_RECVDSTADDR socket option, and */
|
|
||||||
/* 3. the index of the interface on which the datagram was received (the IP_RECVIF socket option).' */
|
|
||||||
extern ssize_t recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
|
||||||
struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp, u_char *ttl);
|
|
||||||
|
|
||||||
struct ifi_info {
|
|
||||||
char ifi_name[IFI_NAME]; /* interface name, null terminated */
|
|
||||||
u_char ifi_haddr[IFI_HADDR]; /* hardware address */
|
|
||||||
u_short ifi_hlen; /* #bytes in hardware address: 0, 6, 8 */
|
|
||||||
short ifi_flags; /* IFF_xxx constants from <net/if.h> */
|
|
||||||
short ifi_myflags; /* our own IFI_xxx flags */
|
|
||||||
int ifi_index; /* interface index */
|
|
||||||
struct sockaddr *ifi_addr; /* primary address */
|
|
||||||
struct sockaddr *ifi_netmask;
|
|
||||||
struct sockaddr *ifi_brdaddr;/* broadcast address */
|
|
||||||
struct sockaddr *ifi_dstaddr;/* destination address */
|
|
||||||
struct ifi_info *ifi_next; /* next of these structures */
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
|
||||||
#define PROC_IFINET6_PATH "/proc/net/if_inet6"
|
|
||||||
extern struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6
|
|
||||||
#define INET6_ADDRSTRLEN 46 /*Maximum length of IPv6 address */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define IFI_ALIAS 1 /* ifi_addr is an alias */
|
|
||||||
|
|
||||||
/* From the text (Stevens, section 16.6): */
|
|
||||||
/* 'Since many programs need to know all the interfaces on a system, we will develop a */
|
|
||||||
/* function of our own named get_ifi_info that returns a linked list of structures, one */
|
|
||||||
/* for each interface that is currently "up."' */
|
|
||||||
extern struct ifi_info *get_ifi_info(int family, int doaliases);
|
|
||||||
|
|
||||||
/* 'The free_ifi_info function, which takes a pointer that was */
|
|
||||||
/* returned by get_ifi_info and frees all the dynamic memory.' */
|
|
||||||
extern void free_ifi_info(struct ifi_info *);
|
|
||||||
|
|
||||||
#ifdef NOT_HAVE_DAEMON
|
|
||||||
extern int daemon(int nochdir, int noclose);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,59 +0,0 @@
|
|||||||
#-------------------------------------------------
|
|
||||||
#
|
|
||||||
# Project created by QtCreator 2011-10-14T10:22:27
|
|
||||||
#
|
|
||||||
#-------------------------------------------------
|
|
||||||
|
|
||||||
QT -= gui
|
|
||||||
QT += core
|
|
||||||
|
|
||||||
TARGET = mdnssd
|
|
||||||
CONFIG += console
|
|
||||||
CONFIG -= app_bundle
|
|
||||||
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
include(../../../qtcreator.pri)
|
|
||||||
DESTDIR = $$IDE_BIN_PATH
|
|
||||||
|
|
||||||
DEFINES += PID_FILE=\\\"/var/run/mdnsd.pid\\\" MDNS_UDS_SERVERPATH=\\\"/var/run/mdnsd\\\" MDNS_DEBUGMSGS=0
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
uds_daemon.c \
|
|
||||||
uDNS.c \
|
|
||||||
PosixDaemon.c \
|
|
||||||
PlatformCommon.c \
|
|
||||||
mDNSUNP.c \
|
|
||||||
mDNSPosix.c \
|
|
||||||
mDNSDebug.c \
|
|
||||||
mDNS.c \
|
|
||||||
GenLinkedList.c \
|
|
||||||
dnssd_ipc.c \
|
|
||||||
DNSDigest.c \
|
|
||||||
DNSCommon.c
|
|
||||||
|
|
||||||
HEADERS += \
|
|
||||||
uds_daemon.h \
|
|
||||||
uDNS.h \
|
|
||||||
PlatformCommon.h \
|
|
||||||
mDNSUNP.h \
|
|
||||||
mDNSPosix.h \
|
|
||||||
mDNSEmbeddedAPI.h \
|
|
||||||
mDNSDebug.h \
|
|
||||||
GenLinkedList.h \
|
|
||||||
dnssd_ipc.h \
|
|
||||||
DNSCommon.h \
|
|
||||||
DebugServices.h \
|
|
||||||
dns_sd.h
|
|
||||||
|
|
||||||
*-g++ {
|
|
||||||
QMAKE_CFLAGS += -Wno-unused-but-set-variable
|
|
||||||
QMAKE_CXXFLAGS += -Wno-unused-but-set-variable
|
|
||||||
}
|
|
||||||
linux-* {
|
|
||||||
DEFINES += _GNU_SOURCE HAVE_IPV6 NOT_HAVE_SA_LEN USES_NETLINK HAVE_LINUX TARGET_OS_LINUX
|
|
||||||
}
|
|
||||||
macx {
|
|
||||||
DEFINES += HAVE_IPV6 __MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 __APPLE_USE_RFC_2292
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@@ -1,136 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UDNS_H_
|
|
||||||
#define __UDNS_H_
|
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
|
||||||
#include "DNSCommon.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RESTART_GOODBYE_DELAY (6 * mDNSPlatformOneSecond) // delay after restarting LLQ before nuking previous known answers (avoids flutter if we restart before we have networking up)
|
|
||||||
#define INIT_UCAST_POLL_INTERVAL (3 * mDNSPlatformOneSecond) // this interval is used after send failures on network transitions
|
|
||||||
// which typically heal quickly, so we start agressively and exponentially back off
|
|
||||||
#define MAX_UCAST_POLL_INTERVAL (60 * 60 * mDNSPlatformOneSecond)
|
|
||||||
//#define MAX_UCAST_POLL_INTERVAL (1 * 60 * mDNSPlatformOneSecond)
|
|
||||||
#define LLQ_POLL_INTERVAL (15 * 60 * mDNSPlatformOneSecond) // Polling interval for zones w/ an advertised LLQ port (ie not static zones) if LLQ fails due to NAT, etc.
|
|
||||||
#define RESPONSE_WINDOW (60 * mDNSPlatformOneSecond) // require server responses within one minute of request
|
|
||||||
#define MAX_UCAST_UNANSWERED_QUERIES 2 // the number of unanswered queries from any one uDNS server before trying another server
|
|
||||||
#define DNSSERVER_PENALTY_TIME (60 * mDNSPlatformOneSecond) // number of seconds for which new questions don't pick this server
|
|
||||||
|
|
||||||
// On some interfaces, we want to delay the first retransmission to a minimum of 2 seconds
|
|
||||||
// rather than the default (1 second).
|
|
||||||
#define MIN_UCAST_RETRANS_TIMEOUT (2 * mDNSPlatformOneSecond)
|
|
||||||
|
|
||||||
#define DEFAULT_UPDATE_LEASE 7200
|
|
||||||
|
|
||||||
#define QuestionIntervalStep 3
|
|
||||||
#define QuestionIntervalStep2 (QuestionIntervalStep*QuestionIntervalStep)
|
|
||||||
#define QuestionIntervalStep3 (QuestionIntervalStep*QuestionIntervalStep*QuestionIntervalStep)
|
|
||||||
#define InitialQuestionInterval ((mDNSPlatformOneSecond + QuestionIntervalStep-1) / QuestionIntervalStep)
|
|
||||||
|
|
||||||
// For Unicast record registrations, we initialize the interval to 1 second. When we send any query for
|
|
||||||
// the record registration e.g., GetZoneData, we always back off by QuestionIntervalStep
|
|
||||||
// so that the first retry does not happen until 3 seconds which should be enough for TCP/TLS to be done.
|
|
||||||
#define INIT_RECORD_REG_INTERVAL (1 * mDNSPlatformOneSecond)
|
|
||||||
#define MAX_RECORD_REG_INTERVAL (15 * 60 * mDNSPlatformOneSecond)
|
|
||||||
#define MERGE_DELAY_TIME (1 * mDNSPlatformOneSecond)
|
|
||||||
|
|
||||||
// If we are refreshing, we do it at least 5 times with a min update frequency of
|
|
||||||
// 5 minutes
|
|
||||||
#define MAX_UPDATE_REFRESH_COUNT 5
|
|
||||||
#define MIN_UPDATE_REFRESH_TIME (5 * 60 * mDNSPlatformOneSecond)
|
|
||||||
|
|
||||||
// For questions that use kDNSServiceFlagsTimeout and we don't have a matching resolver e.g., no dns servers,
|
|
||||||
// then use the default value of 30 seconds
|
|
||||||
#define DEFAULT_UDNS_TIMEOUT 30 // in seconds
|
|
||||||
|
|
||||||
// Entry points into unicast-specific routines
|
|
||||||
|
|
||||||
extern void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo);
|
|
||||||
extern void startLLQHandshake(mDNS *m, DNSQuestion *q);
|
|
||||||
extern void sendLLQRefresh(mDNS *m, DNSQuestion *q);
|
|
||||||
|
|
||||||
extern void SleepRecordRegistrations(mDNS *m);
|
|
||||||
|
|
||||||
// uDNS_UpdateRecord
|
|
||||||
// following fields must be set, and the update validated, upon entry.
|
|
||||||
// rr->NewRData
|
|
||||||
// rr->newrdlength
|
|
||||||
// rr->UpdateCallback
|
|
||||||
|
|
||||||
extern mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr);
|
|
||||||
|
|
||||||
extern void SetNextQueryTime(mDNS *const m, const DNSQuestion *const q);
|
|
||||||
extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name);
|
|
||||||
extern mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr);
|
|
||||||
extern mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr, mDNS_Dereg_type drt);
|
|
||||||
extern mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const question);
|
|
||||||
extern mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const question);
|
|
||||||
extern mStatus mDNS_StartNATOperation_internal(mDNS *const m, NATTraversalInfo *traversal);
|
|
||||||
|
|
||||||
extern void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneData);
|
|
||||||
extern mStatus uDNS_DeregisterRecord(mDNS *const m, AuthRecord *const rr);
|
|
||||||
extern const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr);
|
|
||||||
extern void uDNS_CheckCurrentQuestion(mDNS *const m);
|
|
||||||
|
|
||||||
// integer fields of msg header must be in HOST byte order before calling this routine
|
|
||||||
extern void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
|
|
||||||
const mDNSAddr *const srcaddr, const mDNSIPPort srcport);
|
|
||||||
|
|
||||||
extern void uDNS_Tasks(mDNS *const m);
|
|
||||||
extern void UpdateAllSRVRecords(mDNS *m);
|
|
||||||
extern void CheckNATMappings(mDNS *m);
|
|
||||||
|
|
||||||
extern mStatus uDNS_SetupDNSConfig(mDNS *const m);
|
|
||||||
|
|
||||||
// uDNS_SetupSearchDomains by default adds search domains. It also can be called with one or
|
|
||||||
// more values for "action" which does the following:
|
|
||||||
//
|
|
||||||
// -UDNS_START_WAB_QUERY - start Wide Area Bonjour (domain enumeration) queries
|
|
||||||
|
|
||||||
#define UDNS_START_WAB_QUERY 0x00000001
|
|
||||||
|
|
||||||
extern mStatus uDNS_SetupSearchDomains(mDNS *const m, int action);
|
|
||||||
extern domainname *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
uDNS_LLQ_Not = 0, // Normal uDNS answer: Flush any stale records from cache, and respect record TTL
|
|
||||||
uDNS_LLQ_Ignore, // LLQ initial challenge packet: ignore -- has no useful records for us
|
|
||||||
uDNS_LLQ_Entire, // LLQ initial set of answers: Flush any stale records from cache, but assume TTL is 2 x LLQ refresh interval
|
|
||||||
uDNS_LLQ_Events // LLQ event packet: don't flush cache; assume TTL is 2 x LLQ refresh interval
|
|
||||||
} uDNS_LLQType;
|
|
||||||
|
|
||||||
extern uDNS_LLQType uDNS_recvLLQResponse(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, DNSQuestion **matchQuestion);
|
|
||||||
extern DomainAuthInfo *GetAuthInfoForName_internal(mDNS *m, const domainname *const name);
|
|
||||||
extern DomainAuthInfo *GetAuthInfoForQuestion(mDNS *m, const DNSQuestion *const q);
|
|
||||||
extern void DisposeTCPConn(struct tcpInfo_t *tcp);
|
|
||||||
|
|
||||||
// NAT traversal
|
|
||||||
extern void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID InterfaceID, mDNSu8 *pkt, mDNSu16 len); // Called for each received NAT-PMP packet
|
|
||||||
extern void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv4Addr ExtAddr);
|
|
||||||
extern void natTraversalHandlePortMapReply(mDNS *const m, NATTraversalInfo *n, const mDNSInterfaceID InterfaceID, mDNSu16 err, mDNSIPPort extport, mDNSu32 lease);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __UDNS_H_
|
|
File diff suppressed because it is too large
Load Diff
@@ -1,80 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
|
|
||||||
File: uds_daemon.h
|
|
||||||
|
|
||||||
Contains: Interfaces necessary to talk to uds_daemon.c.
|
|
||||||
|
|
||||||
Version: 1.0
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
|
||||||
#include "dnssd_ipc.h"
|
|
||||||
|
|
||||||
/* Client interface: */
|
|
||||||
|
|
||||||
#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)
|
|
||||||
|
|
||||||
extern int udsserver_init(dnssd_sock_t skts[], mDNSu32 count);
|
|
||||||
extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
|
|
||||||
extern void udsserver_info(mDNS *const m); // print out info about current state
|
|
||||||
extern void udsserver_handle_configchange(mDNS *const m);
|
|
||||||
extern int udsserver_exit(void); // should be called prior to app exit
|
|
||||||
|
|
||||||
/* Routines that uds_daemon expects to link against: */
|
|
||||||
|
|
||||||
typedef void (*udsEventCallback)(int fd, short filter, void *context);
|
|
||||||
extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback callback, void *context, void **platform_data);
|
|
||||||
extern int udsSupportReadFD(dnssd_sock_t fd, char* buf, int len, int flags, void *platform_data);
|
|
||||||
extern mStatus udsSupportRemoveFDFromEventLoop(dnssd_sock_t fd, void *platform_data); // Note: This also CLOSES the file descriptor as well
|
|
||||||
|
|
||||||
extern void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay);
|
|
||||||
|
|
||||||
// Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X
|
|
||||||
|
|
||||||
extern mDNS mDNSStorage;
|
|
||||||
extern DNameListElem *AutoRegistrationDomains;
|
|
||||||
extern DNameListElem *AutoBrowseDomains;
|
|
||||||
|
|
||||||
extern mDNSs32 ChopSubTypes(char *regtype);
|
|
||||||
extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p);
|
|
||||||
extern int CountExistingRegistrations(domainname *srv, mDNSIPPort port);
|
|
||||||
extern void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result);
|
|
||||||
extern int CountPeerRegistrations(mDNS *const m, ServiceRecordSet *const srs);
|
|
||||||
|
|
||||||
#if APPLE_OSX_mDNSResponder
|
|
||||||
extern void machserver_automatic_browse_domain_changed(const domainname *d, mDNSBool add);
|
|
||||||
extern void machserver_automatic_registration_domain_changed(const domainname *d, mDNSBool add);
|
|
||||||
// External support
|
|
||||||
extern void mDNSInitPacketFilter(void);
|
|
||||||
extern void external_start_browsing_for_service(mDNS *const m, const domainname *const type, DNS_TypeValues qtype);
|
|
||||||
extern void external_stop_browsing_for_service(mDNS *const m, const domainname *const type, DNS_TypeValues qtype);
|
|
||||||
extern void external_start_advertising_service(const ResourceRecord *const resourceRecord);
|
|
||||||
extern void external_stop_advertising_service(const ResourceRecord *const resourceRecord);
|
|
||||||
extern void external_start_resolving_service(const domainname *const fqdn);
|
|
||||||
extern void external_stop_resolving_service(const domainname *const fqdn);
|
|
||||||
#else
|
|
||||||
#define external_start_browsing_for_service(A,B,C) (void)(A)
|
|
||||||
#define external_stop_browsing_for_service(A,B,C) (void)(A)
|
|
||||||
#define external_start_advertising_service(A) (void)(A)
|
|
||||||
#define external_stop_advertising_service(A) (void)(A)
|
|
||||||
#define external_start_resolving_service(A) (void)(A)
|
|
||||||
#define external_stop_resolving_service(A) (void)(A)
|
|
||||||
#endif // APPLE_OSX_mDNSResponder
|
|
||||||
|
|
||||||
extern const char mDNSResponderVersionString_SCCS[];
|
|
||||||
#define mDNSResponderVersionString (mDNSResponderVersionString_SCCS+5)
|
|
@@ -18,10 +18,6 @@ win32 {
|
|||||||
SUBDIRS += valgrindfake
|
SUBDIRS += valgrindfake
|
||||||
}
|
}
|
||||||
|
|
||||||
linux-* {
|
|
||||||
SUBDIRS += mdnssd
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
|
QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
|
||||||
!isEmpty(QT_BREAKPAD_ROOT_PATH) {
|
!isEmpty(QT_BREAKPAD_ROOT_PATH) {
|
||||||
SUBDIRS += qtcrashhandler
|
SUBDIRS += qtcrashhandler
|
||||||
|
Reference in New Issue
Block a user