szymonwieloch / rust-rawsock

Rust library for obtaining and sending raw network packets from interfaces.
MIT License
68 stars 14 forks source link

different struct timeval on macOS #5

Closed spacemeowx2 closed 5 years ago

spacemeowx2 commented 5 years ago

tv_usec is 64bit unsigned integer.

https://github.com/szymonwieloch/rust-rawsock/blob/88801a29cc81ad6b00d4bbbaa0b5934710572884/src/pcap_common/structs.rs#L73

But on macOS, tv_usec is 32bit unsigned integer with 32bit padding:

/usr/include/sys/_types/_timeval.h

#ifndef _STRUCT_TIMEVAL
#define _STRUCT_TIMEVAL     struct timeval

#include <machine/types.h> /* __darwin_time_t */
#include <sys/_types.h> /* __darwin_suseconds_t */

_STRUCT_TIMEVAL
{
    __darwin_time_t         tv_sec;         /* seconds */
    __darwin_suseconds_t    tv_usec;        /* and microseconds */
};
#endif /* _STRUCT_TIMEVAL */

/usr/include/sys/_types.h

typedef __int32_t   __darwin_suseconds_t;   /* [???] microseconds */

And using ida to see how the struct looks like:

00000000 timeval         struc ; (sizeof=0x10, align=0x8, copyof_63)
00000000                                         ; XREF: _uv__fs_futime/r
00000000                                         ; _uv__fs_utime/r ...
00000000 tv_sec          dq ?                    ; XREF: _uv_getrusage:loc_1001258B9/r
00000000                                         ; _uv_getrusage+56/r ...
00000008 tv_usec         dd ?                    ; XREF: _uv_getrusage+47/r
00000008                                         ; _uv_getrusage+65/r ...
0000000C                 db ? ; undefined
0000000D                 db ? ; undefined
0000000E                 db ? ; undefined
0000000F                 db ? ; undefined
00000010 timeval         ends

With this declaration, rawsock works fine on my machine.

///Equivalent of C struct timeval_t
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct TimeVal {
    pub tv_sec: c_long,         /* seconds */
    pub tv_usec: c_uint        /* and microseconds */
}
szymonwieloch commented 5 years ago

@spacemeowx2 I use libc::timeval now, it should be totally portable.