Project

General

Profile

Download (33.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
	/*
3
	 * PHP.updateDNS (pfSense version)
4
	 *
5
	 * +====================================================+
6
	 *  Services Supported:
7
	 *    - DynDns (dyndns.org) [dynamic, static, custom]
8
	 *    - DHSDns (dhs.org)
9
	 *    - No-IP (no-ip.com)
10
	 *    - EasyDNS (easydns.com)
11
	 *    - DHS (www.dhs.org)
12
	 *    - HN (hn.org) -- incomplete checking!
13
	 *    - DynS (dyns.org)
14
	 *    - ZoneEdit (zoneedit.com)
15
	 *    - FreeDNS (freedns.afraid.org)
16
	 *    - Loopia (loopia.se)
17
	 *    - StaticCling (staticcling.org)
18
	 *    - DNSexit (dnsexit.com)
19
	 *    - OpenDNS (opendns.com)
20
	 *    - Namecheap (namecheap.com)
21
	 * +----------------------------------------------------+
22
	 *  Requirements:
23
	 *    - PHP version 4.0.2 or higher with CURL Library
24
	 * +----------------------------------------------------+
25
	 *  Public Functions
26
	 *    - updatedns()
27
	 *
28
	 *  Private Functions
29
	 *    - _update()
30
	 *    - _checkStatus()
31
	 *    - _error()
32
	 *    - _detectChange()
33
	 *    - _debug()
34
	 *    - _checkIP()
35
	 * +----------------------------------------------------+
36
	 *  DynDNS Dynamic - Last Tested: 12 July 2005
37
	 *  DynDNS Static  - Last Tested: NEVER
38
	 *  DynDNS Custom  - Last Tested: NEVER
39
	 *  No-IP          - Last Tested: 20 July 2008
40
	 *  HN.org         - Last Tested: 12 July 2005
41
	 *  EasyDNS        - Last Tested: 20 July 2008
42
	 *  DHS            - Last Tested: 12 July 2005
43
	 *  ZoneEdit       - Last Tested: NEVER
44
	 *  Dyns           - Last Tested: NEVER
45
	 *  ODS            - Last Tested: 02 August 2005
46
	 *  FreeDNS        - Last Tested: NEVER
47
	 *  Loopia         - Last Tested: NEVER
48
	 *  StaticCling    - Last Tested: 27 April 2006
49
	 *  DNSexit	   - Last Tested: 20 July 2008
50
	 *  OpenDNS	   - Last Tested: 4 August 2008
51
	 * +====================================================+
52
	 *
53
	 * @author 	E.Kristensen
54
	 * @link    	http://www.idylldesigns.com/projects/phpdns/
55
	 * @version 	0.8
56
	 * @updated	13 October 05 at 21:02:42 GMT
57
	 *
58
	 * DNSexit/OpenDNS support and multiwan extension for pfSense by Ermal Lu?i
59
	 *
60
	 */
61

    
62
	class updatedns {
63
		var $_cacheFile;
64
		var $_debugFile;
65
		var $_UserAgent = 'User-Agent: phpDynDNS/0.7';
66
		var $_errorVerbosity = 0;
67
		var $_dnsService;
68
		var $_dnsUser;
69
		var $_dnsPass;
70
		var $_dnsHost;
71
		var $_dnsIP;
72
		/* This is needed for support on addresses behind NAT. */
73
		var $_ifIP;
74
		var $_dnsWildcard;
75
		var $_dnsMX;
76
		var $_dnsBackMX;
77
		var $_dnsServer;
78
		var $_dnsPort;
79
		var $_dnsUpdateURL;
80
		var $status;
81
		var $_debugID;
82
		var $_if;
83
		
84
		/* 
85
		 * Public Constructor Function (added 12 July 05) [beta]
86
		 *   - Gets the dice rolling for the update. 
87
		 */
88
		function updatedns ($dnsService = '', $dnsHost = '', $dnsUser = '', $dnsPass = '',
89
				    $dnsWildcard = 'OFF', $dnsMX = '', $dnsIf = '', $dnsBackMX = '',
90
				    $dnsServer = '', $dnsPort = '', $dnsUpdateURL = '') {
91
			
92
			global $config, $g;
93
			
94
			$this->_cacheFile = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}.cache";
95
			$this->_debugFile = "{$g['varetc_path']}/dyndns_{$dnsIf}{$dnsService}.debug";
96

    
97
			log_error("DynDns: updatedns() starting");
98
			
99
			if (!$dnsService) $this->_error(2);
100
			if (!($dnsService == 'freedns')) {
101

    
102
				/* all services except freedns use these */
103

    
104
				if (!$dnsUser) $this->_error(3);
105
				if (!$dnsPass) $this->_error(4);
106
				if (!$dnsHost) $this->_error(5);
107
			} else {
108

    
109
				/* freedns needs this */
110

    
111
				if (!$dnsHost) $this->_error(5);
112
			}
113
			
114
			$this->_dnsService = strtolower($dnsService);
115
			$this->_dnsUser = $dnsUser;
116
			$this->_dnsPass = $dnsPass;
117
			$this->_dnsHost = $dnsHost;
118
			$this->_dnsServer = $dnsServer;
119
			$this->_dnsPort = $dnsPort;
120
			$this->_dnsWildcard = $dnsWildcard;
121
			$this->_dnsMX = $dnsMX;
122
			$this->_if = get_real_interface($dnsIf);
123
			$this->_ifIP = get_interface_ip($dnsIf);
124
			//$this->_dnsIP = get_interface_ip($dnsIf);
125

    
126
			// Ensure that we where able to lookup the IP
127
			if(!$this->_ifIP)
128
				log_error("There was an error trying to determine the IP for interface - {$dnsIf}({$this->_if}).");
129

    
130
			$this->_debugID = rand(1000000, 9999999);
131
			
132
			if ($this->_detectChange() == false) {
133
				$this->_error(10);
134
			} else {
135
				switch ($this->_dnsService) {
136
				case 'dnsomatic':
137
				case 'dyndns':
138
				case 'dyndns-static':
139
				case 'dyndns-custom':
140
				case 'dhs':
141
				case 'noip':
142
				case 'easydns':
143
				case 'hn':
144
				case 'zoneedit':
145
				case 'dyns':
146
				case 'ods':
147
				case 'freedns':
148
				case 'loopia':
149
				case 'staticcling':
150
				case 'dnsexit':
151
				case 'opendns':
152
				case 'namecheap':
153
					$this->_update();	
154
					break;
155
				default:
156
					$this->_error(6);
157
					break;
158
				}
159
			}
160
		}
161
			
162
		/*
163
		 * Private Function (added 12 July 05) [beta]
164
		 *   Send Update To Selected Service.
165
		 */
166
		function _update() {
167
		
168
			log_error("DynDns: DynDns _update() starting.");
169
		
170
			if ($this->_dnsService != 'ods') {
171
				$ch = curl_init();
172
				curl_setopt($ch, CURLOPT_HEADER, 0);
173
				curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
174
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
175
				curl_setopt($ch, CURLOPT_INTERFACE, $this->_ifIP);
176
				curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Completely empirical
177
			}
178

    
179
			switch ($this->_dnsService) {
180
				case 'dyndns':
181
				case 'dyndns-static':
182
				case 'dyndns-custom':
183
					$needsIP = FALSE;
184
					//log_error("DynDns: DynDns _update() starting. Dynamic");
185
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
186
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
187
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
188
					$server = "https://members.dyndns.org/nic/update";
189
					$port = "";
190
					if($this->_dnsServer)
191
						$server = $this->_dnsServer;
192
					if($this->_dnsPort)
193
						$port = ":" . $this->_dnsPort;
194
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
195
					$data = curl_exec($ch);
196
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
197
					curl_close($ch);
198
					$this->_checkStatus($data);
199
					break;
200
				case 'dhs':
201
					$needsIP = TRUE;
202
					$post_data['hostscmd'] = 'edit';
203
					$post_data['hostscmdstage'] = '2';
204
					$post_data['type'] = '4';
205
					$post_data['updatetype'] = 'Online';
206
					$post_data['mx'] = $this->_dnsMX;
207
					$post_data['mx2'] = '';
208
					$post_data['txt'] = '';
209
					$post_data['offline_url'] = '';
210
					$post_data['cloak'] = 'Y';
211
					$post_data['cloak_title'] = '';
212
					$post_data['ip'] = $this->_dnsIP;
213
					$post_data['domain'] = 'dyn.dhs.org';
214
					$post_data['hostname'] = $this->_dnsHost;
215
					$post_data['submit'] = 'Update';
216
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
217
					$server = "https://members.dhs.org/nic/hosts";
218
					$port = "";
219
					if($this->_dnsServer)
220
						$server = $this->_dnsServer;
221
					if($this->_dnsPort)
222
						$port = ":" . $this->_dnsPort;					
223
					curl_setopt($ch, CURLOPT_URL, '{$server}{$port}');
224
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
225
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
226
					$data = curl_exec($ch);
227
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
228
					curl_close($ch);
229
					$this->_checkStatus($data);
230
					break;
231
				case 'noip':
232
					$needsIP = TRUE;
233
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
234
					$server = "http://dynupdate.no-ip.com/ducupdate.php";
235
					$port = "";
236
					if($this->_dnsServer)
237
						$server = $this->_dnsServer;
238
					if($this->_dnsPort)
239
						$port = ":" . $this->_dnsPort;
240
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?username=' . urlencode($this->_dnsUser) . '&pass=' . urlencode($this->_dnsPass) . '&hostname=' . $this->_dnsHost.'&ip=' . $this->_dnsIP);
241
					$data = curl_exec($ch);
242
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
243
					curl_close($ch);
244
					$this->_checkStatus($data);
245
					break;
246
				case 'easydns':
247
					$needsIP = TRUE;
248
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
249
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
250
					$server = "http://members.easydns.com/dyn/dyndns.php";
251
					$port = "";
252
					if($this->_dnsServer)
253
						$server = $this->_dnsServer;
254
					if($this->_dnsPort)
255
						$port = ":" . $this->_dnsPort;
256
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard=' . $this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=' . $this->_dnsBackMX);
257
					$data = curl_exec($ch);
258
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
259
					curl_close($ch);
260
					$this->_checkStatus($data);
261
					break;
262
				case 'hn':
263
					$needsIP = TRUE;
264
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
265
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
266
					$server = "http://dup.hn.org/vanity/update";
267
					$port = "";
268
					if($this->_dnsServer)
269
						$server = $this->_dnsServer;
270
					if($this->_dnsPort)
271
						$port = ":" . $this->_dnsPort;
272
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?ver=1&IP=' . $this->_dnsIP);
273
					$data = curl_exec($ch);
274
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
275
					curl_close($ch);
276
					$this->_checkStatus($data);
277
					break;
278
				case 'zoneedit':
279
					$needsIP = FALSE;
280
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
281
					curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
282
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
283

    
284
					$server = "https://dynamic.zoneedit.com/auth/dynamic.html";
285
					$port = "";
286
					if($this->_dnsServer)
287
						$server = $this->_dnsServer;
288
					if($this->_dnsPort)
289
						$port = ":" . $this->_dnsPort;
290
					curl_setopt($ch, CURLOPT_URL, "{$server}{$port}?host=" .$this->_dnsHost);
291

    
292
					$data = curl_exec($ch);
293
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
294
					curl_close($ch);
295
					$this->_checkStatus($data);
296
					break;
297
				case 'dyns':
298
					$needsIP = FALSE;
299
					$server = "http://www.dyns.cx/postscript011.php";
300
					$port = "";
301
					if($this->_dnsServer)
302
						$server = $this->_dnsServer;
303
					if($this->_dnsPort)
304
						$port = ":" . $this->_dnsPort;					
305
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?username=' . urlencode($this->_dnsUser) . '&password=' . $this->_dnsPass . '&host=' . $this->_dnsHost);
306
					$data = curl_exec($ch);
307
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
308
					curl_close($ch);
309
					$this->_checkStatus($data);
310
					break;
311
				case 'ods':
312
					$needsIP = FALSE;
313
					$misc_errno = 0;
314
					$misc_error = "";
315
					$server = "ods.org";
316
					$port = "";
317
					if($this->_dnsServer)
318
						$server = $this->_dnsServer;
319
					if($this->_dnsPort)
320
						$port = ":" . $this->_dnsPort;						
321
					$this->con['socket'] = fsockopen("{$server}{$port}", "7070", $misc_errno, $misc_error, 30);
322
					/* Check that we have connected */
323
					if (!$this->con['socket']) {
324
						print "error! could not connect.";
325
						break;
326
					}
327
					/* Here is the loop. Read the incoming data (from the socket connection) */
328
					while (!feof($this->con['socket'])) {
329
						$this->con['buffer']['all'] = trim(fgets($this->con['socket'], 4096));
330
						$code = substr($this->con['buffer']['all'], 0, 3);
331
						sleep(1);
332
						switch($code) {
333
							case 100:
334
								fputs($this->con['socket'], "LOGIN ".$this->_dnsUser." ".$this->_dnsPass."\n");
335
								break;
336
							case 225:
337
								fputs($this->con['socket'], "DELRR ".$this->_dnsHost." A\n");
338
								break;
339
							case 901:
340
								fputs($this->con['socket'], "ADDRR ".$this->_dnsHost." A ".$this->_dnsIP."\n");
341
								break;
342
							case 795:
343
								fputs($this->con['socket'], "QUIT\n");
344
								break;
345
						}
346
					}
347
					$this->_checkStatus($code);
348
					break;
349
				case 'freedns':
350
					$needIP = FALSE;
351
					curl_setopt($ch, CURLOPT_URL, 'http://freedns.afraid.org/dynamic/update.php?' . $this->_dnsHost);
352
					$data = curl_exec($ch);
353
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
354
					curl_close($ch);
355
					$this->_checkStatus($data);
356
					break;
357
				case 'dnsexit':
358
					$needsIP = TRUE;
359
					curl_setopt($ch, CURLOPT_URL, 'http://www.dnsexit.com/RemoteUpdate.sv?login='.$this->_dnsUser. '&password='.$this->_dnsPass.'&host='.$this->_dnsHost.'&myip='.$this->_dnsIP);
360
					$data = curl_exec($ch);
361
					if (@curl_error($ch)) log_error("Curl error occurred:" . curl_error($ch));
362
					curl_close($ch);
363
					$this->_checkStatus($data);
364
					break;
365
				case 'loopia':
366
					$needsIP = TRUE;
367
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
368
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
369
					curl_setopt($ch, CURLOPT_URL, 'https://dns.loopia.se/XDynDNSServer/XDynDNS.php?hostname='.$this->_dnsHost.'&myip='.$this->_dnsIP);
370
					$data = curl_exec($ch);
371
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
372
					curl_close($ch);
373
					$this->_checkStatus($data);
374
					break;
375
				case 'opendns':
376
					$needsIP = FALSE;
377
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
378
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
379
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
380
					$server = "https://updates.opendns.com/nic/update?hostname=". $this->_dnsHost;
381
					$port = "";
382
					if($this->_dnsServer)
383
						$server = $this->_dnsServer;
384
					if($this->_dnsPort)
385
						$port = ":" . $this->_dnsPort;
386
					curl_setopt($ch, CURLOPT_URL, $server .$port);
387
					$data = curl_exec($ch);
388
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
389
					curl_close($ch);
390
					$this->_checkStatus($data);
391
					break;
392

    
393
				case 'staticcling':
394
					$needsIP = FALSE;
395
					curl_setopt($ch, CURLOPT_URL, 'http://www.staticcling.org/update.html?login='.$this->_dnsUser.'&pass='.$this->_dnsPass);
396
					$data = curl_exec($ch);
397
					if (@curl_error($ch)) log_error("Curl error occured: " . curl_error($ch));
398
					curl_close($ch);
399
					$this->_checkStatus($data);
400
					break;	                    
401
				case 'dnsomatic':
402
					/* Example syntax 
403
						https://username:password@updates.dnsomatic.com/nic/update?hostname=yourhostname&myip=ipaddress&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG
404
					*/
405
					$needsIP = FALSE;
406
					log_error("DNS-O-Matic: DNS update() starting.");
407
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
408
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
409
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
410
					$server = "https://" . $this->_dnsUser . ":" . $this->_dnsPass . "@updates.dnsomatic.com/nic/update?hostname=";
411
					if($this->_dnsServer)
412
						$server = $this->_dnsServer;
413
					if($this->_dnsPort)
414
						$port = ":" . $this->_dnsPort;
415
					curl_setopt($ch, CURLOPT_URL, $server . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NOCHG');
416
					$data = curl_exec($ch);
417
					if (@curl_error($ch)) log_error("Request completed. DNS-O-Matic reported: " . curl_error($ch));
418
					curl_close($ch);
419
					$this->_checkStatus($data);
420
					break;
421
				case 'namecheap':
422
					/* Example:
423
						https://dynamicdns.park-your-domain.com/update?host=[host_name]&domain=[domain.com]&password=[domain_password]&ip=[your_ip]
424
					*/
425
					$needsIP = FALSE;
426
					log_error("Namecheap: DNS update() starting.");
427
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
428
					list($hostname, $domain) = explode(".", $this->_dnsHost, 2);
429
					$server = "https://dynamicdns.park-your-domain.com/update?host={$hostname}&domain={$domain}&password={$this->_dnsPass}&ip={$this->_dnsIP}";
430
					curl_setopt($ch, CURLOPT_URL, $server);
431
					$data = curl_exec($ch);
432
					if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch));
433
					curl_close($ch);
434
					$this->_checkStatus($data);
435
				default:
436
					break;
437
			}
