Project

General

Profile

« Previous | Next » 

Revision ce996bd3

Added by Simon Cornelius P. Umacob over 16 years ago

add IPv6.inc and NetUtils.js

View differences:

etc/inc/IPv6.inc
1
<?php
2

  
3
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4

  
5
/**
6
 * This file contains the implementation of the Net_IPv6 class
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * LICENSE: This source file is subject to the New BSD license, that is
11
 * available through the world-wide-web at 
12
 * http://www.opensource.org/licenses/bsd-license.php
13
 * If you did not receive a copy of the new BSDlicense and are unable
14
 * to obtain it through the world-wide-web, please send a note to
15
 * license@php.net so we can mail you a copy immediately
16
 *
17
 * @category  Net
18
 * @package   Net_IPv6
19
 * @author    Alexander Merz <alexander.merz@web.de>
20
 * @copyright 2003-2005 The PHP Group
21
 * @license   http://www.opensource.org/licenses/bsd-license.php
22
 * @version   CVS: $Id: IPv6.inc,v 1.2 2008/11/26 03:54:43 sumacob Exp $
23
 * @link      http://pear.php.net/package/Net_IPv6
24
 */
25

  
26
// {{{ constants
27

  
28
/**
29
 * Error message if netmask bits was not found
30
 * @see isInNetmask
31
 */
32
define("NET_IPV6_NO_NETMASK_MSG", "Netmask length not found");
33

  
34
/**
35
 * Error code if netmask bits was not found
36
 * @see isInNetmask
37
 */
38
define("NET_IPV6_NO_NETMASK", 10);
39

  
40
/**
41
 * Address Type: Unassigned (RFC 1884, Section 2.3)
42
 * @see getAddressType()
43
 */
44
define("NET_IPV6_UNASSIGNED", 1);
45

  
46
/**
47
 * Address Type: Reserved (RFC 1884, Section 2.3)
48
 * @see getAddressType()
49
 */
50
define("NET_IPV6_RESERVED", 11);
51

  
52
/**
53
 * Address Type: Reserved for NSAP Allocation (RFC 1884, Section 2.3)
54
 * @see getAddressType()
55
 */
56
define("NET_IPV6_RESERVED_NSAP", 12);
57

  
58
/**
59
 * Address Type: Reserved for IPX Allocation (RFC 1884, Section 2.3)
60
 * @see getAddressType()
61
 */
62
define("NET_IPV6_RESERVED_IPX", 13);
63

  
64
/**
65
 * Address Type: Reserved for Geographic-Based Unicast Addresses 
66
 * (RFC 1884, Section 2.3)
67
 * @see getAddressType()
68
 */
69
define("NET_IPV6_RESERVED_UNICAST_GEOGRAPHIC", 14);
70

  
71
/**
72
 * Address Type: Provider-Based Unicast Address (RFC 1884, Section 2.3)
73
 * @see getAddressType()
74
 */
75
define("NET_IPV6_UNICAST_PROVIDER", 22);
76

  
77
/**
78
 * Address Type: Multicast Addresses (RFC 1884, Section 2.3)
79
 * @see getAddressType()
80
 */
81
define("NET_IPV6_MULTICAST", 31);
82

  
83
/**
84
 * Address Type: Link Local Use Addresses (RFC 1884, Section 2.3)
85
 * @see getAddressType()
86
 */
87
define("NET_IPV6_LOCAL_LINK", 42);
88

  
89
/**
90
 * Address Type: Link Local Use Addresses (RFC 1884, Section 2.3)
91
 * @see getAddressType()
92
 */
93
define("NET_IPV6_LOCAL_SITE", 43);
94

  
95
/**
96
 * Address Type: address can not assigned to a specific type
97
 * @see getAddressType()
98
 */
