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