1 #include <sys/types.h>
2 #include <sys/param.h>
3 #include <sys/socket.h>
4 #include <netinet/in.h>
5 #include "byte.h"
6 #include "socket.h"
7 #include "ip6.h"
8 #include "haveip6.h"
9 #include "error.h"
10
socket_recv6(int s,char * buf,unsigned int len,char ip[16],uint16 * port,uint32 * scope_id)11 int socket_recv6(int s,char *buf,unsigned int len,char ip[16],uint16 *port,uint32 *scope_id)
12 {
13 #ifdef LIBC_HAS_IP6
14 struct sockaddr_in6 sa;
15 #else
16 struct sockaddr_in sa;
17 #endif
18 unsigned int dummy = sizeof sa;
19 int r;
20
21 byte_zero(&sa,dummy);
22 r = recvfrom(s,buf,len,0,(struct sockaddr *) &sa,&dummy);
23 if (r == -1) return -1;
24
25 #ifdef LIBC_HAS_IP6
26 if (noipv6) {
27 struct sockaddr_in *sa4=(struct sockaddr_in *)&sa;
28 byte_copy(ip,12,V4mappedprefix);
29 byte_copy(ip+12,4,(char *) &sa4->sin_addr);
30 uint16_unpack_big((char *) &sa4->sin_port,port);
31 return r;
32 }
33 byte_copy(ip,16,(char *) &sa.sin6_addr);
34 uint16_unpack_big((char *) &sa.sin6_port,port);
35 if (scope_id) *scope_id=sa.sin6_scope_id;
36 #else
37 byte_copy(ip,12,(char *)V4mappedprefix);
38 byte_copy(ip+12,4,(char *) &sa.sin_addr);
39 uint16_unpack_big((char *) &sa.sin_port,port);
40 if (scope_id) *scope_id=0;
41 #endif
42
43 return r;
44 }
45