1 /*
2 20131206
3 Jan Mojzis
4 Public domain.
5 */
6
7 #include <sys/types.h>
8 #include <sys/param.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <unistd.h>
12 #include "e.h"
13 #include "byte.h"
14 #include "hasipv6.h"
15 #include "xsocket.h"
16
xsocket_accept6(int s,unsigned char * ip,unsigned char * port,long long * id)17 static int xsocket_accept6(int s, unsigned char *ip, unsigned char *port, long long *id) {
18
19 #ifdef HASIPV6
20 struct sockaddr_in6 sa;
21 socklen_t salen = sizeof sa;
22 int fd;
23
24 byte_zero(&sa, sizeof sa);
25 fd = accept(s, (struct sockaddr *)&sa, &salen);
26 if (fd == -1) return -1;
27
28 if (((struct sockaddr *)&sa)->sa_family != PF_INET6) { close(fd); errno = EPROTO; return -1; }
29
30 if (ip) byte_copy(ip, 16, &sa.sin6_addr);
31 if (port) byte_copy(port, 2, &sa.sin6_port);
32 if (id) *id = sa.sin6_scope_id;
33 return fd;
34 #else
35 errno = EPROTONOSUPPORT;
36 return -1;
37 #endif
38
39 }
40
xsocket_accept4(int s,unsigned char * ip,unsigned char * port,long long * id)41 static int xsocket_accept4(int s, unsigned char *ip, unsigned char *port, long long *id) {
42
43 struct sockaddr_in sa;
44 socklen_t salen = sizeof sa;
45 int fd;
46
47 byte_zero(&sa, sizeof sa);
48 fd = accept(s, (struct sockaddr *)&sa, &salen);
49 if (fd == -1) return -1;
50
51 if (((struct sockaddr *)&sa)->sa_family != PF_INET) { close(fd); errno = EPROTO; return -1; }
52
53 if (ip) byte_copy(ip, 12, "\0\0\0\0\0\0\0\0\0\0\377\377");
54 if (ip) byte_copy(ip + 12, 4, &sa.sin_addr);
55 if (port) byte_copy(port, 2, &sa.sin_port);
56 if (id) *id = 0;
57 return fd;
58 }
59
xsocket_accept(int fd,int type,unsigned char * ip,unsigned char * port,long long * id)60 int xsocket_accept(int fd, int type, unsigned char *ip, unsigned char *port, long long *id) {
61
62 if (type == XSOCKET_V4) {
63 return xsocket_accept4(fd, ip, port, id);
64 }
65 if (type == XSOCKET_V6) {
66 return xsocket_accept6(fd, ip, port, id);
67 }
68 errno = EPROTO;
69 return -1;
70 }
71