can_address.cpp 1.24 KB
#include "socket-cpp/can_address.h"
#include "socket-cpp/socket.h"
#include <cstring>
#include <stdexcept>
#include <sys/ioctl.h>
#include <net/if.h>

using namespace std;
using namespace osdev::components::socket-cpp;

constexpr sa_family_t can_address::ADDRESS_FAMILY;

// --------------------------------------------------------------------------

can_address::can_address(unsigned ifindex) : addr_{}
{
	addr_.can_family = AF_CAN;
	addr_.can_ifindex = ifindex;
}

can_address::can_address(const string& iface) : addr_{}
{
	unsigned idx = if_nametoindex(iface.c_str());

	if (idx != 0) {
		addr_.can_family = AF_CAN;
		addr_.can_ifindex = idx;
	}
}

can_address::can_address(const sockaddr& addr)
{
    auto domain = addr.sa_family;
    if (domain != AF_CAN)
        throw std::invalid_argument("Not a SocketCAN address");

    std::memcpy(&addr_, &addr, sizeof(sockaddr));
}

string can_address::iface() const
{
	if (addr_.can_family == AF_UNSPEC)
		return string("none");

	if (addr_.can_ifindex == 0)
		return string("any");

	char buf[IF_NAMESIZE];
	const char* iface = if_indextoname(addr_.can_ifindex, buf);

	return string(iface ? iface : "unknown");
}

ostream& operator<<(ostream& os, const can_address& addr)
{
	os << "can:" << addr.iface();
	return os;
}