1<?php 2/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4/** 5 * DNS Library for handling lookups and updates. 6 * 7 * PHP Version 5 8 * 9 * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * * Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * * Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in 21 * the documentation and/or other materials provided with the 22 * distribution. 23 * 24 * * Neither the name of Mike Pultz nor the names of his contributors 25 * may be used to endorse or promote products derived from this 26 * software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 31 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 32 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 34 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 * POSSIBILITY OF SUCH DAMAGE. 40 * 41 * @category Networking 42 * @package Net_DNS2 43 * @author Mike Pultz <mike@mikepultz.com> 44 * @copyright 2010 Mike Pultz <mike@mikepultz.com> 45 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 46 * @version SVN: $Id$ 47 * @link http://pear.php.net/package/Net_DNS2 48 * @since File available since Release 0.6.0 49 * 50 */ 51 52/** 53 * a class to handle converting RR bitmaps to arrays and back; used on NSEC 54 * and NSEC3 RR's 55 * 56 * @category Networking 57 * @package Net_DNS2 58 * @author Mike Pultz <mike@mikepultz.com> 59 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 60 * @link http://pear.php.net/package/Net_DNS2 61 * @see Net_DNS2_Packet 62 * 63 */ 64class Net_DNS2_BitMap 65{ 66 /** 67 * parses a RR bitmap field defined in RFC3845, into an array of RR names. 68 * 69 * Type Bit Map(s) Field = ( Window Block # | Bitmap Length | Bitmap ) + 70 * 71 * @param string $data a bitmap stringto parse 72 * 73 * @return array 74 * @access public 75 * 76 */ 77 public static function bitMapToArray($data) 78 { 79 if (strlen($data) == 0) { 80 return array(); 81 } 82 83 $output = array(); 84 $offset = 0; 85 $length = strlen($data); 86 87 while ($offset < $length) { 88 89 // 90 // unpack the window and length values 91 // 92 $x = unpack('@' . $offset . '/Cwindow/Clength', $data); 93 $offset += 2; 94 95 // 96 // copy out the bitmap value 97 // 98 $bitmap = unpack('C*', substr($data, $offset, $x['length'])); 99 $offset += $x['length']; 100 101 // 102 // I'm not sure if there's a better way of doing this, but PHP doesn't 103 // have a 'B' flag for unpack() 104 // 105 $bitstr = ''; 106 foreach ($bitmap as $r) { 107 108 $bitstr .= sprintf('%08b', $r); 109 } 110 111 $blen = strlen($bitstr); 112 for ($i=0; $i<$blen; $i++) { 113 114 if ($bitstr[$i] == '1') { 115 116 $type = $x['window'] * 256 + $i; 117 118 if (isset(Net_DNS2_Lookups::$rr_types_by_id[$type])) { 119 120 $output[] = Net_DNS2_Lookups::$rr_types_by_id[$type]; 121 } else { 122 123 $output[] = 'TYPE' . $type; 124 } 125 } 126 } 127 } 128 129 return $output; 130 } 131 132 /** 133 * builds a RR Bit map from an array of RR type names 134 * 135 * @param array $data a list of RR names 136 * 137 * @return string 138 * @access public 139 * 140 */ 141 public static function arrayToBitMap(array $data) 142 { 143 if (count($data) == 0) { 144 return ''; 145 } 146 147 $current_window = 0; 148 149 // 150 // go through each RR 151 // 152 $max = 0; 153 $bm = array(); 154 155 foreach ($data as $rr) { 156 157 $rr = strtoupper($rr); 158 159 // 160 // get the type id for the RR 161 // 162 $type = @Net_DNS2_Lookups::$rr_types_by_name[$rr]; 163 if (isset($type)) { 164 165 // 166 // skip meta types or qtypes 167 // 168 if ( (isset(Net_DNS2_Lookups::$rr_qtypes_by_id[$type])) 169 || (isset(Net_DNS2_Lookups::$rr_metatypes_by_id[$type])) 170 ) { 171 continue; 172 } 173 174 } else { 175 176 // 177 // if it's not found, then it must be defined as TYPE<id>, per 178 // RFC3845 section 2.2, if it's not, we ignore it. 179 // 180 list($name, $type) = explode('TYPE', $rr); 181 if (!isset($type)) { 182 183 continue; 184 } 185 } 186 187 // 188 // build the current window 189 // 190 $current_window = (int)($type / 256); 191 192 $val = $type - $current_window * 256.0; 193 if ($val > $max) { 194 $max = $val; 195 } 196 197 $bm[$current_window][$val] = 1; 198 $bm[$current_window]['length'] = ceil(($max + 1) / 8); 199 } 200 201 $output = ''; 202 203 foreach ($bm as $window => $bitdata) { 204 205 $bitstr = ''; 206 207 for ($i=0; $i<$bm[$window]['length'] * 8; $i++) { 208 if (isset($bm[$window][$i])) { 209 $bitstr .= '1'; 210 } else { 211 $bitstr .= '0'; 212 } 213 } 214 215 $output .= pack('CC', $window, $bm[$window]['length']); 216 $output .= pack('H*', self::bigBaseConvert($bitstr)); 217 } 218 219 return $output; 220 } 221 222 /** 223 * a base_convert that handles large numbers; forced to 2/16 224 * 225 * @param string $number a bit string 226 * 227 * @return string 228 * @access public 229 * 230 */ 231 public static function bigBaseConvert($number) 232 { 233 $result = ''; 234 235 $bin = substr(chunk_split(strrev($number), 4, '-'), 0, -1); 236 $temp = preg_split('[-]', $bin, -1, PREG_SPLIT_DELIM_CAPTURE); 237 238 for ($i = count($temp)-1;$i >= 0;$i--) { 239 240 $result = $result . base_convert(strrev($temp[$i]), 2, 16); 241 } 242 243 return strtoupper($result); 244 } 245} 246 247/* 248 * Local variables: 249 * tab-width: 4 250 * c-basic-offset: 4 251 * c-hanging-comment-ender-p: nil 252 * End: 253 */ 254?> 255