@@ -30,9 +30,9 @@ const WINDOW_SIZE_OFFSET: usize = 14;
30
30
const CHECKSUM_OFFSET : usize = 16 ;
31
31
const URG_POINTER_OFFSET : usize = 18 ;
32
32
33
- const OPTIONS_OFFSET : usize = 20 ;
33
+ const OPTIONS_OFFSET : u8 = 20 ;
34
34
35
- const MAX_HEADER_LEN : usize = 60 ;
35
+ const MAX_HEADER_LEN : u8 = 60 ;
36
36
37
37
const OPTION_KIND_EOL : u8 = 0x00 ;
38
38
const OPTION_KIND_NOP : u8 = 0x01 ;
@@ -127,18 +127,18 @@ impl<'a, T: NetworkBytes + Debug> TcpSegment<'a, T> {
127
127
/// Returns the header length, the value of the reserved bits, and whether the `NS` flag
128
128
/// is set or not.
129
129
#[ inline]
130
- pub fn header_len_rsvd_ns ( & self ) -> ( usize , u8 , bool ) {
130
+ pub fn header_len_rsvd_ns ( & self ) -> ( u8 , u8 , bool ) {
131
131
let value = self . bytes [ DATAOFF_RSVD_NS_OFFSET ] ;
132
132
let data_offset = value >> 4 ;
133
- let header_len = data_offset as usize * 4 ;
133
+ let header_len = data_offset * 4 ;
134
134
let rsvd = value & 0x0e ;
135
135
let ns = ( value & 1 ) != 0 ;
136
136
( header_len, rsvd, ns)
137
137
}
138
138
139
139
/// Returns the length of the header.
140
140
#[ inline]
141
- pub fn header_len ( & self ) -> usize {
141
+ pub fn header_len ( & self ) -> u8 {
142
142
self . header_len_rsvd_ns ( ) . 0
143
143
}
144
144
@@ -174,7 +174,7 @@ impl<'a, T: NetworkBytes + Debug> TcpSegment<'a, T> {
174
174
/// This method may panic if the value of `header_len` is invalid.
175
175
#[ inline]
176
176
pub fn options_unchecked ( & self , header_len : usize ) -> & [ u8 ] {
177
- & self . bytes [ OPTIONS_OFFSET ..header_len]
177
+ & self . bytes [ usize :: from ( OPTIONS_OFFSET ) ..header_len]
178
178
}
179
179
180
180
/// Returns a slice which contains the payload of the segment. May panic if the value of
@@ -190,20 +190,23 @@ impl<'a, T: NetworkBytes + Debug> TcpSegment<'a, T> {
190
190
191
191
/// Returns the length of the segment.
192
192
#[ inline]
193
- pub fn len ( & self ) -> usize {
194
- self . bytes . len ( )
193
+ pub fn len ( & self ) -> u16 {
194
+ // NOTE: This appears to be a safe conversion in all current cases.
195
+ // Packets are always set up in the context of an Ipv4Packet, which is
196
+ // capped at a u16 size. However, I'd rather be safe here.
197
+ u16:: try_from ( self . bytes . len ( ) ) . unwrap_or ( u16:: MAX )
195
198
}
196
199
197
200
/// Returns a slice which contains the payload of the segment.
198
201
#[ inline]
199
202
pub fn payload ( & self ) -> & [ u8 ] {
200
- self . payload_unchecked ( self . header_len ( ) )
203
+ self . payload_unchecked ( self . header_len ( ) . into ( ) )
201
204
}
202
205
203
206
/// Returns the length of the payload.
204
207
#[ inline]
205
- pub fn payload_len ( & self ) -> usize {
206
- self . len ( ) - self . header_len ( )
208
+ pub fn payload_len ( & self ) -> u16 {
209
+ self . len ( ) - u16 :: from ( self . header_len ( ) )
207
210
}
208
211
209
212
/// Computes the TCP checksum of the segment. More details about TCP checksum computation can
@@ -285,7 +288,7 @@ impl<'a, T: NetworkBytes + Debug> TcpSegment<'a, T> {
285
288
bytes : T ,
286
289
verify_checksum : Option < ( Ipv4Addr , Ipv4Addr ) > ,
287
290
) -> Result < Self , Error > {
288
- if bytes. len ( ) < OPTIONS_OFFSET {
291
+ if bytes. len ( ) < usize :: from ( OPTIONS_OFFSET ) {
289
292
return Err ( Error :: SliceTooShort ) ;
290
293
}
291
294
@@ -295,7 +298,9 @@ impl<'a, T: NetworkBytes + Debug> TcpSegment<'a, T> {
295
298
296
299
let header_len = segment. header_len ( ) ;
297
300
298
- if header_len < OPTIONS_OFFSET || header_len > min ( MAX_HEADER_LEN , segment. len ( ) ) {
301
+ if header_len < OPTIONS_OFFSET
302
+ || u16:: from ( header_len) > min ( u16:: from ( MAX_HEADER_LEN ) , segment. len ( ) )
303
+ {
299
304
return Err ( Error :: HeaderLen ) ;
300
305
}
301
306
@@ -342,8 +347,8 @@ impl<'a, T: NetworkBytesMut + Debug> TcpSegment<'a, T> {
342
347
/// of 4), clears the reserved bits, and sets the `NS` flag according to the last parameter.
343
348
// TODO: Check that header_len | 0b11 == 0 and the resulting data_offset is valid?
344
349
#[ inline]
345
- pub fn set_header_len_rsvd_ns ( & mut self , header_len : usize , ns : bool ) -> & mut Self {
346
- let mut value = ( header_len as u8 ) << 2 ;
350
+ pub fn set_header_len_rsvd_ns ( & mut self , header_len : u8 , ns : bool ) -> & mut Self {
351
+ let mut value = header_len << 2 ;
347
352
if ns {
348
353
value |= 1 ;
349
354
}
@@ -393,7 +398,7 @@ impl<'a, T: NetworkBytesMut + Debug> TcpSegment<'a, T> {
393
398
#[ inline]
394
399
pub fn payload_mut ( & mut self ) -> & mut [ u8 ] {
395
400
let header_len = self . header_len ( ) ;
396
- self . payload_mut_unchecked ( header_len)
401
+ self . payload_mut_unchecked ( header_len. into ( ) )
397
402
}
398
403
399
404
/// Writes a complete TCP segment.
@@ -479,24 +484,24 @@ impl<'a, T: NetworkBytesMut + Debug> TcpSegment<'a, T> {
479
484
mss_remaining : u16 ,
480
485
payload : Option < ( & R , usize ) > ,
481
486
) -> Result < Incomplete < Self > , Error > {
482
- let mut mss_left = mss_remaining as usize ;
487
+ let mut mss_left = mss_remaining;
483
488
484
489
// We're going to need at least this many bytes.
485
- let mut segment_len = OPTIONS_OFFSET ;
490
+ let mut segment_len = u16 :: from ( OPTIONS_OFFSET ) ;
486
491
487
492
// The TCP options will require this much more bytes.
488
493
let options_len = if mss_option. is_some ( ) {
489
494
mss_left = mss_left
490
495
. checked_sub ( OPTION_LEN_MSS . into ( ) )
491
496
. ok_or ( Error :: MssRemaining ) ?;
492
- usize :: from ( OPTION_LEN_MSS )
497
+ OPTION_LEN_MSS
493
498
} else {
494
499
0
495
500
} ;
496
501
497
- segment_len += options_len;
502
+ segment_len += u16 :: from ( options_len) ;
498
503
499
- if buf. len ( ) < segment_len {
504
+ if buf. len ( ) < usize :: from ( segment_len) {
500
505
return Err ( Error :: SliceTooShort ) ;
501
506
}
502
507
@@ -513,9 +518,11 @@ impl<'a, T: NetworkBytesMut + Debug> TcpSegment<'a, T> {
513
518
514
519
// Let's write the MSS option if we have to.
515
520
if let Some ( value) = mss_option {
516
- segment. bytes [ OPTIONS_OFFSET ] = OPTION_KIND_MSS ;
517
- segment. bytes [ OPTIONS_OFFSET + 1 ] = OPTION_LEN_MSS ;
518
- segment. bytes . htons_unchecked ( OPTIONS_OFFSET + 2 , value) ;
521
+ segment. bytes [ usize:: from ( OPTIONS_OFFSET ) ] = OPTION_KIND_MSS ;
522
+ segment. bytes [ usize:: from ( OPTIONS_OFFSET ) + 1 ] = OPTION_LEN_MSS ;
523
+ segment
524
+ . bytes
525
+ . htons_unchecked ( usize:: from ( OPTIONS_OFFSET ) + 2 , value) ;
519
526
}
520
527
521
528
let payload_bytes_count = if let Some ( ( payload_buf, max_payload_bytes) ) = payload {
@@ -524,7 +531,9 @@ impl<'a, T: NetworkBytesMut + Debug> TcpSegment<'a, T> {
524
531
// The subtraction makes sense because we previously checked that
525
532
// buf.len() >= segment_len.
526
533
let mut room_for_payload = min ( segment. len ( ) - segment_len, mss_left) ;
527
- room_for_payload = min ( room_for_payload, left_to_read) ;
534
+ // The unwrap is safe because room_for_payload is a u16.
535
+ room_for_payload =
536
+ u16:: try_from ( min ( usize:: from ( room_for_payload) , left_to_read) ) . unwrap ( ) ;
528
537
529
538
if room_for_payload == 0 {
530
539
return Err ( Error :: EmptyPayload ) ;
@@ -535,7 +544,8 @@ impl<'a, T: NetworkBytesMut + Debug> TcpSegment<'a, T> {
535
544
// `offset + room_for_payload <= payload_buf.len()`.
536
545
payload_buf. read_to_slice (
537
546
0 ,
538
- & mut segment. bytes [ segment_len..segment_len + room_for_payload] ,
547
+ & mut segment. bytes
548
+ [ usize:: from ( segment_len) ..usize:: from ( segment_len + room_for_payload) ] ,
539
549
) ;
540
550
room_for_payload
541
551
} else {
@@ -544,7 +554,7 @@ impl<'a, T: NetworkBytesMut + Debug> TcpSegment<'a, T> {
544
554
segment_len += payload_bytes_count;
545
555
546
556
// This is ok because segment_len <= buf.len().
547
- segment. bytes . shrink_unchecked ( segment_len) ;
557
+ segment. bytes . shrink_unchecked ( segment_len. into ( ) ) ;
548
558
549
559
// Shrink the resulting segment to a slice of exact size, so using self.len() makes sense.
550
560
Ok ( Incomplete :: new ( segment) )
0 commit comments