438
		}
439

    
440
		/*
441
		 * Private Function (added 12 July 2005) [beta]
442
		 *   Retrieve Update Status
443
		 */
444
		function _checkStatus($data) {
445
			log_error("DynDns: DynDns _checkStatus() starting.");
446
			log_error("DynDns: Current Service: {$this->_dnsService}");
447
			$successful_update = false;
448
			switch ($this->_dnsService) {
449
				case 'dnsomatic':
450
					if (preg_match('/badauth/i', $data)) {
451
						$status = "DNS-O-Matic: The DNS-O-Matic username or password specified are incorrect. No updates will be distributed to services until this is resolved.";
452
					} else if (preg_match('/notfqdn /i', $data)) {
453
						$status = "DNS-O-Matic: The hostname specified is not a fully-qualified domain name. If no hostnames included, notfqdn will be returned once.";
454
					} else if (preg_match('/nohost/i', $data)) {
455
						$status = "DNS-O-Matic: The hostname passed could not be matched to any services configured. The service field will be blank in the return code.";
456
					} else if (preg_match('/numhost/i', $data)) {
457
						$status = "DNS-O-Matic: You may update up to 20 hosts. numhost is returned if you try to update more than 20 or update a round-robin.";	
458
					} else if (preg_match('/abuse/i', $data)) {
459
						$status = "DNS-O-Matic: The hostname is blocked for update abuse.";
460
					} else if (preg_match('/good/i', $data)) {
461
						$status = "DNS-O-Matic: (Success) IP Address Changed Successfully! (".$this->_dnsIP.")";
462
						$successful_update = true;
463
					} else if (preg_match('/dnserr/i', $data)) {
464
						$status = "DNS-O-Matic: DNS error encountered. Stop updating for 30 minutes.";
465
					} else {
466
						$status = "DNS-O-Matic: (Unknown Response)";
467
						log_error("DNS-O-Matic: PAYLOAD: {$data}");
468
						$this->_debug($data);
469
					}
470
					break;
471
				case 'dyndns':
472
					if (preg_match('/notfqdn/i', $data)) {
473
						$status = "phpDynDNS: (Error) Not A FQDN!";
474
					} else if (preg_match('/nochg/i', $data)) {
475
						$status = "phpDynDNS: (Success) No Change In IP Address";
476
						$successful_update = true;
477
					} else if (preg_match('/good/i', $data)) {
478
						$status = "phpDynDNS: (Success) IP Address Changed Successfully! (".$this->_dnsIP.")";
479
						$successful_update = true;
480
					} else if (preg_match('/noauth/i', $data)) {
481
						$status = "phpDynDNS: (Error) User Authorization Failed";
482
					} else {
483
						$status = "phpDynDNS: (Unknown Response)";
484
						log_error("phpDynDNS: PAYLOAD: {$data}");
485
						$this->_debug($data);
486
					}
487
					break;
488
				case 'dyndns-static':
489
					if (preg_match('/notfqdn/i', $data)) {
490
						$status = "phpDynDNS: (Error) Not A FQDN!";
491
					} else if (preg_match('/nochg/i', $data)) {
492
						$status = "phpDynDNS: (Success) No Change In IP Address";
493
						$successful_update = true;
494
					} else if (preg_match('/good/i', $data)) {
495
						$status = "phpDynDNS: (Success) IP Address Changed Successfully!";
496
						$successful_update = true;
497
					} else if (preg_match('/noauth/i', $data)) {
498
						$status = "phpDynDNS: (Error) User Authorization Failed";
499
					} else {
500
						$status = "phpDynDNS: (Unknown Response)";
501
						log_error("phpDynDNS: PAYLOAD: {$data}");
502
						$this->_debug($data);
503
					}
504
					break;
505
				case 'dyndns-custom':
506
					if (preg_match('/notfqdn/i', $data)) {
507
						$status = "phpDynDNS: (Error) Not A FQDN!";
508
					} else if (preg_match('/nochg/i', $data)) {
509
						$status = "phpDynDNS: (Success) No Change In IP Address";
510
						$successful_update = true;
511
					} else if (preg_match('/good/i', $data)) {
512
						$status = "phpDynDNS: (Success) IP Address Changed Successfully!";
513
						$successful_update = true;
514
					} else if (preg_match('/noauth/i', $data)) {
515
						$status = "phpDynDNS: (Error) User Authorization Failed";
516
					} else {
517
						$status = "phpDynDNS: (Unknown Response)";
518
						log_error("phpDynDNS: PAYLOAD: {$data}");
519
						$this->_debug($data);
520
					}
521
					break;
522
				case 'dhs':
523
					break;
524
				case 'noip':
525
					list($ip,$code) = split(":",$data);
526
					switch ($code) {
527
						case 0:
528
							$status = "phpDynDNS: (Success) IP address is current, no update performed.";
529
							$successful_update = true;
530
							break;
531
						case 1:
532
							$status = "phpDynDNS: (Success) DNS hostname update successful.";
533
							$successful_update = true;
534
							break;
535
						case 2:
536
							$status = "phpDynDNS: (Error) Hostname supplied does not exist.";
537
							break;
538
						case 3:
539
							$status = "phpDynDNS: (Error) Invalid Username.";
540
							break;
541
						case 4:
542
							$status = "phpDynDNS: (Error) Invalid Password.";
543
							break;
544
						case 5:
545
							$status = "phpDynDNS: (Error) To many updates sent.";
546
							break;
547
						case 6:
548
							$status = "phpDynDNS: (Error) Account disabled due to violation of No-IP terms of service.";
549
							break;
550
						case 7:
551
							$status = "phpDynDNS: (Error) Invalid IP. IP Address submitted is improperly formatted or is a private IP address or is on a blacklist.";
552
							break;
553
						case 8:
554
							$status = "phpDynDNS: (Error) Disabled / Locked Hostname.";
555
							break;
556
						case 9:
557
							$status = "phpDynDNS: (Error) Host updated is configured as a web redirect and no update was performed.";
558
							break;
559
						case 10:
560
							$status = "phpDynDNS: (Error) Group supplied does not exist.";
561
							break;
562
						case 11:
563
							$status = "phpDynDNS: (Success) DNS group update is successful.";
564
							$successful_update = true;
565
							break;
566
						case 12:
567
							$status = "phpDynDNS: (Success) DNS group is current, no update performed.";
568
							$successful_update = true;
569
							break;
570
						case 13:
571
							$status = "phpDynDNS: (Error) Update client support not available for supplied hostname or group.";
572
							break;
573
						case 14:
574
							$status = "phpDynDNS: (Error) Hostname supplied does not have offline settings configured.";
575
							break;
576
						case 99:
577
							$status = "phpDynDNS: (Error) Client disabled. Client should exit and not perform any more updates without user intervention.";
578
							break;
579
						case 100:
580
							$status = "phpDynDNS: (Error) Client disabled. Client should exit and not perform any more updates without user intervention.";
581
							break;
582
						default:
583
							$status = "phpDynDNS: (Unknown Response)";
584
							$this->_debug("Unknown Response: ".$data);
585
							break;
586
					}
587
					break;
588
				case 'easydns':
589
					if (preg_match('/NOACCESS/i', $data)) {
590
						$status = "phpDynDNS: (Error) Authentication Failed: Username and/or Password was Incorrect.";
591
					} else if (preg_match('/NOSERVICE/i', $data)) {
592
						$status = "phpDynDNS: (Error) No Service: Dynamic DNS Service has been disabled for this domain.";
593
					} else if (preg_match('/ILLEGAL INPUT/i', $data)) {
594
						$status = "phpDynDNS: (Error) Illegal Input: Self-Explantory";
595
					} else if (preg_match('/TOOSOON/i', $data)) {
596
						$status = "phpDynDNS: (Error) Too Soon: Not Enough Time Has Elapsed Since Last Update";
597
					} else if (preg_match('/NOERROR/i', $data)) {
598
						$status = "phpDynDNS: (Success) IP Updated Successfully!";
599
						$successful_update = true;
600
					} else {
601
						$status = "phpDynDNS: (Unknown Response)";
602
						log_error("phpDynDNS: PAYLOAD: {$data}");
603
						$this->_debug($data);
604
					}
605
					break;
606
				case 'hn':
607
					/* FIXME: add checks */
608
					break;
609
				case 'zoneedit':
610
					if (preg_match('/799/i', $data)) {
611
						$status = "phpDynDNS: (Error 799) Update Failed!";				
612
					} else if (preg_match('/700/i', $data)) {
613
						$status = "phpDynDNS: (Error 700) Update Failed!";
614
					} else if (preg_match('/200/i', $data)) {
615
						$status = "phpDynDNS: (Success) IP Address Updated Successfully!";
616
						$successful_update = true;
617
					} else if (preg_match('/201/i', $data)) {
618
						$status = "phpDynDNS: (Success) IP Address Updated Successfully!";
619
						$successful_update = true;						
620
					} else {
621
						$status = "phpDynDNS: (Unknown Response)";
622
						log_error("phpDynDNS: PAYLOAD: {$data}");
623
						$this->_debug($data);
624
					}
625
					break;
626
				case 'dyns':
627
					if (preg_match("/400/i", $data)) {
628
						$status = "phpDynDNS: (Error) Bad Request - The URL was malformed. Required parameters were not provided.";
629
					} else if (preg_match('/402/i', $data)) {
630
						$status = "phpDynDNS: (Error) Update Too Soon - You have tried updating to quickly since last change.";
631
					} else if (preg_match('/403/i', $data)) {
632
						$status = "phpDynDNS: (Error) Database Error - There was a server-sided database error.";
633
					} else if (preg_match('/405/i', $data)) {
634
						$status = "phpDynDNS: (Error) Hostname Error - The hostname (".$this->_dnsHost.") doesn't belong to you.";
635
					} else if (preg_match('/200/i', $data)) {
636
						$status = "phpDynDNS: (Success) IP Address Updated Successfully!";
637
						$successful_update = true;
638
					} else {
639
						$status = "phpDynDNS: (Unknown Response)";
640
						log_error("phpDynDNS: PAYLOAD: {$data}");
641
						$this->_debug($data);
642
					}
643
					break;
644
				case 'ods':
645
					if (preg_match("/299/i", $data)) {
646
						$status = "phpDynDNS: (Success) IP Address Updated Successfully!";
647
						$successful_update = true;
648
					} else {
649
						$status = "phpDynDNS: (Unknown Response)";
650
						log_error("phpDynDNS: PAYLOAD: {$data}");
651
						$this->_debug($data);
652
					}
653
					break;
654
				case 'freedns':
655
					if (preg_match("/has not changed./i", $data)) {
656
						$status = "phpDynDNS: (Success) No Change In IP Address";
657
						$successful_update = true;
658
					} else if (preg_match("/Updated/i", $data)) {
659
						$status = "phpDynDNS: (Success) IP Address Changed Successfully!";
660
						$successful_update = true;
661
					} else {
662
						$status = "phpDynDNS: (Unknown Response)";
663
						log_error("phpDynDNS: PAYLOAD: {$data}");
664
						$this->_debug($data);
665
					} 
666
					break;
667
				case 'dnsexit':
668
					if (preg_match("/is the same/i", $data)) {
669
						$status = "phpDynDns: (Success) No Change In IP Address";
670
						$successful_update = true;
671
					} else if (preg_match("/Success/i", $data)) {
672
						$status = "phpDynDNS: (Success) IP Address Changed Successfully!";
673
						$successful_update = true;
674
					} else {
675
						$status = "phpDynDNS: (Unknown Response)";
676
                                                log_error("phpDynDNS: PAYLOAD: {$data}");
677
                                                $this->_debug($data);
678
					}
679
					break;
680
				case 'loopia':
681
					if (preg_match("/nochg/i", $data)) {
682
						$status = "phpDynDNS: (Success) No Change In IP Address";
683
						$successful_update = true;
684
					} else if (preg_match("/good/i", $data)) {
685
						$status = "phpDynDNS: (Success) IP Address Changed Successfully!";
686
						$successful_update = true;
687
					} else if (preg_match('/badauth/i', $data)) {
688
						$status = "phpDynDNS: (Error) User Authorization Failed";
689
					} else {
690
						$status = "phpDynDNS: (Unknown Response)";
691
						log_error("phpDynDNS: PAYLOAD: {$data}");
692
						$this->_debug($data);
693
					}
694
					break;
695
				case 'opendns':
696
					if (preg_match('/badauth/i', $data)) {
697
						$status = "phpDynDNS: (Error) Not a valid username or password!";
698
					} else if (preg_match('/nohost/i', $data)) {
699
						$status = "phpDynDNS: (Error) Hostname you are trying to update does not exist.";
700
						$successful_update = true;
701
					} else if (preg_match('/good/i', $data)) {
702
						$status = "phpDynDNS: (Success) IP Address Changed Successfully! (".$this->_dnsIP.")";
703
						$successful_update = true;
704
					} else if (preg_match('/yours/i', $data)) {
705
						$status = "phpDynDNS: (Error) hostname specified exists, but not under the username specified.";
706
					} else if (preg_match('/abuse/i', $data)) {
707
						$status = "phpDynDns: (Error) Updating to frequently, considered abuse.";
708
					} else {
709
						$status = "phpDynDNS: (Unknown Response)";
710
						log_error("phpDynDNS: PAYLOAD: {$data}");
711
						$this->_debug($data);
712
					}
713
					break;
714
                 case 'staticcling':
715
					if (preg_match("/invalid ip/i", $data)) {
716
					        $status = "phpDynDNS: (Error) Bad Request - The IP provided was invalid.";
717
					} else if (preg_match('/required info missing/i', $data)) {
718
					        $status = "phpDynDNS: (Error) Bad Request - Required parameters were not provided.";
719
					} else if (preg_match('/invalid characters/i', $data)) {
720
					        $status = "phpDynDNS: (Error) Bad Request - Illegal characters in either the username or the password.";
721
					} else if (preg_match('/bad password/i', $data)) {
722
					        $status = "phpDynDNS: (Error) Invalid password.";
723
					} else if (preg_match('/account locked/i', $data)) {
724
					        $status = "phpDynDNS: (Error) This account has been administratively locked.";
725
					} else if (preg_match('/update too frequent/i', $data)) {
726
					        $status = "phpDynDNS: (Error) Updating too frequently.";
727
					} else if (preg_match('/DB error/i', $data)) {
728
					        $status = "phpDynDNS: (Error) Server side error.";
729
					} else if (preg_match('/success/i', $data)) {
730
					        $status = "phpDynDNS: (Success) IP Address Updated Successfully!";
731
					        $successful_update = true;
732
					} else {
733
					        $status = "phpDynDNS: (Unknown Response)";
734
					        log_error("phpDynDNS: PAYLOAD: {$data}");
735
					        $this->_debug($data);
736
					}
737
					break;
738
				case 'namecheap':
739
					if (preg_match("/internal server error/i", $data)) {
740
						$status = "phpDynDNS: (Error) Server side error.";
741
					} else if (preg_match('/success/i', $data)) {
742
					        $status = "phpDynDNS: (Success) IP Address Updated Successfully!";
743
					        $successful_update = true;
744
					} else {
745
						$status = "phpDynDNS: (Unknown Response)";
746
						log_error("phpDynDNS: PAYLOAD: {$data}");
747
						$this->_debug($data);
748
					}
749
					break;
750
			}
751
			
752
			if($successful_update == true) {
753
				/* Write WAN IP to cache file */
754
				$wan_ip = $this->_checkIP();
755
				$currentTime = time();				  
756
				log_error("phpDynDNS: updating cache file {$this->_cacheFile}: {$wan_ip}");
757
				conf_mount_rw();
758
				$file = fopen($this->_cacheFile, 'w');
759
				fwrite($file, $wan_ip.':'.$currentTime);
760
				fclose($file);
761
				conf_mount_ro();
762
			}
763
			$this->status = $status;
764
			log_error($status);
765
		}
