diff --git a/CHANGES b/CHANGES index f3f554a..577639f 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,7 @@ fix typo breaking fmt_long for dest==NULL add fmt_*longlong() add range check to scan_ulong, scan_ulonglong + extended socket API; you can now pass NULL for results you don't want 0.14: avoid bus errors in byte_copy diff --git a/socket.h b/socket.h index 7c9c429..1de1127 100644 --- a/socket.h +++ b/socket.h @@ -12,33 +12,33 @@ extern int socket_udp6(void); #define socket_tcp() socket_tcp4() #define socket_udp() socket_udp4() -extern int socket_connect4(int s,const char *ip,uint16 port); -extern int socket_connect6(int s,const char *ip,uint16 port,uint32 scope_id); +extern int socket_connect4(int s,const char* ip,uint16 port); +extern int socket_connect6(int s,const char* ip,uint16 port,uint32 scope_id); extern int socket_connected(int s); -extern int socket_bind4(int s,const char *ip,uint16 port); -extern int socket_bind4_reuse(int s,const char *ip,uint16 port); -extern int socket_bind6(int s,const char *ip,uint16 port,uint32 scope_id); -extern int socket_bind6_reuse(int s,const char *ip,uint16 port,uint32 scope_id); +extern int socket_bind4(int s,const char* ip,uint16 port); +extern int socket_bind4_reuse(int s,const char* ip,uint16 port); +extern int socket_bind6(int s,const char* ip,uint16 port,uint32 scope_id); +extern int socket_bind6_reuse(int s,const char* ip,uint16 port,uint32 scope_id); extern int socket_listen(int s,unsigned int backlog); -extern int socket_accept4(int s,char *ip,uint16 *port); -extern int socket_accept6(int s,char *ip,uint16 *port,uint32 *scope_id); -extern int socket_recv4(int s,char *buf,unsigned int len,char *ip,uint16 *port); -extern int socket_recv6(int s,char *buf,unsigned int len,char *ip,uint16 *port,uint32 *scope_id); -extern int socket_send4(int s,const char *buf,unsigned int len,const char *ip,uint16 port); -extern int socket_send6(int s,const char *buf,unsigned int len,const char *ip,uint16 port,uint32 scope_id); -extern int socket_local4(int s,char *ip,uint16 *port); -extern int socket_local6(int s,char *ip,uint16 *port,uint32 *scope_id); -extern int socket_remote4(int s,char *ip,uint16 *port); -extern int socket_remote6(int s,char *ip,uint16 *port,uint32 *scope_id); +extern int socket_accept4(int s,char* ip,uint16* port); +extern int socket_accept6(int s,char* ip,uint16* port,uint32* scope_id); +extern int socket_recv4(int s,char* buf,unsigned int len,char* ip,uint16* port); +extern int socket_recv6(int s,char* buf,unsigned int len,char* ip,uint16* port,uint32* scope_id); +extern int socket_send4(int s,const char* buf,unsigned int len,const char* ip,uint16 port); +extern int socket_send6(int s,const char* buf,unsigned int len,const char* ip,uint16 port,uint32 scope_id); +extern int socket_local4(int s,char* ip,uint16* port); +extern int socket_local6(int s,char* ip,uint16* port,uint32* scope_id); +extern int socket_remote4(int s,char* ip,uint16* port); +extern int socket_remote6(int s,char* ip,uint16* port,uint32* scope_id); /* enable sending udp packets to the broadcast address */ extern int socket_broadcast(int s); /* join a multicast group on the given interface */ -extern int socket_mcjoin4(int s,const char *groupip,const char *interface); -extern int socket_mcjoin6(int s,const char *groupip,int interface); +extern int socket_mcjoin4(int s,const char* groupip,const char* interface); +extern int socket_mcjoin6(int s,const char* groupip,int interface); /* leave a multicast group on the given interface */ -extern int socket_mcleave4(int s,const char *groupip); -extern int socket_mcleave6(int s,const char *groupip); +extern int socket_mcleave4(int s,const char* groupip); +extern int socket_mcleave6(int s,const char* groupip); /* set multicast TTL/hop count for outgoing packets */ extern int socket_mcttl4(int s,char hops); extern int socket_mchopcount6(int s,char hops); @@ -49,7 +49,7 @@ extern int socket_mcloop6(int s,char hops); extern void socket_tryreservein(int s,int size); extern const char* socket_getifname(uint32 interface); -extern uint32 socket_getifidx(const char *ifname); +extern uint32 socket_getifidx(const char* ifname); extern int socket_sendfile(int out,int in,uint32 offset,uint32 bytes); diff --git a/socket/socket_accept6.c b/socket/socket_accept6.c index e4bd1e0..2ff1627 100644 --- a/socket/socket_accept6.c +++ b/socket/socket_accept6.c @@ -8,7 +8,7 @@ #include "haveip6.h" #include "havesl.h" -int socket_accept6(int s,char ip[16],uint16 *port,uint32 *scope_id) +int socket_accept6(int s,char* ip,uint16* port,uint32* scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 sa; @@ -24,20 +24,24 @@ int socket_accept6(int s,char ip[16],uint16 *port,uint32 *scope_id) #ifdef LIBC_HAS_IP6 if (sa.sin6_family==AF_INET) { struct sockaddr_in *sa4=(struct sockaddr_in*)&sa; - byte_copy(ip,12,V4mappedprefix); - byte_copy(ip+12,4,(char *) &sa4->sin_addr); - uint16_unpack_big((char *) &sa4->sin_port,port); + if (ip) { + byte_copy(ip,12,V4mappedprefix); + byte_copy(ip+12,4,(char *) &sa4->sin_addr); + } + if (port) uint16_unpack_big((char *) &sa4->sin_port,port); return fd; } - byte_copy(ip,16,(char *) &sa.sin6_addr); - uint16_unpack_big((char *) &sa.sin6_port,port); + if (ip) byte_copy(ip,16,(char *) &sa.sin6_addr); + if (port) uint16_unpack_big((char *) &sa.sin6_port,port); if (scope_id) *scope_id=sa.sin6_scope_id; return fd; #else - byte_copy(ip,12,V4mappedprefix); - byte_copy(ip+12,4,(char *) &sa.sin_addr); - uint16_unpack_big((char *) &sa.sin_port,port); + if (ip) { + byte_copy(ip,12,V4mappedprefix); + byte_copy(ip+12,4,(char *) &sa.sin_addr); + } + if (port) uint16_unpack_big((char *) &sa.sin_port,port); if (scope_id) *scope_id=0; return fd; #endif diff --git a/socket/socket_bind4.c b/socket/socket_bind4.c index 3f43e49..566dbc2 100644 --- a/socket/socket_bind4.c +++ b/socket/socket_bind4.c @@ -11,6 +11,9 @@ int socket_bind4(int s,const char *ip,uint16 port) { byte_zero(&si,sizeof si); si.sin_family = AF_INET; uint16_pack_big((char*) &si.sin_port,port); - *(uint32*)&si.sin_addr = *(uint32*)ip; + if (ip) + *(uint32*)&si.sin_addr = *(uint32*)ip; + else + si.sin_addr.s_addr=INADDR_ANY; return bind(s,(struct sockaddr*)&si,sizeof si); } diff --git a/socket/socket_bind6.c b/socket/socket_bind6.c index fd02c4a..4cadfac 100644 --- a/socket/socket_bind6.c +++ b/socket/socket_bind6.c @@ -11,7 +11,11 @@ int socket_bind6(int s,const char ip[16],uint16 port,uint32 scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 sa; +#endif + + if (!ip) ip=V6any; +#ifdef LIBC_HAS_IP6 if (noipv6) { #endif int i; diff --git a/socket/socket_local4.c b/socket/socket_local4.c index e36cfcb..52db123 100644 --- a/socket/socket_local4.c +++ b/socket/socket_local4.c @@ -12,8 +12,8 @@ int socket_local4(int s,char ip[4],uint16 *port) socklen_t len = sizeof si; if (getsockname(s,(struct sockaddr *) &si,&len) == -1) return -1; - *(uint32*)ip = *(uint32*)&si.sin_addr; - uint16_unpack_big((char *) &si.sin_port,port); + if (ip) *(uint32*)ip = *(uint32*)&si.sin_addr; + if (port) uint16_unpack_big((char *) &si.sin_port,port); return 0; } diff --git a/socket/socket_local6.c b/socket/socket_local6.c index 1a72477..37689b1 100644 --- a/socket/socket_local6.c +++ b/socket/socket_local6.c @@ -22,18 +22,22 @@ int socket_local6(int s,char ip[16],uint16 *port,uint32 *scope_id) #ifdef LIBC_HAS_IP6 if (si.sin6_family==AF_INET) { struct sockaddr_in *si4=(struct sockaddr_in*)&si; - byte_copy(ip,12,V4mappedprefix); - byte_copy(ip+12,4,(char *) &si4->sin_addr); - uint16_unpack_big((char *) &si4->sin_port,port); + if (ip) { + byte_copy(ip,12,V4mappedprefix); + byte_copy(ip+12,4,(char *) &si4->sin_addr); + } + if (port) uint16_unpack_big((char *) &si4->sin_port,port); return 0; } - byte_copy(ip,16,(char *) &si.sin6_addr); - uint16_unpack_big((char *) &si.sin6_port,port); + if (ip) byte_copy(ip,16,(char *) &si.sin6_addr); + if (port) uint16_unpack_big((char *) &si.sin6_port,port); if (scope_id) *scope_id=si.sin6_scope_id; #else - byte_copy(ip,12,V4mappedprefix); - byte_copy(ip+12,4,(char *) &si.sin_addr); - uint16_unpack_big((char *) &si.sin_port,port); + if (ip) { + byte_copy(ip,12,V4mappedprefix); + byte_copy(ip+12,4,(char *) &si.sin_addr); + } + if (port) uint16_unpack_big((char *) &si.sin_port,port); if (scope_id) *scope_id=0; #endif return 0; diff --git a/socket/socket_recv4.c b/socket/socket_recv4.c index 61b45d7..f48f640 100644 --- a/socket/socket_recv4.c +++ b/socket/socket_recv4.c @@ -11,7 +11,7 @@ int socket_recv4(int s,char *buf,unsigned int len,char ip[4],uint16 *port) { int r; if ((r = recvfrom(s,buf,len,0,(struct sockaddr *) &si,&Len))<0) return -1; - *(uint32*)ip = *(uint32*)&si.sin_addr; - uint16_unpack_big((char *) &si.sin_port,port); + if (ip) *(uint32*)ip = *(uint32*)&si.sin_addr; + if (port) uint16_unpack_big((char *) &si.sin_port,port); return r; } diff --git a/socket/socket_recv6.c b/socket/socket_recv6.c index 7372246..b04acc2 100644 --- a/socket/socket_recv6.c +++ b/socket/socket_recv6.c @@ -24,18 +24,22 @@ int socket_recv6(int s,char *buf,unsigned int len,char ip[16],uint16 *port,uint3 #ifdef LIBC_HAS_IP6 if (noipv6) { struct sockaddr_in *si4=(struct sockaddr_in *)&si; - byte_copy(ip,12,V4mappedprefix); - byte_copy(ip+12,4,(char *) &si4->sin_addr); - uint16_unpack_big((char *) &si4->sin_port,port); + if (ip) { + byte_copy(ip,12,V4mappedprefix); + byte_copy(ip+12,4,(char *) &si4->sin_addr); + } + if (port) uint16_unpack_big((char *) &si4->sin_port,port); return r; } - byte_copy(ip,16,(char *) &si.sin6_addr); - uint16_unpack_big((char *) &si.sin6_port,port); + if (ip) byte_copy(ip,16,(char *) &si.sin6_addr); + if (port) uint16_unpack_big((char *) &si.sin6_port,port); if (scope_id) *scope_id=si.sin6_scope_id; #else - byte_copy(ip,12,(char *)V4mappedprefix); - byte_copy(ip+12,4,(char *) &si.sin_addr); - uint16_unpack_big((char *) &si.sin_port,port); + if (ip) { + byte_copy(ip,12,(char *)V4mappedprefix); + byte_copy(ip+12,4,(char *) &si.sin_addr); + } + if (port) uint16_unpack_big((char *) &si.sin_port,port); if (scope_id) *scope_id=0; #endif diff --git a/socket/socket_remote4.c b/socket/socket_remote4.c index d8be55b..4ab4028 100644 --- a/socket/socket_remote4.c +++ b/socket/socket_remote4.c @@ -12,8 +12,8 @@ int socket_remote4(int s,char ip[4],uint16 *port) socklen_t len = sizeof si; if (getpeername(s,(struct sockaddr *) &si,&len) == -1) return -1; - *(uint32*)ip = *(uint32*)&si.sin_addr; - uint16_unpack_big((char *) &si.sin_port,port); + if (ip) *(uint32*)ip = *(uint32*)&si.sin_addr; + if (port) uint16_unpack_big((char *) &si.sin_port,port); return 0; } diff --git a/socket/socket_remote6.c b/socket/socket_remote6.c index 5b0e514..0f3f4a7 100644 --- a/socket/socket_remote6.c +++ b/socket/socket_remote6.c @@ -22,18 +22,22 @@ int socket_remote6(int s,char ip[16],uint16 *port,uint32 *scope_id) #ifdef LIBC_HAS_IP6 if (si.sin6_family==AF_INET) { struct sockaddr_in *si4=(struct sockaddr_in*)&si; - byte_copy(ip,12,V4mappedprefix); - byte_copy(ip+12,4,(char *) &si4->sin_addr); - uint16_unpack_big((char *) &si4->sin_port,port); + if (ip) { + byte_copy(ip,12,V4mappedprefix); + byte_copy(ip+12,4,(char *) &si4->sin_addr); + } + if (port) uint16_unpack_big((char *) &si4->sin_port,port); return 0; } - byte_copy(ip,16,(char *) &si.sin6_addr); - uint16_unpack_big((char *) &si.sin6_port,port); + if (ip) byte_copy(ip,16,(char *) &si.sin6_addr); + if (port) uint16_unpack_big((char *) &si.sin6_port,port); if (scope_id) *scope_id=si.sin6_scope_id; #else - byte_copy(ip,12,V4mappedprefix); - byte_copy(ip+12,4,(char *) &si.sin_addr); - uint16_unpack_big((char *) &si.sin_port,port); + if (ip) { + byte_copy(ip,12,V4mappedprefix); + byte_copy(ip+12,4,(char *) &si.sin_addr); + } + if (port) uint16_unpack_big((char *) &si.sin_port,port); if (scope_id) *scope_id=0; #endif return 0;