File: exceptions.py

package info (click to toggle)
python-icmplib 2.1.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 256 kB
  • sloc: python: 1,903; makefile: 17
file content (221 lines) | stat: -rw-r--r-- 5,990 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
'''
    icmplib
    ~~~~~~~

    A powerful library for forging ICMP packets and performing ping
    and traceroute.

        https://github.com/ValentinBELYN/icmplib

    :copyright: Copyright 2017-2021 Valentin BELYN.
    :license: GNU LGPLv3, see the LICENSE for details.

    ~~~~~~~

    This program is free software: you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public License
    as published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    This program 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this program.  If not, see
    <https://www.gnu.org/licenses/>.
'''


class ICMPLibError(Exception):
    '''
    Exception class for the icmplib package.

    '''
    def __init__(self, message):
        self._message = message

    def __str__(self):
        return self._message

    @property
    def message(self):
        return self._message


class NameLookupError(ICMPLibError):
    '''
    Raised when the requested name does not exist or cannot be
    resolved. This concerns both Fully Qualified Domain Names and
    hostnames.

    '''
    def __init__(self, name):
        message = f'The name \'{name}\' cannot be resolved'
        super().__init__(message)


class ICMPSocketError(ICMPLibError):
    '''
    Base class for ICMP sockets exceptions.

    '''


class SocketAddressError(ICMPSocketError):
    '''
    Raised when the requested address cannot be assigned to the socket.

    '''
    def __init__(self, address):
        message = f'The requested address ({address}) cannot be ' \
                   'assigned to the socket'
        super().__init__(message)


class SocketPermissionError(ICMPSocketError):
    '''
    Raised when the privileges are insufficient to create the socket.

    '''
    def __init__(self):
        message = 'Root privileges are required to create the socket'
        super().__init__(message)


class SocketUnavailableError(ICMPSocketError):
    '''
    Raised when an action is performed while the socket is closed.

    '''
    def __init__(self):
        message = 'The socket can no longer be used after its closure'
        super().__init__(message)


class SocketBroadcastError(ICMPSocketError):
    '''
    Raised when a broadcast address is used and the corresponding
    option is not enabled on the socket.

    '''
    def __init__(self):
        message = 'Broadcast is not allowed: ' \
                  'please use the \'broadcast\' property to allow it'
        super().__init__(message)


class TimeoutExceeded(ICMPSocketError):
    '''
    Raised when a timeout occurs on a socket.

    '''
    def __init__(self, timeout):
        message = f'The timeout has been reached ({timeout}s)'
        super().__init__(message)


class ICMPError(ICMPLibError):
    '''
    Base class for ICMP error messages.

    '''
    def __init__(self, message, reply):
        super().__init__(message)
        self._reply = reply

    @property
    def reply(self):
        return self._reply


class DestinationUnreachable(ICMPError):
    '''
    Base class for ICMP Destination Unreachable messages.

    Destination Unreachable message is generated by the host or its
    inbound gateway to inform the client that the destination is
    unreachable for some reason.

    '''
    _CODES = {}

    def __init__(self, reply):
        if reply.code in self._CODES:
            message = self._CODES[reply.code]

        else:
            message = f'Destination unreachable, bad code: {reply.code}'

        super().__init__(message, reply)


class ICMPv4DestinationUnreachable(DestinationUnreachable):
    _CODES = {
        0:  'Destination network unreachable',
        1:  'Destination host unreachable',
        2:  'Destination protocol unreachable',
        3:  'Destination port unreachable',
        4:  'Fragmentation needed and DF set',
        5:  'Source route failed',
        6:  'Destination network unknown',
        7:  'Destination host unknown',
        8:  'Source host isolated',
        9:  'Destination network prohibed',
        10: 'Destination host prohibed',
        11: 'Destination network unreachable for ToS',
        12: 'Destination host unreachable for ToS',
        13: 'Packet filtered',
        14: 'Precedence violation',
        15: 'Precedence cutoff'
    }


class ICMPv6DestinationUnreachable(DestinationUnreachable):
    _CODES = {
        0:  'No route to destination',
        1:  'Communication with destination administratively prohibited',
        2:  'Beyond scope of source address',
        3:  'Address unreachable',
        4:  'Port unreachable',
        5:  'Source address failed ingress/egress policy',
        6:  'Reject route to destination'
    }


class TimeExceeded(ICMPError):
    '''
    Base class for ICMP Time Exceeded messages.

    Time Exceeded message is generated by a gateway to inform the
    source of a discarded datagram due to the time to live field
    reaching zero. A Time Exceeded message may also be sent by a host
    if it fails to reassemble a fragmented datagram within its time
    limit.

    '''
    _CODES = {}

    def __init__(self, reply):
        if reply.code in self._CODES:
            message = self._CODES[reply.code]

        else:
            message = f'Time exceeded, bad code: {reply.code}'

        super().__init__(message, reply)


class ICMPv4TimeExceeded(TimeExceeded):
    _CODES = {
        0:  'Time to live exceeded',
        1:  'Fragment reassembly time exceeded'
    }


class ICMPv6TimeExceeded(TimeExceeded):
    _CODES = {
        0:  'Hop limit exceeded',
        1:  'Fragment reassembly time exceeded'
    }