766

    
767
		/*
768
		 * Private Function (added 12 July 05) [beta]
769
		 *   Return Error, Set Last Error, and Die.
770
		 */
771
		function _error($errorNumber = '1') {
772
			switch ($errorNumber) {
773
				case 0:
774
					break;
775
				case 2:
776
					$error = 'phpDynDNS: (ERROR!) No Dynamic DNS Service provider was selected.';
777
					break;
778
				case 3:
779
					$error = 'phpDynDNS: (ERROR!) No Username Provided.';
780
					break;
781
				case 4:
782
					$error = 'phpDynDNS: (ERROR!) No Password Provided.';
783
					break;
784
				case 5:
785
					$error = 'phpDynDNS: (ERROR!) No Hostname Provided.';
786
					break;
787
				case 6:
788
					$error = 'phpDynDNS: (ERROR!) The Dynamic DNS Service provided is not yet supported.';
789
					break;
790
				case 7:
791
					$error = 'phpDynDNS: (ERROR!) No Update URL Provided.';
792
					break;
793
				case 10:
794
					$error = 'phpDynDNS: No change in my IP address and/or 25 days has not passed. Not updating dynamic DNS entry.';
795
					break;
796
				default:
797
					$error = "phpDynDNS: (ERROR!) Unknown Response.";
798
					/* FIXME: $data isn't in scope here */
799
					/* $this->_debug($data); */
800
					break;
801
			}
802
			$this->lastError = $error;
803
			log_error($error);
804
		}
