@@ -34,18 +34,18 @@ pub enum OptionData {
34
34
Pad ,
35
35
End ,
36
36
SubnetMask ( Ipv4Addr ) ,
37
- TimeOffset ,
37
+ TimeOffset ( u32 ) ,
38
38
Router ( Vec < Ipv4Addr > ) ,
39
- TimeServer ,
40
- NameServer ,
39
+ TimeServer ( Vec < Ipv4Addr > ) ,
40
+ NameServer ( Vec < Ipv4Addr > ) ,
41
41
DomainNameServer ( Vec < Ipv4Addr > ) ,
42
- LogServer ,
43
- CookieServer ,
44
- LprServer ,
45
- ImpressServer ,
46
- ResourceLocationServer ,
42
+ LogServer ( Vec < Ipv4Addr > ) ,
43
+ CookieServer ( Vec < Ipv4Addr > ) ,
44
+ LprServer ( Vec < Ipv4Addr > ) ,
45
+ ImpressServer ( Vec < Ipv4Addr > ) ,
46
+ ResourceLocationServer ( Vec < Ipv4Addr > ) ,
47
47
HostName ( String ) ,
48
- BootFileSize ,
48
+ BootFileSize ( u16 ) ,
49
49
MeritDumpFile ,
50
50
DomainName ,
51
51
SwapServer ,
@@ -166,18 +166,18 @@ impl Writeable for OptionData {
166
166
OptionData :: Pad => 0u8 . write :: < E > ( buf) ?,
167
167
OptionData :: End => 255u8 . write :: < E > ( buf) ?,
168
168
OptionData :: SubnetMask ( mask) => mask. write :: < E > ( buf) ?,
169
- OptionData :: TimeOffset => todo ! ( ) ,
169
+ OptionData :: TimeOffset ( off ) => off . write :: < E > ( buf ) ? ,
170
170
OptionData :: Router ( ips) => ips. write :: < E > ( buf) ?,
171
- OptionData :: TimeServer => todo ! ( ) ,
172
- OptionData :: NameServer => todo ! ( ) ,
171
+ OptionData :: TimeServer ( ips ) => ips . write :: < E > ( buf ) ? ,
172
+ OptionData :: NameServer ( ips ) => ips . write :: < E > ( buf ) ? ,
173
173
OptionData :: DomainNameServer ( ips) => ips. write :: < E > ( buf) ?,
174
- OptionData :: LogServer => todo ! ( ) ,
175
- OptionData :: CookieServer => todo ! ( ) ,
176
- OptionData :: LprServer => todo ! ( ) ,
177
- OptionData :: ImpressServer => todo ! ( ) ,
178
- OptionData :: ResourceLocationServer => todo ! ( ) ,
174
+ OptionData :: LogServer ( ips ) => ips . write :: < E > ( buf ) ? ,
175
+ OptionData :: CookieServer ( ips ) => ips . write :: < E > ( buf ) ? ,
176
+ OptionData :: LprServer ( ips ) => ips . write :: < E > ( buf ) ? ,
177
+ OptionData :: ImpressServer ( ips ) => ips . write :: < E > ( buf ) ? ,
178
+ OptionData :: ResourceLocationServer ( ips ) => ips . write :: < E > ( buf ) ? ,
179
179
OptionData :: HostName ( name) => name. write :: < E > ( buf) ?,
180
- OptionData :: BootFileSize => todo ! ( ) ,
180
+ OptionData :: BootFileSize ( size ) => size . write :: < E > ( buf ) ? ,
181
181
OptionData :: MeritDumpFile => todo ! ( ) ,
182
182
OptionData :: DomainName => todo ! ( ) ,
183
183
OptionData :: SwapServer => todo ! ( ) ,
@@ -241,39 +241,39 @@ impl OptionData {
241
241
OptionTag :: Pad => Self :: Pad ,
242
242
OptionTag :: End => Self :: End ,
243
243
OptionTag :: SubnetMask => Self :: SubnetMask ( Ipv4Addr :: read :: < E > ( buf) ?) ,
244
- OptionTag :: TimeOffset => todo ! ( ) ,
244
+ OptionTag :: TimeOffset => Self :: TimeOffset ( u32 :: read :: < E > ( buf ) ? ) ,
245
245
OptionTag :: Router => {
246
- if header. len % 4 != 0 {
247
- return Err ( OptionDataError :: InvalidData ) ;
248
- }
249
-
250
- let mut ips = Vec :: new ( ) ;
251
-
252
- for _ in 0 ..header. len / 4 {
253
- ips. push ( Ipv4Addr :: read :: < E > ( buf) ?) ;
254
- }
255
-
246
+ let ips = read_ip_addrs_set :: < E > ( buf, header. len ) ?;
256
247
Self :: Router ( ips)
257
248
}
258
- OptionTag :: TimeServer => todo ! ( ) ,
259
- OptionTag :: NameServer => todo ! ( ) ,
249
+ OptionTag :: TimeServer => {
250
+ let ips = read_ip_addrs_set :: < E > ( buf, header. len ) ?;
251
+ Self :: TimeServer ( ips)
252
+ }
253
+ OptionTag :: NameServer => {
254
+ let ips = read_ip_addrs_set :: < E > ( buf, header. len ) ?;
255
+ Self :: NameServer ( ips)
256
+ }
260
257
OptionTag :: DomainNameServer => {
261
- if header. len % 4 != 0 {
262
- return Err ( OptionDataError :: InvalidData ) ;
263
- }
264
-
265
- let mut ips = Vec :: new ( ) ;
266
-
267
- for _ in 0 ..header. len / 4 {
268
- ips. push ( Ipv4Addr :: read :: < E > ( buf) ?) ;
269
- }
270
-
258
+ let ips = read_ip_addrs_set :: < E > ( buf, header. len ) ?;
271
259
Self :: DomainNameServer ( ips)
272
260
}
273
- OptionTag :: LogServer => todo ! ( ) ,
274
- OptionTag :: CookieServer => todo ! ( ) ,
275
- OptionTag :: LprServer => todo ! ( ) ,
276
- OptionTag :: ImpressServer => todo ! ( ) ,
261
+ OptionTag :: LogServer => {
262
+ let ips = read_ip_addrs_set :: < E > ( buf, header. len ) ?;
263
+ Self :: LogServer ( ips)
264
+ }
265
+ OptionTag :: CookieServer => {
266
+ let ips = read_ip_addrs_set :: < E > ( buf, header. len ) ?;
267
+ Self :: CookieServer ( ips)
268
+ }
269
+ OptionTag :: LprServer => {
270
+ let ips = read_ip_addrs_set :: < E > ( buf, header. len ) ?;
271
+ Self :: LprServer ( ips)
272
+ }
273
+ OptionTag :: ImpressServer => {
274
+ let ips = read_ip_addrs_set :: < E > ( buf, header. len ) ?;
275
+ Self :: ImpressServer ( ips)
276
+ }
277
277
OptionTag :: ResourceLocationServer => todo ! ( ) ,
278
278
OptionTag :: HostName => {
279
279
let b = buf. read_vec ( header. len as usize ) ?;
@@ -349,23 +349,23 @@ impl OptionData {
349
349
Ok ( option_data)
350
350
}
351
351
352
- pub fn len ( & self ) -> u8 {
352
+ pub fn size ( & self ) -> u8 {
353
353
match self {
354
354
OptionData :: Pad => 1 ,
355
355
OptionData :: End => 1 ,
356
356
OptionData :: SubnetMask ( _) => 4 ,
357
- OptionData :: TimeOffset => 4 ,
358
- OptionData :: Router ( ips) => ips. len ( ) as u8 ,
359
- OptionData :: TimeServer => todo ! ( ) ,
360
- OptionData :: NameServer => todo ! ( ) ,
361
- OptionData :: DomainNameServer ( ips) => ips. len ( ) as u8 ,
362
- OptionData :: LogServer => todo ! ( ) ,
363
- OptionData :: CookieServer => todo ! ( ) ,
364
- OptionData :: LprServer => todo ! ( ) ,
365
- OptionData :: ImpressServer => todo ! ( ) ,
366
- OptionData :: ResourceLocationServer => todo ! ( ) ,
357
+ OptionData :: TimeOffset ( _ ) => 4 ,
358
+ OptionData :: Router ( ips) => ( ips. len ( ) * 4 ) as u8 ,
359
+ OptionData :: TimeServer ( ips ) => ( ips . len ( ) * 4 ) as u8 ,
360
+ OptionData :: NameServer ( ips ) => ( ips . len ( ) * 4 ) as u8 ,
361
+ OptionData :: DomainNameServer ( ips) => ( ips. len ( ) * 4 ) as u8 ,
362
+ OptionData :: LogServer ( ips ) => ( ips . len ( ) * 4 ) as u8 ,
363
+ OptionData :: CookieServer ( ips ) => ( ips . len ( ) * 4 ) as u8 ,
364
+ OptionData :: LprServer ( ips ) => ( ips . len ( ) * 4 ) as u8 ,
365
+ OptionData :: ImpressServer ( ips ) => ( ips . len ( ) * 4 ) as u8 ,
366
+ OptionData :: ResourceLocationServer ( ips ) => ( ips . len ( ) * 4 ) as u8 ,
367
367
OptionData :: HostName ( h) => h. len ( ) as u8 ,
368
- OptionData :: BootFileSize => 2 ,
368
+ OptionData :: BootFileSize ( _ ) => 2 ,
369
369
OptionData :: MeritDumpFile => todo ! ( ) ,
370
370
OptionData :: DomainName => todo ! ( ) ,
371
371
OptionData :: SwapServer => todo ! ( ) ,
@@ -417,3 +417,22 @@ impl OptionData {
417
417
}
418
418
}
419
419
}
420
+
421
+ /// Reads a set of IPv4 addresses. This function ensures that the provided
422
+ /// length is at least 4 and a multiple of 4.
423
+ fn read_ip_addrs_set < E : Endianness > (
424
+ buf : & mut ReadBuffer ,
425
+ len : u8 ,
426
+ ) -> Result < Vec < Ipv4Addr > , OptionDataError > {
427
+ if len < 4 || len % 4 != 0 {
428
+ return Err ( OptionDataError :: InvalidData ) ;
429
+ }
430
+
431
+ let mut ips = Vec :: new ( ) ;
432
+
433
+ for _ in 0 ..len / 4 {
434
+ ips. push ( Ipv4Addr :: read :: < E > ( buf) ?) ;
435
+ }
436
+
437
+ Ok ( ips)
438
+ }
0 commit comments