src/IPSet.php
private function addCidr( $cidr ) {
		// v4 or v6 check
		if ( strpos( $cidr, ':' ) === false ) {
			$node =& $this->root4;
			$defMask = '32';
		} else {
			$node =& $this->root6;
			$defMask = '128';
		}

		// Default to all-1's mask if no netmask in the input
		if ( strpos( $cidr, '/' ) === false ) {
			$net = $cidr;
			$mask = $defMask;
		} else {
			list( $net, $mask ) = explode( '/', $cidr, 2 );
			if ( !ctype_digit( $mask ) || intval( $mask ) > $defMask ) {
				trigger_error( "IPSet: Bad mask '$mask' from '$cidr', ignored", E_USER_WARNING );
				return false;
			}
		}
		$mask = intval( $mask ); // explicit integer convert, checked above

		// convert $net to an array of integer bytes, length 4 or 16:
		$raw = AtEase::quietCall( 'inet_pton', $net );
		if ( $raw === false ) {
			return false;
		}
		$rawOrd = array_map( 'ord', str_split( $raw ) );

		// iterate the bits of the address while walking the tree structure for inserts
		// at the end, $snode will point to the highest node that could only lead to a
		// successful match (and thus can be set to true)
		$snode =& $node;
		$curBit = 0;
		while ( 1 ) {
			if ( $node === true ) {
				// already added a larger supernet, no need to go deeper
				return;
			} elseif ( $curBit == $mask ) {
				// this may wipe out deeper subnets from earlier
				$snode = true;
				return;
			} elseif ( $node === false ) {
				// create new subarray to go deeper
				if ( !( $curBit & 7 ) && $curBit <= $mask - 8 ) {
					$node = [ 'comp' => $rawOrd[$curBit >> 3], 'next' => false ];
				} else {
					$node = [ false, false ];
				}
			}

			if ( isset( $node['comp'] ) ) {
				$comp = $node['comp'];
				if ( $rawOrd[$curBit >> 3] == $comp && $curBit <= $mask - 8 ) {
					// whole byte matches, skip over the compressed node
					$node =& $node['next'];
					$snode =& $node;
					$curBit += 8;
					continue;
				} else {
					// have to decompress the node and check individual bits
					$unode = $node['next'];
					for ( $i = 0; $i < 8; ++$i ) {
						$unode = ( $comp & ( 1 << $i ) )
							? [ false, $unode ]
							: [ $unode, false ];
					}
					$node = $unode;
				}
			}

			$maskShift = 7 - ( $curBit & 7 );
			$index = ( $rawOrd[$curBit >> 3] & ( 1 << $maskShift ) ) >> $maskShift;
			if ( $node[$index ^ 1] !== true ) {
				// no adjacent subnet, can't form a supernet at this level
				$snode =& $node[$index];
			}
			$node =& $node[$index];
			++$curBit;
		} // Unreachable outside 'while'
	}
private function addCidr( $cidr ) {
		// v4 or v6 check
		if ( strpos( $cidr, ':' ) === false ) {
			$node =& $this->root4;
			$defMask = '32';
		} else {
			$node =& $this->root6;
			$defMask = '128';
		}

		// Default to all-1's mask if no netmask in the input
		if ( strpos( $cidr, '/' ) === false ) {
			$net = $cidr;
			$mask = $defMask;
		} else {
			list( $net, $mask ) = explode( '/', $cidr, 2 );
			if ( !ctype_digit( $mask ) || intval( $mask ) > $defMask ) {
				trigger_error( "IPSet: Bad mask '$mask' from '$cidr', ignored", E_USER_WARNING );
				return false;
			}
		}
		$mask = intval( $mask ); // explicit integer convert, checked above

		// convert $net to an array of integer bytes, length 4 or 16:
		$raw = AtEase::quietCall( 'inet_pton', $net );
		if ( $raw === false ) {
			return false;
		}
		$rawOrd = array_map( 'ord', str_split( $raw ) );

		// iterate the bits of the address while walking the tree structure for inserts
		// at the end, $snode will point to the highest node that could only lead to a
		// successful match (and thus can be set to true)
		$snode =& $node;
		$curBit = 0;
		while ( 1 ) {
			if ( $node === true ) {
				// already added a larger supernet, no need to go deeper
				return;
			} elseif ( $curBit == $mask ) {
				// this may wipe out deeper subnets from earlier
				$snode = true;
				return;
			} elseif ( $node === false ) {
				// create new subarray to go deeper
				if ( !( $curBit & 7 ) && $curBit <= $mask - 8 ) {
					$node = [ 'comp' => $rawOrd[$curBit >> 3], 'next' => false ];
				} else {
					$node = [ false, false ];
				}
			}

			if ( isset( $node['comp'] ) ) {
				$comp = $node['comp'];
				if ( $rawOrd[$curBit >> 3] == $comp && $curBit <= $mask - 8 ) {
					// whole byte matches, skip over the compressed node
					$node =& $node['next'];
					$snode =& $node;
					$curBit += 8;
					continue;
				} else {
					// have to decompress the node and check individual bits
					$unode = $node['next'];
					for ( $i = 0; $i < 8; ++$i ) {
						$unode = ( $comp & ( 1 << $i ) )
							? [ false, $unode ]
							: [ $unode, false ];
					}
					$node = $unode;
				}
			}

			$maskShift = 7 - ( $curBit & 7 );
			$index = ( $rawOrd[$curBit >> 3] & ( 1 << $maskShift ) ) >> $maskShift;
			if ( $node[$index ^ 1] !== true ) {
				// no adjacent subnet, can't form a supernet at this level
				$snode =& $node[$index];
			}
			$node =& $node[$index];
			++$curBit;
		} // Unreachable outside 'while'
	}