805

    
806
		/*
807
		 * Private Function (added 12 July 05) [beta]
808
		 *   - Detect whether or not IP needs to be updated.
809
		 *      | Written Specifically for pfSense (pfsense.com) may
810
		 *      | work with other systems. pfSense base is FreeBSD.
811
		 */
812
		function _detectChange() {
813
			
814
			log_error("DynDns: _detectChange() starting.");
815
		
816
			$currentTime = time();
817

    
818
			$wan_ip = $this->_checkIP();
819
			$this->_dnsIP = $wan_ip;
820
			log_error("DynDns: Current WAN IP: {$wan_ip}");
821

    
822
			if (file_exists($this->_cacheFile)) {
823
				if(file_exists($this->_cacheFile))
824
					$contents = file_get_contents($this->_cacheFile);
825
				else
826
					$contents = "";
827
				list($cacheIP,$cacheTime) = split(':', $contents);
828
				$this->_debug($cacheIP.'/'.$cacheTime);
829
				$initial = false;
830
				log_error("DynDns: Cached IP: {$cacheIP}");
831
			} else {
832
				conf_mount_rw();
833
				$file = fopen($this->_cacheFile, 'w');
834
				fwrite($file, '0.0.0.0:'.$currentTime);
835
				fclose($file);
836
				conf_mount_ro();
837
				$cacheIP = '0.0.0.0';
838
				$cacheTime = $currentTime;
839
				$initial = true;
840
				log_error("DynDns: No Cached IP found.");
841
			}
842

    
843
			/*   use 2419200 for dyndns, dhs, easydns, noip, hn
844
			 *   zoneedit, dyns, ods
845
			 */
846
			$time = '2160000';
847

    
848
			$needs_updating = FALSE;
849
			/* lets determine if the item needs updating */
850
			if ($cacheIP != $wan_ip) {
851
				$needs_updating = true;
852
				$update_reason = "DynDns: cacheIP != wan_ip.  Updating. ";
853
				$update_reason .= "Cached IP: {$cacheIP} WAN IP: {$wan_ip} ";
854
			}
855
			if (($currentTime - $cacheTime) > $time ) {
856
				$needs_updating = true;
857
				$update_reason = "DynDns: More than 25 days.  Updating. ";
858
				$update_reason .= "{$currentTime} - {$cacheTime} > {$time} ";
859
			}
860
			if ($initial == true) {
861
				$needs_updating = true;
862
				$update_reason .= "Inital update. ";
863
			}
864

    
865
			/*   finally if we need updating then store the
866
			 *   new cache value and return true
867
                         */
868
			if ($needs_updating == true) {
869
				log_error("DynDns debug information: {$update_reason}");
870
				return true;
871
			}
872

    
873
			return false;			
874
		}
