aboutsummaryrefslogtreecommitdiffstats
path: root/testing/ddclient/ddclient-ipv6.patch
blob: 52f80da54cd209ad4234bcad0f231187413ab28d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
--- a/ddclient.orig	2015-01-18 13:53:05.060668715 +0100
+++ b/ddclient	2015-01-18 13:59:55.607618249 +0100
@@ -55,6 +55,7 @@
 sub T_FQDNP	{'fully qualified host name and optional port number'};
 sub T_PROTO	{'protocol'}
 sub T_USE	{'ip strategy'}
+sub T_USEV6	{'ipv6 strategy'}
 sub T_IF        {'interface'}
 sub T_PROG      {'program name'}
 sub T_IP        {'ip'}
@@ -330,6 +331,7 @@
 	'protocol'            => setv(T_PROTO, 0, 0, 1, 'dyndns2',            undef),
 
 	'use'                 => setv(T_USE,   0, 0, 1, 'ip',                 undef),
+	'usev6'               => setv(T_USEV6, 0, 0, 1, undef,                undef),
 	'ip'                  => setv(T_IP,    0, 0, 1, undef,                undef),
 	'if'                  => setv(T_IF,    0, 0, 1, 'ppp0',               undef),
 	'if-skip'             => setv(T_STRING,1, 0, 1, '',                   undef),
@@ -370,6 +372,7 @@
 	'host'                => setv(T_STRING, 1, 1, 1, '',                  undef),
 
 	'use'                 => setv(T_USE,   0, 0, 1, 'ip',                 undef),
+	'usev6'               => setv(T_USE,   0, 0, 1, undef,                undef),
 	'if'                  => setv(T_IF,    0, 0, 1, 'ppp0',               undef),
 	'if-skip'             => setv(T_STRING,0, 0, 1, '',                   undef),
 	'web'                 => setv(T_STRING,0, 0, 1, 'dyndns',             undef),
@@ -597,7 +600,8 @@
     [ "cache",       "=s", "-cache path           : record address used in 'path'" ],
     [ "pid",         "=s", "-pid path             : record process id in 'path'" ],
     "",			     
-    [ "use",         "=s", "-use which            : how the should IP address be obtained." ],
+    [ "use",         "=s", "-use which            : how should the IP address be obtained." ],
+    [ "usev6",       "=s", "-usev6 which          : how should the IPv6 address be obtained." ],
                                                   &ip_strategies_usage(),
     "",			     
     [ "ip",          "=s", "-ip address           : set the IP address to 'address'" ],
@@ -788,12 +792,20 @@
 		my (@hosts, %ips) = ();
 		my $updateable = $services{$s}{'updateable'};
 		my $update     = $services{$s}{'update'};
