| [3073] | 1 | #!/usr/bin/env python |
|---|
| 2 | # -*- coding: utf-8 -*- |
|---|
| 3 | |
|---|
| 4 | # Copyright (C) 2008 Adriano Monteiro Marques. |
|---|
| 5 | # |
|---|
| 6 | # Author: Bartosz SKOWRON <getxsick at gmail dot com> |
|---|
| 7 | # |
|---|
| [3122] | 8 | # This library is free software; you can redistribute it and/or modify |
|---|
| 9 | # it under the terms of the GNU Lesser General Public License as published |
|---|
| 10 | # by the Free Software Foundation; either version 2.1 of the License, or |
|---|
| [3073] | 11 | # (at your option) any later version. |
|---|
| 12 | # |
|---|
| [3122] | 13 | # This library is distributed in the hope that it will be useful, but |
|---|
| 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|---|
| 15 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
|---|
| 16 | # License for more details. |
|---|
| [3073] | 17 | # |
|---|
| [3122] | 18 | # You should have received a copy of the GNU Lesser General Public License |
|---|
| 19 | # along with this library; if not, write to the Free Software Foundation, |
|---|
| 20 | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| [3073] | 21 | |
|---|
| [3192] | 22 | from _ import * |
|---|
| [3120] | 23 | from umpa.utils.my_exceptions import UMPAAttributeException |
|---|
| [3073] | 24 | |
|---|
| [3173] | 25 | class HIHL(IntField): |
|---|
| 26 | bits = 4 |
|---|
| 27 | def generate_value(self): |
|---|
| [3088] | 28 | pass |
|---|
| [3173] | 29 | # FIXME: how to get length of every fields in this scope? |
|---|
| [3084] | 30 | |
|---|
| [3173] | 31 | class HTotalLength(Field): |
|---|
| 32 | bits = 16 |
|---|
| [3088] | 33 | def fillout(self): |
|---|
| [3084] | 34 | pass |
|---|
| 35 | |
|---|
| [3173] | 36 | class HIdentification(Field): |
|---|
| 37 | bits = 16 |
|---|
| [3088] | 38 | def fillout(self): |
|---|
| [3084] | 39 | pass |
|---|
| 40 | |
|---|
| [3173] | 41 | class HFragmentOffset(Field): |
|---|
| 42 | bits = 13 |
|---|
| [3088] | 43 | def fillout(self): |
|---|
| [3084] | 44 | pass |
|---|
| 45 | |
|---|
| [3173] | 46 | class HProtocol(Field): |
|---|
| 47 | bits = 8 |
|---|
| [3088] | 48 | def fillout(self): |
|---|
| [3084] | 49 | pass |
|---|
| 50 | |
|---|
| [3173] | 51 | class HHeaderChecksum(Field): |
|---|
| 52 | bits = 16 |
|---|
| [3088] | 53 | def fillout(self): |
|---|
| [3084] | 54 | pass |
|---|
| [3088] | 55 | |
|---|
| [3173] | 56 | class HPadding(Field): |
|---|
| 57 | bits = 0 |
|---|
| [3088] | 58 | def fillout(self): |
|---|
| 59 | pass |
|---|
| 60 | |
|---|
| 61 | # main IP class |
|---|
| 62 | |
|---|
| [3173] | 63 | class IP(Protocol): |
|---|
| [3166] | 64 | """This is Internet Protocol. |
|---|
| 65 | The main protocol in third layer of OSI model. |
|---|
| 66 | """ |
|---|
| [3169] | 67 | layer = 3 # layer of OSI |
|---|
| [3088] | 68 | |
|---|
| [3190] | 69 | _ordered_fields = ('_version', '_ihl', 'type_of_service', '_total_length', |
|---|
| 70 | '_identification', 'flags', '_fragment_offset', |
|---|
| 71 | 'time_to_live', '_protocol', '_header_checksum', |
|---|
| 72 | 'source_address', 'destination_address', 'options', |
|---|
| 73 | '_padding',) |
|---|
| 74 | |
|---|
| [3088] | 75 | def __init__(self, **kw): |
|---|
| [3167] | 76 | tos = ('precedence0','precedence1', 'precedence2', 'delay', |
|---|
| [3136] | 77 | 'throughput', 'relibility', 'reserved0', 'reserverd1') |
|---|
| 78 | flags = ('reserved', 'df', 'mf') |
|---|
| [3088] | 79 | |
|---|
| [3173] | 80 | fields_list = [ IntField(4, 4), HIHL(), Flags(tos), HTotalLength(), |
|---|
| [3140] | 81 | HIdentification(), Flags(flags, reserved=0), |
|---|
| 82 | HFragmentOffset(), Field(255, 8), HProtocol(), |
|---|
| [3141] | 83 | HHeaderChecksum(), Field(bits=16), Field(bits=16), |
|---|
| 84 | Flags(()), HPadding() ] |
|---|
| [3136] | 85 | |
|---|
| [3128] | 86 | # we pack objects of header's fields to the dict |
|---|
| [3190] | 87 | fields = dict(zip(self._ordered_fields, fields_list)) |
|---|
| 88 | super(IP, self).__init__(fields, **kw) |
|---|
| [3128] | 89 | |
|---|
| [3088] | 90 | # setting up passed fields |
|---|
| 91 | for field in kw: |
|---|
| 92 | self.__setattr__(field, kw[field]) |
|---|
| 93 | |
|---|
| [3166] | 94 | |
|---|
| 95 | # set __doc__ for fields - it's important if you want to get hints |
|---|
| 96 | # in some frontends. E.g. Umit Project provides one... |
|---|
| [3200] | 97 | self._fields['_version'].set_doc("The Version field indicates the \ |
|---|
| 98 | format of the internet header. See RFC 791 for more.") |
|---|
| [3190] | 99 | self._fields['_ihl'].set_doc("Internet Header Length is the length \ |
|---|
| [3200] | 100 | of the internet header in 32 bit words, and thus points to the beginning of \ |
|---|
| 101 | the data. See RFC 791 for more.") |
|---|
| [3190] | 102 | self._fields['type_of_service'].set_doc("The Type of Service provides \ |
|---|
| [3200] | 103 | an indication of the abstract parameters of the quality of service desired. \ |
|---|
| 104 | See RFC 791 for more.") |
|---|
| [3190] | 105 | self._fields['_total_length'].set_doc("Total Length is the length of \ |
|---|
| [3200] | 106 | the datagram, measured in octets, including internet header and data. \ |
|---|
| 107 | See RFC 791 for more.") |
|---|
| [3190] | 108 | self._fields['_identification'].set_doc("An identifying value \ |
|---|
| [3200] | 109 | assigned by the sender to aid in assembling the fragments of a datagram. \ |
|---|
| 110 | See RFC 791 for more.") |
|---|
| [3190] | 111 | self._fields['flags'].set_doc("Various Control Flags. See RFC 791 \ |
|---|
| [3200] | 112 | for more.") |
|---|
| [3190] | 113 | self._fields['_fragment_offset'].set_doc("This field indicates where \ |
|---|
| [3200] | 114 | in the datagram this fragment belongs. See RFC 791 for more.") |
|---|
| [3190] | 115 | self._fields['time_to_live'].set_doc("This field indicates the \ |
|---|
| [3200] | 116 | maximum time the datagram is allowed to remain in the internet system. \ |
|---|
| 117 | See RFC 791 for more.") |
|---|
| [3190] | 118 | self._fields['_protocol'].set_doc("This field indicates the next \ |
|---|
| [3200] | 119 | level protocol used in the data portion of the internet datagram. See RFC 791 \ |
|---|
| 120 | for more.") |
|---|
| [3190] | 121 | self._fields['_header_checksum'].set_doc("A checksum on the header \ |
|---|
| [3200] | 122 | only. See RFC 791 for more.") |
|---|
| [3190] | 123 | self._fields['source_address'].set_doc("The source address. \ |
|---|
| [3200] | 124 | See RFC 791 for more.") |
|---|
| [3190] | 125 | self._fields['destination_address'].set_doc("The destination address. \ |
|---|
| [3200] | 126 | See RFC 791 for more.") |
|---|
| [3190] | 127 | self._fields['options'].set_doc("The options may appear or not in \ |
|---|
| [3200] | 128 | datagrams. See RFC 791 for more.") |
|---|
| [3190] | 129 | self._fields['_padding'].set_doc("The internet header padding is used \ |
|---|
| [3200] | 130 | to ensure that the internet header ends on a 32 bit boundary. See RFC 791 for \ |
|---|
| 131 | more.") |
|---|
| [3166] | 132 | |
|---|
| [3088] | 133 | def _is_valid(self, name): |
|---|
| [3124] | 134 | """Check if attribute is allowed.""" |
|---|
| [3128] | 135 | return self._fields.has_key(name) |
|---|
| [3204] | 136 | |
|---|
| 137 | protocols = [ IP, ] |
|---|