Browse Source

Provide a mechanism for returning the encapsulator as well as the

encapsulated option; this will be needed for modifications to the options
block.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
51d62d1a3c
2 changed files with 37 additions and 15 deletions
  1. 14
    0
      src/include/gpxe/dhcp.h
  2. 23
    15
      src/net/dhcpopts.c

+ 14
- 0
src/include/gpxe/dhcp.h View File

@@ -88,6 +88,20 @@ extern unsigned long dhcp_num_option ( struct dhcp_option *option );
88 88
 extern struct dhcp_option * find_dhcp_option ( unsigned int tag,
89 89
 					   struct dhcp_option_block *options );
90 90
 
91
+/**
92
+ * Find DHCP numerical option, and return its value
93
+ *
94
+ * @v tag		DHCP option tag to search for
95
+ * @v options		DHCP options block
96
+ * @ret value		Numerical value of the option, or 0 if not found
97
+ *
98
+ * This function exists merely as a notational shorthand for a call to
99
+ * find_dhcp_option() followed by a call to dhcp_num_option().  It is
100
+ * not possible to distinguish between the cases "option not found"
101
+ * and "option has a value of zero" using this function; if this
102
+ * matters to you then issue the two constituent calls directly and
103
+ * check that find_dhcp_option() returns a non-NULL value.
104
+ */
91 105
 static inline unsigned long
92 106
 find_dhcp_num_option ( unsigned int tag, struct dhcp_option_block *options ) {
93 107
 	return dhcp_num_option ( find_dhcp_option ( tag, options ) );

+ 23
- 15
src/net/dhcpopts.c View File

@@ -78,26 +78,32 @@ static inline unsigned int dhcp_option_len ( struct dhcp_option *option ) {
78 78
 }
79 79
 
80 80
 /**
81
- * Find DHCP option within block of raw data
81
+ * Find DHCP option within DHCP options block, and its encapsulator (if any)
82 82
  *
83 83
  * @v tag		DHCP option tag to search for
84
- * @v data		Data block
85
- * @v len		Length of data block
84
+ * @v options		DHCP options block
85
+ * @ret encapsulator	Encapsulating option (if applicable, may be NULL)
86 86
  * @ret option		DHCP option, or NULL if not found
87 87
  *
88 88
  * Searches for the DHCP option matching the specified tag within the
89 89
  * block of data.  Encapsulated options may be searched for by using
90
- * DHCP_ENCAP_OPT() to construct the tag value.
90
+ * DHCP_ENCAP_OPT() to construct the tag value.  If the option is an
91
+ * encapsulated option, and @c encapsulator is non-NULL, it will be
92
+ * filled in with a pointer to the encapsulating option, if present.
93
+ * Note that the encapsulating option may be present even if the
94
+ * encapsulated option is absent, in which case @c encapsulator will
95
+ * be set but the function will return NULL.
91 96
  *
92 97
  * This routine is designed to be paranoid.  It does not assume that
93 98
  * the option data is well-formatted, and so must guard against flaws
94 99
  * such as options missing a @c DHCP_END terminator, or options whose
95 100
  * length would take them beyond the end of the data block.
96 101
  */
97
-static struct dhcp_option * find_dhcp_option_raw ( unsigned int tag,
98
-						   void *data, size_t len ) {
99
-	struct dhcp_option *option = data;
100
-	ssize_t remaining = len;
102
+static struct dhcp_option *
103
+find_dhcp_option_encap ( unsigned int tag, struct dhcp_option_block *options,
104
+			 struct dhcp_option **encapsulator ) {
105
+	struct dhcp_option *option = options->data;
106
+	ssize_t remaining = options->len;
101 107
 	unsigned int option_len;
102 108
 
103 109
 	while ( remaining ) {
@@ -118,10 +124,12 @@ static struct dhcp_option * find_dhcp_option_raw ( unsigned int tag,
118 124
 		/* Check for start of matching encapsulation block */
119 125
 		if ( DHCP_ENCAPSULATOR ( tag ) &&
120 126
 		     ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
121
-			/* Search within encapsulated option block */
122
-			return find_dhcp_option_raw ( DHCP_ENCAPSULATED( tag ),
123
-						      &option->data,
124
-						      option->len );
127
+			/* Continue search within encapsulated option block */
128
+			if ( encapsulator )
129
+				*encapsulator = option;
130
+			remaining = option->len;
131
+			option = ( void * ) &option->data;
132
+			continue;
125 133
 		}
126 134
 		option = ( ( ( void * ) option ) + option_len );
127 135
 	}
@@ -129,19 +137,19 @@ static struct dhcp_option * find_dhcp_option_raw ( unsigned int tag,
129 137
 }
130 138
 
131 139
 /**
132
- * Find DHCP option within options block
140
+ * Find DHCP option within DHCP options block
133 141
  *
134 142
  * @v tag		DHCP option tag to search for
135 143
  * @v options		DHCP options block
136 144
  * @ret option		DHCP option, or NULL if not found
137 145
  *
138 146
  * Searches for the DHCP option matching the specified tag within the
139
- * options block.  Encapsulated options may be searched for by using
147
+ * block of data.  Encapsulated options may be searched for by using
140 148
  * DHCP_ENCAP_OPT() to construct the tag value.
141 149
  */
142 150
 struct dhcp_option * find_dhcp_option ( unsigned int tag,
143 151
 					struct dhcp_option_block *options ) {
144
-	return find_dhcp_option_raw ( tag, options->data, options->len );
152
+	return find_dhcp_option_encap ( tag, options, NULL );
145 153
 }
146 154
 
147 155
 /**

Loading…
Cancel
Save