Skip to content

Commit

Permalink
More networking trampolines.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Feb 9, 2013
1 parent e224968 commit 7e7ad8f
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 5 deletions.
77 changes: 77 additions & 0 deletions macelf/mactrampolines.c
Expand Up @@ -2139,6 +2139,83 @@ static int mactrampoline_getsockopt(int fd, int level, int option, void *value,
} // mactrampoline_getsockopt


typedef enum
{
LINUX_MSG_OOB=0x01,
LINUX_MSG_PEEK=0x02,
LINUX_MSG_DONTROUTE=0x04,
LINUX_MSG_CTRUNC=0x08,
LINUX_MSG_TRUNC=0x20,
LINUX_MSG_DONTWAIT=0x40,
LINUX_MSG_EOR=0x80,
LINUX_MSG_WAITALL=0x100,
} LinuxSendRecvFlags;

static int linux_sendrecvflags_to_mac(int lnxflags)
{
int macflags = 0;

#define CVTFLAG(fl) if (lnxflags & LINUX_##fl) { macflags |= fl; lnxflags &= ~fl; }
CVTFLAG(MSG_OOB);
CVTFLAG(MSG_PEEK);
CVTFLAG(MSG_DONTROUTE);
CVTFLAG(MSG_CTRUNC);
CVTFLAG(MSG_TRUNC);
CVTFLAG(MSG_DONTWAIT);
CVTFLAG(MSG_EOR);
CVTFLAG(MSG_WAITALL);
#undef CVTFLAG

if (lnxflags != 0)
{
STUBBED("unsupported flag");
errno = EINVAL;
return -1;
} // if

assert(macflags != -1);
return macflags;
} // linux_sendrecvflags_to_mac

static ssize_t mactrampoline_recv(int fd, void *buf, size_t buflen, int lnxflags)
{
const int macflags = linux_sendrecvflags_to_mac(lnxflags);
return (macflags == -1) ? -1 : recv(fd, buf, buflen, macflags);
} // mactrampoline_recv

static ssize_t mactrampoline_recvfrom(int fd, void *buf, size_t buflen, int lnxflags, void/*struct sockaddr*/ *addr, socklen_t *addrlen)
{
struct sockaddr_storage macaddr;
const int macflags = linux_sendrecvflags_to_mac(lnxflags);
if (macflags == -1)
return -1;
const int rc = recvfrom(fd, buf, buflen, macflags, (struct sockaddr *) &macaddr, addrlen);
if (rc != -1)
{
if (!mac_sockaddr_to_linux(addr, &macaddr))
return -1;
} // if
return rc;
} // mactrampoline_recvfrom

static ssize_t mactrampoline_send(int fd, const void *buf, size_t buflen, int lnxflags)
{
const int macflags = linux_sendrecvflags_to_mac(lnxflags);
return (macflags == -1) ? -1 : send(fd, buf, buflen, macflags);
} // mactrampoline_send

static ssize_t mactrampoline_sendto(int fd, const void *buf, size_t buflen, int lnxflags, const void/*struct sockaddr*/ *addr, socklen_t addrlen)
{
struct sockaddr_storage macaddr;
const int macflags = linux_sendrecvflags_to_mac(lnxflags);
if (macflags == -1)
return -1;
else if (!linux_sockaddr_to_mac(&macaddr, addr))
return -1;
return sendto(fd, buf, buflen, macflags, (struct sockaddr *) &macaddr, addrlen);
} // mactrampoline_sendto


// !!! FIXME: this should work like the native overrides, but honestly,
// !!! FIXME: who doesn't reference glibc?
int build_trampolines(void)
Expand Down
12 changes: 7 additions & 5 deletions macelf/mactrampolines.h
Expand Up @@ -290,7 +290,10 @@ MACTRAMPOLINE_OVERRIDE(gai_strerror)
MACTRAMPOLINE_OVERRIDE(getaddrinfo)
MACTRAMPOLINE_OVERRIDE(setsockopt)
MACTRAMPOLINE_OVERRIDE(getsockopt)

MACTRAMPOLINE_OVERRIDE(recv)
MACTRAMPOLINE_OVERRIDE(recvfrom)
MACTRAMPOLINE_OVERRIDE(send)
MACTRAMPOLINE_OVERRIDE(sendto)

// !!! FIXME: mode_t is 2 bytes on Mac OS X, but 4 on Linux.
//MACTRAMPOLINE(DBM*,dbm_open,(const char *a, int b, mode_t c),(a,b,c),return)
Expand Down Expand Up @@ -598,6 +601,9 @@ MACTRAMPOLINE(gid_t,getgid,(void),(),return)
//MACTRAMPOLINE(int,getgroups,(int a, gid_t b[]),(a,b),return)
MACTRAMPOLINE(long,gethostid,(void),(),return)
MACTRAMPOLINE(int,gethostname,(char *a, size_t b),(a,b),return)
MACTRAMPOLINE(int,sethostname,(const char *a, size_t b),(a,b),return)
MACTRAMPOLINE(int,getdomainname,(char *a, size_t b),(a,b),return)
MACTRAMPOLINE(int,setdomainname,(const char *a, size_t b),(a,b),return)
MACTRAMPOLINE(char*,getlogin,(void),(),return)
MACTRAMPOLINE(int,getlogin_r,(char *a, size_t b),(a,b),return)
MACTRAMPOLINE(int,getopt,(int a, char *const *b, const char *c),(a,b,c),return)
Expand Down Expand Up @@ -1085,12 +1091,8 @@ MACTRAMPOLINE(pid_t,wait,(int *a),(a),return)
//MACTRAMPOLINE(int,msgsnd,(int a, const void *b, size_t c, int d),(a,b,c,d),return)
//MACTRAMPOLINE(int,ftime,(struct timeb *a),(a),return)
MACTRAMPOLINE(int,listen,(int a, int b),(a,b),return)
//MACTRAMPOLINE(ssize_t,recv,(int a, void *b, size_t c, int d),(a,b,c,d),return)
//MACTRAMPOLINE(ssize_t,recvfrom,(int a, void *b, size_t c, int d, struct sockaddr *e, socklen_t *f),(a,b,c,d,e,f),return)
//MACTRAMPOLINE(ssize_t,recvmsg,(int a, struct msghdr *b, int c),(a,b,c),return)
//MACTRAMPOLINE(ssize_t,send,(int a, const void *b, size_t c, int d),(a,b,c,d),return)
//MACTRAMPOLINE(ssize_t,sendmsg,(int a, const struct msghdr *b, int c),(a,b,c),return)
//MACTRAMPOLINE(ssize_t,sendto,(int a, const void *b, size_t c, int d, const struct sockaddr *e, socklen_t f),(a,b,c,d,e,f),return)
MACTRAMPOLINE(int,shutdown,(int a, int b),(a,b),return)

// This doesn't match up exactly with Linux, but it does for the things people care about (AF_UNIX, AF_INET, etc).
Expand Down

0 comments on commit 7e7ad8f

Please sign in to comment.