2 ##############################################################################
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 2 as
6 # published by the Free Software Foundation.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # Copyright (C) 2016 Eric Luehrsen
15 ##############################################################################
17 # Turn DHCP records into meaningful A, AAAA, and PTR records. Also lift a
18 # function from dnsmasq and use DHCPv4 MAC to find IPV6 SLAAC hosts.
21 # "hostfile" = where this script will cache host DNS data
22 # "domain" = text domain suffix
23 # "bslaac" = boolean, use DHCPv4 MAC to find GA and ULA IPV6 SLAAC
24 # "bisolt" = boolean, format <host>.<network>.<domain>. so you can isolate
25 # "bconf" = boolean, write conf file format rather than pipe records
27 ##############################################################################
30 # We need to pick out DHCP v4 or v6 records
31 net = $
2 ; id = $
3 ; cls = $
4 ; hst = $
5 ; adr = $
9 ;
33 sub( /\
/.
*/, "", adr
) ;
34 sub( /.
*\
//, "", cdr
) ;
38 # TODO: this might be better with a substituion option,
39 # or per DHCP pool do-not-DNS option, but its getting busy here.
41 fqdn =
sub( /\.
/, "-", fqdn
) ;
42 fqdn =
tolower( hst
"." fqdn
"." domain
) ;
46 fqdn =
tolower( hst
"." domain
) ;
50 if ( cls ==
"ipv4" ) {
52 # odhcpd errata in field format without host name
53 adr = $
8 ; hst =
"-" ; cdr = adr
;
54 sub( /\
/.
*/, "", adr
) ;
55 sub( /.
*\
//, "", cdr
) ;
59 if (( cdr ==
32 ) && ( hst
!= "-" )) {
60 # only for provided hostnames and full /32 assignments
61 ptr = adr
; qpr =
"" ; split( ptr
, ptr
, "." ) ;
62 slaac = slaac_eui64
( id
) ;
66 x =
( "local-data: \"" fqdn
". 120 IN A " adr
"\"" ) ;
67 y =
( "local-data-ptr: \"" adr
" 120 " fqdn
"\"" ) ;
68 print ( x
"\n" y
) > hostfile
;
72 for( i=
1; i
<=
4; i
++ ) { qpr =
( ptr
[i
] "." qpr
) ; }
73 x =
( fqdn
". 120 IN A " adr
) ;
74 y =
( qpr
"in-addr.arpa. 120 IN PTR " fqdn
) ;
75 print ( x
"\n" y
) > hostfile
;
79 if (( bslaac ==
1 ) && ( slaac
!= 0 )) {
80 # UCI option to discover IPV6 routed SLAAC addresses
81 # NOT TODO - ping probe take too long when added in awk-rule loop
82 cmd =
( "ip -6 --oneline route show dev " net
) ;
85 while ( ( cmd
| getline adr
) > 0 ) {
86 if (( substr( adr
, 1, 5 ) <=
"fd00:" ) \
87 && ( index( adr
, "via" ) ==
0 )) {
88 # GA or ULA routed addresses only (not LL or MC)
89 sub( /\
/.
*/, "", adr
) ;
93 if ( split( adr
, tmp0
, ":" ) >=
8 ) {
94 sub( "::", ":", adr
) ;
99 x =
( "local-data: \"" fqdn
". 120 IN AAAA " adr
"\"" ) ;
100 y =
( "local-data-ptr: \"" adr
" 120 " fqdn
"\"" ) ;
101 print ( x
"\n" y
) > hostfile
;
105 qpr = ipv6_ptr
( adr
) ;
106 x =
( fqdn
". 120 IN AAAA " adr
) ;
107 y =
( qpr
". 120 IN PTR " fqdn
) ;
108 print ( x
"\n" y
) > hostfile
;
120 if (( cdr ==
128 ) && ( hst
!= "-" )) {
122 x =
( "local-data: \"" fqdn
". 120 IN AAAA " adr
"\"" ) ;
123 y =
( "local-data-ptr: \"" adr
" 120 " fqdn
"\"" ) ;
124 print ( x
"\n" y
) > hostfile
;
128 # only for provided hostnames and full /128 assignments
129 qpr = ipv6_ptr
( adr
) ;
130 x =
( fqdn
". 120 IN AAAA " adr
) ;
131 y =
( qpr
". 120 IN PTR " fqdn
) ;
132 print ( x
"\n" y
) > hostfile
;
138 ##############################################################################
140 function ipv6_ptr
( ipv6
, arpa
, ary
, end, i
, j
, new6
, sz
, start
) {
141 # IPV6 colon flexibility is a challenge when creating [ptr].ip6.arpa.
142 sz =
split( ipv6
, ary
, ":" ) ; end =
9 - sz
;
145 for( i=
1; i
<=sz
; i
++ ) {
146 if( length(ary
[i
]) ==
0 ) {
147 for( j=
1; j
<=
end; j
++ ) { ary
[i
] =
( ary
[i
] "0000" ) ; }
151 ary
[i
] =
substr( ( "0000" ary
[i
] ), length( ary
[i
] )+5-4 ) ;
157 for( i =
2; i
<= sz
; i
++ ) { new6 =
( new6 ary
[i
] ) ; }
158 start =
length( new6
) ;
159 for( i=start
; i
>0; i
-- ) { arpa =
( arpa
substr( new6
, i
, 1 ) ) ; } ;
160 gsub( /.
/, "&\.", arpa
) ; arpa =
( arpa
"ip6.arpa" ) ;
165 ##############################################################################
167 function slaac_eui64
( mac
, ary
, glbit
, eui64
) {
168 if ( length(mac
) >=
12 ) {
169 # RFC2373 and use DHCPv4 registered MAC to find SLAAC addresses
170 split( mac
, ary
, "" ) ;
171 glbit =
( "0x" ary
[2] ) ;
172 glbit =
sprintf( "%d", glbit
) ;
173 glbit = or
( glbit
, 2 ) ;
174 ary
[2] =
sprintf( "%x", glbit
) ;
175 eui64 =
( ary
[1] ary
[2] ary
[3] ary
[4] ":" ary
[5] ary
[6] "ff:fe" ) ;
176 eui64 =
( eui64 ary
[7] ary
[8] ":" ary
[9] ary
[10] ary
[11] ary
[12] ) ;
187 ##############################################################################