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
 extern struct dhcp_option * find_dhcp_option ( unsigned int tag,
88
 extern struct dhcp_option * find_dhcp_option ( unsigned int tag,
89
 					   struct dhcp_option_block *options );
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
 static inline unsigned long
105
 static inline unsigned long
92
 find_dhcp_num_option ( unsigned int tag, struct dhcp_option_block *options ) {
106
 find_dhcp_num_option ( unsigned int tag, struct dhcp_option_block *options ) {
93
 	return dhcp_num_option ( find_dhcp_option ( tag, options ) );
107
 	return dhcp_num_option ( find_dhcp_option ( tag, options ) );

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

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
  * @v tag		DHCP option tag to search for
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
  * @ret option		DHCP option, or NULL if not found
86
  * @ret option		DHCP option, or NULL if not found
87
  *
87
  *
88
  * Searches for the DHCP option matching the specified tag within the
88
  * Searches for the DHCP option matching the specified tag within the
89
  * block of data.  Encapsulated options may be searched for by using
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
  * This routine is designed to be paranoid.  It does not assume that
97
  * This routine is designed to be paranoid.  It does not assume that
93
  * the option data is well-formatted, and so must guard against flaws
98
  * the option data is well-formatted, and so must guard against flaws
94
  * such as options missing a @c DHCP_END terminator, or options whose
99
  * such as options missing a @c DHCP_END terminator, or options whose
95
  * length would take them beyond the end of the data block.
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
 	unsigned int option_len;
107
 	unsigned int option_len;
102
 
108
 
103
 	while ( remaining ) {
109
 	while ( remaining ) {
118
 		/* Check for start of matching encapsulation block */
124
 		/* Check for start of matching encapsulation block */
119
 		if ( DHCP_ENCAPSULATOR ( tag ) &&
125
 		if ( DHCP_ENCAPSULATOR ( tag ) &&
120
 		     ( option->tag == DHCP_ENCAPSULATOR ( tag ) ) ) {
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
 		option = ( ( ( void * ) option ) + option_len );
134
 		option = ( ( ( void * ) option ) + option_len );
127
 	}
135
 	}
129
 }
137
 }
130
 
138
 
131
 /**
139
 /**
132
- * Find DHCP option within options block
140
+ * Find DHCP option within DHCP options block
133
  *
141
  *
134
  * @v tag		DHCP option tag to search for
142
  * @v tag		DHCP option tag to search for
135
  * @v options		DHCP options block
143
  * @v options		DHCP options block
136
  * @ret option		DHCP option, or NULL if not found
144
  * @ret option		DHCP option, or NULL if not found
137
  *
145
  *
138
  * Searches for the DHCP option matching the specified tag within the
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
  * DHCP_ENCAP_OPT() to construct the tag value.
148
  * DHCP_ENCAP_OPT() to construct the tag value.
141
  */
149
  */
142
 struct dhcp_option * find_dhcp_option ( unsigned int tag,
150
 struct dhcp_option * find_dhcp_option ( unsigned int tag,
143
 					struct dhcp_option_block *options ) {
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