Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

dhcp.h 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #ifndef _GPXE_DHCP_H
  2. #define _GPXE_DHCP_H
  3. /** @file
  4. *
  5. * Dynamic Host Configuration Protocol
  6. *
  7. */
  8. #include <stdint.h>
  9. #include <gpxe/list.h>
  10. #include <gpxe/in.h>
  11. /**
  12. * A DHCP packet
  13. *
  14. */
  15. struct dhcp_packet {
  16. /** Operation
  17. *
  18. * This must be either @c BOOTP_REQUEST or @c BOOTP_REPLY.
  19. */
  20. uint8_t op;
  21. /** Hardware address type
  22. *
  23. * This is an ARPHRD_XXX constant.
  24. */
  25. uint8_t htype;
  26. /** Hardware address length */
  27. uint8_t hlen;
  28. /** Number of hops from server */
  29. uint8_t hops;
  30. /** Transaction ID */
  31. uint32_t xid;
  32. /** Seconds since start of acquisition */
  33. uint16_t secs;
  34. /** Flags */
  35. uint16_t flags;
  36. /** "Client" IP address
  37. *
  38. * This is filled in if the client already has an IP address
  39. * assigned and can respond to ARP requests.
  40. */
  41. struct in_addr ciaddr;
  42. /** "Your" IP address
  43. *
  44. * This is the IP address assigned by the server to the client.
  45. */
  46. struct in_addr yiaddr;
  47. /** "Server" IP address
  48. *
  49. * This is the IP address of the next server to be used in the
  50. * boot process.
  51. */
  52. struct in_addr siaddr;
  53. /** "Gateway" IP address
  54. *
  55. * This is the IP address of the DHCP relay agent, if any.
  56. */
  57. struct in_addr giaddr;
  58. /** Client hardware address */
  59. uint8_t chaddr[16];
  60. /** Server host name (null terminated)
  61. *
  62. * This field may be overridden and contain DHCP options
  63. */
  64. uint8_t sname[64];
  65. /** Boot file name (null terminated)
  66. *
  67. * This field may be overridden and contain DHCP options
  68. */
  69. uint8_t file[128];
  70. /** DHCP magic cookie
  71. *
  72. * Must have the value @c DHCP_MAGIC_COOKIE.
  73. */
  74. uint32_t magic;
  75. /** DHCP options
  76. *
  77. * Variable length; extends to the end of the packet.
  78. */
  79. uint8_t options[0];
  80. };
  81. /** Opcode for a request from client to server */
  82. #define BOOTP_REQUEST 1
  83. /** Opcode for a reply from server to client */
  84. #define BOOTP_REPLY 2
  85. /** DHCP magic cookie */
  86. #define DHCP_MAGIC_COOKIE 0x63825363UL
  87. /** Construct a tag value for an encapsulated option
  88. *
  89. * This tag value can be passed to Etherboot functions when searching
  90. * for DHCP options in order to search for a tag within an
  91. * encapsulated options block.
  92. */
  93. #define DHCP_ENCAP_OPT( encapsulator, encapsulated ) \
  94. ( ( (encapsulator) << 8 ) | (encapsulated) )
  95. /** Extract encapsulating option block tag from encapsulated tag value */
  96. #define DHCP_ENCAPSULATOR( encap_opt ) ( (encap_opt) >> 8 )
  97. /** Extract encapsulated option tag from encapsulated tag value */
  98. #define DHCP_ENCAPSULATED( encap_opt ) ( (encap_opt) & 0xff )
  99. /** Option is encapsulated */
  100. #define DHCP_IS_ENCAP_OPT( opt ) DHCP_ENCAPSULATOR( opt )
  101. /**
  102. * @defgroup dhcpopts DHCP option tags
  103. * @{
  104. */
  105. /** Padding
  106. *
  107. * This tag does not have a length field; it is always only a single
  108. * byte in length.
  109. */
  110. #define DHCP_PAD 0
  111. /** Minimum normal DHCP option */
  112. #define DHCP_MIN_OPTION 1
  113. /** Vendor encapsulated options */
  114. #define DHCP_VENDOR_ENCAP 43
  115. /** Option overloading
  116. *
  117. * The value of this option is the bitwise-OR of zero or more
  118. * DHCP_OPTION_OVERLOAD_XXX constants.
  119. */
  120. #define DHCP_OPTION_OVERLOAD 52
  121. /** The "file" field is overloaded to contain extra DHCP options */
  122. #define DHCP_OPTION_OVERLOAD_FILE 1
  123. /** The "sname" field is overloaded to contain extra DHCP options */
  124. #define DHCP_OPTION_OVERLOAD_SNAME 2
  125. /** DHCP message type */
  126. #define DHCP_MESSAGE_TYPE 53
  127. #define DHCPDISCOVER 1
  128. #define DHCPOFFER 2
  129. #define DHCPREQUEST 3
  130. #define DHCPDECLINE 4
  131. #define DHCPACK 5
  132. #define DHCPNAK 6
  133. #define DHCPRELEASE 7
  134. #define DHCPINFORM 8
  135. /** TFTP server name
  136. *
  137. * This option replaces the fixed "sname" field, when that field is
  138. * used to contain overloaded options.
  139. */
  140. #define DHCP_TFTP_SERVER_NAME 66
  141. /** Bootfile name
  142. *
  143. * This option replaces the fixed "file" field, when that field is
  144. * used to contain overloaded options.
  145. */
  146. #define DHCP_BOOTFILE_NAME 67
  147. /** Etherboot-specific encapsulated options
  148. *
  149. * This encapsulated options field is used to contain all options
  150. * specific to Etherboot (i.e. not assigned by IANA or other standards
  151. * bodies).
  152. */
  153. #define DHCP_EB_ENCAP 175
  154. /** Priority of this options block
  155. *
  156. * This is a signed 8-bit integer field indicating the priority of
  157. * this block of options. It can be used to specify the relative
  158. * priority of multiple option blocks (e.g. options from non-volatile
  159. * storage versus options from a DHCP server).
  160. */
  161. #define DHCP_EB_PRIORITY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 1 )
  162. /** "Your" IP address
  163. *
  164. * This option is used internally to contain the value of the "yiaddr"
  165. * field, in order to provide a consistent approach to storing and
  166. * processing options. It should never be present in a DHCP packet.
  167. */
  168. #define DHCP_EB_YIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 2 )
  169. /** "Server" IP address
  170. *
  171. * This option is used internally to contain the value of the "siaddr"
  172. * field, in order to provide a consistent approach to storing and
  173. * processing options. It should never be present in a DHCP packet.
  174. */
  175. #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 )
  176. /** Maximum normal DHCP option */
  177. #define DHCP_MAX_OPTION 254
  178. /** End of options
  179. *
  180. * This tag does not have a length field; it is always only a single
  181. * byte in length.
  182. */
  183. #define DHCP_END 255
  184. /** @} */
  185. /**
  186. * A DHCP option
  187. *
  188. * DHCP options consist of a mandatory tag, a length field that is
  189. * mandatory for all options except @c DHCP_PAD and @c DHCP_END, and a
  190. * payload.
  191. */
  192. struct dhcp_option {
  193. /** Tag
  194. *
  195. * Must be a @c DHCP_XXX value.
  196. */
  197. uint8_t tag;
  198. /** Length
  199. *
  200. * This is the length of the data field (i.e. excluding the
  201. * tag and length fields). For the two tags @c DHCP_PAD and
  202. * @c DHCP_END, the length field is implicitly zero and is
  203. * also missing, i.e. these DHCP options are only a single
  204. * byte in length.
  205. */
  206. uint8_t len;
  207. /** Option data
  208. *
  209. * Interpretation of the content is entirely dependent upon
  210. * the tag. For fields containing a multi-byte integer, the
  211. * field is defined to be in network-endian order (unless you
  212. * are Intel and feel like violating the spec for fun).
  213. */
  214. union {
  215. uint8_t byte;
  216. uint16_t word;
  217. uint32_t dword;
  218. uint8_t bytes[0];
  219. } data;
  220. } __attribute__ (( packed ));
  221. /**
  222. * Length of a DHCP option header
  223. *
  224. * The header is the portion excluding the data, i.e. the tag and the
  225. * length.
  226. */
  227. #define DHCP_OPTION_HEADER_LEN ( offsetof ( struct dhcp_option, data ) )
  228. /** Maximum length for a single DHCP option */
  229. #define DHCP_MAX_LEN 0xff
  230. /** A DHCP options block */
  231. struct dhcp_option_block {
  232. /** List of option blocks */
  233. struct list_head list;
  234. /** Option block raw data */
  235. void *data;
  236. /** Option block length */
  237. size_t len;
  238. /** Option block maximum length */
  239. size_t max_len;
  240. /** Block priority
  241. *
  242. * This is determined at the time of the call to
  243. * register_options() by searching for the @c DHCP_EB_PRIORITY
  244. * option.
  245. */
  246. signed int priority;
  247. };
  248. extern unsigned long dhcp_num_option ( struct dhcp_option *option );
  249. extern struct dhcp_option *
  250. find_dhcp_option ( struct dhcp_option_block *options, unsigned int tag );
  251. extern struct dhcp_option * find_global_dhcp_option ( unsigned int tag );
  252. extern void register_dhcp_options ( struct dhcp_option_block *options );
  253. extern void unregister_dhcp_options ( struct dhcp_option_block *options );
  254. extern void init_dhcp_options ( struct dhcp_option_block *options,
  255. void *data, size_t max_len );
  256. extern struct dhcp_option_block * alloc_dhcp_options ( size_t max_len );
  257. extern void free_dhcp_options ( struct dhcp_option_block *options );
  258. extern struct dhcp_option *
  259. set_dhcp_option ( struct dhcp_option_block *options, unsigned int tag,
  260. const void *data, size_t len );
  261. /**
  262. * Find DHCP numerical option, and return its value
  263. *
  264. * @v options DHCP options block
  265. * @v tag DHCP option tag to search for
  266. * @ret value Numerical value of the option, or 0 if not found
  267. *
  268. * This function exists merely as a notational shorthand for a call to
  269. * find_dhcp_option() followed by a call to dhcp_num_option(). It is
  270. * not possible to distinguish between the cases "option not found"
  271. * and "option has a value of zero" using this function; if this
  272. * matters to you then issue the two constituent calls directly and
  273. * check that find_dhcp_option() returns a non-NULL value.
  274. */
  275. static inline unsigned long
  276. find_dhcp_num_option ( struct dhcp_option_block *options, unsigned int tag ) {
  277. return dhcp_num_option ( find_dhcp_option ( options, tag ) );
  278. }
  279. /**
  280. * Find DHCP numerical option, and return its value
  281. *
  282. * @v tag DHCP option tag to search for
  283. * @ret value Numerical value of the option, or 0 if not found
  284. *
  285. * This function exists merely as a notational shorthand for a call to
  286. * find_global_dhcp_option() followed by a call to dhcp_num_option().
  287. * It is not possible to distinguish between the cases "option not
  288. * found" and "option has a value of zero" using this function; if
  289. * this matters to you then issue the two constituent calls directly
  290. * and check that find_global_dhcp_option() returns a non-NULL value.
  291. */
  292. static inline unsigned long
  293. find_global_dhcp_num_option ( unsigned int tag ) {
  294. return dhcp_num_option ( find_global_dhcp_option ( tag ) );
  295. }
  296. /**
  297. * Delete DHCP option
  298. *
  299. * @v options DHCP options block
  300. * @v tag DHCP option tag
  301. */
  302. static inline void delete_dhcp_option ( struct dhcp_option_block *options,
  303. unsigned int tag ) {
  304. set_dhcp_option ( options, tag, NULL, 0 );
  305. }
  306. #endif /* _GPXE_DHCP_H */