lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

odhcpd.awk (6207B)


      1 #!/usr/bin/awk
      2 ##############################################################################
      3 #
      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.
      7 #
      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.
     12 #
     13 # Copyright (C) 2016 Eric Luehrsen
     14 #
     15 ##############################################################################
     16 #
     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.
     19 #
     20 # External Parameters
     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
     26 #
     27 ##############################################################################
     28 
     29 /^#/ {
     30   # We need to pick out DHCP v4 or v6 records
     31   net = $2 ; id = $3 ; cls = $4 ; hst = $5 ; adr = $9 ; adr2 = $10
     32   cdr = adr ;
     33   cdr2 = adr2 ;
     34   sub( /\/.*/, "", adr ) ;
     35   sub( /.*\//, "", cdr ) ;
     36   sub( /\/.*/, "", adr2 ) ;
     37   sub( /.*\//, "", cdr2 ) ;
     38 
     39 
     40   if ( bisolt == 1 ) {
     41     # TODO: this might be better with a substituion option,
     42     # or per DHCP pool do-not-DNS option, but its getting busy here.
     43     fqdn = net
     44     fqdn = sub( /\./, "-", fqdn ) ;
     45     fqdn = tolower( hst "." fqdn "." domain ) ;
     46   }
     47 
     48   else {
     49     fqdn = tolower( hst "." domain ) ;
     50   }
     51 
     52 
     53   if ( cls == "ipv4" ) {
     54     if ( NF == 8 ) {
     55       # odhcpd errata in field format without host name
     56       adr = $8 ; hst = "-" ; cdr = adr ;
     57       sub( /\/.*/, "", adr ) ;
     58       sub( /.*\//, "", cdr ) ;
     59     }
     60 
     61 
     62     if (( cdr == 32 ) && ( hst != "-" )) {
     63       # only for provided hostnames and full /32 assignments
     64       ptr = adr ; qpr = "" ; split( ptr, ptr, "." ) ;
     65       slaac = slaac_eui64( id ) ;
     66 
     67 
     68       if ( bconf == 1 ) {
     69         x = ( "local-data: \"" fqdn ". 120 IN A " adr "\"" ) ;
     70         y = ( "local-data-ptr: \"" adr " 120 " fqdn "\"" ) ;
     71         print ( x "\n" y ) > hostfile ;
     72       }
     73 
     74       else {
     75         for( i=1; i<=4; i++ ) { qpr = ( ptr[i] "." qpr) ; }
     76         x = ( fqdn ". 120 IN A " adr ) ;
     77         y = ( qpr "in-addr.arpa. 120 IN PTR " fqdn ) ;
     78         print ( x "\n" y ) > hostfile ;
     79       }
     80 
     81 
     82       if (( bslaac == 1 ) && ( slaac != 0 )) {
     83         # UCI option to discover IPV6 routed SLAAC addresses
     84         # NOT TODO - ping probe take too long when added in awk-rule loop
     85         cmd = ( "ip -6 --oneline route show dev " net ) ;
     86 
     87 
     88         while ( ( cmd | getline adr ) > 0 ) {
     89           if (( substr( adr, 1, 5 ) <= "fd00:" ) \
     90           && ( index( adr, "via" ) == 0 )) {
     91             # GA or ULA routed addresses only (not LL or MC)
     92             sub( /\/.*/, "", adr ) ;
     93             adr = ( adr slaac ) ;
     94             
     95             
     96             if ( split( adr, tmp0, ":" ) >= 8 ) { 
     97               sub( "::", ":", adr ) ; 
     98             }
     99 
    100 
    101             if ( bconf == 1 ) {
    102               x = ( "local-data: \"" fqdn ". 120 IN AAAA " adr "\"" ) ;
    103               y = ( "local-data-ptr: \"" adr " 120 " fqdn "\"" ) ;
    104               print ( x "\n" y ) > hostfile ;
    105             }
    106 
    107             else {
    108               qpr = ipv6_ptr( adr ) ;
    109               x = ( fqdn ". 120 IN AAAA " adr ) ;
    110               y = ( qpr ". 120 IN PTR " fqdn ) ;
    111               print ( x "\n" y ) > hostfile ;
    112             }
    113           }
    114         }
    115 
    116 
    117         close( cmd ) ;
    118       }
    119     }
    120   }
    121 
    122   else {
    123     if (( cdr == 128 ) && ( hst != "-" )) {
    124       if ( bconf == 1 ) {
    125         x = ( "local-data: \"" fqdn ". 120 IN AAAA " adr "\"" ) ;
    126         y = ( "local-data-ptr: \"" adr " 120 " fqdn "\"" ) ;
    127         print ( x "\n" y ) > hostfile ;
    128       }
    129 
    130       else {
    131         # only for provided hostnames and full /128 assignments
    132         qpr = ipv6_ptr( adr ) ;
    133         x = ( fqdn ". 120 IN AAAA " adr ) ;
    134         y = ( qpr ". 120 IN PTR " fqdn ) ;
    135         print ( x "\n" y ) > hostfile ;
    136       }
    137     }
    138     
    139     if (( cdr2 == 128 ) && ( hst != "-" )) {
    140       if ( bconf == 1 ) {
    141         x = ( "local-data: \"" fqdn ". 120 IN AAAA " adr2 "\"" ) ;
    142         y = ( "local-data-ptr: \"" adr2 " 120 " fqdn "\"" ) ;
    143         print ( x "\n" y ) > hostfile ;
    144       }
    145 
    146       else {
    147         # odhcp puts GA and ULA on the same line (position 9 and 10)
    148         qpr2 = ipv6_ptr( adr2 ) ;
    149         x = ( fqdn ". 120 IN AAAA " adr2 ) ;
    150         y = ( qpr2 ". 120 IN PTR " fqdn ) ;
    151         print ( x "\n" y ) > hostfile ;
    152       }
    153     }
    154   }
    155 }
    156 
    157 ##############################################################################
    158 
    159 function ipv6_ptr( ipv6,    arpa, ary, end, i, j, new6, sz, start ) {
    160   # IPV6 colon flexibility is a challenge when creating [ptr].ip6.arpa.
    161   sz = split( ipv6, ary, ":" ) ; end = 9 - sz ;
    162 
    163 
    164   for( i=1; i<=sz; i++ ) {
    165     if( length(ary[i]) == 0 ) {
    166       for( j=1; j<=end; j++ ) { ary[i] = ( ary[i] "0000" ) ; }
    167     }
    168 
    169     else {
    170       ary[i] = substr( ( "0000" ary[i] ), length( ary[i] )+5-4 ) ;
    171     }
    172   }
    173 
    174 
    175   new6 = ary[1] ;
    176   for( i = 2; i <= sz; i++ ) { new6 = ( new6 ary[i] ) ; }
    177   start = length( new6 ) ;
    178   for( i=start; i>0; i-- ) { arpa = ( arpa substr( new6, i, 1 ) ) ; } ;
    179   gsub( /./, "&\.", arpa ) ; arpa = ( arpa "ip6.arpa" ) ;
    180 
    181   return arpa ;
    182 }
    183 
    184 ##############################################################################
    185 
    186 function slaac_eui64( mac,    ary, glbit, eui64 ) {
    187   if ( length(mac) >= 12 ) {
    188     # RFC2373 and use DHCPv4 registered MAC to find SLAAC addresses
    189     split( mac , ary , "" ) ;
    190     glbit = ( "0x" ary[2] ) ;
    191     glbit = sprintf( "%d", glbit ) ;
    192     glbit = or( glbit, 2 ) ;
    193     ary[2] = sprintf( "%x", glbit ) ;
    194     eui64 = ( ary[1] ary[2] ary[3] ary[4] ":" ary[5] ary[6] "ff:fe" ) ;
    195     eui64 = ( eui64 ary[7] ary[8] ":" ary[9] ary[10]  ary[11] ary[12] ) ;
    196   }
    197 
    198   else {
    199     eui64 = 0 ;
    200   }
    201 
    202 
    203   return eui64 ;
    204 }
    205 
    206 ##############################################################################
    207