+		my $ipv6 = 0;
 
 		foreach my $h (sort keys %config) {
 			next if $config{$h}{'protocol'} ne lc($s);
 			$examined{$h} = 1;
 			# we only do this once per 'use' and argument combination
-			my $use = opt('use', $h);
+			my $use = '';
+			$ipv6 = 1 if (defined $config{$h}{'usev6'});
+			if ($ipv6) {
+				$use = opt('usev6', $h);
+			}
+			else {
+				$use = opt('use', $h);
+			}
 			my $arg_ip = opt('ip', $h) || '';
 			my $arg_fw = opt('fw', $h) || '';
 			my $arg_if = opt('if', $h) || '';
@@ -803,16 +815,20 @@
 			if (exists $iplist{$use}{$arg_ip}{$arg_fw}{$arg_if}{$arg_web}{$arg_cmd}) {
 				$ip = $iplist{$use}{$arg_ip}{$arg_fw}{$arg_if}{$arg_web}{$arg_cmd};
 			} else {
-				$ip = get_ip($use, $h);
+				$ip = get_ip($use, $h) if !$ipv6;
+				$ip = get_ipv6($use, $h) if $ipv6;
 				if (!defined $ip || !$ip) {
 					warning("unable to determine IP address")
 						if !$daemon || opt('verbose');
 					next;
 				}
-				if ($ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
+				if (!$ipv6 and $ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
 					warning("malformed IP address (%s)", $ip);
 					next;
 				}
+				if ($ipv6 and $ip !~ /^[0-9a-f:]+$/) {
+					warning("malformed IPv6 address (%s)", $ip);
+				}
 				$iplist{$use}{$arg_ip}{$arg_fw}{$arg_if}{$arg_web}{$arg_cmd} = $ip;
 			}
 			$config{$h}{'wantip'} = $ip;
@@ -953,7 +969,7 @@
     my ($c, $name, $value);
     my ($escape, $quote) = (0, '');
 
-    if ($rest =~ /^\s*([a-z][a-z_-]*)=(.*)/i) {
+    if ($rest =~ /^\s*([a-z][0-9a-z_-]*)=(.*)/i) {
 	($name, $rest, $value) = ($1, $2, '');
 
 	while (length($c = substr($rest,0,1))) {
@@ -1131,6 +1147,11 @@
     $opt{'use'} = 'if'  if !define($opt{'use'}) && defined($opt{'if'});
     $opt{'use'} = 'web' if !define($opt{'use'}) && defined($opt{'web'});
 
+    ## infer the IPv6 strategy if possible
+    $opt{'usev6'} = 'ip'  if !define($opt{'usev6'}) && defined($opt{'ip'});
+    $opt{'usev6'} = 'if'  if !define($opt{'usev6'}) && defined($opt{'if'});
+    $opt{'usev6'} = 'web' if !define($opt{'usev6'}) && defined($opt{'web'});
+
     ## sanity check
     $opt{'max-interval'}       = min(interval(opt('max-interval')), interval(default('max-interval')));
     $opt{'min-interval'}       = max(interval(opt('min-interval')), interval(default('min-interval')));
@@ -1740,6 +1761,10 @@
 	$value = lc $value;
 	return undef if ! exists $ip_strategies{$value};
 
+    } elsif ($type eq T_USEV6) {
+	$value = lc $value;
+	return undef if ! exists $ip_strategies{$value};
+
     } elsif ($type eq T_FILE) {
 	return undef if $value eq "";
 
@@ -1756,7 +1781,7 @@
 #	return undef if $value =~ /:/;
 
     } elsif ($type eq T_IP) {
-	return undef if $value !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
+	return undef if $value !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ and $value !~ /^[0-9a-f:]+$/;
     }
     return $value;
 }
@@ -2046,6 +2071,42 @@
 	$ip = $1;
     }
     if (($use ne 'ip') && (define($ip,'') eq '0.0.0.0')) {
+	$ip = undef;
+    }
+
+    debug("get_ip: using %s, %s reports %s", $use, $arg, define($ip, "<undefined>"));
+    return $ip;
+}
+
+######################################################################
+## get_ipv6
+######################################################################
+sub get_ipv6 {
+    my $use = lc shift;
+    my $h = shift;
+    my ($ip, $arg, $reply, $url, $skip) = (undef, opt($use), '');
+    $arg = '' unless $arg;
+
+    if ($use eq 'ip') {
+	$ip  = opt('ip', $h);
+	$arg = 'ip';
+
+    } elsif ($use eq 'if') {
+	$skip  = opt('if-skip', $h)  || '';
+	$reply = `ip -6 addr list dev $arg | grep "scope.global" | grep -v temporary | grep -v "inet6 f[cd]" 2> /dev/null`;
+	$reply = '' if $?;
+    }
+    if (!defined $reply) {
+	$reply = '';
+    }
+    if ($skip) {
+	$skip  =~ s/ /\\s/is;
+    	$reply =~ s/^.*?${skip}//is;
+    }
+    if ($reply =~ /.*? ([0-9:][^\/]*)/i) {
+	$ip = $1;
+    }
+    if (($use ne 'ip') && (define($ip,'') eq '0.0.0.0')) {
 	$ip = undef;
     }