|
@@ -67,15 +67,15 @@ struct Cjdns_in6_ifreq
|
|
|
* @param ifRequestOut an ifreq which will be populated with the interface index of the interface.
|
|
|
* @return a socket for interacting with this interface.
|
|
|
*/
|
|
|
-static int socketForIfName(const char* interfaceName,
|
|
|
+static Er_DEFUN(int socketForIfName(const char* interfaceName,
|
|
|
int af,
|
|
|
- struct Except* eh,
|
|
|
- struct ifreq* ifRequestOut)
|
|
|
+ struct Allocator* alloc,
|
|
|
+ struct ifreq* ifRequestOut))
|
|
|
{
|
|
|
int s;
|
|
|
|
|
|
if ((s = socket(af, SOCK_DGRAM, 0)) < 0) {
|
|
|
- Except_throw(eh, "socket() [%s]", strerror(errno));
|
|
|
+ Er_raise(alloc, "socket() [%s]", strerror(errno));
|
|
|
}
|
|
|
|
|
|
memset(ifRequestOut, 0, sizeof(struct ifreq));
|
|
@@ -84,34 +84,34 @@ static int socketForIfName(const char* interfaceName,
|
|
|
if (ioctl(s, SIOCGIFINDEX, ifRequestOut) < 0) {
|
|
|
int err = errno;
|
|
|
close(s);
|
|
|
- Except_throw(eh, "ioctl(SIOCGIFINDEX) [%s]", strerror(err));
|
|
|
+ Er_raise(alloc, "ioctl(SIOCGIFINDEX) [%s]", strerror(err));
|
|
|
}
|
|
|
- return s;
|
|
|
+ Er_ret(s);
|
|
|
}
|
|
|
|
|
|
/** don't use if_nametoindex() because it accesses the filesystem. */
|
|
|
-static int ifIndexForName(const char* interfaceName, struct Except* eh)
|
|
|
+static Er_DEFUN(int ifIndexForName(const char* interfaceName, struct Allocator* alloc))
|
|
|
{
|
|
|
struct ifreq ifRequest;
|
|
|
- int s = socketForIfName(interfaceName, AF_INET, eh, &ifRequest);
|
|
|
+ int s = Er(socketForIfName(interfaceName, AF_INET, alloc, &ifRequest));
|
|
|
close(s);
|
|
|
- return ifRequest.ifr_ifindex;
|
|
|
+ Er_ret(ifRequest.ifr_ifindex);
|
|
|
}
|
|
|
|
|
|
-static void checkInterfaceUp(int socket,
|
|
|
+static Er_DEFUN(void checkInterfaceUp(int socket,
|
|
|
struct ifreq* ifRequest,
|
|
|
struct Log* logger,
|
|
|
- struct Except* eh)
|
|
|
+ struct Allocator* alloc))
|
|
|
{
|
|
|
if (ioctl(socket, SIOCGIFFLAGS, ifRequest) < 0) {
|
|
|
int err = errno;
|
|
|
close(socket);
|
|
|
- Except_throw(eh, "ioctl(SIOCGIFFLAGS) [%s]", strerror(err));
|
|
|
+ Er_raise(alloc, "ioctl(SIOCGIFFLAGS) [%s]", strerror(err));
|
|
|
}
|
|
|
|
|
|
if (ifRequest->ifr_flags & IFF_UP & IFF_RUNNING) {
|
|
|
// already up.
|
|
|
- return;
|
|
|
+ Er_ret();
|
|
|
}
|
|
|
|
|
|
Log_info(logger, "Bringing up interface [%s]", ifRequest->ifr_name);
|
|
@@ -120,24 +120,24 @@ static void checkInterfaceUp(int socket,
|
|
|
if (ioctl(socket, SIOCSIFFLAGS, ifRequest) < 0) {
|
|
|
int err = errno;
|
|
|
close(socket);
|
|
|
- Except_throw(eh, "ioctl(SIOCSIFFLAGS) [%s]", strerror(err));
|
|
|
+ Er_raise(alloc, "ioctl(SIOCSIFFLAGS) [%s]", strerror(err));
|
|
|
}
|
|
|
+ Er_ret();
|
|
|
}
|
|
|
|
|
|
-void NetPlatform_addAddress(const char* interfaceName,
|
|
|
+Er_DEFUN(void NetPlatform_addAddress(const char* interfaceName,
|
|
|
const uint8_t* address,
|
|
|
int prefixLen,
|
|
|
int addrFam,
|
|
|
struct Log* logger,
|
|
|
- struct Allocator* tempAlloc,
|
|
|
- struct Except* eh)
|
|
|
+ struct Allocator* tempAlloc))
|
|
|
{
|
|
|
struct ifreq ifRequest;
|
|
|
- int s = socketForIfName(interfaceName, addrFam, eh, &ifRequest);
|
|
|
+ int s = Er(socketForIfName(interfaceName, addrFam, tempAlloc, &ifRequest));
|
|
|
int ifIndex = ifRequest.ifr_ifindex;
|
|
|
|
|
|
// checkInterfaceUp() clobbers the ifindex.
|
|
|
- checkInterfaceUp(s, &ifRequest, logger, eh);
|
|
|
+ Er(checkInterfaceUp(s, &ifRequest, logger, tempAlloc));
|
|
|
|
|
|
if (addrFam == Sockaddr_AF_INET6) {
|
|
|
struct Cjdns_in6_ifreq ifr6 = {
|
|
@@ -150,9 +150,9 @@ void NetPlatform_addAddress(const char* interfaceName,
|
|
|
int err = errno;
|
|
|
close(s);
|
|
|
if (err == EPERM) {
|
|
|
- Except_throw(eh, "ioctl permission denied, Are you root and is ipv6 enabled?");
|
|
|
+ Er_raise(tempAlloc, "ioctl permission denied, Are you root and is ipv6 enabled?");
|
|
|
} else {
|
|
|
- Except_throw(eh, "ioctl(SIOCSIFADDR) failed: [%s]", strerror(err));
|
|
|
+ Er_raise(tempAlloc, "ioctl(SIOCSIFADDR) failed: [%s]", strerror(err));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -165,7 +165,7 @@ void NetPlatform_addAddress(const char* interfaceName,
|
|
|
if (ioctl(s, SIOCSIFADDR, &ifRequest) < 0) {
|
|
|
int err = errno;
|
|
|
close(s);
|
|
|
- Except_throw(eh, "ioctl(SIOCSIFADDR) failed: [%s]", strerror(err));
|
|
|
+ Er_raise(tempAlloc, "ioctl(SIOCSIFADDR) failed: [%s]", strerror(err));
|
|
|
}
|
|
|
|
|
|
uint32_t x = (uint32_t)~0 << (32 - prefixLen);
|
|
@@ -176,22 +176,23 @@ void NetPlatform_addAddress(const char* interfaceName,
|
|
|
if (ioctl(s, SIOCSIFNETMASK, &ifRequest) < 0) {
|
|
|
int err = errno;
|
|
|
close(s);
|
|
|
- Except_throw(eh, "ioctl(SIOCSIFNETMASK) failed: [%s]", strerror(err));
|
|
|
+ Er_raise(tempAlloc, "ioctl(SIOCSIFNETMASK) failed: [%s]", strerror(err));
|
|
|
}
|
|
|
} else {
|
|
|
Assert_true(0);
|
|
|
}
|
|
|
|
|
|
close(s);
|
|
|
+ Er_ret();
|
|
|
}
|
|
|
|
|
|
-void NetPlatform_setMTU(const char* interfaceName,
|
|
|
+Er_DEFUN(void NetPlatform_setMTU(const char* interfaceName,
|
|
|
uint32_t mtu,
|
|
|
struct Log* logger,
|
|
|
- struct Except* eh)
|
|
|
+ struct Allocator* alloc))
|
|
|
{
|
|
|
struct ifreq ifRequest;
|
|
|
- int s = socketForIfName(interfaceName, AF_INET6, eh, &ifRequest);
|
|
|
+ int s = Er(socketForIfName(interfaceName, AF_INET6, alloc, &ifRequest));
|
|
|
|
|
|
Log_info(logger, "Setting MTU for device [%s] to [%u] bytes.", interfaceName, mtu);
|
|
|
|
|
@@ -199,10 +200,11 @@ void NetPlatform_setMTU(const char* interfaceName,
|
|
|
if (ioctl(s, SIOCSIFMTU, &ifRequest) < 0) {
|
|
|
int err = errno;
|
|
|
close(s);
|
|
|
- Except_throw(eh, "ioctl(SIOCSIFMTU) [%s]", strerror(err));
|
|
|
+ Er_raise(alloc, "ioctl(SIOCSIFMTU) [%s]", strerror(err));
|
|
|
}
|
|
|
|
|
|
close(s);
|
|
|
+ Er_ret();
|
|
|
}
|
|
|
|
|
|
struct IfIndexAttr {
|
|
@@ -231,20 +233,19 @@ struct RouteInfo {
|
|
|
|
|
|
#define BUFF_SZ 16384
|
|
|
|
|
|
-static bool getMoreMessages(struct RouteInfo** rio,
|
|
|
+static Er_DEFUN(bool getMoreMessages(struct RouteInfo** rio,
|
|
|
int sock,
|
|
|
int ifIndex,
|
|
|
- struct Allocator* alloc,
|
|
|
- struct Except* eh)
|
|
|
+ struct Allocator* alloc))
|
|
|
{
|
|
|
bool retVal = false;
|
|
|
struct Allocator* tempAlloc = Allocator_child(alloc);
|
|
|
struct Message* msg = Message_new(BUFF_SZ, 0, tempAlloc);
|
|
|
ssize_t sz = recv(sock, msg->bytes, BUFF_SZ, MSG_TRUNC);
|
|
|
if (sz < (ssize_t)sizeof(struct nlmsghdr)) {
|
|
|
- Except_throw(eh, "recv() -> %s", strerror(errno));
|
|
|
+ Er_raise(tempAlloc, "recv() -> %s", strerror(errno));
|
|
|
} else if (sz > BUFF_SZ) {
|
|
|
- Except_throw(eh, "recv() -> buffer too small");
|
|
|
+ Er_raise(tempAlloc, "recv() -> buffer too small");
|
|
|
}
|
|
|
|
|
|
msg->length = sz;
|
|
@@ -254,15 +255,15 @@ static bool getMoreMessages(struct RouteInfo** rio,
|
|
|
struct RouteInfo ri = { .protocol = 0 };
|
|
|
int initMsgLen = msg->length;
|
|
|
struct nlmsghdr hdr;
|
|
|
- Message_pop(msg, &hdr, sizeof(struct nlmsghdr), eh);
|
|
|
+ Er(Message_epop(msg, &hdr, sizeof(struct nlmsghdr)));
|
|
|
//printf("\nHEADER %04x %04x\n", hdr.nlmsg_type, hdr.nlmsg_flags);
|
|
|
if (hdr.nlmsg_flags & NLM_F_MULTI) { retVal = true; }
|
|
|
if (hdr.nlmsg_type == NLMSG_DONE) {
|
|
|
Allocator_free(tempAlloc);
|
|
|
- return false;
|
|
|
+ Er_ret(false);
|
|
|
}
|
|
|
struct rtmsg rtm;
|
|
|
- Message_pop(msg, &rtm, sizeof(struct rtmsg), eh);
|
|
|
+ Er(Message_epop(msg, &rtm, sizeof(struct rtmsg)));
|
|
|
ri.prefix = rtm.rtm_dst_len;
|
|
|
ri.af = rtm.rtm_family;
|
|
|
ri.protocol = rtm.rtm_protocol;
|
|
@@ -271,35 +272,35 @@ static bool getMoreMessages(struct RouteInfo** rio,
|
|
|
if (remainingLen <= (int)sizeof(struct rtattr)) { break; }
|
|
|
struct rtattr attrHead;
|
|
|
//printf(">%s %d\n", Hex_print(msg->bytes, msg->length, tempAlloc), remainingLen);
|
|
|
- Message_pop(msg, &attrHead, sizeof(struct rtattr), eh);
|
|
|
+ Er(Message_epop(msg, &attrHead, sizeof(struct rtattr)));
|
|
|
switch (attrHead.rta_type) {
|
|
|
case RTA_OIF: {
|
|
|
if (attrHead.rta_len != 8) {
|
|
|
- Except_throw(eh, "unexpected rta_len for ifIndex");
|
|
|
+ Er_raise(alloc, "unexpected rta_len for ifIndex");
|
|
|
}
|
|
|
- Message_pop(msg, &ri.ifIndex, 4, eh);
|
|
|
+ Er(Message_epop(msg, &ri.ifIndex, 4));
|
|
|
break;
|
|
|
}
|
|
|
case RTA_DST: {
|
|
|
if (rtm.rtm_family == AF_INET6) {
|
|
|
if (attrHead.rta_len != 20) {
|
|
|
- Except_throw(eh, "unexpected rta_len for RTA_DST (ipv6)");
|
|
|
+ Er_raise(alloc, "unexpected rta_len for RTA_DST (ipv6)");
|
|
|
}
|
|
|
- Message_pop(msg, ri.dstAddr, 16, eh);
|
|
|
+ Er(Message_epop(msg, ri.dstAddr, 16));
|
|
|
} else if (rtm.rtm_family == AF_INET) {
|
|
|
if (attrHead.rta_len != 8) {
|
|
|
- Except_throw(eh, "unexpected rta_len for RTA_DST (ipv4)");
|
|
|
+ Er_raise(alloc, "unexpected rta_len for RTA_DST (ipv4)");
|
|
|
}
|
|
|
- Message_pop(msg, ri.dstAddr, 4, eh);
|
|
|
+ Er(Message_epop(msg, ri.dstAddr, 4));
|
|
|
} else {
|
|
|
- Except_throw(eh, "unexpected af %d", rtm.rtm_family);
|
|
|
+ Er_raise(alloc, "unexpected af %d", rtm.rtm_family);
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
default: {
|
|
|
int effectiveLen = RTA_ALIGN(attrHead.rta_len);
|
|
|
//printf("unrecognized %d (length %d)\n", attrHead.rta_type, effectiveLen);
|
|
|
- Message_pop(msg, NULL, effectiveLen - sizeof(struct rtattr), eh);
|
|
|
+ Er(Message_epop(msg, NULL, effectiveLen - sizeof(struct rtattr)));
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -315,13 +316,12 @@ static bool getMoreMessages(struct RouteInfo** rio,
|
|
|
*rio = outRi;
|
|
|
}
|
|
|
Allocator_free(tempAlloc);
|
|
|
- return retVal;
|
|
|
+ Er_ret(retVal);
|
|
|
}
|
|
|
|
|
|
-static struct RouteInfo* getRoutes(int sock,
|
|
|
+static Er_DEFUN(struct RouteInfo* getRoutes(int sock,
|
|
|
int ifIndex,
|
|
|
- struct Allocator* alloc,
|
|
|
- struct Except* eh)
|
|
|
+ struct Allocator* alloc))
|
|
|
{
|
|
|
struct RouteRequest req = {
|
|
|
.hdr = {
|
|
@@ -335,11 +335,11 @@ static struct RouteInfo* getRoutes(int sock,
|
|
|
};
|
|
|
ssize_t sz = send(sock, &req, req.hdr.nlmsg_len, 0);
|
|
|
if (sz < 0) {
|
|
|
- Except_throw(eh, "send() -> %s", strerror(errno));
|
|
|
+ Er_raise(alloc, "send() -> %s", strerror(errno));
|
|
|
}
|
|
|
struct RouteInfo* ri = NULL;
|
|
|
- while (getMoreMessages(&ri, sock, ifIndex, alloc, eh)) ;
|
|
|
- return ri;
|
|
|
+ while (Er(getMoreMessages(&ri, sock, ifIndex, alloc))) ;
|
|
|
+ Er_ret(ri);
|
|
|
}
|
|
|
|
|
|
static void bitShave(uint8_t* address, int prefix, int af)
|
|
@@ -360,11 +360,10 @@ static void bitShave(uint8_t* address, int prefix, int af)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void addDeleteRoutes(int sock,
|
|
|
+static Er_DEFUN(void addDeleteRoutes(int sock,
|
|
|
bool delete,
|
|
|
struct RouteInfo* ri,
|
|
|
- struct Allocator* tempAlloc,
|
|
|
- struct Except* eh)
|
|
|
+ struct Allocator* tempAlloc))
|
|
|
{
|
|
|
struct Message* msg = Message_new(0, 512, tempAlloc);
|
|
|
for (;ri;ri = ri->next) {
|
|
@@ -375,12 +374,12 @@ static void addDeleteRoutes(int sock,
|
|
|
},
|
|
|
.ifIndex = ri->ifIndex
|
|
|
};
|
|
|
- Message_push(msg, &ifa, sizeof(struct IfIndexAttr), NULL);
|
|
|
+ Er(Message_epush(msg, &ifa, sizeof(struct IfIndexAttr)));
|
|
|
int addrLen = (ri->af == AF_INET6) ? 16 : 4;
|
|
|
- Message_push(msg, ri->dstAddr, addrLen, NULL);
|
|
|
+ Er(Message_epush(msg, ri->dstAddr, addrLen));
|
|
|
bitShave(msg->bytes, ri->prefix, ri->af);
|
|
|
struct rtattr rta = { .rta_len = sizeof(struct rtattr) + addrLen, .rta_type = RTA_DST };
|
|
|
- Message_push(msg, &rta, sizeof(struct rtattr), NULL);
|
|
|
+ Er(Message_epush(msg, &rta, sizeof(struct rtattr)));
|
|
|
struct rtmsg route = {
|
|
|
.rtm_family = ri->af,
|
|
|
.rtm_dst_len = ri->prefix,
|
|
@@ -389,19 +388,20 @@ static void addDeleteRoutes(int sock,
|
|
|
.rtm_protocol = (delete) ? RTPROT_UNSPEC : ri->protocol,
|
|
|
.rtm_type = (delete) ? RTN_UNSPEC : RTN_UNICAST
|
|
|
};
|
|
|
- Message_push(msg, &route, sizeof(struct rtmsg), NULL);
|
|
|
+ Er(Message_epush(msg, &route, sizeof(struct rtmsg)));
|
|
|
struct nlmsghdr hdr = {
|
|
|
.nlmsg_len = msg->length + sizeof(struct nlmsghdr),
|
|
|
.nlmsg_type = (delete) ? RTM_DELROUTE : RTM_NEWROUTE,
|
|
|
.nlmsg_flags = NLM_F_REQUEST | ((delete) ? 0 : NLM_F_CREATE) // | NLM_F_ACK,
|
|
|
};
|
|
|
- Message_push(msg, &hdr, sizeof(struct nlmsghdr), NULL);
|
|
|
+ Er(Message_epush(msg, &hdr, sizeof(struct nlmsghdr)));
|
|
|
ssize_t sz = send(sock, msg->bytes, msg->length, 0);
|
|
|
if (sz < 0) {
|
|
|
- Except_throw(eh, "send() -> %s", strerror(errno));
|
|
|
+ Er_raise(tempAlloc, "send() -> %s", strerror(errno));
|
|
|
}
|
|
|
Message_reset(msg);
|
|
|
}
|
|
|
+ Er_ret();
|
|
|
}
|
|
|
|
|
|
static int closeSocket(struct Allocator_OnFreeJob* job)
|
|
@@ -411,14 +411,14 @@ static int closeSocket(struct Allocator_OnFreeJob* job)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int mkSocket(struct Allocator* alloc, struct Except* eh)
|
|
|
+static Er_DEFUN(int mkSocket(struct Allocator* alloc))
|
|
|
{
|
|
|
int sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
|
if (sock < 0) {
|
|
|
- Except_throw(eh, "socket(PF_NETLINK) -> %s", strerror(errno));
|
|
|
+ Er_raise(alloc, "socket(PF_NETLINK) -> %s", strerror(errno));
|
|
|
}
|
|
|
Allocator_onFree(alloc, closeSocket, (void*) ((long) sock));
|
|
|
- return sock;
|
|
|
+ Er_ret(sock);
|
|
|
}
|
|
|
|
|
|
static struct RouteInfo* riForSockaddrs(struct Sockaddr** prefixSet,
|
|
@@ -457,19 +457,19 @@ static void logRis(struct RouteInfo* ri, struct Log* logger, char* msg)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void NetPlatform_setRoutes(const char* ifName,
|
|
|
+Er_DEFUN(void NetPlatform_setRoutes(const char* ifName,
|
|
|
struct Sockaddr** prefixSet,
|
|
|
int prefixCount,
|
|
|
struct Log* logger,
|
|
|
- struct Allocator* tempAlloc,
|
|
|
- struct Except* eh)
|
|
|
+ struct Allocator* tempAlloc))
|
|
|
{
|
|
|
- int ifIndex = ifIndexForName(ifName, eh);
|
|
|
+ int ifIndex = Er(ifIndexForName(ifName, tempAlloc));
|
|
|
struct RouteInfo* newRi = riForSockaddrs(prefixSet, prefixCount, ifIndex, tempAlloc);
|
|
|
- int sock = mkSocket(tempAlloc, eh);
|
|
|
- struct RouteInfo* oldRi = getRoutes(sock, ifIndex, tempAlloc, eh);
|
|
|
+ int sock = Er(mkSocket(tempAlloc));
|
|
|
+ struct RouteInfo* oldRi = Er(getRoutes(sock, ifIndex, tempAlloc));
|
|
|
logRis(oldRi, logger, "DELETE ROUTE");
|
|
|
- addDeleteRoutes(sock, true, oldRi, tempAlloc, eh);
|
|
|
+ Er(addDeleteRoutes(sock, true, oldRi, tempAlloc));
|
|
|
logRis(newRi, logger, "ADD ROUTE");
|
|
|
- addDeleteRoutes(sock, false, newRi, tempAlloc, eh);
|
|
|
+ Er(addDeleteRoutes(sock, false, newRi, tempAlloc));
|
|
|
+ Er_ret();
|
|
|
}
|