99
define("NET_IPV6_UNKNOWN_TYPE", 1001);
100

  
101
// }}}
102
// {{{ Net_IPv6
103

  
104
/**
105
 * Class to validate and to work with IPv6 addresses.
106
 *
107
 * @category  Net
108
 * @package   Net_IPv6
109
 * @copyright 2003-2005 The PHP Group
110
 * @license   http://www.opensource.org/licenses/bsd-license.php
111
 * @version   $Release$
112
 * @link      http://pear.php.net/package/Net_IPv6
113
 * @author    Alexander Merz <alexander.merz@web.de>
114
 * @author    <elfrink at introweb dot nl>
115
 * @author    Josh Peck <jmp at joshpeck dot org>
116
 */
117
class Net_IPv6 {
118

  
119
    // {{{ removeNetmaskBits()
120

  
121
    /**
122
     * Removes a possible existing netmask specification at an IP addresse.
123
     *
124
     * @param  String $ip the (compressed) IP as Hex representation
125
     *
126
     * @return String the IP without netmask length
127
     * @since  1.1.0
128
     * @access public
129
     * @static
130
     */
131
    function removeNetmaskSpec($ip) 
132
    {
133
        $addr = $ip;
134

  
135
        if (false !== strpos($ip, '/')) {
136

  
137
            $elements = explode('/', $ip);
138

  
139
            if (2 == count($elements)) {
140

  
141
                $addr = $elements[0];
142

  
143
            }
144

  
145
        }
146

  
147
        return $addr;
148
    }
149

  
150
    /**
151
     * Returns a possible existing netmask specification at an IP addresse.
152
     *
153
     * @param  String $ip the (compressed) IP as Hex representation
154
     *
155
     * @return String the netmask spec
156
     * @since  1.1.0
157
     * @access public
158
     * @static
159
     */
160
    function getNetmaskSpec($ip) 
161
    {
162
        $spec = '';
163

  
164
        if (false !== strpos($ip, '/')) {
165

  
166
            $elements = explode('/', $ip);
167

  
168
            if (2 == count($elements)) {
169

  
170
                $spec = $elements[1];
171

  
172
            }
173

  
174
        }
175

  
176
        return $spec;
177
    }
178

  
179
    // }}}
180
    // {{{ getNetmask()
181

  
182
    /**
183
     * Calculates the network prefix based on the netmask bits.
184
     *
185
     * @param  String $ip the (compressed) IP in Hex format
186
     * @param  int $bits if the number of netmask bits is not part of the IP
187
     *                  you must provide the number of bits
188
     *
189
     * @return String the network prefix
190
     * @since  1.1.0
191
     * @access public
192
     * @static
193
     */
194
    function getNetmask($ip, $bits = null)
195
    {
196
        if (null==$bits) {
197

  
198
            $elements = explode('/', $ip);
199

  
200
            if (2 == count($elements)) {
201

  
202
                $addr = $elements[0];
203
                $bits = $elements[1];
204

  
205
            } else {
206

  
207
                include_once 'PEAR.inc';
208

  
209
                return PEAR::raiseError(NET_IPV6_NO_NETMASK_MSG,
210
                                        NET_IPV6_NO_NETMASK);
211
            }
212

  
213
        } else {
214

  
215
            $addr = $ip;
216

  
217
        }
218

  
219
        $addr       = Net_IPv6::uncompress($addr);
220
        $binNetmask = str_repeat('1', $bits).str_repeat('0', 128 - $bits);
221

  
222
        return Net_IPv6::_bin2Ip(Net_IPv6::_ip2Bin($addr) & $binNetmask);
223
    }
224

  
225
    // }}}
226
    // {{{ isInNetmask()
227

  
228
    /**
229
     * Checks if an (compressed) IP is in a specific address space.
230
     *
231
     * IF the IP does not contains the number of netmask bits (F8000::FFFF/16)
232
     * then you have to use the $bits parameter.
233
     *
234
     * @param  String $ip the IP to check (eg. F800::FFFF)
235
     * @param  String $netmask the netmask (eg F800::)
236
     * @param  int $bits the number of netmask bits to compare, 
237
     *                   if not given in $ip
238
     *
239
     * @return boolean true if $ip is in the netmask
240
     * @since  1.1.0
241
     * @access public
242
     * @static
243
     */
244
    function isInNetmask($ip, $netmask, $bits=null) 
245
    {
246
        // try to get the bit count
247

  
248
        if (null == $bits) {
249

  
250
            $elements = explode('/', $ip);
251

  
252
            if (2 == count($elements)) {
253

  
254
                $ip   = $elements[0];
255
                $bits = $elements[1];
256

  
257
            } else if (null == $bits) {
258

  
259
                $elements = explode('/', $netmask);
260

  
261
                if (2 == count($elements)) {
262

  
263
                     $netmask = $elements[0];
264
                     $bits   = $elements[1];
265

  
266
                }
267

  
268
                if (null == $bits) {
269

  
270
                    include_once 'PEAR.inc';
271
                    return PEAR::raiseError(NET_IPV6_NO_NETMASK_MSG,
272
                                            NET_IPV6_NO_NETMASK);
273

  
274
                }
275

  
276
            }
277

  
278
        }
279

  
280
        $binIp      = Net_IPv6::_ip2Bin(Net_IPv6::removeNetmaskSpec($ip));
281
        $binNetmask = Net_IPv6::_ip2Bin(Net_IPv6::removeNetmaskSpec($netmask));
282

  
283
        if (null != $bits 
284
            && "" != $bits 
285
            && 0 == strncmp( $binNetmask, $binIp, $bits)) {
286

  
287
            return true;
288

  
289
        }
290

  
291
        return false;
292
    }
293

  
294
    // }}}
295
    // {{{ getAddressType()
296

  
297
    /**
298
     * Returns the type of an IPv6 address.
299
     *
300
     * RFC 1883, Section 2.3 describes several types of addresses in
301
     * the IPv6 addresse space.
302
     * Several addresse types are markers for reserved spaces and as 
303
     * consequence a subject to change.
304
     *
305
     * @param  String $ip the IP address in Hex format, 
306
     *                    compressed IPs are allowed
307
     *
308
     * @return int one of the addresse type constants
309
     * @access public
310
     * @since  1.1.0
311
     * @static
312
     *
313
     * @see    NET_IPV6_UNASSIGNED
314
     * @see    NET_IPV6_RESERVED
315
     * @see    NET_IPV6_RESERVED_NSAP
316
     * @see    NET_IPV6_RESERVED_IPX
317
     * @see    NET_IPV6_RESERVED_UNICAST_GEOGRAPHIC
318
     * @see    NET_IPV6_UNICAST_PROVIDER
319
     * @see    NET_IPV6_MULTICAST
320
     * @see    NET_IPV6_LOCAL_LINK
321
     * @see    NET_IPV6_LOCAL_SITE
322
     * @see    NET_IPV6_UNKNOWN_TYPE
323
     */
324
    function getAddressType($ip) 
325
    {
326
        $ip    = Net_IPv6::removeNetmaskSpec($ip);
327
        $binip = Net_IPv6::_ip2Bin($ip);
328

  
329
        if (0 == strncmp('1111111010', $binip, 10)) {
330

  
331
            return NET_IPV6_LOCAL_LINK;
332

  
333
        } else if (0 == strncmp('1111111011', $binip, 10)) {
334

  
335
            return NET_IPV6_LOCAL_SITE;
336

  
337
        } else if (0 == strncmp('111111100', $binip, 9)) {
338

  
339
            return NET_IPV6_UNASSIGNED;
340

  
341
        } else if (0 == strncmp('11111111', $binip, 8)) {
342

  
343
            return NET_IPV6_MULTICAST;
344

  
345
        }  else if (0 == strncmp('00000000', $binip, 8)) {
346

  
347
            return NET_IPV6_RESERVED;
348

  
349
        } else if (0 == strncmp('00000001', $binip, 8) 
350
                    || 0 == strncmp('1111110', $binip, 7)) {
351

  
352
            return NET_IPV6_UNASSIGNED;
353

  
354
        } else if (0 == strncmp('0000001', $binip, 7)) {
355

  
356
            return NET_IPV6_RESERVED_NSAP;
357

  
358
        } else if (0 == strncmp('0000010', $binip, 7)) {
359

  
360
            return NET_IPV6_RESERVED_IPX;;
361

  
362
        } else if (0 == strncmp('0000011', $binip, 7) ||
363
                    0 == strncmp('111110', $binip, 6) ||
364
                    0 == strncmp('11110', $binip, 5) ||
365
                    0 == strncmp('00001', $binip, 5) ||
366
                    0 == strncmp('1110', $binip, 4) ||
367
                    0 == strncmp('0001', $binip, 4) ||
368
                    0 == strncmp('001', $binip, 3) ||
369
                    0 == strncmp('011', $binip, 3) ||
370
                    0 == strncmp('101', $binip, 3) ||
371
                    0 == strncmp('110', $binip, 3)) {
372

  
373
            return NET_IPV6_UNASSIGNED;
374

  
375
        } else if (0 == strncmp('010', $binip, 3)) {
376

  
377
            return NET_IPV6_UNICAST_PROVIDER;
378

  
379
        }  else if (0 == strncmp('100', $binip, 3)) {
380

  
381
            return NET_IPV6_RESERVED_UNICAST_GEOGRAPHIC;
382

  
383
        }
384

  
385
        return NET_IPV6_UNKNOWN_TYPE;
386
    }
387

  
388
    // }}}
389
    // {{{ Uncompress()
390

  
391
    /**
392
     * Uncompresses an IPv6 adress
393
     *
394
     * RFC 2373 allows you to compress zeros in an adress to '::'. This
395
     * function expects an valid IPv6 adress and expands the '::' to
396
     * the required zeros.
397
     *
398
     * Example:  FF01::101  ->  FF01:0:0:0:0:0:0:101
399
     *           ::1        ->  0:0:0:0:0:0:0:1
400
     *
401
     * @access public
402
     * @see Compress()
403
     * @static
404
     * @param string $ip    a valid IPv6-adress (hex format)
405
     * @return string   the uncompressed IPv6-adress (hex format)
406
     */
407
    function uncompress($ip) 
408
    {
409

  
410
        $prefix = Net_IPv6::getPrefixLength($ip);
411

  
412
        if (false === $prefix) {
413

  
414
            $prefix = '';
415

  
416
        } else {
417

  
418
            $ip     = Net_IPv6::removePrefixLength($ip);
419
            $prefix = '/'.$prefix;
420

  
421
        }
422

  
423
        $netmask = Net_IPv6::getNetmaskSpec($ip);
424
        $uip     = Net_IPv6::removeNetmaskSpec($ip);
425

  
426
        $c1 = -1;
427
        $c2 = -1;
428

  
429
        if (false !== strpos($uip, '::') ) {
430

  
431
            list($ip1, $ip2) = explode('::', $uip);
432

  
433
            if("" == $ip1) {
434

  
435
                $c1 = -1;
436

  
437
            } else {
438

  
439
                $pos = 0;
440

  
441
                if (0 < ($pos = substr_count($ip1, ':'))) {
442

  
443
                    $c1 = $pos;
444

  
445
                } else {
446

  
447
                    $c1 = 0;
448

  
449
                }
450
            }
451
            if ("" == $ip2) {
452

  
453
                $c2 = -1;
454

  
455
            } else {
456

  
457
                $pos = 0;
458

  
459
                if (0 < ($pos = substr_count($ip2, ':'))) {
460

  
461
                    $c2 = $pos;
462

  
463
                } else {
464

  
465
                    $c2 = 0;
466

  
467
                }
468

  
469
            }
470

  
471
            if (strstr($ip2, '.')) {
472

  
473
                $c2++;
474

  
475
            }
476
            if (-1 == $c1 && -1 == $c2) { // ::
477

  
478
                $uip = "0:0:0:0:0:0:0:0";
479

  
480
            } else if (-1 == $c1) {              // ::xxx
481

  
482
                $fill = str_repeat('0:', 7-$c2);
483
                $uip  = str_replace('::', $fill, $uip);
484

  
485
            } else if (-1 == $c2) {              // xxx::
486

  
487
                $fill = str_repeat(':0', 7-$c1);
488
                $uip  = str_replace('::', $fill, $uip);
489

  
490
            } else {                          // xxx::xxx
491

  
492
                $fill = str_repeat(':0:', 6-$c2-$c1);
493
                $uip  = str_replace('::', $fill, $uip);
494
                $uip  = str_replace('::', ':', $uip);
495

  
496
            }
497
        }
498
        if ('' != $netmask) {
499

  
500
                $uip = $uip.'/'.$netmask;
501

  
502
        }
503

  
504
        return $uip.$prefix;
505
    }
506

  
507
    // }}}
508
    // {{{ Compress()
509

  
510
    /**
511
     * Compresses an IPv6 adress
512
     *
513
     * RFC 2373 allows you to compress zeros in an adress to '::'. This
514
     * function expects an valid IPv6 adress and compresses successive zeros
515
     * to '::'
516
     *
517
     * Example:  FF01:0:0:0:0:0:0:101   -> FF01::101
518
     *           0:0:0:0:0:0:0:1        -> ::1
519
     *
520
     * @access public
521
     * @see Uncompress()
522
     * @static
523
     * @param string $ip    a valid IPv6-adress (hex format)
524
     * @return string   the compressed IPv6-adress (hex format)
525
     * @author elfrink at introweb dot nl
526
     */
527
    function compress($ip)  
528
    {
529
        $prefix = Net_IPv6::getPrefixLength($ip);
530

  
531
        if (false === $prefix) {
532

  
533
            $prefix = '';
534

  
535
        } else {
536

  
537
            $ip     = Net_IPv6::removePrefixLength($ip);
538
            $prefix = '/'.$prefix;
539

  
540
        }
541

  
542
        $netmask = Net_IPv6::getNetmaskSpec($ip);
543
        $ip      = Net_IPv6::removeNetmaskSpec($ip);
544

  
545
        if (!strstr($ip, '::')) {
546

  
547
            $ipp = explode(':',$ip);
548

  
549
            for ($i = 0; $i < count($ipp); $i++) {
550

  
551
                $ipp[$i] = dechex(hexdec($ipp[$i]));
552

  
553
            }
554

  
555
            $cip = ':' . join(':',$ipp) . ':';
556

  
557
            preg_match_all("/(:0)+/", $cip, $zeros);
558

  
559
            if (count($zeros[0]) > 0) {
560

  
561
                $match = '';
562

  
563
                foreach($zeros[0] as $zero) {
564

  
565
                    if (strlen($zero) > strlen($match)) {
566

  
567
                        $match = $zero;
568

  
569
                    }
570
                }
571

  
572
                $cip = preg_replace('/' . $match . '/', ':', $cip, 1);
573

  
574
            }
575

  
576
            $cip = preg_replace('/((^:)|(:$))/', '' ,$cip);
577
            $cip = preg_replace('/((^:)|(:$))/', '::' ,$cip);
578

  
579
         }
580
         if ('' != $netmask) {
581

  
582
                $cip = $cip.'/'.$netmask;
583

  
584
         }
585

  
586
         return $cip.$prefix;
587
    }
588

  
589
    // }}}
590
    // {{{ SplitV64()
591

  
592
    /**
593
     * Splits an IPv6 adress into the IPv6 and a possible IPv4 part
594
     *
595
     * RFC 2373 allows you to note the last two parts of an IPv6 adress as
596
     * an IPv4 compatible adress
597
     *
598
     * Example:  0:0:0:0:0:0:13.1.68.3
599
     *           0:0:0:0:0:FFFF:129.144.52.38
600
     *
601
     * @param  string $ip  a valid IPv6-adress (hex format)
602
     *
603
     * @return array  [0] contains the IPv6 part, 
604
     *                [1] the IPv4 part (hex format)
605
     * @access public
606
     * @static
607
     */
608
    function SplitV64($ip, $uncompress = true) 
609
    {
610
        $ip = Net_IPv6::removeNetmaskSpec($ip);
611

  
612
        if ($uncompress) {
613

  
614
            $ip = Net_IPv6::Uncompress($ip);
615

  
616
        }
617

  
618
        if (strstr($ip, '.')) {
619

  
620
            $pos      = strrpos($ip, ':');
621
            $ip{$pos} = '_';
622
            $ipPart   = explode('_', $ip);
623

  
624
            return $ipPart;
625

  
626
        } else {
627

  
628
            return array($ip, "");
629

  
630
        }
631
    }
632

  
633
    // }}}
634
    // {{{ checkIPv6()
635

  
636
    /**
637
     * Checks an IPv6 adress
638
     *
639
     * Checks if the given IP is IPv6-compatible
640
     *
641
     * @access public
642
     * @static
643
     * @param string $ip    a valid IPv6-adress
644
     * @return boolean  true if $ip is an IPv6 adress
645
     */
646
    function checkIPv6($ip) 
647
    {
648
        $ip = Net_IPv6::removePrefixLength($ip);
649
        $ip = Net_IPv6::removeNetmaskSpec($ip);
650

  
651
        $ipPart = Net_IPv6::SplitV64($ip);
652
        $count  = 0;
653

  
654
        if (!empty($ipPart[0]))
655
        {
656
            $ipv6 =explode(':', $ipPart[0]);
657

  
658
            for ($i = 0; $i < count($ipv6); $i++) {
659

  
660
                $dec = hexdec($ipv6[$i]);
661
                $hex = strtoupper(preg_replace("/^[0]{1,3}(.*[0-9a-fA-F])$/",
662
                                                "\\1", 
663
                                                $ipv6[$i]));
664

  
665
                if ($ipv6[$i] >= 0 && $dec <= 65535
666
                    && $hex == strtoupper(dechex($dec))) {
667

  
668
                    $count++;
669

  
670
                }
671

  
672
            }
673

  
674
            if (8 == $count) {
675

  
676
                return true;
677

  
678
            } else if (6 == $count and !empty($ipPart[1])) {
679

  
680
                $ipv4  = explode('.',$ipPart[1]);
681
                $count = 0;
682

  
683
                for ($i = 0; $i < count($ipv4); $i++) {
684

  
685
                    if ($ipv4[$i] >= 0 && (integer)$ipv4[$i] <= 255
686
                        && preg_match("/^\d{1,3}$/", $ipv4[$i])) {
687

  
688
                        $count++;
689

  
690
                    }
691

  
692
                }
693

  
694
                if (4 == $count) {
695

  
696
                    return true;
697

  
698
                }
699

  
700
            } else {
701

  
702
                return false;
703

  
704
            }
705

  
706
        } else {
707

  
708
            return false;
709

  
710
        }
711

  
712
    }
713

  
714
    // }}}
715
    // {{{ getPrefixLength()
716

  
717
    /**
718
     * Tests for a prefix length specification in the address
719
     * and returns the prefix length, if exists
720
     *
721
     * @param  String $ip a valid ipv6 address
722
     *
723
     * @return Mixed the prefix as String or false, if no prefix was found
724
     * @access public
725
     * @static
726
     */
727
    function getPrefixLength($ip) 
728
    {
729
        if (preg_match("/^([0-9a-fA-F:]{2,39})\/(\d{1,3})*$/", 
730
                        $ip, $matches)) {
731

  
732
            return $matches[2];
733

  
734
        } else {
735

  
736
            return false;
737

  
738
        }
739

  
740
    }
741

  
742
    // }}}
743
    // {{{ removePrefixLength()
744

  
745
    /**
746
     * Tests for a prefix length specification in the address
747
     * and removes the prefix length, if exists
748
     *
749
     * @param  String $ip a valid ipv6 address
750
     *
751
     * @return String the address without a prefix length
752
     * @access public
753
     * @static
754
     */
755
    function removePrefixLength($ip) 
756
    {
757
        $pos = strrpos($ip, '/');
758

  
759
        if (false !== $pos) {
760

  
761
            return substr($ip, 0, $pos);
762

  
763
        }
764

  
765
        return $ip;
766
    }
767

  
768
    // }}}
769

  
770
    // {{{ _parseAddress()
771

  
772
    /**
773
     * Returns the lowest and highest IPv6 address
774
     * for a given IP and netmask specification
775
     * 
776
     * The netmask may be a part of the $ip or 
777
     * the number of netwask bits is provided via $bits
778
     *
779
     * The result is an indexed array. The key 'start'
780
     * contains the lowest possible IP adress. The key
781
     * 'end' the highest address.
782
     *
783
     * @param  String $ip the IPv6 address
784
     * @param  String $bits the optional count of netmask bits
785
     *
786
     * @return Array ['start', 'end'] the lowest and highest IPv6 address
787
     * @access public
788
     * @static
789
     * @author Nicholas Williams
790
     */
791

  
792
    function parseAddress($ipToParse, $bits = null)
793
    {
794

  
795
        $ip      = null;
796
        $bitmask = null;
797

  
798
    	if( null == $bits )
799
    	{
800

  
801
    		$elements = explode('/', $ipToParse);
802

  
803
    		if( 2 == count($elements) ) {
804

  
805
    			$ip      = Net_IPv6::uncompress($elements[0]);
806
    			$bitmask = $elements[1];
807

  
808
    		} else {
809

  
810
    			include_once 'PEAR.inc';
811

  
812
    			return PEAR::raiseError(NET_IPV6_NO_NETMASK_MSG,
813
                                        NET_IPV6_NO_NETMASK);
814
    		}
815
    	}
816
    	else
817
    	{
818

  
819
    		$ip      = Net_IPv6::uncompress($ipToParse);
820
    		$bitmask = $bits;
821

  
822
    	}
823

  
824
    	$binNetmask = str_repeat('1', $bitmask).
825
                      str_repeat('0', 128 - $bitmask);
826
    	$maxNetmask = str_repeat('1', 128);
827
    	$netmask    = Net_IPv6::_bin2Ip($binNetmask);
828

  
829
    	$startAddress = Net_IPv6::_bin2Ip(Net_IPv6::_ip2Bin($ip) 
830
                        & $binNetmask);
831
    	$endAddress   = Net_IPv6::_bin2Ip(Net_IPv6::_ip2Bin($ip)
832
                        | ($binNetmask ^ $maxNetmask));
833

  
834
    	return array('start' => $startAddress, 'end' => $endAddress);
835
    }
836

  
837
    // }}}
838

  
839
    // {{{ _ip2Bin()
840

  
841
    /**
842
     * Converts an IPv6 address from Hex into Binary representation.
843
     *
844
     * @param String $ip the IP to convert (a:b:c:d:e:f:g:h), 
845
     *                   compressed IPs are allowed
846
     *
847
     * @return String the binary representation
848
     * @access private
849
     @ @since 1.1.0
850
     */
851
    function _ip2Bin($ip) 
852
    {
853
        $binstr = '';
854

  
855
        $ip = Net_IPv6::removeNetmaskSpec($ip);
856
        $ip = Net_IPv6::Uncompress($ip);
857

  
858
        $parts = explode(':', $ip);
859

  
860
        foreach($parts as $v) {
861

  
862
            $str     = base_convert($v, 16, 2);
863
            $binstr .= str_pad($str, 16, '0', STR_PAD_LEFT);
864

  
865
        }
866

  
867
        return $binstr;
868
    }
869

  
870
    // }}}
871
    // {{{ _bin2Ip()
872

  
873
    /**
874
     * Converts an IPv6 address from Binary into Hex representation.
875
     *
876
     * @param String $ip the IP as binary
877
     *
878
     * @return String the uncompressed Hex representation
879
     * @access private
880
     @ @since 1.1.0
881
     */
882
    function _bin2Ip($bin)
883
    {
884
        $ip = "";
885

  
886
        if (strlen($bin) < 128) {
887

  
888
            $bin = str_pad($str, 128, '0', STR_PAD_LEFT);
889

  
890
        }
891

  
892
        $parts = str_split($bin, "16");
893

  
894
        foreach($parts as $v) {
895

  
896
            $str = base_convert($v, 2, 16);
897
            $ip .= $str.":";
898

  
899
        }
900

  
901
        $ip = substr($ip, 0,-1);
902

  
903
        return $ip;
904
    }
905

  
906
    // }}}
907
}
908
// }}}
909

  
910
/*
911
 * Local variables:
912
 * tab-width: 4
913
 * c-basic-offset: 4
914
 * c-hanging-comment-ender-p: nil
915
 * End:
916
 */
