1 #include "unittest_common.h"
3 #include "mDNSEmbeddedAPI.h"
4 #include "mDNSMacOSX.h"
6 static mDNS_PlatformSupport PlatformStorage
;
7 #define RR_CACHE_SIZE ((32*1024) / sizeof(CacheRecord))
8 static CacheEntity gRrcachestorage
[RR_CACHE_SIZE
];
10 // Primary interface info that is used when simulating the receive of the response packet
11 mDNSInterfaceID primary_interfaceID
;
14 mDNSAddr primary_router
;
16 // This function sets up the minimum environement to run a unit test. It
17 // initializes logging, interfaces, and timenow.
18 mDNSexport mStatus
init_mdns_environment(mDNSBool enableLogging
)
20 mDNS
*m
= &mDNSStorage
;
23 mDNS_LoggingEnabled
= enableLogging
;
24 mDNS_PacketLoggingEnabled
= enableLogging
;
26 mStatus result
= mDNS_InitStorage_ut(m
, &PlatformStorage
, gRrcachestorage
, RR_CACHE_SIZE
, mDNSfalse
, mDNSNULL
, mDNSNULL
);
27 if (result
!= mStatus_NoError
)
30 primary_v4
= primary_v6
= primary_router
= zeroAddr
;
31 SetInterfaces_ut(&primary_interfaceID
, &primary_v4
, &primary_v6
, &primary_router
);
33 m
->timenow
= mDNS_TimeNow_NoLock(m
);
34 return mStatus_NoError
;
37 // This function sets up the minimum environement to run a unit test. It
38 // initializes logging and timenow. This is the call to use if your
39 // unit test does not use interfaces.
40 mDNSexport mStatus
init_mdns_storage()
42 mDNS
*m
= &mDNSStorage
;
45 mDNS_LoggingEnabled
= 1;
46 mDNS_PacketLoggingEnabled
= 1;
48 mStatus result
= mDNS_InitStorage_ut(m
, &PlatformStorage
, gRrcachestorage
, RR_CACHE_SIZE
, mDNSfalse
, mDNSNULL
, mDNSNULL
);
49 if (result
!= mStatus_NoError
)
52 return mStatus_NoError
;
55 mDNSlocal
void init_client_request(request_state
* req
, char *msgbuf
, size_t msgSize
, uint32_t op
)
57 // Simulate read_msg behavior since unit test does not open a socket
58 memset(req
, 0, sizeof(request_state
));
61 req
->msgbuf
= mDNSNULL
;
63 req
->msgend
= msgbuf
+ msgSize
;
65 // The rest of the request values are set in order to simulate a request
66 req
->sd
= client_req_sd
;
67 req
->uid
= client_req_uid
;
68 req
->hdr_bytes
= client_req_hdr_bytes
;
69 req
->hdr
.version
= client_req_hdr_version
;
70 req
->hdr
.op
= op
; // query_request
71 req
->hdr
.datalen
= msgSize
;
72 req
->data_bytes
= msgSize
;
73 req
->process_id
= client_req_process_id
;
74 memcpy(req
->pid_name
, client_req_pid_name
, strlen(client_req_pid_name
));
77 // This function calls the mDNSResponder handle_client_request() API. It initializes
78 // the request and query data structures.
79 mDNSexport mStatus
start_client_request(request_state
* req
, char *msgbuf
, size_t msgsz
, uint32_t op
, UDPSocket
* socket
)
81 // Process the unit test's client request
82 init_client_request(req
, msgbuf
, msgsz
, op
);
84 mStatus result
= handle_client_request_ut((void*)req
);
85 DNSQuestion
* q
= &req
->u
.queryrecord
.q
;
86 q
->LocalSocket
= socket
;
90 // This function calls the mDNSResponder mDNSCoreReceive() API.
91 mDNSexport
void receive_response(const request_state
* req
, DNSMessage
*msg
, size_t msgSize
)
93 mDNS
*m
= &mDNSStorage
;
95 mDNSIPPort srcport
, dstport
;
97 DNSQuestion
*q
= (DNSQuestion
*)&req
->u
.queryrecord
.q
;
98 UInt8
* data
= (UInt8
*)msg
;
100 // Used same values for DNS server as specified during init of unit test
101 srcaddr
.type
= mDNSAddrType_IPv4
;
102 srcaddr
.ip
.v4
.NotAnInteger
= dns_server_ipv4
.NotAnInteger
;
103 srcport
.NotAnInteger
= client_resp_src_port
;
105 // Used random value for dstport
106 dstport
.NotAnInteger
= swap16((mDNSu16
)client_resp_dst_port
);
108 // Set DNS message (that was copied from a WireShark packet)
109 end
= (const mDNSu8
*)msg
+ msgSize
;
111 // Set socket info that mDNSCoreReceive uses to verify socket context
112 q
->LocalSocket
->ss
.port
.NotAnInteger
= swap16((mDNSu16
)client_resp_dst_port
);
113 q
->TargetQID
.b
[0] = data
[0];
114 q
->TargetQID
.b
[1] = data
[1];
116 // Execute mDNSCoreReceive which copies two DNS records into the cache
117 mDNSCoreReceive(m
, msg
, end
, &srcaddr
, srcport
, &primary_v4
, dstport
, primary_interfaceID
);
120 mDNSexport
size_t get_reply_len(char* name
, uint16_t rdlen
)
122 size_t len
= sizeof(DNSServiceFlags
);
123 len
+= sizeof(mDNSu32
); // interface index
124 len
+= sizeof(DNSServiceErrorType
);
125 len
+= strlen(name
) + 1;
126 len
+= 3 * sizeof(mDNSu16
); // type, class, rdlen
128 len
+= sizeof(mDNSu32
); // TTL
133 void free_req(request_state
* req
)
135 // Cleanup request's memory usage
138 reply_state
*reply
= req
->replies
;
139 req
->replies
= req
->replies
->next
;
140 mDNSPlatformMemFree(reply
);
143 mDNSPlatformMemFree(req
);
146 // Unit test support functions follow
147 #define SA_LEN(addr) (((addr)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
149 mDNSexport
void get_ip(const char *const name
, struct sockaddr_storage
*result
)
151 struct addrinfo
* aiList
;
152 int err
= getaddrinfo(name
, NULL
, NULL
, &aiList
);
153 if (err
) fprintf(stderr
, "getaddrinfo error %d for %s", err
, name
);
154 else memcpy(result
, aiList
->ai_addr
, SA_LEN(aiList
->ai_addr
));
155 if (aiList
) freeaddrinfo(aiList
);