875

    
876
		/*
877
		 * Private Funcation (added 16 July 05) [beta]
878
		 *   - Writes debug information to a file.
879
		 *   - This function is only called when a unknown response
880
		 *   - status is returned from a DynDNS service provider.
881
		 */
882
		function _debug ($data) {
883
			$string = '\n'.date('m-d-y h:i:s').' - ('.$this->_debugID.') - ['.$this->_dnsService.'] - '.$data.'\n';
884
			conf_mount_rw();
885
			$file = fopen($this->_debugFile, 'a');
886
			fwrite($file, $string);
887
			fclose($file);
888
			conf_mount_ro();
889
		}
890
		function _checkIP() {
891

    
892
			log_error("DynDns: _checkIP() starting.");
893

    
894
			$ip_address = find_interface_ip($this->_if);
895
			$this->_ifIP = $ip_address;
896
			if (is_private_ip($ip_address)) {
897
				$hosttocheck = "checkip.dyndns.org";
898
				$checkip = gethostbyname($hosttocheck);
899
				$ip_ch = curl_init("http://{$checkip}");
900
				curl_setopt($ip_ch, CURLOPT_RETURNTRANSFER, 1);
901
				curl_setopt($ip_ch, CURLOPT_SSL_VERIFYPEER, FALSE);
902
				curl_setopt($ip_ch, CURLOPT_INTERFACE, $ip_address);
903
				$ip_result_page = curl_exec($ip_ch);
904
				curl_close($ip_ch);
905
				$ip_result_decoded = urldecode($ip_result_page);
906
				preg_match('/Current IP Address: (.*)<\/body>/', $ip_result_decoded, $matches);
907
				$ip_address = trim($matches[1]);
908
				log_error("DynDns debug information: {$ip_address} extracted from {$hosttocheck}");
909
			} else
910
				log_error("DynDns debug information: {$ip_address} extracted from local system.");
911

    
912
			return $ip_address;
913
		}
914

    
915
	}
916

    
917
?>
(14-14/54)