Subversion Repositories oidplus

Rev

Rev 1121 | Rev 1174 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
635 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
1086 daniel-mar 5
 * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
635 daniel-mar 6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
1050 daniel-mar 20
namespace ViaThinkSoft\OIDplus;
635 daniel-mar 21
 
1086 daniel-mar 22
// phpcs:disable PSR1.Files.SideEffects
23
\defined('INSIDE_OIDPLUS') or die;
24
// phpcs:enable PSR1.Files.SideEffects
25
 
635 daniel-mar 26
class OIDplusIpv4 extends OIDplusObject {
1130 daniel-mar 27
        /**
28
         * @var string
29
         */
635 daniel-mar 30
        private $ipv4;
1130 daniel-mar 31
 
32
        /**
33
         * @var string
34
         */
635 daniel-mar 35
        private $bare;
1130 daniel-mar 36
 
37
        /**
38
         * @var int
39
         */
635 daniel-mar 40
        private $cidr;
41
 
1116 daniel-mar 42
        /**
1130 daniel-mar 43
         * @param string $ipv4
1116 daniel-mar 44
         * @throws OIDplusException
45
         */
1130 daniel-mar 46
        public function __construct(string $ipv4) {
635 daniel-mar 47
                $this->ipv4 = $ipv4;
48
 
49
                if (!empty($ipv4)) {
50
                        if (strpos($ipv4, '/') === false) $ipv4 .= '/32';
51
                        list($bare, $cidr) = explode('/', $ipv4);
52
                        $this->bare = $bare;
1130 daniel-mar 53
                        if (is_numeric($cidr)) throw new OIDplusException(_L('Invalid IPv4'));
54
                        $this->cidr = (int)$cidr;
635 daniel-mar 55
                        if (!ipv4_valid($bare)) throw new OIDplusException(_L('Invalid IPv4'));
56
                        if (!is_numeric($cidr)) throw new OIDplusException(_L('Invalid IPv4'));
57
                        if ($cidr < 0) throw new OIDplusException(_L('Invalid IPv4'));
58
                        if ($cidr > 32) throw new OIDplusException(_L('Invalid IPv4'));
59
                        $this->bare = ipv4_normalize($this->bare);
856 daniel-mar 60
                        $this->ipv4 = $this->bare . '/' . $this->cidr;
635 daniel-mar 61
                }
62
        }
63
 
1116 daniel-mar 64
        /**
65
         * @param string $node_id
66
         * @return OIDplusIpv4|null
1130 daniel-mar 67
         * @throws OIDplusException
1116 daniel-mar 68
         */
69
        public static function parse(string $node_id)/*: ?OIDplusIpv4*/ {
635 daniel-mar 70
                @list($namespace, $ipv4) = explode(':', $node_id, 2);
1116 daniel-mar 71
                if ($namespace !== self::ns()) return null;
635 daniel-mar 72
                return new self($ipv4);
73
        }
74
 
1116 daniel-mar 75
        /**
76
         * @return string
77
         */
78
        public static function objectTypeTitle(): string {
635 daniel-mar 79
                return _L('IPv4 Network Blocks');
80
        }
81
 
1116 daniel-mar 82
        /**
83
         * @return string
84
         */
85
        public static function objectTypeTitleShort(): string {
635 daniel-mar 86
                return _L('IPv4');
87
        }
88
 
1116 daniel-mar 89
        /**
90
         * @return string
91
         */
92
        public static function ns(): string {
635 daniel-mar 93
                return 'ipv4';
94
        }
95
 
1116 daniel-mar 96
        /**
97
         * @return string
98
         */
99
        public static function root(): string {
860 daniel-mar 100
                return self::ns().':';
635 daniel-mar 101
        }
102
 
1116 daniel-mar 103
        /**
104
         * @return bool
105
         */
106
        public function isRoot(): bool {
635 daniel-mar 107
                return $this->ipv4 == '';
108
        }
109
 
1116 daniel-mar 110
        /**
111
         * @param bool $with_ns
112
         * @return string
113
         */
114
        public function nodeId(bool $with_ns=true): string {
859 daniel-mar 115
                return $with_ns ? self::root().$this->ipv4 : $this->ipv4;
635 daniel-mar 116
        }
117
 
1116 daniel-mar 118
        /**
119
         * @param string $str
120
         * @return string
121
         * @throws OIDplusException
122
         */
123
        public function addString(string $str): string {
635 daniel-mar 124
                if (strpos($str, '/') === false) $str .= "/32";
125
 
126
                if (!$this->isRoot()) {
127
                        if (!ipv4_in_cidr($this->bare.'/'.$this->cidr, $str)) {
128
                                throw new OIDplusException(_L('Cannot add this address, because it must be inside the address range of the superior range.'));
129
                        }
130
                }
131
 
132
                list($ipv4, $cidr) = explode('/', $str);
133
                if ($cidr < 0) throw new OIDplusException(_L('Invalid IPv4 address %1',$str));
134
                if ($cidr > 32) throw new OIDplusException(_L('Invalid IPv4 address %1',$str));
135
                $ipv4_normalized = ipv4_normalize($ipv4);
136
                if (!$ipv4_normalized) throw new OIDplusException(_L('Invalid IPv4 address %1',$str));
859 daniel-mar 137
                return self::root().$ipv4_normalized.'/'.$cidr; // overwrite; no hierarchical tree
635 daniel-mar 138
        }
139
 
1116 daniel-mar 140
        /**
141
         * @param OIDplusObject $parent
142
         * @return string
143
         */
144
        public function crudShowId(OIDplusObject $parent): string {
635 daniel-mar 145
                return $this->ipv4;
146
        }
147
 
1116 daniel-mar 148
        /**
149
         * @param OIDplusObject|null $parent
150
         * @return string
151
         */
152
        public function jsTreeNodeName(OIDplusObject $parent = null): string {
635 daniel-mar 153
                if ($parent == null) return $this->objectTypeTitle();
154
                return $this->ipv4;
155
        }
156
 
1116 daniel-mar 157
        /**
158
         * @return string
159
         */
160
        public function defaultTitle(): string {
635 daniel-mar 161
                return $this->ipv4;
162
        }
163
 
1116 daniel-mar 164
        /**
165
         * @return bool
166
         */
167
        public function isLeafNode(): bool {
635 daniel-mar 168
                return $this->cidr >= 32;
169
        }
170
 
1116 daniel-mar 171
        /**
172
         * @return array
173
         */
174
        private function getTechInfo(): array {
753 daniel-mar 175
                if ($this->isRoot()) return array();
176
 
177
                $tech_info = array();
178
 
179
                $tech_info[_L('IPv4/CIDR')] = ipv4_normalize($this->bare) . '/' . $this->cidr;
180
                if ($this->cidr < 32) {
181
                        $tech_info[_L('First address')] = ipv4_cidr_min_ip($this->bare . '/' . $this->cidr);
182
                        $tech_info[_L('Last address')]  = ipv4_cidr_max_ip($this->bare . '/' . $this->cidr);
183
                }
184
 
185
                return $tech_info;
186
        }
187
 
1116 daniel-mar 188
        /**
189
         * @param string $title
190
         * @param string $content
191
         * @param string $icon
192
         * @return void
193
         * @throws OIDplusException
194
         */
195
        public function getContentPage(string &$title, string &$content, string &$icon) {
801 daniel-mar 196
                $icon = file_exists(__DIR__.'/img/main_icon.png') ? OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon.png' : '';
635 daniel-mar 197
 
198
                if ($this->isRoot()) {
199
                        $title = OIDplusIpv4::objectTypeTitle();
200
 
201
                        $res = OIDplus::db()->query("select * from ###objects where parent = ?", array(self::root()));
790 daniel-mar 202
                        if ($res->any()) {
962 daniel-mar 203
                                $content  = '<p>'._L('Please select a network block in the tree view at the left to show its contents.').'</p>';
635 daniel-mar 204
                        } else {
962 daniel-mar 205
                                $content  = '<p>'._L('Currently, no network blocks are registered in the system.').'</p>';
635 daniel-mar 206
                        }
207
 
208
                        if (!$this->isLeafNode()) {
209
                                if (OIDplus::authUtils()->isAdminLoggedIn()) {
210
                                        $content .= '<h2>'._L('Manage root objects').'</h2>';
211
                                } else {
212
                                        $content .= '<h2>'._L('Available objects').'</h2>';
213
                                }
214
                                $content .= '%%CRUD%%';
215
                        }
216
                } else {
217
                        $title = $this->getTitle();
218
 
753 daniel-mar 219
                        $tech_info = $this->getTechInfo();
220
                        $tech_info_html = '';
221
                        if (count($tech_info) > 0) {
222
                                $tech_info_html .= '<h2>'._L('Technical information').'</h2>';
223
                                $tech_info_html .= '<table border="0">';
224
                                foreach ($tech_info as $key => $value) {
225
                                        $tech_info_html .= '<tr><td>'.$key.': </td><td><code>'.$value.'</code></td></tr>';
226
                                }
227
                                $tech_info_html .= '</table>';
635 daniel-mar 228
                        }
753 daniel-mar 229
                        if ($this->cidr == 32) $tech_info_html .= _L('Single host address');
635 daniel-mar 230
 
753 daniel-mar 231
                        $content = $tech_info_html;
232
 
635 daniel-mar 233
                        $content .= '<h2>'._L('Description').'</h2>%%DESC%%';
234
 
235
                        if (!$this->isLeafNode()) {
236
                                if ($this->userHasWriteRights()) {
928 daniel-mar 237
                                        $content .= '<h2>'._L('Create or change subordinate objects').'</h2>';
635 daniel-mar 238
                                } else {
928 daniel-mar 239
                                        $content .= '<h2>'._L('Subordinate objects').'</h2>';
635 daniel-mar 240
                                }
241
                                $content .= '%%CRUD%%';
242
                        }
243
                }
244
        }
245
 
1116 daniel-mar 246
        /**
247
         * @return OIDplusIpv4|null
248
         */
249
        public function one_up()/*: ?OIDplusIpv4*/ {
635 daniel-mar 250
                $cidr = $this->cidr - 1;
1116 daniel-mar 251
                if ($cidr < 0) return null; // cannot go further up
635 daniel-mar 252
 
253
                $tmp = ipv4_normalize_range($this->bare . '/' . $cidr);
254
                return self::parse($this->ns() . ':' . $tmp);
255
        }
256
 
1116 daniel-mar 257
        /**
1130 daniel-mar 258
         * @param OIDplusObject|string $to
1116 daniel-mar 259
         * @return float|int|mixed|string|null
260
         */
635 daniel-mar 261
        public function distance($to) {
262
                if (!is_object($to)) $to = OIDplusObject::parse($to);
1121 daniel-mar 263
                if (!$to) return null;
1116 daniel-mar 264
                if (!($to instanceof $this)) return null;
265
                $res = ipv4_distance($to->ipv4, $this->ipv4);
266
                return $res !== false ? $res : null;
635 daniel-mar 267
        }
268
 
1116 daniel-mar 269
        /**
270
         * @return string
271
         */
272
        public function getDirectoryName(): string {
635 daniel-mar 273
                if ($this->isRoot()) return $this->ns();
274
                $bare = str_replace('.','_',ipv4_normalize($this->bare));
275
                if ($this->isLeafNode()) {
276
                        return $this->ns().'_'.$bare;
277
                } else {
278
                        return $this->ns().'_'.$bare.'__'.$this->cidr;
279
                }
280
        }
800 daniel-mar 281
 
1116 daniel-mar 282
        /**
283
         * @param string $mode
284
         * @return string
285
         */
286
        public static function treeIconFilename(string $mode): string {
800 daniel-mar 287
                return 'img/'.$mode.'_icon16.png';
288
        }
707 daniel-mar 289
}