source: trunk/packages/sipb-xen-python-pydhcplib/pydhcplib/dhcp_packet.py @ 361

Last change on this file since 361 was 361, checked in by broder, 16 years ago

Splitting pydhcplib off into its own package

Hold onto your hats, folks - this could get messy

File size: 7.8 KB
Line 
1# Anemon Dhcp
2# Copyright (C) 2005 Mathieu Ignacio -- mignacio@april.org
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
17
18import operator
19from struct import unpack
20from struct import pack
21from dhcp_basic_packet import *
22from dhcp_constants import *
23from type_ipv4 import ipv4
24from type_strlist import strlist
25class DhcpPacket(DhcpBasicPacket):
26
27
28    # Useful function for debugging
29    def PrintHeaders(self):
30        print "# Header fields\n"
31        print "readable_dhcp_headers = {"
32        for opt in  ['op','htype','hlen','hops','xid','secs','flags',
33                     'ciaddr','yiaddr','siaddr','giaddr','chaddr','sname','file'] :
34            begin = DhcpFields[opt][0]
35            end = DhcpFields[opt][0]+DhcpFields[opt][1]
36            data = self.packet_data[begin:end]
37            if DhcpFieldsTypes[opt] == "int" : result = str(data[0])
38            if DhcpFieldsTypes[opt] == "int2" : result = str(data[0]*256+data[0])
39            if DhcpFieldsTypes[opt] == "int4" : result = str(ipv4(data).int())
40            if DhcpFieldsTypes[opt] == "str" : result = strlist(data).str()
41            if DhcpFieldsTypes[opt] == "ipv4" : result = ipv4(data).str()
42            if DhcpFieldsTypes[opt] == "hwmac" : result = "".join(map(chr,data))
43
44            line = "\t'"+opt+"':"+str(data)+",\t# "+result
45            print line
46        print "\t'end':'true'}"
47
48    # Useful function for debugging
49    def PrintOptions(self):
50        print "# Options fields"
51        print "readable_dhcp_options = {"
52        for opt in self.options_data.keys():
53            data = self.options_data[opt]
54            result = ""
55            optnum  = DhcpOptions[opt]
56            if DhcpOptionsTypes[optnum] == "char" : result = str(data[0])
57            if DhcpOptionsTypes[optnum] == "16-bits" : result = str(data[0]*256+data[0])
58            if DhcpOptionsTypes[optnum] == "32bits" : result = str(ipv4(data).int())
59            if DhcpOptionsTypes[optnum] == "string" : result = strlist(data).str()
60            if DhcpOptionsTypes[optnum] == "ipv4" : result = ipv4(data).str()
61            if DhcpOptionsTypes[optnum] == "ipv4+" :
62                for i in range(0,len(data),4) :
63                    if len(data[i:i+4]) == 4 :
64                        result += ipv4(data[i:i+4]).str() + " - "
65            line = "\t'"+opt+"':"+str(data)+",\t# "+result
66            print line
67        print "\t'end':'true'}"
68       
69
70           
71    # FIXME: This is called from IsDhcpSomethingPacket, but is this really
72    # needed?  Or maybe this testing should be done in
73    # DhcpBasicPacket.DecodePacket().
74
75    # Test Packet Type
76    def IsDhcpSomethingPacket(self,type):
77        if self.IsDhcpPacket() == False : return False
78        if self.IsOption("dhcp_message_type") == False : return False
79        if self.GetOption("dhcp_message_type") != type : return False
80        return True
81   
82    def IsDhcpDiscoverPacket(self):
83        return self.IsDhcpSomethingPacket([1])
84
85    def IsDhcpOfferPacket(self):
86        return self.IsDhcpSomethingPacket([2])
87
88    def IsDhcpRequestPacket(self):
89        return self.IsDhcpSomethingPacket([3])
90
91    def IsDhcpDeclinePacket(self):
92        return self.IsDhcpSomethingPacket([4])
93
94    def IsDhcpAckPacket(self):
95        return self.IsDhcpSomethingPacket([5])
96
97    def IsDhcpNackPacket(self):
98        return self.IsDhcpSomethingPacket([6])
99
100    def IsDhcpReleasePacket(self):
101        return self.IsDhcpSomethingPacket([7])
102
103    def IsDhcpInformPacket(self):
104        return self.IsDhcpSomethingPacket([8])
105
106
107    def GetMultipleOptions(self,options=()):
108        result = {}
109        for each in options:
110            result[each] = self.GetOption(each)
111        return result
112
113    def SetMultipleOptions(self,options={}):
114        for each in options.keys():
115            self.SetOption(each,options[each])
116
117
118
119
120
121
122    # Creating Response Packet
123
124    # Server-side functions
125    # From RFC 2132 page 28/29
126    def CreateDhcpOfferPacketFrom(self,src): # src = discover packet
127        self.SetOption("htype",src.GetOption("htype"))
128        self.SetOption("xid",src.GetOption("xid"))
129        self.SetOption("flags",src.GetOption("flags"))
130        self.SetOption("giaddr",src.GetOption("giaddr"))
131        self.SetOption("chaddr",src.GetOption("chaddr"))
132        self.SetOption("ip_address_lease_time",src.GetOption("ip_address_lease_time"))
133        self.TransformToDhcpOfferPacket()
134
135    def TransformToDhcpOfferPacket(self):
136        self.SetOption("dhcp_message_type",[2])
137        self.SetOption("op",[2])
138        self.SetOption("hlen",[6]) 
139
140        self.DeleteOption("secs")
141        self.DeleteOption("ciaddr")
142        self.DeleteOption("request_ip_address")
143        self.DeleteOption("parameter_request_list")
144        self.DeleteOption("client_identifier")
145        self.DeleteOption("maximum_message_size")
146
147
148
149
150
151    """ Dhcp ACK packet creation """
152    def CreateDhcpAckPacketFrom(self,src): # src = request or inform packet
153        self.SetOption("htype",src.GetOption("htype"))
154        self.SetOption("xid",src.GetOption("xid"))
155        self.SetOption("ciaddr",src.GetOption("ciaddr"))
156        self.SetOption("flags",src.GetOption("flags"))
157        self.SetOption("giaddr",src.GetOption("giaddr"))
158        self.SetOption("chaddr",src.GetOption("chaddr"))
159        self.SetOption("ip_address_lease_time_option",src.GetOption("ip_address_lease_time_option"))
160        self.TransformToDhcpAckPacket()
161
162    def TransformToDhcpAckPacket(self): # src = request or inform packet
163        self.SetOption("op",[2])
164        self.SetOption("hlen",[6]) 
165        self.SetOption("dhcp_message_type",[5])
166
167        self.DeleteOption("secs")
168        self.DeleteOption("request_ip_address")
169        self.DeleteOption("parameter_request_list")
170        self.DeleteOption("client_identifier")
171        self.DeleteOption("maximum_message_size")
172
173
174    """ Dhcp NACK packet creation """
175    def CreateDhcpNackPacketFrom(self,src): # src = request or inform packet
176       
177        self.SetOption("htype",src.GetOption("htype"))
178        self.SetOption("xid",src.GetOption("xid"))
179        self.SetOption("flags",src.GetOption("flags"))
180        self.SetOption("giaddr",src.GetOption("giaddr"))
181        self.SetOption("chaddr",src.GetOption("chaddr"))
182        self.TransformToDhcpNackPacket()
183
184    def TransformToDhcpNackPacket(self):
185        self.SetOption("op",[2])
186        self.SetOption("hlen",[6]) 
187        self.DeleteOption("secs")
188        self.DeleteOption("ciaddr")
189        self.DeleteOption("yiaddr")
190        self.DeleteOption("siaddr")
191        self.DeleteOption("sname")
192        self.DeleteOption("file")
193        self.DeleteOption("request_ip_address")
194        self.DeleteOption("ip_address_lease_time_option")
195        self.DeleteOption("parameter_request_list")
196        self.DeleteOption("client_identifier")
197        self.DeleteOption("maximum_message_size")
198        self.SetOption("dhcp_message_type",[6])
199
200
201
202
203
204
205
206    """ GetClientIdentifier """
207
208    def GetClientIdentifier(self) :
209        if self.IsOption("client_identifier") :
210            return self.GetOption("client_identifier")
211        return []
212
213    def GetGiaddr(self) :
214        return self.GetOption("giaddr")
215
216    def GetHardwareAddress(self) :
217        length = self.GetOption("hlen")[0]
218        full_hw = self.GetOption("chaddr")
219        if length!=[] and length<len(full_hw) : return full_hw[0:length]
220        return full_hw
221
Note: See TracBrowser for help on using the repository browser.