1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
/*
20131117
Jan Mojzis
Public domain.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "e.h"
#include "byte.h"
#include "xsocket.h"
static long long xsocket_send6(int fd, const unsigned char *x, long long xlen, const unsigned char *ip, const unsigned char *port, long long id) {
#ifdef HASIPV6
struct sockaddr_in6 sa;
if (byte_isequal("\0\0\0\0\0\0\0\0\0\0\377\377", 12, ip)) { errno = EPROTO; return -1; }
byte_zero(&sa, sizeof sa);
sa.sin6_family = PF_INET6;
byte_copy(&sa.sin6_addr, 16, ip);
byte_copy(&sa.sin6_port, 2, port);
sa.sin6_scope_id = id;
return sendto(fd, x, xlen, 0, (struct sockaddr *)&sa, sizeof sa);
#else
errno = EPROTONOSUPPORT;
return -1;
#endif
}
static long long xsocket_send4(int fd, const unsigned char *x, long long xlen, const unsigned char *ip, const unsigned char *port, long long id) {
struct sockaddr_in sa;
if (!byte_isequal("\0\0\0\0\0\0\0\0\0\0\377\377", 12, ip)) { errno = EPROTO; return -1; }
byte_zero(&sa, sizeof sa);
sa.sin_family = PF_INET;
byte_copy(&sa.sin_addr, 4, ip + 12);
byte_copy(&sa.sin_port, 2, port);
return sendto(fd, x, xlen, 0, (struct sockaddr *)&sa, sizeof sa);
}
long long xsocket_send(int fd, int type, const unsigned char *x, long long xlen, const unsigned char *ip, const unsigned char *port, long long id) {
if (xlen < 0 || xlen > 1048576) { errno = EPROTO; return -1; }
if (type == XSOCKET_V4) {
return xsocket_send4(fd, x, xlen, ip, port, id);
}
if (type == XSOCKET_V6) {
return xsocket_send6(fd, x, xlen, ip, port, id);
}
errno = EPROTO;
return -1;
}
|