| 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 | # |
|---|
| 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 |
|---|
| 11 | # (at your option) any later version. |
|---|
| 12 | # |
|---|
| 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. |
|---|
| 17 | # |
|---|
| 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 |
|---|
| 21 | |
|---|
| 22 | from _ import * |
|---|
| 23 | from umpa.utils.my_exceptions import UMPAAttributeException |
|---|
| 24 | |
|---|
| 25 | class HIHL(IntField): |
|---|
| 26 | bits = 4 |
|---|
| 27 | def generate_value(self): |
|---|
| 28 | pass |
|---|
| 29 | # FIXME: how to get length of every fields in this scope? |
|---|
| 30 | |
|---|
| 31 | class HTotalLength(Field): |
|---|
| 32 | bits = 16 |
|---|
| 33 | def fillout(self): |
|---|
| 34 | pass |
|---|
| 35 | |
|---|
| 36 | class HIdentification(Field): |
|---|
| 37 | bits = 16 |
|---|
| 38 | def fillout(self): |
|---|
| 39 | pass |
|---|
| 40 | |
|---|
| 41 | class HFragmentOffset(Field): |
|---|
| 42 | bits = 13 |
|---|
| 43 | def fillout(self): |
|---|
| 44 | pass |
|---|
| 45 | |
|---|
| 46 | class HProtocol(Field): |
|---|
| 47 | bits = 8 |
|---|
| 48 | def fillout(self): |
|---|
| 49 | pass |
|---|
| 50 | |
|---|
| 51 | class HHeaderChecksum(Field): |
|---|
| 52 | bits = 16 |
|---|
| 53 | def fillout(self): |
|---|
| 54 | pass |
|---|
| 55 | |
|---|
| 56 | class HPadding(Field): |
|---|
| 57 | bits = 0 |
|---|
| 58 | def fillout(self): |
|---|
| 59 | pass |
|---|
| 60 | |
|---|
| 61 | # main IP class |
|---|
| 62 | |
|---|
| 63 | class IP(Protocol): |
|---|
| 64 | """This is Internet Protocol. |
|---|
| 65 | The main protocol in third layer of OSI model. |
|---|
| 66 | """ |
|---|
| 67 | layer = 3 # layer of OSI |
|---|
| 68 | |
|---|
| 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 | |
|---|
| 75 | def __init__(self, **kw): |
|---|
| 76 | tos = ('precedence0','precedence1', 'precedence2', 'delay', |
|---|
| 77 | 'throughput', 'relibility', 'reserved0', 'reserverd1') |
|---|
| 78 | flags = ('reserved', 'df', 'mf') |
|---|
| 79 | |
|---|
| 80 | fields_list = [ IntField(4, 4), HIHL(), Flags(tos), HTotalLength(), |
|---|
| 81 | HIdentification(), Flags(flags, reserved=0), |
|---|
| 82 | HFragmentOffset(), Field(255, 8), HProtocol(), |
|---|
| 83 | HHeaderChecksum(), Field(bits=16), Field(bits=16), |
|---|
| 84 | Flags(()), HPadding() ] |
|---|
| 85 | |
|---|
| 86 | # we pack objects of header's fields to the dict |
|---|
| 87 | fields = dict(zip(self._ordered_fields, fields_list)) |
|---|
| 88 | super(IP, self).__init__(fields, **kw) |
|---|
| 89 | |
|---|
| 90 | # setting up passed fields |
|---|
| 91 | for field in kw: |
|---|
| 92 | self.__setattr__(field, kw[field]) |
|---|
| 93 | |
|---|
| 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... |
|---|
| 97 | self._fields['_version'].set_doc("The Version field indicates the \ |
|---|
| 98 | format of the internet header. See RFC 791 for more.") |
|---|
| 99 | self._fields['_ihl'].set_doc("Internet Header Length is the length \ |
|---|
| 100 | of the internet header in 32 bit words, and thus points to the beginning of \ |
|---|
| 101 | the data. See RFC 791 for more.") |
|---|
| 102 | self._fields['type_of_service'].set_doc("The Type of Service provides \ |
|---|
| 103 | an indication of the abstract parameters of the quality of service desired. \ |
|---|
| 104 | See RFC 791 for more.") |
|---|
| 105 | self._fields['_total_length'].set_doc("Total Length is the length of \ |
|---|
| 106 | the datagram, measured in octets, including internet header and data. \ |
|---|
| 107 | See RFC 791 for more.") |
|---|
| 108 | self._fields['_identification'].set_doc("An identifying value \ |
|---|
| 109 | assigned by the sender to aid in assembling the fragments of a datagram. \ |
|---|
| 110 | See RFC 791 for more.") |
|---|
| 111 | self._fields['flags'].set_doc("Various Control Flags. See RFC 791 \ |
|---|
| 112 | for more.") |
|---|
| 113 | self._fields['_fragment_offset'].set_doc("This field indicates where \ |
|---|
| 114 | in the datagram this fragment belongs. See RFC 791 for more.") |
|---|
| 115 | self._fields['time_to_live'].set_doc("This field indicates the \ |
|---|
| 116 | maximum time the datagram is allowed to remain in the internet system. \ |
|---|
| 117 | See RFC 791 for more.") |
|---|
| 118 | self._fields['_protocol'].set_doc("This field indicates the next \ |
|---|
| 119 | level protocol used in the data portion of the internet datagram. See RFC 791 \ |
|---|
| 120 | for more.") |
|---|
| 121 | self._fields['_header_checksum'].set_doc("A checksum on the header \ |
|---|
| 122 | only. See RFC 791 for more.") |
|---|
| 123 | self._fields['source_address'].set_doc("The source address. \ |
|---|
| 124 | See RFC 791 for more.") |
|---|
| 125 | self._fields['destination_address'].set_doc("The destination address. \ |
|---|
| 126 | See RFC 791 for more.") |
|---|
| 127 | self._fields['options'].set_doc("The options may appear or not in \ |
|---|
| 128 | datagrams. See RFC 791 for more.") |
|---|
| 129 | self._fields['_padding'].set_doc("The internet header padding is used \ |
|---|
| 130 | to ensure that the internet header ends on a 32 bit boundary. See RFC 791 for \ |
|---|
| 131 | more.") |
|---|
| 132 | |
|---|
| 133 | def _is_valid(self, name): |
|---|
| 134 | """Check if attribute is allowed.""" |
|---|
| 135 | return self._fields.has_key(name) |
|---|
| 136 | |
|---|
| 137 | protocols = [ IP, ] |
|---|