Source code for linuxnet.iptables.matches.addrtypematch
# Copyright (c) 2023, Panagiotis Tsirigotis
# This file is part of linuxnet-iptables.
#
# linuxnet-iptables is free software: you can redistribute it and/or
# modify it under the terms of version 3 of the GNU Affero General Public
# License as published by the Free Software Foundation.
#
# linuxnet-iptables is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General
# Public License along with linuxnet-iptables. If not, see
# <https://www.gnu.org/licenses/>.
"""
This module provides matching against the address type
"""
from typing import Iterable
from ..deps import get_logger
from .match import Match, MatchParser
from .util import GenericCriterion, BooleanCriterion
_logger = get_logger('linuxnet.iptables.matches.addrtype')
[docs]class AddressTypeMatch(Match):
"""Match against the address type
"""
def __init__(self):
self.__src_addr_type_crit = None
self.__dst_addr_type_crit = None
self.__limit_iface_in = None
self.__limit_iface_out = None
[docs] @staticmethod
def get_match_name() -> str:
"""Returns the **iptables(8)** match extension name
"""
return 'addrtype'
[docs] def get_criteria(self) -> Iterable['Criterion']:
"""Returns the addrtype match criteria.
"""
return (self.__src_addr_type_crit, self.__dst_addr_type_crit,
self.__limit_iface_in, self.__limit_iface_out)
[docs] def src_addr_type(self) -> GenericCriterion:
"""Compare with the source address type.
The comparison value is a string and should be one of the
address type values listed in the documentation of the **addrtype**
module in **iptables(8)**
"""
if self.__src_addr_type_crit is None:
self.__src_addr_type_crit = GenericCriterion(self, '--src-type')
return self.__src_addr_type_crit
[docs] def dst_addr_type(self) -> GenericCriterion:
"""Compare with the destination address type
The comparison value is a string and should be one of the
address type values listed in the documentation of the **addrtype**
module in **iptables(8)**
"""
if self.__dst_addr_type_crit is None:
self.__dst_addr_type_crit = GenericCriterion(self, '--dst-type')
return self.__dst_addr_type_crit
[docs] def limit_iface_in(self) -> BooleanCriterion:
"""Address checking limited to the interface that the packet came from.
This criterion does not support negation.
Invocation of the :meth:`BooleanCriterion.not_equals` method
will raise an :exc:`IptablesError`
"""
if self.__limit_iface_in is None:
self.__limit_iface_in = BooleanCriterion(self, '--limit-iface-in',
supports_negation=False)
return self.__limit_iface_in
[docs] def limit_iface_out(self) -> BooleanCriterion:
"""Address checking limited to the interface that the packet
is going out from.
This criterion does not support negation.
Invocation of the :meth:`BooleanCriterion.not_equals` method
will raise an :exc:`IptablesError`
"""
if self.__limit_iface_out is None:
self.__limit_iface_out = BooleanCriterion(self, '--limit-iface-out',
supports_negation=False)
return self.__limit_iface_out
@classmethod
def parse(cls, parser: MatchParser) -> Match:
"""Parse ADDRTYPE; the expected form is::
ADDRTYPE match src-type UNICAST dst-type !UNICAST
ADDRTYPE match src-type !BLACKHOLE dst-type !UNICAST limit-in
ADDRTYPE match src-type MULTICAST limit-out
ADDRTYPE match src-type PROHIBIT /* comment */
The PKTTYPE field has already been consumed.
:meta private:
"""
parser.skip_field('match')
criteria_iter = parser.get_iter()
match = AddressTypeMatch()
for val in criteria_iter:
if val == 'src-type':
eq_test, addr_type = parser.parse_value(next(criteria_iter))
match.src_addr_type().compare(eq_test, addr_type)
elif val == 'dst-type':
eq_test, addr_type = parser.parse_value(next(criteria_iter))
match.dst_addr_type().compare(eq_test, addr_type)
elif val == 'limit-in':
match.limit_iface_in().equals()
elif val == 'limit-out':
match.limit_iface_out().equals()
else:
# next match, or target
criteria_iter.put_back(val)
break
return match
MatchParser.register_match('ADDRTYPE', AddressTypeMatch)