917

  
918
?>
usr/local/www/javascript/NetUtils.js
1
/*
2
	NetUtils.js
3
	part of pfSense (http://www.pfsense.com)
4
	Various helper functions for IPv6 support.
5

  
6
	Copyright (C) 2007 Simon Cornelius P. Umacob <simoncpu@gmail.com>
7
	All rights reserved.
8

  
9
	Redistribution and use in source and binary forms, with or without
10
	modification, are permitted provided that the following conditions are met:
11

  
12
	1. Redistributions of source code must retain the above copyright notice,
13
	   this list of conditions and the following disclaimer.
14

  
15
	2. Redistributions in binary form must reproduce the above copyright
16
	   notice, this list of conditions and the following disclaimer in the
17
	   documentation and/or other materials provided with the distribution.
18

  
19
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
	POSSIBILITY OF SUCH DAMAGE.
29

  
30
*/
31

  
32
function NetUtils_changeIPVersionMask(field, version) {
33
	switch(version){
34
		case 'IPv4':
35
			NetUtils_clearOptions(document.getElementById(field));
36
			NetUtils_loadMaskIPv4(document.getElementById(field), 32);
37

  
38
			break;
39
		case 'IPv6':
40
			NetUtils_clearOptions(document.getElementById(field));
41
			NetUtils_loadMaskIPv6(document.getElementById(field), 64);
42

  
43
			break;
44
		case 'IPv4_net':
45
			NetUtils_clearOptions(document.getElementById(field));
46
			NetUtils_loadMaskIPv4(document.getElementById(field), 32, 1, 31);
47

  
48
			break;
49
		case 'IPv6_net':
50
			NetUtils_clearOptions(document.getElementById(field));
51
			NetUtils_loadMaskIPv6(document.getElementById(field), 64, 1, 63);
52

  
53
			break;
54
	}
55
}
56

  
57
function NetUtils_clearOptions(obj) {
58
	var	len = obj.length;
59

  
60
	for (var i = 0; i < len; i++) {
61
		obj[0] = null;
62
	}
63
}
64

  
65
function NetUtils_loadMaskIPv4(obj, sel, min, max) {
66
	var	min,
67
		max,
68
		j = 0;
69

  
70
	min = min == undefined ? 1 : min;
71
	max = max == undefined ? 32 : max;
72

  
73
	for (var i = max; i >= min; i--) {
74
		obj[j] = new Option(i, i);
75
		if (sel == i) {
76
			obj[j].selected = true;
77
		}
78
		j++;
79
	}
80
}
81

  
82
function NetUtils_loadMaskIPv6(obj, sel, min, max) {
83
	var	min,
84
		max,
85
		j = 0;
86

  
87
	min = min == undefined ? 1 : min;
88
	max = max == undefined ? 64 : max;
89

  
90
	if ((max % 4) != 0) {
91
		obj[j++] = new Option(max, max);
92

  
93
		/**
94
		 * NOTE: This solution is a kludge.
95
		 * If you have a better way, don't hesitate
96
		 * to change this.  Please send patches. :)
97
		 */
98
		for (var i = 1; i <= 3; i++) {
99
			if (((max - i) % 4) == 0) {
100
				max = max - i;
101
				break;
102
			}
103
		} 
104
	}
105

  
106
	for (var i = max; i >= min; i -= 4) {
107
		obj[j] = new Option(i, i);
108
		if (sel == i) {
109
			obj[j].selected = true;
110
		}
111
		j++;
112
	}
113
}
114

  

Also available in: Unified diff