@@ -9,6 +9,7 @@ use libc::{c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
9
9
use std:: { mem, ptr, slice} ;
10
10
use std:: os:: unix:: io:: RawFd ;
11
11
use sys:: uio:: IoVec ;
12
+ use sys:: time:: TimeVal ;
12
13
13
14
mod addr;
14
15
mod consts;
@@ -162,6 +163,10 @@ impl<'a> Iterator for CmsgIterator<'a> {
162
163
slice:: from_raw_parts (
163
164
& cmsg. cmsg_data as * const _ as * const _ , 1 ) ) )
164
165
} ,
166
+ ( SOL_SOCKET , SCM_TIMESTAMP ) => unsafe {
167
+ Some ( ControlMessage :: ScmTimestamp (
168
+ & * ( & cmsg. cmsg_data as * const _ as * const _ ) ) )
169
+ } ,
165
170
( _, _) => unsafe {
166
171
Some ( ControlMessage :: Unknown ( UnknownCmsg (
167
172
& cmsg,
@@ -182,6 +187,11 @@ pub enum ControlMessage<'a> {
182
187
/// "Ancillary messages" section of the
183
188
/// [unix(7) man page](http://man7.org/linux/man-pages/man7/unix.7.html).
184
189
ScmRights ( & ' a [ RawFd ] ) ,
190
+ /// A message of type SCM_TIMESTAMP, containing the time the packet
191
+ /// was received by the kernel. See the kernel's explanation in
192
+ /// "SO_TIMESTAMP" of
193
+ /// [networking/timestamping](https://www.kernel.org/doc/Documentation/networking/timestamping.txt).
194
+ ScmTimestamp ( & ' a TimeVal ) ,
185
195
#[ doc( hidden) ]
186
196
Unknown ( UnknownCmsg < ' a > ) ,
187
197
}
@@ -207,6 +217,9 @@ impl<'a> ControlMessage<'a> {
207
217
ControlMessage :: ScmRights ( fds) => {
208
218
mem:: size_of_val ( fds)
209
219
} ,
220
+ ControlMessage :: ScmTimestamp ( t) => {
221
+ mem:: size_of_val ( t)
222
+ } ,
210
223
ControlMessage :: Unknown ( UnknownCmsg ( _, bytes) ) => {
211
224
mem:: size_of_val ( bytes)
212
225
}
@@ -237,6 +250,25 @@ impl<'a> ControlMessage<'a> {
237
250
238
251
copy_bytes ( fds, buf) ;
239
252
} ,
253
+ ControlMessage :: ScmTimestamp ( t) => {
254
+ let cmsg = cmsghdr {
255
+ cmsg_len : self . len ( ) as type_of_cmsg_len ,
256
+ cmsg_level : SOL_SOCKET ,
257
+ cmsg_type : SCM_TIMESTAMP ,
258
+ cmsg_data : [ ] ,
259
+ } ;
260
+ copy_bytes ( & cmsg, buf) ;
261
+
262
+ let padlen = cmsg_align ( mem:: size_of_val ( & cmsg) ) -
263
+ mem:: size_of_val ( & cmsg) ;
264
+
265
+ let mut tmpbuf = & mut [ ] [ ..] ;
266
+ mem:: swap ( & mut tmpbuf, buf) ;
267
+ let ( _padding, mut remainder) = tmpbuf. split_at_mut ( padlen) ;
268
+ mem:: swap ( buf, & mut remainder) ;
269
+
270
+ copy_bytes ( t, buf) ;
271
+ } ,
240
272
ControlMessage :: Unknown ( UnknownCmsg ( orig_cmsg, bytes) ) => {
241
273
copy_bytes ( orig_cmsg, buf) ;
242
274
copy_bytes ( bytes, buf) ;
0 commit comments