1
2 #include "netx_dhcp_clone_function.h"
3 #include "nxd_dhcp_client.h"
4 #include "nxd_dhcp_server.h"
5
6
dhcp_get_option_value(UCHAR * bootp_message,UINT option,ULONG * value,UINT length)7 UINT dhcp_get_option_value(UCHAR *bootp_message, UINT option, ULONG *value, UINT length)
8 {
9
10 UCHAR *data;
11
12
13 /* Find the option. */
14 if ((option != NX_DHCP_OPTION_PAD) && (option != NX_DHCP_OPTION_END))
15 {
16
17 /* Search the buffer for the option. */
18 data = dhcp_search_buffer(bootp_message, option, length);
19
20 /* Check to see if the option was found. */
21 if (data != NX_NULL)
22 {
23
24 /* Check for the proper size. */
25 if (*data > 4)
26 {
27
28 /* Check for the gateway option. */
29 if (option == NX_DHCP_OPTION_GATEWAYS)
30 {
31
32 /* Pickup the first gateway address. */
33 *value = dhcp_get_data(data + 1, 4);
34
35 /* For now, just disregard any additional gateway addresses. */
36 return(NX_SUCCESS);
37 }
38 else
39 {
40
41 /* Invalid size, return error. */
42 return(NX_SIZE_ERROR);
43 }
44 }
45 else
46 {
47
48 /* Get the actual value. */
49 *value = dhcp_get_data(data + 1, *data);
50 return(NX_SUCCESS);
51 }
52 }
53 }
54
55 /* Return an error if not found. */
56 return(NX_OPTION_ERROR);
57 }
dhcp_search_buffer(UCHAR * bootp_message,UINT option,UINT length)58 UCHAR *dhcp_search_buffer(UCHAR *bootp_message, UINT option, UINT length)
59 {
60
61 UCHAR *data;
62 UINT i;
63
64
65 /* Setup buffer pointer. */
66 data = &bootp_message[NX_BOOTP_OFFSET_OPTIONS];
67 i = NX_BOOTP_OFFSET_OPTIONS;
68
69 /* Search as long as there are valid options. */
70 while (i < length)
71 {
72
73 /* Simply skip any padding */
74 if (*data == NX_DHCP_OPTION_PAD)
75 {
76
77 data++;
78 i++;
79 }
80
81 /* On a match, return a pointer to the size. */
82 else if (*data == option)
83 {
84
85 /* Return a pointer to the option size byte. */
86 return(data + 1);
87 }
88
89 /* Otherwise skip the option by adding the size to the pointer. */
90 else
91 {
92
93 UINT size = *(++data);
94
95 /* skip the data plus the size byte */
96 data += size + 1;
97 i += size + 1;
98 }
99 }
100
101 /* Return NULL to indicate the option was not found. */
102 return(NX_NULL);
103 }
dhcp_get_data(UCHAR * data,UINT size)104 ULONG dhcp_get_data(UCHAR *data, UINT size)
105 {
106
107 ULONG value = 0;
108
109
110 /* Process the data retrieval request. */
111 while (size-- > 0)
112 {
113
114 /* Build return value. */
115 value = (value << 8) | *data++;
116 }
117
118 /* Return value. */
119 return(value);
120 }
121