@@ -85,7 +85,10 @@ pub enum IPOption {
8585pub struct IPv4 {
8686 version : u8 ,
8787 hdr_len : u8 ,
88- tos : u8 ,
88+ #[ serde( serialize_with = "crate::types::hex::serialize_lower_hex_u8" ) ]
89+ dscp : u8 ,
90+ #[ serde( serialize_with = "crate::types::hex::serialize_lower_hex_u8" ) ]
91+ ecn : u8 ,
8992 len : u16 ,
9093 #[ serde( serialize_with = "crate::types::hex::serialize_lower_hex_u16" ) ]
9194 id : u16 ,
@@ -256,8 +259,16 @@ impl IPv4 {
256259 }
257260
258261 #[ cfg( feature = "sculpting" ) ]
259- fn calculate_checksum ( _bytes : & [ u8 ] ) -> u16 {
260- 0
262+ fn calculate_checksum ( bytes : & [ u8 ] ) -> u16 {
263+ // 16 bit one's complement of one's complement sum of all 16 bit words
264+ let len = bytes. len ( ) ;
265+ let mut csum = 0_u32 ;
266+ for i in 0 ..len/2 {
267+ let word = u16:: from_be_bytes ( bytes[ 2 * i..2 * ( i+1 ) ] . try_into ( ) . unwrap ( ) ) ;
268+ csum += word as u32 ;
269+ }
270+ csum = ( ( csum >> 16 ) + ( csum & 0xffff ) ) as u32 ;
271+ ( !csum & 0xffff ) as u16
261272 }
262273}
263274
@@ -279,7 +290,8 @@ impl Layer for IPv4 {
279290 data : hex:: encode ( bytes) ,
280291 } ) ;
281292 }
282- self . tos = bytes[ 1 ] ;
293+ self . dscp = bytes[ 1 ] >> 2 ;
294+ self . ecn = bytes[ 1 ] & 0b11 ;
283295 self . len = u16:: from_be_bytes ( bytes[ 2 ..4 ] . try_into ( ) . unwrap ( ) ) ;
284296 self . id = u16:: from_be_bytes ( bytes[ 4 ..6 ] . try_into ( ) . unwrap ( ) ) ;
285297 let flags_offset = u16:: from_be_bytes ( bytes[ 6 ..8 ] . try_into ( ) . unwrap ( ) ) ;
@@ -337,9 +349,11 @@ impl Layer for IPv4 {
337349
338350 let mut result = Vec :: with_capacity ( self . len as usize ) ;
339351
340- let byte = ( self . version << 4 ) | self . hdr_len ;
352+ let mut byte = ( self . version << 4 ) | self . hdr_len ;
353+ result. push ( byte) ;
354+
355+ byte = ( self . dscp << 2 ) | self . ecn ;
341356 result. push ( byte) ;
342- result. push ( self . tos ) ;
343357 result. extend ( self . len . to_be_bytes ( ) ) ;
344358 result. extend ( self . id . to_be_bytes ( ) ) ;
345359
@@ -357,10 +371,11 @@ impl Layer for IPv4 {
357371 todo ! ( ) ;
358372 }
359373
360- result. extend ( next_layer. unwrap_or_default ( ) ) ;
361-
362374 let checksum = IPv4 :: calculate_checksum ( & result) ;
363375 result[ checksum_start..checksum_start + 2 ] . copy_from_slice ( & checksum. to_be_bytes ( ) ) ;
376+
377+ result. extend ( next_layer. unwrap_or_default ( ) ) ;
378+
364379 Ok ( result)
365380 }
366381}
0 commit comments