/src/PcapPlusPlus/Packet++/header/DhcpLayer.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef PACKETPP_DHCP_LAYER |
2 | | #define PACKETPP_DHCP_LAYER |
3 | | |
4 | | #include "Layer.h" |
5 | | #include "TLVData.h" |
6 | | #include "IpAddress.h" |
7 | | #include "MacAddress.h" |
8 | | #include <string.h> |
9 | | |
10 | | #ifndef PCPP_DEPRECATED |
11 | | #if defined(__GNUC__) || defined(__clang__) |
12 | | #define PCPP_DEPRECATED __attribute__((deprecated)) |
13 | | #elif defined(_MSC_VER) |
14 | | #define PCPP_DEPRECATED __declspec(deprecated) |
15 | | #else |
16 | | #pragma message("WARNING: DEPRECATED feature is not implemented for this compiler") |
17 | | #define PCPP_DEPRECATED |
18 | | #endif |
19 | | #endif |
20 | | |
21 | | /// @file |
22 | | |
23 | | /** |
24 | | * \namespace pcpp |
25 | | * \brief The main namespace for the PcapPlusPlus lib |
26 | | */ |
27 | | namespace pcpp |
28 | | { |
29 | | |
30 | | /** |
31 | | * @struct dhcp_header |
32 | | * Represents a DHCP protocol header |
33 | | */ |
34 | | #pragma pack(push, 1) |
35 | | struct dhcp_header |
36 | | { |
37 | | /** BootP opcode */ |
38 | | uint8_t opCode; |
39 | | /** Hardware type, set to 1 (Ethernet) by default */ |
40 | | uint8_t hardwareType; |
41 | | /** Hardware address length, set to 6 (MAC address length) by default */ |
42 | | uint8_t hardwareAddressLength; |
43 | | /** Hop count */ |
44 | | uint8_t hops; |
45 | | /** DHCP/BootP transaction ID */ |
46 | | uint32_t transactionID; |
47 | | /** The elapsed time, in seconds since the client sent its first BOOTREQUEST message */ |
48 | | uint16_t secondsElapsed; |
49 | | /** BootP flags */ |
50 | | uint16_t flags; |
51 | | /** Client IPv4 address */ |
52 | | uint32_t clientIpAddress; |
53 | | /** Your IPv4 address */ |
54 | | uint32_t yourIpAddress; |
55 | | /** Server IPv4 address */ |
56 | | uint32_t serverIpAddress; |
57 | | /** Gateway IPv4 address */ |
58 | | uint32_t gatewayIpAddress; |
59 | | /** Client hardware address, by default contains the MAC address (only 6 first bytes are used) */ |
60 | | uint8_t clientHardwareAddress[16]; |
61 | | /** BootP server name */ |
62 | | uint8_t serverName[64]; |
63 | | /** BootP boot file name */ |
64 | | uint8_t bootFilename[128]; |
65 | | /** DHCP magic number (set to the default value of 0x63538263) */ |
66 | | uint32_t magicNumber; |
67 | | }; |
68 | | #pragma pack(pop) |
69 | | |
70 | | |
71 | | /** |
72 | | * BootP opcodes |
73 | | */ |
74 | | enum BootpOpCodes |
75 | | { |
76 | | /** BootP request */ |
77 | | DHCP_BOOTREQUEST = 1, |
78 | | /** BootP reply */ |
79 | | DHCP_BOOTREPLY = 2 |
80 | | }; |
81 | | |
82 | | /** |
83 | | * DHCP message types |
84 | | */ |
85 | | enum DhcpMessageType |
86 | | { |
87 | | /** Unknown message type */ |
88 | | DHCP_UNKNOWN_MSG_TYPE = 0, |
89 | | /** Discover message type */ |
90 | | DHCP_DISCOVER = 1, |
91 | | /** Offer message type */ |
92 | | DHCP_OFFER = 2, |
93 | | /** Request message type */ |
94 | | DHCP_REQUEST = 3, |
95 | | /** Decline message type */ |
96 | | DHCP_DECLINE = 4, |
97 | | /** Acknowledge message type */ |
98 | | DHCP_ACK = 5, |
99 | | /** Non-acknowledge message type */ |
100 | | DHCP_NAK = 6, |
101 | | /** Release message type */ |
102 | | DHCP_RELEASE = 7, |
103 | | /** Inform message type */ |
104 | | DHCP_INFORM = 8 |
105 | | }; |
106 | | |
107 | | /** |
108 | | * DHCP option types. |
109 | | */ |
110 | | enum DhcpOptionTypes |
111 | | { |
112 | | /** Unknown option type */ |
113 | | DHCPOPT_UNKNOWN = -1, |
114 | | /** Pad */ |
115 | | DHCPOPT_PAD = 0, |
116 | | /** Subnet Mask Value */ |
117 | | DHCPOPT_SUBNET_MASK = 1, |
118 | | /** Time Offset in Seconds from UTC */ |
119 | | DHCPOPT_TIME_OFFSET = 2, |
120 | | /** N/4 Router addresses */ |
121 | | DHCPOPT_ROUTERS = 3, |
122 | | /** N/4 Timeserver addresses */ |
123 | | DHCPOPT_TIME_SERVERS = 4, |
124 | | /** N/4 IEN-116 Server addresses */ |
125 | | DHCPOPT_NAME_SERVERS = 5, |
126 | | /** N/4 DNS Server addresses */ |
127 | | DHCPOPT_DOMAIN_NAME_SERVERS = 6, |
128 | | /** N/4 Logging Server addresses */ |
129 | | DHCPOPT_LOG_SERVERS = 7, |
130 | | /** N/4 Quotes Server addresses */ |
131 | | DHCPOPT_QUOTES_SERVERS = 8, |
132 | | /** N/4 Quotes Server addresses */ |
133 | | DHCPOPT_LPR_SERVERS = 9, |
134 | | /** N/4 Quotes Server addresses */ |
135 | | DHCPOPT_IMPRESS_SERVERS = 10, |
136 | | /** N/4 RLP Server addresses */ |
137 | | DHCPOPT_RESOURCE_LOCATION_SERVERS = 11, |
138 | | /** Hostname string */ |
139 | | DHCPOPT_HOST_NAME = 12, |
140 | | /** Size of boot file in 512 byte chunks */ |
141 | | DHCPOPT_BOOT_SIZE = 13, |
142 | | /** Client to dump and name the file to dump it to */ |
143 | | DHCPOPT_MERIT_DUMP = 14, |
144 | | /** The DNS domain name of the client */ |
145 | | DHCPOPT_DOMAIN_NAME = 15, |
146 | | /** Swap Server address */ |
147 | | DHCPOPT_SWAP_SERVER = 16, |
148 | | /** Path name for root disk */ |
149 | | DHCPOPT_ROOT_PATH = 17, |
150 | | /** Path name for more BOOTP info */ |
151 | | DHCPOPT_EXTENSIONS_PATH = 18, |
152 | | /** Enable/Disable IP Forwarding */ |
153 | | DHCPOPT_IP_FORWARDING = 19, |
154 | | /** Enable/Disable Source Routing */ |
155 | | DHCPOPT_NON_LOCAL_SOURCE_ROUTING = 20, |
156 | | /** Routing Policy Filters */ |
157 | | DHCPOPT_POLICY_FILTER = 21, |
158 | | /** Max Datagram Reassembly Size */ |
159 | | DHCPOPT_MAX_DGRAM_REASSEMBLY = 22, |
160 | | /** Default IP Time to Live */ |
161 | | DEFAULT_IP_TTL = 23, |
162 | | /** Path MTU Aging Timeout */ |
163 | | DHCPOPT_PATH_MTU_AGING_TIMEOUT = 24, |
164 | | /** Path MTU Plateau Table */ |
165 | | PATH_MTU_PLATEAU_TABLE = 25, |
166 | | /** Interface MTU Size */ |
167 | | DHCPOPT_INTERFACE_MTU = 26, |
168 | | /** All Subnets are Local */ |
169 | | DHCPOPT_ALL_SUBNETS_LOCAL = 27, |
170 | | /** Broadcast Address */ |
171 | | DHCPOPT_BROADCAST_ADDRESS = 28, |
172 | | /** Perform Mask Discovery */ |
173 | | DHCPOPT_PERFORM_MASK_DISCOVERY = 29, |
174 | | /** Provide Mask to Others */ |
175 | | DHCPOPT_MASK_SUPPLIER = 30, |
176 | | /** Perform Router Discovery */ |
177 | | DHCPOPT_ROUTER_DISCOVERY = 31, |
178 | | /** Router Solicitation Address */ |
179 | | DHCPOPT_ROUTER_SOLICITATION_ADDRESS = 32, |
180 | | /** Static Routing Table */ |
181 | | DHCPOPT_STATIC_ROUTES = 33, |
182 | | /** Trailer Encapsulation */ |
183 | | DHCPOPT_TRAILER_ENCAPSULATION = 34, |
184 | | /** ARP Cache Timeout */ |
185 | | DHCPOPT_ARP_CACHE_TIMEOUT = 35, |
186 | | /** IEEE802.3 Encapsulation */ |
187 | | DHCPOPT_IEEE802_3_ENCAPSULATION = 36, |
188 | | /** Default TCP Time to Live */ |
189 | | DHCPOPT_DEFAULT_TCP_TTL = 37, |
190 | | /** TCP Keepalive Interval */ |
191 | | DHCPOPT_TCP_KEEPALIVE_INTERVAL = 38, |
192 | | /** TCP Keepalive Garbage */ |
193 | | DHCPOPT_TCP_KEEPALIVE_GARBAGE = 39, |
194 | | /** NIS Domain Name */ |
195 | | DHCPOPT_NIS_DOMAIN = 40, |
196 | | /** NIS Server Addresses */ |
197 | | DHCPOPT_NIS_SERVERS = 41, |
198 | | /** NTP Server Addresses */ |
199 | | DHCPOPT_NTP_SERVERS = 42, |
200 | | /** Vendor Specific Information */ |
201 | | DHCPOPT_VENDOR_ENCAPSULATED_OPTIONS = 43, |
202 | | /** NETBIOS Name Servers */ |
203 | | DHCPOPT_NETBIOS_NAME_SERVERS = 44, |
204 | | /** NETBIOS Datagram Distribution */ |
205 | | DHCPOPT_NETBIOS_DD_SERVER = 45, |
206 | | /** NETBIOS Node Type */ |
207 | | DHCPOPT_NETBIOS_NODE_TYPE = 46, |
208 | | /** NETBIOS Scope */ |
209 | | DHCPOPT_NETBIOS_SCOPE = 47, |
210 | | /** X Window Font Server */ |
211 | | DHCPOPT_FONT_SERVERS = 48, |
212 | | /** X Window Display Manager */ |
213 | | DHCPOPT_X_DISPLAY_MANAGER = 49, |
214 | | /** Requested IP Address */ |
215 | | DHCPOPT_DHCP_REQUESTED_ADDRESS = 50, |
216 | | /** IP Address Lease Time */ |
217 | | DHCPOPT_DHCP_LEASE_TIME = 51, |
218 | | /** Overload "sname" or "file" */ |
219 | | DHCPOPT_DHCP_OPTION_OVERLOAD = 52, |
220 | | /** DHCP Message Type */ |
221 | | DHCPOPT_DHCP_MESSAGE_TYPE = 53, |
222 | | /** DHCP Server Identification */ |
223 | | DHCPOPT_DHCP_SERVER_IDENTIFIER = 54, |
224 | | /** Parameter Request List */ |
225 | | DHCPOPT_DHCP_PARAMETER_REQUEST_LIST = 55, |
226 | | /** DHCP Error Message */ |
227 | | DHCPOPT_DHCP_MESSAGE = 56, |
228 | | /** DHCP Maximum Message Size */ |
229 | | DHCPOPT_DHCP_MAX_MESSAGE_SIZE = 57, |
230 | | /** DHCP Renewal (T1) Time */ |
231 | | DHCPOPT_DHCP_RENEWAL_TIME = 58, |
232 | | /** DHCP Rebinding (T2) Time */ |
233 | | DHCPOPT_DHCP_REBINDING_TIME = 59, |
234 | | /** Class Identifier */ |
235 | | DHCPOPT_VENDOR_CLASS_IDENTIFIER = 60, |
236 | | /** Class Identifier */ |
237 | | DHCPOPT_DHCP_CLIENT_IDENTIFIER = 61, |
238 | | /** NetWare/IP Domain Name */ |
239 | | DHCPOPT_NWIP_DOMAIN_NAME = 62, |
240 | | /** NetWare/IP sub Options */ |
241 | | DHCPOPT_NWIP_SUBOPTIONS = 63, |
242 | | /** NIS+ v3 Client Domain Name */ |
243 | | DHCPOPT_NIS_DOMAIN_NAME = 64, |
244 | | /** NIS+ v3 Server Addresses */ |
245 | | DHCPOPT_NIS_SERVER_ADDRESS = 65, |
246 | | /** TFTP Server Name */ |
247 | | DHCPOPT_TFTP_SERVER_NAME = 66, |
248 | | /** Boot File Name */ |
249 | | DHCPOPT_BOOTFILE_NAME = 67, |
250 | | /** Home Agent Addresses */ |
251 | | DHCPOPT_HOME_AGENT_ADDRESS = 68, |
252 | | /** Simple Mail Server (SMTP) Addresses */ |
253 | | DHCPOPT_SMTP_SERVER = 69, |
254 | | /** Post Office (POP3) Server Addresses */ |
255 | | DHCPOPT_POP3_SERVER = 70, |
256 | | /** Network News (NNTP) Server Addresses */ |
257 | | DHCPOPT_NNTP_SERVER = 71, |
258 | | /** WWW Server Addresses */ |
259 | | DHCPOPT_WWW_SERVER = 72, |
260 | | /** Finger Server Addresses */ |
261 | | DHCPOPT_FINGER_SERVER = 73, |
262 | | /** Chat (IRC) Server Addresses */ |
263 | | DHCPOPT_IRC_SERVER = 74, |
264 | | /** StreetTalk Server Addresses */ |
265 | | DHCPOPT_STREETTALK_SERVER = 75, |
266 | | /** ST Directory Assist. Addresses */ |
267 | | DHCPOPT_STDA_SERVER = 76, |
268 | | /** User Class Information */ |
269 | | DHCPOPT_USER_CLASS = 77, |
270 | | /** Directory Agent Information */ |
271 | | DHCPOPT_DIRECTORY_AGENT = 78, |
272 | | /** Service Location Agent Scope */ |
273 | | DHCPOPT_SERVICE_SCOPE = 79, |
274 | | /** Rapid Commit */ |
275 | | DHCPOPT_RAPID_COMMIT = 80, |
276 | | /** Fully Qualified Domain Name */ |
277 | | DHCPOPT_FQDN = 81, |
278 | | /** Relay Agent Information */ |
279 | | DHCPOPT_DHCP_AGENT_OPTIONS = 82, |
280 | | /** Internet Storage Name Service */ |
281 | | DHCPOPT_ISNS = 83, |
282 | | /** Novell Directory Services */ |
283 | | DHCPOPT_NDS_SERVERS = 85, |
284 | | /** Novell Directory Services */ |
285 | | DHCPOPT_NDS_TREE_NAME = 86, |
286 | | /** Novell Directory Services */ |
287 | | DHCPOPT_NDS_CONTEXT = 87, |
288 | | /** BCMCS Controller Domain Name list */ |
289 | | DHCPOPT_BCMCS_CONTROLLER_DOMAIN_NAME_LIST = 88, |
290 | | /** BCMCS Controller IPv4 address option */ |
291 | | DHCPOPT_BCMCS_CONTROLLER_IPV4_ADDRESS = 89, |
292 | | /** Authentication */ |
293 | | DHCPOPT_AUTHENTICATION = 90, |
294 | | /** Client Last Transaction Time */ |
295 | | DHCPOPT_CLIENT_LAST_TXN_TIME = 91, |
296 | | /** Associated IP */ |
297 | | DHCPOPT_ASSOCIATED_IP = 92, |
298 | | /** Client System Architecture */ |
299 | | DHCPOPT_CLIENT_SYSTEM = 93, |
300 | | /** Client Network Device Interface */ |
301 | | DHCPOPT_CLIENT_NDI = 94, |
302 | | /** Lightweight Directory Access Protocol [ */ |
303 | | DHCPOPT_LDAP = 95, |
304 | | /** UUID/GUID-based Client Identifier */ |
305 | | DHCPOPT_UUID_GUID = 97, |
306 | | /** Open Group's User Authentication */ |
307 | | DHCPOPT_USER_AUTH = 98, |
308 | | /** GEOCONF_CIVIC */ |
309 | | DHCPOPT_GEOCONF_CIVIC = 99, |
310 | | /** IEEE 1003.1 TZ String */ |
311 | | DHCPOPT_PCODE = 100, |
312 | | /** Reference to the TZ Database */ |
313 | | DHCPOPT_TCODE = 101, |
314 | | /** NetInfo Parent Server Address */ |
315 | | DHCPOPT_NETINFO_ADDRESS = 112, |
316 | | /** NetInfo Parent Server Tag */ |
317 | | DHCPOPT_NETINFO_TAG = 113, |
318 | | /** URL */ |
319 | | DHCPOPT_URL = 114, |
320 | | /** DHCP Auto-Configuration */ |
321 | | DHCPOPT_AUTO_CONFIG = 116, |
322 | | /** Name Service Search */ |
323 | | DHCPOPT_NAME_SERVICE_SEARCH = 117, |
324 | | /** Subnet Selection Option */ |
325 | | DHCPOPT_SUBNET_SELECTION = 118, |
326 | | /** DNS Domain Search List */ |
327 | | DHCPOPT_DOMAIN_SEARCH = 119, |
328 | | /** SIP Servers DHCP Option */ |
329 | | DHCPOPT_SIP_SERVERS = 120, |
330 | | /** Classless Static Route Option */ |
331 | | DHCPOPT_CLASSLESS_STATIC_ROUTE = 121, |
332 | | /** CableLabs Client Configuration */ |
333 | | DHCPOPT_CCC = 122, |
334 | | /** GeoConf Option */ |
335 | | DHCPOPT_GEOCONF = 123, |
336 | | /** Vendor-Identifying Vendor Class */ |
337 | | DHCPOPT_V_I_VENDOR_CLASS = 124, |
338 | | /** Vendor-Identifying Vendor-Specific Information */ |
339 | | DHCPOPT_V_I_VENDOR_OPTS = 125, |
340 | | /** OPTION_PANA_AGENT */ |
341 | | DHCPOPT_OPTION_PANA_AGENT = 136, |
342 | | /** OPTION_V4_LOST */ |
343 | | DHCPOPT_OPTION_V4_LOST = 137, |
344 | | /** CAPWAP Access Controller addresses */ |
345 | | DHCPOPT_OPTION_CAPWAP_AC_V4 = 138, |
346 | | /** A Series Of Suboptions */ |
347 | | DHCPOPT_OPTION_IPV4_ADDRESS_MOS = 139, |
348 | | /** A Series Of Suboptions */ |
349 | | DHCPOPT_OPTION_IPV4_FQDN_MOS = 140, |
350 | | /** List of domain names to search for SIP User Agent Configuration */ |
351 | | DHCPOPT_SIP_UA_CONFIG = 141, |
352 | | /** ANDSF IPv4 Address Option for DHCPv4 */ |
353 | | DHCPOPT_OPTION_IPV4_ADDRESS_ANDSF = 142, |
354 | | /** Geospatial Location with Uncertainty [RF */ |
355 | | DHCPOPT_GEOLOC = 144, |
356 | | /** Forcerenew Nonce Capable */ |
357 | | DHCPOPT_FORCERENEW_NONCE_CAPABLE = 145, |
358 | | /** Information for selecting RDNSS */ |
359 | | DHCPOPT_RDNSS_SELECTION = 146, |
360 | | /** Status code and optional N byte text message describing status */ |
361 | | DHCPOPT_STATUS_CODE = 151, |
362 | | /** Absolute time (seconds since Jan 1, 1970) message was sent */ |
363 | | DHCPOPT_BASE_TIME = 152, |
364 | | /** Number of seconds in the past when client entered current state */ |
365 | | DHCPOPT_START_TIME_OF_STATE = 153, |
366 | | /** Absolute time (seconds since Jan 1, 1970) for beginning of query */ |
367 | | DHCPOPT_QUERY_START_TIME = 154, |
368 | | /** Absolute time (seconds since Jan 1, 1970) for end of query */ |
369 | | DHCPOPT_QUERY_END_TIME = 155, |
370 | | /** State of IP address */ |
371 | | DHCPOPT_DHCP_STATE = 156, |
372 | | /** Indicates information came from local or remote server */ |
373 | | DHCPOPT_DATA_SOURCE = 157, |
374 | | /** Includes one or multiple lists of PCP server IP addresses; each list is treated as a separate PCP server */ |
375 | | DHCPOPT_OPTION_V4_PCP_SERVER = 158, |
376 | | /** This option is used to configure a set of ports bound to a shared IPv4 address */ |
377 | | DHCPOPT_OPTION_V4_PORTPARAMS = 159, |
378 | | /** DHCP Captive-Portal */ |
379 | | DHCPOPT_CAPTIVE_PORTAL = 160, |
380 | | /** Manufacturer Usage Descriptions */ |
381 | | DHCPOPT_OPTION_MUD_URL_V4 = 161, |
382 | | /** Etherboot */ |
383 | | DHCPOPT_ETHERBOOT = 175, |
384 | | /** IP Telephone */ |
385 | | DHCPOPT_IP_TELEPHONE = 176, |
386 | | /** Magic string = F1:00:74:7E */ |
387 | | DHCPOPT_PXELINUX_MAGIC = 208, |
388 | | /** Configuration file */ |
389 | | DHCPOPT_CONFIGURATION_FILE = 209, |
390 | | /** Path Prefix Option */ |
391 | | DHCPOPT_PATH_PREFIX = 210, |
392 | | /** Reboot Time */ |
393 | | DHCPOPT_REBOOT_TIME = 211, |
394 | | /** OPTION_6RD with N/4 6rd BR addresses */ |
395 | | DHCPOPT_OPTION_6RD = 212, |
396 | | /** Access Network Domain Name */ |
397 | | DHCPOPT_OPTION_V4_ACCESS_DOMAIN = 213, |
398 | | /** Subnet Allocation Option */ |
399 | | DHCPOPT_SUBNET_ALLOCATION = 220, |
400 | | /** Virtual Subnet Selection (VSS) Option */ |
401 | | DHCPOPT_VIRTUAL_SUBNET_SELECTION = 221, |
402 | | /** End (last option) */ |
403 | | DHCPOPT_END = 255 |
404 | | }; |
405 | | |
406 | | |
407 | | /** |
408 | | * @class DhcpOption |
409 | | * A wrapper class for DHCP options. This class does not create or modify DHCP option records, but rather |
410 | | * serves as a wrapper and provides useful methods for setting and retrieving data to/from them |
411 | | */ |
412 | | class DhcpOption : public TLVRecord<uint8_t, uint8_t> |
413 | | { |
414 | | public: |
415 | | |
416 | | /** |
417 | | * A c'tor for this class that gets a pointer to the option raw data (byte array) |
418 | | * @param[in] optionRawData A pointer to the option raw data |
419 | | */ |
420 | 0 | explicit DhcpOption(uint8_t* optionRawData) : TLVRecord(optionRawData) { } |
421 | | |
422 | | /** |
423 | | * A d'tor for this class, currently does nothing |
424 | | */ |
425 | 0 | virtual ~DhcpOption() { } |
426 | | |
427 | | /** |
428 | | * Retrieve DHCP option data as IPv4 address. Relevant only if option value is indeed an IPv4 address |
429 | | * @return DHCP option data as IPv4 address |
430 | | */ |
431 | | IPv4Address getValueAsIpAddr() const |
432 | 0 | { |
433 | 0 | return getValueAs<uint32_t>(); |
434 | 0 | } |
435 | | |
436 | | /** |
437 | | * Set DHCP option data as IPv4 address. This method copies the 4 bytes of the IP address to the option value |
438 | | * @param[in] addr The IPv4 address to set |
439 | | * @param[in] valueOffset An optional parameter that specifies where to start set the option data (default set to 0). For example: |
440 | | * if option data is 20 bytes long and you want to set the IP address in the 4 last bytes then use this method like this: |
441 | | * setValueIpAddr(your_addr, 16) |
442 | | */ |
443 | | void setValueIpAddr(const IPv4Address& addr, int valueOffset = 0) |
444 | 0 | { |
445 | 0 | setValue<uint32_t>(addr.toInt(), valueOffset); |
446 | 0 | } |
447 | | |
448 | | /** |
449 | | * Retrieve DHCP option data as string. Relevant only if option value is indeed a string |
450 | | * @param[in] valueOffset An optional parameter that specifies where to start copy the DHCP option data. For example: |
451 | | * when retrieving Client FQDN option, you may ignore the flags and RCODE fields using this method like this: |
452 | | * getValueAsString(3). The default is 0 - start copying from the beginning of option data |
453 | | * @return DHCP option data as string |
454 | | */ |
455 | | std::string getValueAsString(int valueOffset = 0) const |
456 | 0 | { |
457 | 0 | if (m_Data->recordLen - valueOffset < 1) |
458 | 0 | return ""; |
459 | 0 |
|
460 | 0 | return std::string((const char*)m_Data->recordValue + valueOffset, (int)m_Data->recordLen - valueOffset); |
461 | 0 | } |
462 | | |
463 | | /** |
464 | | * Set DHCP option data as string. This method copies the string to the option value. If the string is longer than option length |
465 | | * the string is trimmed so it will fit the option length |
466 | | * @param[in] stringValue The string to set |
467 | | * @param[in] valueOffset An optional parameter that specifies where to start set the option data (default set to 0). For example: |
468 | | * if option data is 20 bytes long and you want to set a 6 char-long string in the 6 last bytes then use this method like this: |
469 | | * setValueString("string", 14) |
470 | | */ |
471 | | void setValueString(const std::string& stringValue, int valueOffset = 0) |
472 | 0 | { |
473 | 0 | // calculate the maximum length of the destination buffer |
474 | 0 | size_t len = (size_t)m_Data->recordLen - (size_t)valueOffset; |
475 | 0 |
|
476 | 0 | // use the length of input string if a buffer is large enough for whole string |
477 | 0 | if (stringValue.length() < len) |
478 | 0 | len = stringValue.length(); |
479 | 0 |
|
480 | 0 | memcpy(m_Data->recordValue + valueOffset, stringValue.data(), len); |
481 | 0 | } |
482 | | |
483 | | |
484 | | // implement abstract methods |
485 | | |
486 | | size_t getTotalSize() const |
487 | 0 | { |
488 | 0 | if (m_Data->recordType == (uint8_t)DHCPOPT_END || m_Data->recordType == (uint8_t)DHCPOPT_PAD) |
489 | 0 | return sizeof(uint8_t); |
490 | | |
491 | 0 | return sizeof(uint8_t) * 2 + (size_t)m_Data->recordLen; |
492 | 0 | } |
493 | | |
494 | | size_t getDataSize() const |
495 | 0 | { |
496 | 0 | if (m_Data->recordType == (uint8_t)DHCPOPT_END || m_Data->recordType == (uint8_t)DHCPOPT_PAD) |
497 | 0 | return 0; |
498 | | |
499 | 0 | return m_Data->recordLen; |
500 | 0 | } |
501 | | }; |
502 | | |
503 | | |
504 | | /** |
505 | | * @class DhcpOptionBuilder |
506 | | * A class for building DHCP options. This builder receives the option parameters in its c'tor, |
507 | | * builds the DHCP option raw buffer and provides a build() method to get a DhcpOption object out of it |
508 | | */ |
509 | | class DhcpOptionBuilder : public TLVRecordBuilder |
510 | | { |
511 | | public: |
512 | | |
513 | | /** |
514 | | * A c'tor for building DHCP options which their value is a byte array. The DhcpOption object can later |
515 | | * be retrieved by calling build() |
516 | | * @param[in] optionType DHCP option type |
517 | | * @param[in] optionValue A buffer containing the option value. This buffer is read-only and isn't modified in any way |
518 | | * @param[in] optionValueLen DHCP option value length in bytes |
519 | | */ |
520 | | DhcpOptionBuilder(DhcpOptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen) : |
521 | 0 | TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen) { } |
522 | | |
523 | | /** |
524 | | * A c'tor for building DHCP options which have a 1-byte value. The DhcpOption object can later be retrieved |
525 | | * by calling build() |
526 | | * @param[in] optionType DHCP option type |
527 | | * @param[in] optionValue A 1-byte option value |
528 | | */ |
529 | | DhcpOptionBuilder(DhcpOptionTypes optionType, uint8_t optionValue) : |
530 | 0 | TLVRecordBuilder((uint8_t)optionType, optionValue) { } |
531 | | |
532 | | /** |
533 | | * A c'tor for building DHCP options which have a 2-byte value. The DhcpOption object can later be retrieved |
534 | | * by calling build() |
535 | | * @param[in] optionType DHCP option type |
536 | | * @param[in] optionValue A 2-byte option value |
537 | | */ |
538 | | DhcpOptionBuilder(DhcpOptionTypes optionType, uint16_t optionValue) : |
539 | 0 | TLVRecordBuilder((uint8_t)optionType, optionValue) { } |
540 | | |
541 | | /** |
542 | | * A c'tor for building DHCP options which have a 4-byte value. The DhcpOption object can later be retrieved |
543 | | * by calling build() |
544 | | * @param[in] optionType DHCP option type |
545 | | * @param[in] optionValue A 4-byte option value |
546 | | */ |
547 | | DhcpOptionBuilder(DhcpOptionTypes optionType, uint32_t optionValue) : |
548 | 0 | TLVRecordBuilder((uint8_t)optionType, optionValue) { } |
549 | | |
550 | | /** |
551 | | * A c'tor for building DHCP options which have an IPv4Address value. The DhcpOption object can later be |
552 | | * retrieved by calling build() |
553 | | * @param[in] optionType DHCP option type |
554 | | * @param[in] optionValue The IPv4 address option value |
555 | | */ |
556 | | DhcpOptionBuilder(DhcpOptionTypes optionType, const IPv4Address& optionValue) : |
557 | 0 | TLVRecordBuilder((uint8_t)optionType, optionValue) { } |
558 | | |
559 | | /** |
560 | | * A c'tor for building DHCP options which have a string value. The DhcpOption object can later be retrieved |
561 | | * by calling build() |
562 | | * @param[in] optionType DHCP option type |
563 | | * @param[in] optionValue The string option value |
564 | | */ |
565 | | DhcpOptionBuilder(DhcpOptionTypes optionType, const std::string& optionValue) : |
566 | 0 | TLVRecordBuilder((uint8_t)optionType, optionValue) { } |
567 | | |
568 | | /** |
569 | | * A copy c'tor which copies all the data from another instance of DhcpOptionBuilder |
570 | | * @param[in] other The instance to copy from |
571 | | */ |
572 | | DhcpOptionBuilder(const DhcpOptionBuilder& other) : |
573 | 0 | TLVRecordBuilder(other) { } |
574 | | |
575 | | /** |
576 | | * Assignment operator that copies all data from another instance of DhcpOptionBuilder |
577 | | * @param[in] other The instance to assign from |
578 | | * @return A reference to the assignee |
579 | | */ |
580 | | DhcpOptionBuilder& operator=(const DhcpOptionBuilder& other) |
581 | 0 | { |
582 | 0 | TLVRecordBuilder::operator=(other); |
583 | 0 | return *this; |
584 | 0 | } |
585 | | |
586 | | /** |
587 | | * Build the DhcpOption object out of the parameters defined in the c'tor |
588 | | * @return The DhcpOption object |
589 | | */ |
590 | | DhcpOption build() const; |
591 | | }; |
592 | | |
593 | | |
594 | | |
595 | | /** |
596 | | * @class DhcpLayer |
597 | | * Represents a DHCP (Dynamic Host Configuration Protocol) protocol layer |
598 | | */ |
599 | | class DhcpLayer : public Layer |
600 | | { |
601 | | public: |
602 | | |
603 | | /** |
604 | | * A constructor that creates the layer from an existing packet raw data |
605 | | * @param[in] data A pointer to the raw data |
606 | | * @param[in] dataLen Size of the data in bytes |
607 | | * @param[in] prevLayer A pointer to the previous layer |
608 | | * @param[in] packet A pointer to the Packet instance where layer will be stored in |
609 | | */ |
610 | | DhcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); |
611 | | |
612 | | /** |
613 | | * A constructor that creates the layer from scratch. Adds a ::DHCPOPT_DHCP_MESSAGE_TYPE and a ::DHCPOPT_END |
614 | | * options |
615 | | * @param[in] msgType A DHCP message type to be set |
616 | | * @param[in] clientMacAddr A client MAC address to set in dhcp_header#clientHardwareAddress field |
617 | | */ |
618 | | DhcpLayer(DhcpMessageType msgType, const MacAddress& clientMacAddr); |
619 | | |
620 | | /** |
621 | | * A constructor that creates the layer from scratch with clean data |
622 | | */ |
623 | | DhcpLayer(); |
624 | | |
625 | | /** |
626 | | * A destructor for this layer |
627 | | */ |
628 | 448 | virtual ~DhcpLayer() {} |
629 | | |
630 | | /** |
631 | | * Get a pointer to the DHCP header. Notice this points directly to the data, so every change will change the actual packet data |
632 | | * @return A pointer to the @ref dhcp_header |
633 | | */ |
634 | 0 | dhcp_header* getDhcpHeader() const { return (dhcp_header*)m_Data; } |
635 | | |
636 | | /** |
637 | | * @return The BootP opcode of this message |
638 | | */ |
639 | 0 | BootpOpCodes getOpCode() const { return (BootpOpCodes)getDhcpHeader()->opCode; } |
640 | | |
641 | | /** |
642 | | * @return The client IPv4 address (as extracted from dhcp_header#clientIpAddress converted to IPv4Address object) |
643 | | */ |
644 | 0 | IPv4Address getClientIpAddress() const { return getDhcpHeader()->clientIpAddress; } |
645 | | |
646 | | /** |
647 | | * Set the client IPv4 address in dhcp_header#clientIpAddress |
648 | | * @param[in] addr The IPv4 address to set |
649 | | */ |
650 | 0 | void setClientIpAddress(const IPv4Address& addr) { getDhcpHeader()->clientIpAddress = addr.toInt(); } |
651 | | |
652 | | /** |
653 | | * @return The server IPv4 address (as extracted from dhcp_header#serverIpAddress converted to IPv4Address object) |
654 | | */ |
655 | 0 | IPv4Address getServerIpAddress() const { return getDhcpHeader()->serverIpAddress; } |
656 | | |
657 | | /** |
658 | | * Set the server IPv4 address in dhcp_header#serverIpAddress |
659 | | * @param[in] addr The IPv4 address to set |
660 | | */ |
661 | 0 | void setServerIpAddress(const IPv4Address& addr) { getDhcpHeader()->serverIpAddress = addr.toInt(); } |
662 | | |
663 | | /** |
664 | | * @return Your IPv4 address (as extracted from dhcp_header#yourIpAddress converted to IPv4Address object) |
665 | | */ |
666 | 0 | IPv4Address getYourIpAddress() const { return getDhcpHeader()->yourIpAddress; } |
667 | | |
668 | | /** |
669 | | * Set your IPv4 address in dhcp_header#yourIpAddress |
670 | | * @param[in] addr The IPv4 address to set |
671 | | */ |
672 | 0 | void setYourIpAddress(const IPv4Address& addr) { getDhcpHeader()->yourIpAddress = addr.toInt(); } |
673 | | |
674 | | /** |
675 | | * @return Gateway IPv4 address (as extracted from dhcp_header#gatewayIpAddress converted to IPv4Address object) |
676 | | */ |
677 | 0 | IPv4Address getGatewayIpAddress() const { return getDhcpHeader()->gatewayIpAddress; } |
678 | | |
679 | | /** |
680 | | * Set the gateway IPv4 address in dhcp_header#gatewayIpAddress |
681 | | * @param[in] addr The IPv4 address to set |
682 | | */ |
683 | 0 | void setGatewayIpAddress(const IPv4Address& addr) { getDhcpHeader()->gatewayIpAddress = addr.toInt(); } |
684 | | |
685 | | /** |
686 | | * @return The client MAC address as extracted from dhcp_header#clientHardwareAddress, assuming dhcp_header#hardwareType is 1 (Ethernet) |
687 | | * and dhcp_header#hardwareAddressLength is 6 (MAC address length). Otherwise returns MacAddress#Zero |
688 | | */ |
689 | | MacAddress getClientHardwareAddress() const; |
690 | | |
691 | | /** |
692 | | * Set a MAC address into the first 6 bytes of dhcp_header#clientHardwareAddress. This method also sets dhcp_header#hardwareType |
693 | | * to 1 (Ethernet) and dhcp_header#hardwareAddressLength to 6 (MAC address length) |
694 | | * @param[in] addr The MAC address to set |
695 | | */ |
696 | | void setClientHardwareAddress(const MacAddress& addr); |
697 | | |
698 | | /** |
699 | | * @deprecated Deprecated due to typo. Please use getMessageType() |
700 | | */ |
701 | 0 | PCPP_DEPRECATED DhcpMessageType getMesageType() const { return getMessageType(); }; |
702 | | |
703 | | /** |
704 | | * @return DHCP message type as extracted from ::DHCPOPT_DHCP_MESSAGE_TYPE option. If this option doesn't exist the value of |
705 | | * ::DHCP_UNKNOWN_MSG_TYPE is returned |
706 | | */ |
707 | | DhcpMessageType getMessageType() const; |
708 | | |
709 | | /** |
710 | | * @deprecated Deprecated due to typo. Please use setMessageType() |
711 | | */ |
712 | 0 | bool setMesageType(DhcpMessageType msgType) { return setMessageType(msgType); }; |
713 | | |
714 | | /** |
715 | | * Set DHCP message type. This method searches for existing ::DHCPOPT_DHCP_MESSAGE_TYPE option. If found, it sets the requested |
716 | | * message type as its value. If not, it creates a ::DHCPOPT_DHCP_MESSAGE_TYPE option and sets the requested message type as its |
717 | | * value |
718 | | * @param[in] msgType Message type to set |
719 | | * @return True if message type was set successfully or false if msgType is ::DHCP_UNKNOWN_MSG_TYPE or if failed to add |
720 | | * ::DHCPOPT_DHCP_MESSAGE_TYPE option |
721 | | */ |
722 | | bool setMessageType(DhcpMessageType msgType); |
723 | | |
724 | | /** |
725 | | * @return The first DHCP option in the packet. If there are no DHCP options the returned value will contain |
726 | | * a logical NULL (DhcpOption#isNull() == true) |
727 | | */ |
728 | | DhcpOption getFirstOptionData() const; |
729 | | |
730 | | /** |
731 | | * Get the DHCP option that comes after a given option. If the given option was the last one, the |
732 | | * returned value will contain a logical NULL (DhcpOption#isNull() == true) |
733 | | * @param[in] dhcpOption A given DHCP option |
734 | | * @return A DhcpOption object containing the option data that comes next, or logical NULL if the given DHCP |
735 | | * option: (1) was the last one; (2) contains a logical NULL or (3) doesn't belong to this packet |
736 | | */ |
737 | | DhcpOption getNextOptionData(DhcpOption dhcpOption) const; |
738 | | |
739 | | /** |
740 | | * Get a DHCP option by type |
741 | | * @param[in] option DHCP option type |
742 | | * @return A DhcpOption object containing the first DHCP option data that matches this type, or logical NULL |
743 | | * (DhcpOption#isNull() == true) if no such option found |
744 | | */ |
745 | | DhcpOption getOptionData(DhcpOptionTypes option) const; |
746 | | |
747 | | /** |
748 | | * @return The number of DHCP options in this layer |
749 | | */ |
750 | | size_t getOptionsCount() const; |
751 | | |
752 | | /** |
753 | | * Add a new DHCP option at the end of the layer |
754 | | * @param[in] optionBuilder A DhcpOptionBuilder object that contains the requested DHCP option data to add |
755 | | * @return A DhcpOption object containing the newly added DHCP option data or logical NULL |
756 | | * (DhcpOption#isNull() == true) if addition failed |
757 | | */ |
758 | | DhcpOption addOption(const DhcpOptionBuilder& optionBuilder); |
759 | | |
760 | | /** |
761 | | * Add a new DHCP option after an existing one |
762 | | * @param[in] optionBuilder A DhcpOptionBuilder object that contains the requested DHCP option data to add |
763 | | * @param[in] prevOption The DHCP option type which the newly added option will come after |
764 | | * @return A DhcpOption object containing the newly added DHCP option data or logical NULL |
765 | | * (DhcpOption#isNull() == true) if addition failed |
766 | | */ |
767 | | DhcpOption addOptionAfter(const DhcpOptionBuilder& optionBuilder, DhcpOptionTypes prevOption); |
768 | | |
769 | | /** |
770 | | * Remove an existing DHCP option from the layer |
771 | | * @param[in] optionType The DHCP option type to remove |
772 | | * @return True if DHCP option was successfully removed or false if type wasn't found or if removal failed |
773 | | */ |
774 | | bool removeOption(DhcpOptionTypes optionType); |
775 | | |
776 | | /** |
777 | | * Remove all DHCP options in this layer |
778 | | * @return True if all DHCP options were successfully removed or false if removal failed for some reason |
779 | | */ |
780 | | bool removeAllOptions(); |
781 | | |
782 | | // implement abstract methods |
783 | | |
784 | | /** |
785 | | * Does nothing for this layer (DhcpLayer is always last) |
786 | | */ |
787 | 448 | void parseNextLayer() {} |
788 | | |
789 | | /** |
790 | | * @return The size of @ref dhcp_header + size of options |
791 | | */ |
792 | 0 | size_t getHeaderLen() const { return m_DataLen; } |
793 | | |
794 | | /** |
795 | | * Calculate the following fields: |
796 | | * - @ref dhcp_header#magicNumber = DHCP magic number (0x63538263) |
797 | | * - @ref dhcp_header#opCode = ::DHCP_BOOTREQUEST for message types: ::DHCP_DISCOVER, ::DHCP_REQUEST, ::DHCP_DECLINE, ::DHCP_RELEASE, |
798 | | * ::DHCP_INFORM, ::DHCP_UNKNOWN_MSG_TYPE |
799 | | * ::DHCP_BOOTREPLY for message types: ::DHCP_OFFER, ::DHCP_ACK, ::DHCP_NAK |
800 | | * - @ref dhcp_header#hardwareType = 1 (Ethernet) |
801 | | * - @ref dhcp_header#hardwareAddressLength = 6 (MAC address length) |
802 | | */ |
803 | | void computeCalculateFields(); |
804 | | |
805 | | std::string toString() const; |
806 | | |
807 | 448 | OsiModelLayer getOsiModelLayer() const { return OsiModelApplicationLayer; } |
808 | | |
809 | | private: |
810 | | |
811 | 0 | uint8_t* getOptionsBasePtr() const { return m_Data + sizeof(dhcp_header); } |
812 | | |
813 | | TLVRecordReader<DhcpOption> m_OptionReader; |
814 | | |
815 | | void initDhcpLayer(size_t numOfBytesToAllocate); |
816 | | |
817 | | DhcpOption addOptionAt(const DhcpOptionBuilder& optionBuilder, int offset); |
818 | | }; |
819 | | } |
820 | | |
821 | | #endif /* PACKETPP_DHCP_LAYER */ |