### -*- Perl -*- ### # See the COPYING.txt file in this directory for Copyright information # and usage restrictions # Routines to parse out entries in the inventory database # MFB 6/14/95 package InvStuff; # # Global variables # $main'DBHOME="/var/local/etc/invdb5"; $main'INVDBFILE="$main'DBHOME/inventory"; $main'HN2KEYFILE="$main'DBHOME/hn2invkey"; $main'NETGROUP_SPECIALS="$main'DBHOME/netgroup.specials"; $main'OBJDIR="$main'DBHOME/obj"; $main'DOMAIN="CS.Princeton.EDU"; @main'VPNNETS=('192.168.42','192.168.84','192.168.126'); @main'SUBNETS=(4,5,6,7,92,93,94,95,104,105, 106,107,136,137,138,139,152,153,154,155,168,169,170,171); %main'SUBNETNAMES=( '4', 'cs-staff', '5', 'cs-staff2', '6', 'cs-test', '7', 'cs-devices', '92', 'cs-grad', '93', 'cs-grad2', '94', 'cs-ugrad', '95', 'cs-faculty', '104', 'cs-wireless', '105', 'cs-wireless2', '106', 'cs-wireless3', '107', 'cs-wireless4', '136', 'cs-136', '137', 'cs-136-hidden', '138', 'cs-138s', '139', 'cs-139s', '152', 'cs-mr', '153', 'cs-ag', '154', 'cs-slip', '155', 'cs-slipether', '168', 'cs-xdm1', '169', 'cs-xdm2', '170', 'cs-xdm3', '171', 'cs-cluster', ); %main'HOSTDEFAULTS=( 'OS', '*REQUIRED*', 'account', '175-9999', 'acct1059', '175', 'adminDomain', 'CompSci', 'building', '35 Olden St.', 'citType', 'HOST', 'citnetgroups', 'princetonhosts', 'class', 'hidden', 'cs_holder', '*REQUIRED*', 'cs_owned', '*REQUIRED*', 'deptNumber', '175', 'dnsDomain', 'CS.Princeton.EDU', 'infoContact', 'csstaff@cs.Princeton.EDU', 'ifExposed', 'NONE', 'ifType', 'Ethernet', 'interface', 'xx:xx:xx:xx:xx:xx,128.112.xxx.xxx,IPv6addr,ALIASES *REQUIRED*', 'locPrecision', '1m 10m 10m', 'mx', 'mail SMTP', 'srv', '_Service._Proto.OPT_Name,Priority,Weight,Port,OPT_Target', 'status', '*REQUIRED*', 'techContacts', 'csstaff@cs.princeton.edu', 'use', '*REQUIRED*', 'whoLastEdited','*REQUIRED*', 'wks', 'udp/bootpc', 'ypDomain', 'cs' ); %main'ENTRYDEFAULTS=( 'serialNumber', '*REQUIRED*', 'sysType', '*REQUIRED*', ); @main'VALIDFIELDS=( 'OS', 'PUmodel', 'PUtag', 'account', 'acct1059', 'adminDomain', 'aliases', 'building', 'citType', 'citnetgroups', 'class', 'clock', 'comments', 'cpu', 'cs_holder', 'cs_owned', 'csnetgroups', 'dateCreated', 'dateLastChanged', 'deptNumber', 'description', 'dnsDomain', 'hostname', 'infoContact', 'interface', 'keyLockNum','manufacturer', 'mem', 'printerUse','printerRes','printerImage','queueFeatures', 'printerPPM','printerLang','printerHost','printerQueue','printerRemote', 'model', 'mx', 'NCDbaseSerialNumber', 'purchaseAccount', 'purchaseOrder', 'room', 'serialNumber', 'srv', 'status', 'sysType', 'techContacts','userModel', 'use', 'wks', 'ypDomain', 'bootpParams', 'ifType', 'altitude', 'latitude', 'locPrecision', 'longitude', 'awareBarcode', 'awareID', 'whoLastEdited', 'ifExposed', 'expirationDate' ); # Call as &ParseInvEntry(*array, $entry) sub main'ParseInvEntry ## Public { local(*array, $entry) = @_; local ($keyw, $val); %array = (); @array = (); foreach (split(/\n/,$entry)) { if (($keyw,$val) = /^(.*): (.*\S+)\s*$/) { if (defined($array{$keyw})) { $array{$keyw} .= "|$val"; } else { $array{$keyw} = $val; } } } } sub main'BuildAttr2KeyArray ## Public { local($attr, *array, *DB) = @_; local ($keyw, $val, %entryarray); %array = (); @array = (); while (($keyw,$val)=each %DB) { &main'ParseInvEntry(*entryarray,$val); if (defined($entryarray{$attr})) { if (defined($array{$entryarray{$attr}})) { $array{$entryarray{$attr}} .= "|$keyw"; } else { $array{$entryarray{$attr}} = $keyw; } } } } sub main'Date ## Public { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year = $year + 1900; $retval = sprintf("%02d-%02d-%02d",$year,$mon + 1,$mday); return $retval; } # Added 12/17/99 by cmmiller for HostDB dates to conform # to CIT's desired format. This was previously the Date() function. sub main'dnsSerial ## Public { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year = $year + 1900; $retval = sprintf("%02d%02d%02d",$year,$mon + 1,$mday); return $retval; } sub main'Hostname ## Public { ($_, @junk) = gethostbyaddr(pack('C4',split('\.',$_[0])),2); if ( $_ ) { s/\.CS\.Princeton\.EDU//gi; } else { $_ = "__unknown__"; } return ($_); } sub main'Canonicalize ## Public { # To begin with, $_[0] = "0000a7006162" @temp = unpack("A2A2A2A2A2A2", $_[0]); # "00","00","a7","00","61","62" $tempbin = pack("H2H2H2H2H2H2", @temp); # 0x0000a7006162 @temp = unpack("C2C2C2C2C2C2", $tempbin); # 0x0,0x0,0xa7,0x0,0x61,0x62 $_=sprintf("%x:%x:%x:%x:%x:%x",@temp); # "0:0:a7:0:61:62" return ($_); } $main'parmSITENAME = "Princeton University, Department of Computer Science"; $main'parmDOMAIN = "Princeton.EDU"; $main'parmStudentSubDOMAIN = "student"; $main'parmRemoteSubDOMAIN = "remote"; @main'parmDeptSubDOMAINS = ( "CS", "aos", "astro", "athletics", "cfd", "cit", "cogsci", "ee", "hep", "geo", "mae", "math", "molbiol", "music", "pmi", "pupress", "wws" ); foreach $temp (@main'parmDeptSubDOMAINS) { push(@main'parmDomainList,"$temp.$main'parmDOMAIN"); } push(@main'parmDomainList,join(".",$main'parmRemoteSubDOMAIN,$main'parmDOMAIN)); push(@main'parmDomainList,join(".",$main'parmStudentSubDOMAIN,$main'parmDOMAIN)); @main'parmDomainList = sort(@main'parmDomainList); unshift(@main'parmDomainList,$main'parmDOMAIN); $main'parmURLbase = "http://heymon.Princeton.EDU/hostmaster/"; @main'parmINTERESTEDPARTIES = ('hostmaster@princeton'); @main'parmINTERESTEDerrorPARTIES = ('hostmaster@princeton'); @main'parmINTERESTEDsuccessPARTIES = ('hostlogs@lists'); @main'parmWIZARDS = ( 'cmmiller@CS.Princeton.EDU', 'cmsanche@CS.Princeton.EDU', 'elgersma@CS.Princeton.EDU', 'jonesy@CS.Princeton.EDU', 'jrc@CS.Princeton.EDU', 'pel@CS.Princeton.EDU', 'scott@CS.Princeton.EDU', 'tengi@CS.Princeton.EDU' ); @main'parmTRUSTEDPARTIES = ( 'cmmiller@CS.Princeton.EDU', 'cmsanche@CS.Princeton.EDU', 'elgersma@CS.Princeton.EDU', 'jonesy@CS.Princeton.EDU', 'jrc@CS.Princeton.EDU', 'pel@CS.Princeton.EDU', 'scott@CS.Princeton.EDU', 'tengi@CS.Princeton.EDU' ); @main'parmEQUIVHOSTS = ( "arachne", "arachne.princeton.edu", "ariel", "ariel.princeton.edu", "cit", "cit.princeton.edu", "heymon", "heymon.princeton.edu", "phoenix", "phoenix.princeton.edu", "pseudo", "pseudo.princeton.edu", "pucc.princeton.edu", "pucc" ); %main'parmEXTERNPARTIES = ( 'root@cs.princeton.edu', 'CompSci', 'cmmiller@cs.princeton.edu', 'CompSci', 'cmsanche@cs.princeton.edu', 'CompSci', 'elgersma@cs.princeton.edu', 'CompSci', 'jonesy@cs.princeton.edu', 'CompSci', 'jrc@cs.princeton.edu', 'CompSci', 'pel@cs.princeton.edu', 'CompSci', 'scott@cs.princeton.edu', 'CompSci', 'tengi@cs.princeton.edu', 'CompSci' ); $main'parmNUMNETS = 6; @main'parmNETWORK = ("128.112", "140.180", "204.153.48", "204.153.49", "204.153.50", "204.153.51"); @main'parmNETMASK = ("255.255.252.0", "255.255.224.0", "255.255.255.0", "255.255.255.0", "255.255.255.0", "255.255.255.0"); @main'parmBACKBONESUBNET = ("128", "128", "0", "0", "0", "0"); $main'parmISO_NSAP_PREFIX = "47.0005.80FF.F200.0000.0101"; $main'parmHOMEDIRECTORY = "/var/local/etc/invdb5/obj"; $main'parmAUDITINFO= "$main'parmHOMEDIRECTORY/auditinfo"; $main'parmLOGFILES = "$main'parmHOMEDIRECTORY/logfiles"; $main'parmNAMES = "$main'parmHOMEDIRECTORY/names"; $main'parmNUMBERS = "$main'parmHOMEDIRECTORY/numbers"; $main'parmETHERS = "$main'parmHOMEDIRECTORY/ethers"; $main'parmDELETED = "$main'parmHOMEDIRECTORY/deleted"; $main'parmAUDITDIRECTORY = "$main'parmHOMEDIRECTORY/AuditTrail"; $main'parmEXTERNDB = "$main'parmHOMEDIRECTORY/extern.db"; $main'parmBOOTPTAB = "$main'parmHOMEDIRECTORY/bootptab"; $main'parmHOSTSDATABASE = "$main'parmHOMEDIRECTORY/hosts.database"; $main'parmNAMEDDATABASE = "$main'parmHOMEDIRECTORY/named.database"; $main'parmREVERSEDDATABASE = "$main'parmHOMEDIRECTORY/reversed.database"; $main'parmQUERYDATABASE = "$main'parmHOMEDIRECTORY/query.database"; $main'parmETHERSDATABASE = "$main'parmHOMEDIRECTORY/ethers.database"; $main'parmTACPASSWD = "$main'parmHOMEDIRECTORY/tacpasswd"; $main'parmHOSTS_PREAMBLE = "$main'parmHOMEDIRECTORY/hosts.preamble"; $main'parmNAMED_PREAMBLE = "$main'parmHOMEDIRECTORY/named.preamble"; $main'parmNAMED_POSTAMBLE = "$main'parmHOMEDIRECTORY/named.postamble"; $main'parmREVERSED_PREAMBLE = "$main'parmHOMEDIRECTORY/reversed.preamble"; $main'parmREVERSED_POSTAMBLE = "$main'parmHOMEDIRECTORY/reversed.postamble"; $main'parmVERSIONFILE = "$main'parmHOMEDIRECTORY/Version"; $main'parmVALID = "$main'parmHOMEDIRECTORY/../validation_data"; $main'parmVALIDDEPT = "$main'parmVALID/departments"; $main'parmVALIDMEDIA = "$main'parmVALID/media"; $main'parmVALIDSUBNETMASKS = "$main'parmVALID/IP_subnet_masks"; $main'parmVALIDSUBNETNAMES = "$main'parmVALID/IP_subnet_names"; $main'parmVALIDBUILDINGS = "$main'parmVALID/buildings"; $main'parmVALIDTYPES = "$main'parmVALID/types"; $main'parmVALIDCPU = "$main'parmVALID/CPU"; $main'parmVALIDOS = "$main'parmVALID/OS"; $main'parmVALIDMAILINGLISTS = "$main'parmVALID/mailingLists"; $main'parmVALIDEMAILEQUIVHOSTS = "$main'parmVALID/emailEquivHosts"; $main'parmVALIDWT = "$main'parmVALID/wireType"; $main'parmVALIDWKS = "$main'parmVALID/wks"; $main'parmFIELDINFO = "$main'parmVALID/fields"; $main'parmREMOTEINFO = "$main'parmHOMEDIRECTORY/REMOTE.INFO"; $main'parmREMOTEUSERS = "$main'parmHOMEDIRECTORY/remote.access.users"; $main'parmSTUDENTINFO = "$main'parmHOMEDIRECTORY/STUDENT.INFO"; $main'parmSTUDENTUSERS = "$main'parmVALID/studentUsernames"; $main'parmMAILGATEWAY = "CS.Princeton.EDU."; $main'parmSUBNET6INFO = "$main'DBHOME/subnet6.info"; $main'parmSUBNETINFO = "$main'DBHOME/subnet.info"; $main'parmSUBNETDPV = "$main'DBHOME/subnet.dynamicPortVLANs"; %main'SN6domain = (); %main'SN6network = (); %main'SN6bits = (); %main'SN6dnssrv = (); %main'SN6ntpsrv = (); %main'SN6vlan = (); @main'IPV6_SUBNETS = (); %main'SNdomain = (); %main'SNnetwork = (); %main'SNmask = (); %main'SNipxnet = (); %main'SNadmdom = (); %main'SNaliases = (); %main'SNrouters = (); %main'SNdnssrv = (); %main'SNatzones = (); %main'SNntpsrv = (); %main'SNvlan = (); %main'SNleaserange = (); %main'SNssid = (); %main'SNdpv = (); # # void initSNinfo() # sub main'initSN6info ## Public { open(SUBNET6INFO,$main'parmSUBNET6INFO) || die "${0}: could not open $main'parmSUBNET6INFO: $!\n"; while () { chomp; next if (/^#/); my($SN6name,$SN6domain,$SN6network,$SN6dnssrv,$SN6ntpsrv,$SN6vlan) = split(/;/,$_); $main'SN6domain{$SN6name} = $SN6domain if $SN6domain; if ($SN6network) { push(@main'IPV6_SUBNETS,$SN6network); ($main'SN6network{$SN6name},$main'SN6bits{$SN6name}) = split(/\//,$SN6network); $main'SN6network{$SN6name} =~ s/::$//; } $main'SN6dnssrv{$SN6name} = $SN6dnssrv if $SN6dnssrv; $main'SN6ntpsrv{$SN6name} = $SN6ntpsrv if $SN6ntpsrv; $main'SN6vlan{$SN6name} = $SN6vlan if $SN6vlan; $main'SUBNETNAMES{$SN6network} = $SN6name; } close SUBNET6INFO; } # # void initSNinfo() # sub main'initSNinfo ## Public { open(SUBNETINFO,$main'parmSUBNETINFO) || die "${0}: could not open $main'parmSUBNETINFO: $!\n"; while () { chomp; next if (/^#/); my($SNname,$SNdomain,$SNnetwork,$SNmask, $SNipxnet,$SNadmdom,$SNaliases,$SNrouters, $SNdnssrv,$SNatzones,$SNntpsrv,$SNvlan, $SNleaserange,$SNssid) = split(/;/,$_); $main'SNdomain{$SNname} = $SNdomain if $SNdomain; $main'SNnetwork{$SNname} = $SNnetwork if $SNnetwork; $main'SNmask{$SNname} = $SNmask if $SNmask; $main'SNipxnet{$SNname} = $SNipxnet if $SNipxnet; $main'SNadmdom{$SNname} = $SNadmdom if $SNadmdom; $main'SNaliases{$SNname} = $SNaliases if $SNaliases; $main'SNrouters{$SNname} = $SNrouters if $SNrouters; $main'SNdnssrv{$SNname} = $SNdnssrv if $SNdnssrv; $main'SNatzones{$SNname} = $SNatzones if $SNatzones; $main'SNntpsrv{$SNname} = $SNntpsrv if $SNntpsrv; $main'SNvlan{$SNname} = $SNvlan if $SNvlan; $main'SNleaserange{$SNname} = $SNleaserange if $SNleaserange; $main'SNssid{$SNname} = $SNssid if $SNssid; $main'SUBNETNAMES{$SNnetwork} = $SNname; } close SUBNETINFO; open(SUBNETDPV,$main'parmSUBNETDPV) || die "${0}: could not open $main'parmSUBNETDPV: $!\n"; while () { chomp; next if (/^#/); $main'SNdpv{$_} = 1; } close SUBNETDPV; foreach $SNname (keys %main'SNleaserange) { my($SNnetwork,$SNleasemin,$SNleasemax,$SNleasebase,$SNleasestart,$SNleaseend); $SNnetwork = $main'SNnetwork{$SNname}; ($SNleasemin,$SNleasemax) = split(/,/,$main'SNleaserange{$SNname}); ($SNleasebase = $SNleasemin) =~ s/^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/\1.\2.\3/; ($SNleasestart = $SNleasemin) =~ s/^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/\4/; ($SNleaseend = $SNleasemax) =~ s/^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/\4/; $main'DDNS_RANGES{$SNnetwork} = "range $SNleasemin $SNleasemax;"; if ($main'DDNS_RANGES{$SNleasebase}) { $main'DDNS_RANGES{$SNleasebase} .= ";${SNleasestart}-${SNleaseend}"; } else { $main'DDNS_RANGES{$SNleasebase} = "${SNleasestart}-${SNleaseend}"; } } } # # char *getSNname(char *ipAddr) # sub main'getSNname($) ## Public { my($txtIP) = shift; my($ip,$network,$mask,$txtSN); $ip = &main'ip_to_int($txtIP); foreach $subnet (keys %main'SNnetwork) { $network = &main'ip_to_int($main'SNnetwork{$subnet}); $mask = &main'ip_to_int($main'SNmask{$subnet}); if (($ip & $mask) == $network) { $txtSN = $subnet; } last if ($txtSN); } return($txtSN); } # # int ip_to_int(char *ipAddr) # sub main'ip_to_int($) ## Public { my($ipAddr) = shift; my(@ipAddr) = split(/\./,$ipAddr); my($ipInt) = $ipAddr[3] * 1; $ipInt += $ipAddr[2] * 256; $ipInt += $ipAddr[1] * 65536; $ipInt += $ipAddr[0] * 16777216; return($ipInt); } # # char *int_to_ip(int ipAddr) # sub main'int_to_ip($) ## Public { my($ipInt) = shift; my(@ipAddr); $ipAddr[0] = int($ipInt / 16777216); $ipInt -= $ipAddr[0] * 16777216; $ipAddr[1] = int($ipInt / 65536); $ipInt -= $ipAddr[1] * 65536; $ipAddr[2] = int($ipInt / 256); $ipInt -= $ipAddr[2] * 256; $ipAddr[3] = $ipInt; return(join('.',@ipAddr)); } # # char *getSNdomain(char *subnetName) # sub main'getSNdomain($) ## Public { my($subnetName) = shift; return($main'SNdomain{$subnetName}); } # # char *getSNnetwork(char *subnetName) # sub main'getSNnetwork($) ## Public { my($subnetName) = shift; return($main'SNnetwork{$subnetName}); } # # char *getSNmask(char *subnetName) # sub main'getSNmask($) ## Public { my($subnetName) = shift; return($main'SNmask{$subnetName}); } # # char *getSNipxnet(char *subnetName) # sub main'getSNipxnet($) ## Public { my($subnetName) = shift; return($main'SNipxnet{$subnetName}); } # # char *getSNadmdom(char *subnetName) # sub main'getSNadmdom($) ## Public { my($subnetName) = shift; return($main'SNadmdom{$subnetName}); } # # char **getSNaliases(char *subnetName) # sub main'getSNaliases($) ## Public { my($subnetName) = shift; return(split(/,/,$main'SNaliases{$subnetName})); } # # char **getSNrouters(char *subnetName) # sub main'getSNrouters($) ## Public { my($subnetName) = shift; return(split(/,/,$main'SNrouters{$subnetName})); } # # char **getSNdnssrv(char *subnetName) # sub main'getSNdnssrv($) ## Public { my($subnetName) = shift; return(split(/,/,$main'SNdnssrv{$subnetName})); } # # char **getSNatzones(char *subnetName) # sub main'getSNatzones($) ## Public { my($subnetName) = shift; return(split(/,/,$main'SNatzones{$subnetName})); } # # char **getSNntpsrv(char *subnetName) # sub main'getSNntpsrv($) ## Public { my($subnetName) = shift; return(split(/,/,$main'SNntpsrv{$subnetName})); } # # char *getSNvlan(char *subnetName) # sub main'getSNvlan($) ## Public { my($subnetName) = shift; return($main'SNvlan{$subnetName}); } # # char *getSNleaserange(char *subnetName) # sub main'getSNleaserange($) ## Public { my($subnetName) = shift; return($main'SNleaserange{$subnetName}); } # # char *getSNssid(char *subnetName) # sub main'getSNssid($) ## Public { my($subnetName) = shift; return($main'SNssid{$subnetName}); } # # bool validipv6addr(char *ipv6addr) # sub main'validipv6addr($) # Public { my($ipv6addr) = @_; return($ipv6addr =~ /^([0-9a-f]{1,4}:)+:?([0-9a-f]{1,4}:)*[0-9a-f]{1,4}$/); } # # bool validipv6subnet(char *ipv6subnet) # sub main'validipv6subnet($) # Public { my($ipv6subnet) = @_; return($ipv6subnet =~ /^([0-9a-f]{1,4}:)+:\/[0-9]+$/); } # # bool validmacaddr(char *macaddr) # sub main'validmacaddr($) # Public { my($macaddr) = @_; return($macaddr =~ /^([0-9a-f]{1,2}:){,5}:([0-9a-f]{1,2})$/); } # # char mac2eui64(char *macaddr) # sub main'mac2eui64($) # Public { my($macaddr) = @_; my @hexbytes, $i; my($base) = $[; @hexbytes = split(/:/,$macaddr,6); $i = hex($hexbytes[$base]); $i ^= 2; $hexbytes[$base] = sprintf("%x",$i); splice(@hexbytes,($base+3),0,'ff','fe'); return(join(':',@hexbytes)); } ## ## char *padv6addr(char *ipv6addr, int bits) ## ## Expand "::" notation to explicit zero fields and ## pad all fields to 4 characters with leading zeros ## as required. The $bits argument is used to determine ## how many words of the address to operate on and would ## be 128 for a host address. For a subnet $bits would ## be the number after the "/" in the subnet specification. ## sub main'padv6addr($$) # Public { my($ipv6addr,$bits) = @_; my $maxWords, @words, $zeroWordCount, $i; $maxWords = int( $bits / 16 ); $ipv6addr =~ s/::/:Z:/g; @words = split(/:/,$ipv6addr); $zeroWordCount = $maxWords - ($#words - $[); foreach $i ($[ .. $#words) { if ($words[$i] eq 'Z') { my @zeros; foreach (1 .. $zeroWordCount) { push(@zeros, '0'); } splice(@words,$i,1,@zeros); } } foreach $i ($[ .. $#words) { while (length($words[$i]) < 4) { $words[$i] = "0$words[$i]"; } } $ipv6addr = join(':',@words); return($ipv6addr); } ## ## bool subnet6member(char *ipv6subnet, char *ipv6addr) ## ## Is host address a member of the subnet? ipv6subnet ## is in "hex::/bits" notation (eg 1:2:3::/64). ## sub subnet6member($$) { my($ipv6subnet,$ipv6addr) = @_; my $subnet, $bits, $host, $chars; ($subnet,$bits) = split(/\//,$ipv6subnet); $subnet = &main'padv6addr($subnet,$bits); $host = &main'padv6addr($ipv6addr,128); $subnet =~ s/://g; $host =~ s/://g; $chars = int($bits/4); return ($subnet eq substr($host,$[,$chars)); } ## ## char *getSN6name(char *ipv6addr) ## ## Return the IPv6 subnet name for an IPv6 host address, ## or NULL if the address is not on any known subnet. ## sub main'getSN6name($) # public { my($ipv6addr) = shift; my $subnetName, $subnet, $match = undef; return(undef) unless ($ipv6addr); foreach $subnetName (keys %main'SN6network) { $subnet = $main'SN6network{$subnetName} . "::/" . $main'SN6bits{$subnetName}; $match = $subnetName if (&subnet6member($subnet,$ipv6addr)); last if ($match); } return($match); } ## ## char *getSN6network(char *subnet6Name) ## sub main'getSN6network($) # Public { my($subnet6Name) = shift; return(undef) unless ($subnet6Name); return($main'SN6network{$subnet6Name}); } ## ## char *getSN6bits(char *subnet6Name) ## sub main'getSN6bits($) # Public { my($subnet6Name) = shift; return(undef) unless ($subnet6Name); return($main'SN6bits{$subnet6Name}); } ## ## char *getSN6hostpart(char *ipv6addr) ## ## Return the host portion of an IPv6 address ## sub main'getSN6hostpart($) # Public { my($ipv6addr) = shift; my $subnetName, $subnet, $bits, @subnet, @host, $hostpart = undef; return(undef) unless ($ipv6addr); $subnetName = &main'getSN6name($ipv6addr); $subnet = &main'getSN6network($subnetName); if ($subnet) { $bits = &main'getSN6bits($subnetName); if (&subnet6member("${subnet}::/${bits}",$ipv6addr)) { @subnet = split(/:/,$subnet); @host = split(/:/,$ipv6addr); splice(@host,$[,@subnet); $hostpart = join(':',@host); } } return($hostpart); } ## ## initialize ## &main'initSN6info; &main'initSNinfo; ## ## Return TRUE to require command ## 1;