1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22/**
23 * A parser for IPv4 and IPv6 addresses
24 */
25class CIPParser extends CParser {
26
27	/**
28	 * @var CIPv4Parser
29	 */
30	private $ipv4_parser;
31
32	/**
33	 * @var CIPv6Parser
34	 */
35	private $ipv6_parser;
36
37	/**
38	 * @var CUserMacroParser
39	 */
40	private $user_macro_parser;
41
42	/**
43	 * @var CLLDMacroParser
44	 */
45	private $lld_macro_parser;
46
47	/**
48	 * @var CLLDMacroFunctionParser
49	 */
50	private $lld_macro_function_parser;
51
52	/**
53	 * Supported options:
54	 *   'v6' => true          Enabled support of IPv6 addresses;
55	 *   'usermacros' => true  Enabled support of user macros;
56	 *   'lldmacros' => true   Enabled support of LLD macros;
57	 *   'macros' => true      Enabled support of all macros. Allows array with list of macros.
58	 *
59	 * @var array
60	 */
61	private $options = [
62		'v6' => true,
63		'usermacros' => false,
64		'lldmacros' => false,
65		'macros' => []
66	];
67
68	/**
69	 * @param array $options
70	 */
71	public function __construct(array $options) {
72		if (array_key_exists('v6', $options)) {
73			$this->options['v6'] = $options['v6'];
74		}
75		if (array_key_exists('usermacros', $options)) {
76			$this->options['usermacros'] = $options['usermacros'];
77		}
78		if (array_key_exists('lldmacros', $options)) {
79			$this->options['lldmacros'] = $options['lldmacros'];
80		}
81		if (array_key_exists('macros', $options)) {
82			$this->options['macros'] = $options['macros'];
83		}
84
85		if ($this->options['v6']) {
86			$this->ipv6_parser = new CIPv6Parser();
87		}
88		if ($this->options['usermacros']) {
89			$this->user_macro_parser = new CUserMacroParser();
90		}
91		if ($this->options['lldmacros']) {
92			$this->lld_macro_parser = new CLLDMacroParser();
93			$this->lld_macro_function_parser = new CLLDMacroFunctionParser();
94		}
95		if ($this->options['macros']) {
96			$this->macro_parser = new CMacroParser(['macros' => $this->options['macros']]);
97		}
98
99		$this->ipv4_parser = new CIPv4Parser();
100	}
101
102	/**
103	 * @param string $source
104	 * @param int    $pos
105	 *
106	 * @return bool
107	 */
108	public function parse($source, $pos = 0) {
109		$this->length = 0;
110		$this->match = '';
111
112		if ($this->ipv4_parser->parse($source, $pos) != self::PARSE_FAIL) {
113			$this->length = $this->ipv4_parser->getLength();
114			$this->match = $this->ipv4_parser->getMatch();
115		}
116		elseif ($this->options['v6'] && $this->ipv6_parser->parse($source, $pos) != self::PARSE_FAIL) {
117			$this->length = $this->ipv6_parser->getLength();
118			$this->match = $this->ipv6_parser->getMatch();
119		}
120		elseif ($this->options['usermacros'] && $this->user_macro_parser->parse($source, $pos) != self::PARSE_FAIL) {
121			$this->length = $this->user_macro_parser->getLength();
122			$this->match = $this->user_macro_parser->getMatch();
123		}
124		elseif ($this->options['lldmacros'] && $this->lld_macro_parser->parse($source, $pos) != self::PARSE_FAIL) {
125			$this->length = $this->lld_macro_parser->getLength();
126			$this->match = $this->lld_macro_parser->getMatch();
127		}
128		elseif ($this->options['lldmacros']
129				&& $this->lld_macro_function_parser->parse($source, $pos) != self::PARSE_FAIL) {
130			$this->length = $this->lld_macro_function_parser->getLength();
131			$this->match = $this->lld_macro_function_parser->getMatch();
132		}
133		elseif ($this->options['macros'] && $this->macro_parser->parse($source, $pos) != self::PARSE_FAIL) {
134			$this->length = $this->macro_parser->getLength();
135			$this->match = $this->macro_parser->getMatch();
136		}
137		else {
138			return self::PARSE_FAIL;
139		}
140
141		return isset($source[$pos + $this->length]) ? self::PARSE_SUCCESS_CONT : self::PARSE_SUCCESS;
142	}
143}
144