private function addCidr ( $ cidr ) { // v4 or v6 check if ( strpos ( $ cidr , ':' ) === false ) { $ node = & $ this -> root4 ; $ defMask = '32' ; } else { $ node = & $ this -> root6 ; $ defMask = '128' ; } // Default to all-1's mask if no netmask in the input if ( strpos ( $ cidr , '/' ) === false ) { $ net = $ cidr ; $ mask = $ defMask ; } else { list ( $ net , $ mask ) = explode ( '/' , $ cidr , 2 ) ; if ( ! ctype_digit ( $ mask ) || intval ( $ mask ) > $ defMask ) { trigger_error ( "IPSet: Bad mask '$mask' from '$cidr', ignored" , E_USER_WARNING ) ; return false ; } } $ mask = intval ( $ mask ) ; // explicit integer convert, checked above // convert $net to an array of integer bytes, length 4 or 16: $ raw = AtEase :: quietCall ( 'inet_pton' , $ net ) ; if ( $ raw === false ) { return false ; } $ rawOrd = array_map ( 'ord' , str_split ( $ raw ) ) ; // iterate the bits of the address while walking the tree structure for inserts // at the end, $snode will point to the highest node that could only lead to a // successful match (and thus can be set to true) $ snode = & $ node ; $ curBit = 0 ; while ( 1 ) { if ( $ node === true ) { // already added a larger supernet, no need to go deeper return ; } elseif ( $ curBit == $ mask ) { // this may wipe out deeper subnets from earlier $ snode = true ; return ; } elseif ( $ node === false ) { // create new subarray to go deeper if ( ! ( $ curBit & 7 ) && $ curBit <= $ mask - 8 ) { $ node = [ 'comp' => $ rawOrd [ $ curBit >> 3 ] , 'next' => false ] ; } else { $ node = [ false , false ] ; } } if ( isset ( $ node [ 'comp' ] ) ) { $ comp = $ node [ 'comp' ] ; if ( $ rawOrd [ $ curBit >> 3 ] == $ comp && $ curBit <= $ mask - 8 ) { // whole byte matches, skip over the compressed node $ node = & $ node [ 'next' ] ; $ snode = & $ node ; $ curBit += 8 ; continue ; } else { // have to decompress the node and check individual bits $ unode = $ node [ 'next' ] ; for ( $ i = 0 ; $ i < 8 ; ++ $ i ) { $ unode = ( $ comp & ( 1 << $ i ) ) ? [ false , $ unode ] : [ $ unode , false ] ; } $ node = $ unode ; } } $ maskShift = 7 - ( $ curBit & 7 ) ; $ index = ( $ rawOrd [ $ curBit >> 3 ] & ( 1 << $ maskShift ) ) >> $ maskShift ; if ( $ node [ $ index ^ 1 ] !== true ) { // no adjacent subnet, can't form a supernet at this level $ snode = & $ node [ $ index ] ; } $ node = & $ node [ $ index ] ; ++ $ curBit ; } // Unreachable outside 'while' }
Add a single CIDR spec to the internal matching trees

@param string $cidr String CIDR spec, IPv[46], optional /mask (def all-1's)
@return false|null Returns null on success, false on failure
Add a single CIDR spec to the internal matching trees