1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
/* vi: set sw=4 ts=4: */
/* common.h
*
* Russ Dill <Russ.Dill@asu.edu> September 2001
* Rewritten by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#ifndef UDHCP_COMMON_H
#define UDHCP_COMMON_H 1
#include "libbb.h"
#include <netinet/udp.h>
#include <netinet/ip.h>
PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
#define DEFAULT_SCRIPT CONFIG_UDHCPC_DEFAULT_SCRIPT
extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */
/*** packet.h ***/
/* DHCP protocol. See RFC 2131 */
#define DHCP_MAGIC 0x63825363
#define DHCP_OPTIONS_BUFSIZE 308
#define BOOTREQUEST 1
#define BOOTREPLY 2
//TODO: rename ciaddr/yiaddr/chaddr
struct dhcp_packet {
uint8_t op; /* BOOTREQUEST or BOOTREPLY */
uint8_t htype; /* hardware address type. 1 = 10mb ethernet */
uint8_t hlen; /* hardware address length */
uint8_t hops; /* used by relay agents only */
uint32_t xid; /* unique id */
uint16_t secs; /* elapsed since client began acquisition/renewal */
uint16_t flags; /* only one flag so far: */
#define BROADCAST_FLAG 0x8000 /* "I need broadcast replies" */
uint32_t ciaddr; /* client IP (if client is in BOUND, RENEW or REBINDING state) */
uint32_t yiaddr; /* 'your' (client) IP address */
/* IP address of next server to use in bootstrap, returned in DHCPOFFER, DHCPACK by server */
uint32_t siaddr_nip;
uint32_t gateway_nip; /* relay agent IP address */
uint8_t chaddr[16]; /* link-layer client hardware address (MAC) */
uint8_t sname[64]; /* server host name (ASCIZ) */
uint8_t file[128]; /* boot file name (ASCIZ) */
uint32_t cookie; /* fixed first four option bytes (99,130,83,99 dec) */
uint8_t options[DHCP_OPTIONS_BUFSIZE + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS];
} PACKED;
#define DHCP_PKT_SNAME_LEN 64
#define DHCP_PKT_FILE_LEN 128
#define DHCP_PKT_SNAME_LEN_STR "64"
#define DHCP_PKT_FILE_LEN_STR "128"
struct ip_udp_dhcp_packet {
struct iphdr ip;
struct udphdr udp;
struct dhcp_packet data;
} PACKED;
/* Let's see whether compiler understood us right */
struct BUG_bad_sizeof_struct_ip_udp_dhcp_packet {
char BUG_bad_sizeof_struct_ip_udp_dhcp_packet
[(sizeof(struct ip_udp_dhcp_packet) != 576 + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS) ? -1 : 1];
};
// RFC 2131 Table 5: Fields and options used by DHCP clients
//
// Field DHCPDISCOVER DHCPREQUEST DHCPDECLINE,
// DHCPINFORM DHCPRELEASE
// ----- ------------ ----------- -----------
// 'op' BOOTREQUEST BOOTREQUEST BOOTREQUEST
// 'hops' 0 0 0
// 'xid' selected by client 'xid' from server selected by
// DHCPOFFER message client
// 'secs' 0 or seconds since 0 or seconds since 0
// DHCP process started DHCP process started
// 'flags' Set 'BROADCAST' Set 'BROADCAST' 0
// flag if client flag if client
// requires broadcast requires broadcast
// reply reply
// 'ciaddr' 0 (DHCPDISCOVER) 0 or client's 0 (DHCPDECLINE)
// client's network address client's network
// network address (BOUND/RENEW/REBIND) address
// (DHCPINFORM) (DHCPRELEASE)
// 'yiaddr' 0 0 0
// 'siaddr' 0 0 0
// 'giaddr' 0 0 0
// 'chaddr' client's hardware client's hardware client's hardware
// address address address
// 'sname' options, if options, if (unused)
// indicated in indicated in
// 'sname/file' 'sname/file'
// option; otherwise option; otherwise
// unused unused
// 'file' options, if options, if (unused)
// indicated in indicated in
// 'sname/file' 'sname/file'
// option; otherwise option; otherwise
// unused unused
// 'options' options options (unused)
//
// Option DHCPDISCOVER DHCPREQUEST DHCPDECLINE,
// DHCPINFORM DHCPRELEASE
// ------ ------------ ----------- -----------
// Requested IP address MAY MUST (in MUST
// (DISCOVER) SELECTING or (DHCPDECLINE),
// MUST NOT INIT-REBOOT) MUST NOT
// (INFORM) MUST NOT (in (DHCPRELEASE)
// BOUND or
// RENEWING)
// IP address lease time MAY MAY MUST NOT
// (DISCOVER)
// MUST NOT
// (INFORM)
// Use 'file'/'sname' fields MAY MAY MAY
// Client identifier MAY MAY MAY
// Vendor class identifier MAY MAY MUST NOT
// Server identifier MUST NOT MUST (after MUST
// SELECTING)
// MUST NOT (after
// INIT-REBOOT,
// BOUND, RENEWING
// or REBINDING)
// Parameter request list MAY MAY MUST NOT
// Maximum message size MAY MAY MUST NOT
// Message SHOULD NOT SHOULD NOT SHOULD
// Site-specific MAY MAY MUST NOT
// All others MAY MAY MUST NOT
uint16_t udhcp_checksum(void *addr, int count) FAST_FUNC;
void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC;
/*int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd); - in dhcpc.h */
int udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) FAST_FUNC;
int udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_ip, int source_port,
uint32_t dest_ip, int dest_port, const uint8_t *dest_arp,
int ifindex) FAST_FUNC;
int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_ip, int source_port,
uint32_t dest_ip, int dest_port) FAST_FUNC;
/**/
void udhcp_run_script(struct dhcp_packet *packet, const char *name) FAST_FUNC;
// Still need to clean these up...
/* from options.h */
#define get_option udhcp_get_option
#define end_option udhcp_end_option
#define add_option_string udhcp_add_option_string
#define add_simple_option udhcp_add_simple_option
void udhcp_sp_setup(void) FAST_FUNC;
int udhcp_sp_fd_set(fd_set *rfds, int extra_fd) FAST_FUNC;
int udhcp_sp_read(const fd_set *rfds) FAST_FUNC;
int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC;
int udhcp_raw_socket(int ifindex) FAST_FUNC;
int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC;
/* Returns 1 if no reply received */
int arpping(uint32_t test_nip,
const uint8_t *safe_mac,
uint32_t from_ip,
uint8_t *from_mac,
const char *interface) FAST_FUNC;
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
extern unsigned dhcp_verbose;
# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0)
# if CONFIG_UDHCP_DEBUG >= 2
void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
# define log2(...) do { if (dhcp_verbose >= 2) bb_info_msg(__VA_ARGS__); } while (0)
# else
# define udhcp_dump_packet(...) ((void)0)
# define log2(...) ((void)0)
# endif
# if CONFIG_UDHCP_DEBUG >= 3
# define log3(...) do { if (dhcp_verbose >= 3) bb_info_msg(__VA_ARGS__); } while (0)
# else
# define log3(...) ((void)0)
# endif
#else
# define udhcp_dump_packet(...) ((void)0)
# define log1(...) ((void)0)
# define log2(...) ((void)0)
# define log3(...) ((void)0)
#endif
POP_SAVED_FUNCTION_VISIBILITY
#endif
|