]>
Commit | Line | Data |
---|---|---|
7f0064bd A |
1 | /* -*- Mode: C; tab-width: 4 -*- |
2 | * | |
3 | * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. | |
4 | * | |
67c8f8a1 A |
5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | * you may not use this file except in compliance with the License. | |
7 | * You may obtain a copy of the License at | |
83fb1e36 | 8 | * |
67c8f8a1 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
83fb1e36 | 10 | * |
67c8f8a1 A |
11 | * Unless required by applicable law or agreed to in writing, software |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
7f0064bd | 15 | * limitations under the License. |
7f0064bd A |
16 | */ |
17 | ||
83fb1e36 A |
18 | #include <stdio.h> // Needed for fopen() etc. |
19 | #include <unistd.h> // Needed for close() | |
20 | #include <string.h> // Needed for strlen() etc. | |
21 | #include <errno.h> // Needed for errno etc. | |
22 | #include <sys/socket.h> // Needed for socket() etc. | |
23 | #include <netinet/in.h> // Needed for sockaddr_in | |
030b743d | 24 | #include <syslog.h> |
7f0064bd | 25 | |
83fb1e36 | 26 | #include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above |
67c8f8a1 | 27 | #include "DNSCommon.h" |
7f0064bd A |
28 | #include "PlatformCommon.h" |
29 | ||
30 | #ifdef NOT_HAVE_SOCKLEN_T | |
83fb1e36 | 31 | typedef unsigned int socklen_t; |
7f0064bd A |
32 | #endif |
33 | ||
67c8f8a1 | 34 | // Bind a UDP socket to find the source address to a destination |
96f69b28 | 35 | mDNSexport void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst) |
83fb1e36 A |
36 | { |
37 | union { struct sockaddr s; struct sockaddr_in a4; struct sockaddr_in6 a6; } addr; | |
38 | socklen_t len = sizeof(addr); | |
39 | socklen_t inner_len = 0; | |
40 | int sock = socket(AF_INET, SOCK_DGRAM, 0); | |
41 | src->type = mDNSAddrType_None; | |
42 | if (sock == -1) return; | |
43 | if (dst->type == mDNSAddrType_IPv4) | |
44 | { | |
45 | inner_len = sizeof(addr.a4); | |
46 | #ifndef NOT_HAVE_SA_LEN | |
47 | addr.a4.sin_len = inner_len; | |
48 | #endif | |
49 | addr.a4.sin_family = AF_INET; | |
50 | addr.a4.sin_port = 1; // Not important, any port will do | |
51 | addr.a4.sin_addr.s_addr = dst->ip.v4.NotAnInteger; | |
52 | } | |
53 | else if (dst->type == mDNSAddrType_IPv6) | |
54 | { | |
55 | inner_len = sizeof(addr.a6); | |
56 | #ifndef NOT_HAVE_SA_LEN | |
57 | addr.a6.sin6_len = inner_len; | |
58 | #endif | |
59 | addr.a6.sin6_family = AF_INET6; | |
60 | addr.a6.sin6_flowinfo = 0; | |
61 | addr.a6.sin6_port = 1; // Not important, any port will do | |
62 | addr.a6.sin6_addr = *(struct in6_addr*)&dst->ip.v6; | |
63 | addr.a6.sin6_scope_id = 0; | |
64 | } | |
65 | else return; | |
66 | ||
67 | if ((connect(sock, &addr.s, inner_len)) < 0) | |
68 | { LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d (%s)", dst, errno, strerror(errno)); goto exit; } | |
69 | ||
70 | if ((getsockname(sock, &addr.s, &len)) < 0) | |
71 | { LogMsg("mDNSPlatformSourceAddrForDest: getsockname failed errno %d (%s)", errno, strerror(errno)); goto exit; } | |
72 | ||
73 | src->type = dst->type; | |
74 | if (dst->type == mDNSAddrType_IPv4) src->ip.v4.NotAnInteger = addr.a4.sin_addr.s_addr; | |
75 | else src->ip.v6 = *(mDNSv6Addr*)&addr.a6.sin6_addr; | |
96f69b28 | 76 | exit: |
83fb1e36 A |
77 | close(sock); |
78 | } | |
7f0064bd | 79 | |
283ee3ff | 80 | // dst must be at least MAX_ESCAPED_DOMAIN_NAME bytes, and option must be less than 32 bytes in length |
7f0064bd | 81 | mDNSlocal mDNSBool GetConfigOption(char *dst, const char *option, FILE *f) |
83fb1e36 A |
82 | { |
83 | char buf[32+1+MAX_ESCAPED_DOMAIN_NAME]; // Option name, one space, option value | |
84 | unsigned int len = strlen(option); | |
85 | if (len + 1 + MAX_ESCAPED_DOMAIN_NAME > sizeof(buf)-1) { LogMsg("GetConfigOption: option %s too long", option); return mDNSfalse; } | |
86 | fseek(f, 0, SEEK_SET); // set position to beginning of stream | |
87 | while (fgets(buf, sizeof(buf), f)) // Read at most sizeof(buf)-1 bytes from file, and append '\0' C-string terminator | |
88 | { | |
89 | if (!strncmp(buf, option, len)) | |
90 | { | |
91 | strncpy(dst, buf + len + 1, MAX_ESCAPED_DOMAIN_NAME-1); | |
92 | if (dst[MAX_ESCAPED_DOMAIN_NAME-1]) dst[MAX_ESCAPED_DOMAIN_NAME-1] = '\0'; | |
93 | len = strlen(dst); | |
94 | if (len && dst[len-1] == '\n') dst[len-1] = '\0'; // chop newline | |
95 | return mDNStrue; | |
96 | } | |
97 | } | |
98 | debugf("Option %s not set", option); | |
99 | return mDNSfalse; | |
100 | } | |
7f0064bd | 101 | |
283ee3ff | 102 | mDNSexport void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled) |
83fb1e36 A |
103 | { |
104 | char buf[MAX_ESCAPED_DOMAIN_NAME] = ""; | |
105 | mStatus err; | |
106 | FILE *f = fopen(filename, "r"); | |
107 | ||
108 | if (hostname) hostname->c[0] = 0; | |
109 | if (domain) domain->c[0] = 0; | |
110 | if (DomainDiscoveryDisabled) *DomainDiscoveryDisabled = mDNSfalse; | |
111 | ||
112 | if (f) | |
113 | { | |
114 | if (DomainDiscoveryDisabled && GetConfigOption(buf, "DomainDiscoveryDisabled", f) && !strcasecmp(buf, "true")) *DomainDiscoveryDisabled = mDNStrue; | |
115 | if (hostname && GetConfigOption(buf, "hostname", f) && !MakeDomainNameFromDNSNameString(hostname, buf)) goto badf; | |
116 | if (domain && GetConfigOption(buf, "zone", f) && !MakeDomainNameFromDNSNameString(domain, buf)) goto badf; | |
117 | buf[0] = 0; | |
118 | GetConfigOption(buf, "secret-64", f); // failure means no authentication | |
119 | fclose(f); | |
120 | f = NULL; | |
121 | } | |
122 | else | |
123 | { | |
124 | if (errno != ENOENT) LogMsg("ERROR: Config file exists, but cannot be opened."); | |
125 | return; | |
126 | } | |
127 | ||
128 | if (domain && domain->c[0] && buf[0]) | |
129 | { | |
130 | DomainAuthInfo *info = (DomainAuthInfo*)mDNSPlatformMemAllocate(sizeof(*info)); | |
131 | // for now we assume keyname = service reg domain and we use same key for service and hostname registration | |
132 | err = mDNS_SetSecretForDomain(m, info, domain, domain, buf, NULL, 0, mDNSfalse); | |
133 | if (err) LogMsg("ERROR: mDNS_SetSecretForDomain returned %d for domain %##s", err, domain->c); | |
134 | } | |
135 | ||
136 | return; | |
137 | ||
138 | badf: | |
139 | LogMsg("ERROR: malformatted config file"); | |
140 | if (f) fclose(f); | |
141 | } | |
030b743d A |
142 | |
143 | #if MDNS_DEBUGMSGS | |
5e65c77f | 144 | mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg) |
83fb1e36 A |
145 | { |
146 | fprintf(stderr,"%s\n", msg); | |
147 | fflush(stderr); | |
148 | } | |
030b743d A |
149 | #endif |
150 | ||
32bb7e43 | 151 | mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, mDNSLogLevel_t loglevel) |
83fb1e36 | 152 | { |
5e65c77f | 153 | #if APPLE_OSX_mDNSResponder && LogTimeStamps |
83fb1e36 A |
154 | extern mDNS mDNSStorage; |
155 | extern mDNSu32 mDNSPlatformClockDivisor; | |
156 | mDNSs32 t = mDNSStorage.timenow ? mDNSStorage.timenow : mDNSPlatformClockDivisor ? mDNS_TimeNow_NoLock(&mDNSStorage) : 0; | |
157 | int ms = ((t < 0) ? -t : t) % 1000; | |
5e65c77f A |
158 | #endif |
159 | ||
83fb1e36 A |
160 | if (mDNS_DebugMode) // In debug mode we write to stderr |
161 | { | |
5e65c77f | 162 | #if APPLE_OSX_mDNSResponder && LogTimeStamps |
83fb1e36 A |
163 | if (ident && ident[0] && mDNSPlatformClockDivisor) |
164 | fprintf(stderr,"%8d.%03d: %s\n", (int)(t/1000), ms, buffer); | |
165 | else | |
5e65c77f | 166 | #endif |
83fb1e36 A |
167 | fprintf(stderr,"%s\n", buffer); |
168 | fflush(stderr); | |
169 | } | |
170 | else // else, in production mode, we write to syslog | |
171 | { | |
172 | static int log_inited = 0; | |
173 | ||
174 | int syslog_level = LOG_ERR; | |
175 | switch (loglevel) | |
176 | { | |
177 | case MDNS_LOG_MSG: syslog_level = LOG_ERR; break; | |
178 | case MDNS_LOG_OPERATION: syslog_level = LOG_WARNING; break; | |
179 | case MDNS_LOG_SPS: syslog_level = LOG_NOTICE; break; | |
180 | case MDNS_LOG_INFO: syslog_level = LOG_INFO; break; | |
181 | case MDNS_LOG_DEBUG: syslog_level = LOG_DEBUG; break; | |
182 | default: | |
183 | fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel); | |
184 | fflush(stderr); | |
185 | } | |
186 | ||
187 | if (!log_inited) { openlog(ident, LOG_CONS, LOG_DAEMON); log_inited++; } | |
32bb7e43 | 188 | |
5e65c77f | 189 | #if APPLE_OSX_mDNSResponder && LogTimeStamps |
83fb1e36 A |
190 | if (ident && ident[0] && mDNSPlatformClockDivisor) |
191 | syslog(syslog_level, "%8d.%03d: %s", (int)(t/1000), ms, buffer); | |
192 | else | |
51601d48 A |
193 | #elif APPLE_OSX_mDNSResponder |
194 | mDNSPlatformLogToFile(syslog_level, buffer); | |
195 | #else | |
83fb1e36 | 196 | syslog(syslog_level, "%s", buffer); |
51601d48 | 197 | #endif |
83fb1e36 A |
198 | } |
199 | } |