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