20const size_t PktFilterInet::CONTROL_BUF_LEN = 512;
 
   35                          const bool receive_bcast,
 
   36                          const bool send_bcast) {
 
   37    struct sockaddr_in addr4;
 
   38    memset(&addr4, 0, 
sizeof(sockaddr));
 
   39    addr4.sin_family = AF_INET;
 
   40    addr4.sin_port = htons(port);
 
   45        addr4.sin_addr.s_addr = INADDR_ANY;
 
   47        addr4.sin_addr.s_addr = htonl(addr.
toUint32());
 
   50    int sock = socket(AF_INET, SOCK_DGRAM, 0);
 
   56    if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
 
   59                  << 
" on socket " << sock);
 
   64    if (setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &enable, 
sizeof(enable))) {
 
   65        const char* errmsg = strerror(errno);
 
   67                  << 
", error: " << errmsg);
 
   74        if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, iface.
getName().c_str(),
 
   75                       iface.
getName().length() + 1) < 0) {
 
   78                      << 
" on socket " << sock);
 
   86        if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &flag, 
sizeof(flag)) < 0) {
 
   89                      << 
" on socket " << sock);
 
   93    if (bind(sock, (
struct sockaddr *)&addr4, 
sizeof(addr4)) < 0) {
 
  102#if defined (IP_PKTINFO) && defined (OS_LINUX) 
  104    if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &flag, 
sizeof(flag)) != 0) {
 
  110#elif defined (IP_RECVDSTADDR) && defined (OS_BSD) 
  112    if (setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &flag, 
sizeof(flag)) != 0) {
 
 
  125    struct sockaddr_in from_addr;
 
  127    uint8_t control_buf[CONTROL_BUF_LEN];
 
  129    memset(&control_buf[0], 0, CONTROL_BUF_LEN);
 
  130    memset(&from_addr, 0, 
sizeof(from_addr));
 
  134    memset(&m, 0, 
sizeof(m));
 
  137    m.msg_name = &from_addr;
 
  138    m.msg_namelen = 
sizeof(from_addr);
 
  141    v.iov_base = 
static_cast<void*
>(buf);
 
  152    m.msg_control = &control_buf[0];
 
  153    m.msg_controllen = CONTROL_BUF_LEN;
 
  155    int result = recvmsg(socket_info.
sockfd_, &m, 0);
 
  163    pkt->updateTimestamp();
 
  165    unsigned int ifindex = iface.
getIndex();
 
  167    IOAddress from(htonl(from_addr.sin_addr.s_addr));
 
  168    uint16_t from_port = htons(from_addr.sin_port);
 
  173    pkt->setIndex(ifindex);
 
  174    pkt->setIface(iface.
getName());
 
  175    pkt->setRemoteAddr(from);
 
  176    pkt->setRemotePort(from_port);
 
  177    pkt->setLocalPort(socket_info.
port_);
 
  182#if defined (IP_PKTINFO) && defined (OS_LINUX) 
  183    struct in_pktinfo* pktinfo;
 
  184    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
 
  186    while (cmsg != NULL) {
 
  187        if ((cmsg->cmsg_level == IPPROTO_IP) &&
 
  188            (cmsg->cmsg_type == IP_PKTINFO)) {
 
  189            pktinfo = 
reinterpret_cast<struct in_pktinfo*
>(CMSG_DATA(cmsg));
 
  191            pkt->setIndex(pktinfo->ipi_ifindex);
 
  192            pkt->setLocalAddr(
IOAddress(htonl(pktinfo->ipi_addr.s_addr)));
 
  205        } 
else if ((cmsg->cmsg_level == SOL_SOCKET) &&
 
  206                   (cmsg->cmsg_type  == SCM_TIMESTAMP)) {
 
  208            struct timeval cmsg_time;
 
  209            memcpy(&cmsg_time, CMSG_DATA(cmsg), 
sizeof(cmsg_time));
 
  214        cmsg = CMSG_NXTHDR(&m, cmsg);
 
  217#elif defined (IP_RECVDSTADDR) && defined (OS_BSD) 
  218    struct in_addr* to_addr;
 
  219    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
 
  221    while (cmsg != NULL) {
 
  222        if ((cmsg->cmsg_level == IPPROTO_IP) &&
 
  223            (cmsg->cmsg_type == IP_RECVDSTADDR)) {
 
  224            to_addr = 
reinterpret_cast<struct in_addr*
>(CMSG_DATA(cmsg));
 
  225            pkt->setLocalAddr(
IOAddress(htonl(to_addr->s_addr)));
 
  230        } 
else if ((cmsg->cmsg_level == SOL_SOCKET) &&
 
  231                   (cmsg->cmsg_type  == SCM_TIMESTAMP)) {
 
  233            struct timeval cmsg_time;
 
  234            memcpy(&cmsg_time, CMSG_DATA(cmsg), 
sizeof(cmsg_time));
 
  238        cmsg = CMSG_NXTHDR(&m, cmsg);
 
  242    pkt->addPktEvent(PktEvent::BUFFER_READ);
 
 
  249    uint8_t control_buf[CONTROL_BUF_LEN];
 
  250    memset(&control_buf[0], 0, CONTROL_BUF_LEN);
 
  254    memset(&to, 0, 
sizeof(to));
 
  255    to.sin_family = AF_INET;
 
  256    to.sin_port = htons(pkt->getRemotePort());
 
  257    to.sin_addr.s_addr = htonl(pkt->getRemoteAddr().toUint32());
 
  261    memset(&m, 0, 
sizeof(m));
 
  263    m.msg_namelen = 
sizeof(to);
 
  269    memset(&v, 0, 
sizeof(v));
 
  272    v.iov_base = 
const_cast<void *
>(pkt->getBuffer().getDataAsVoidPtr());
 
  273    v.iov_len = pkt->getBuffer().getLength();
 
  280#if defined (IP_PKTINFO) && defined (OS_LINUX) 
  286    m.msg_control = &control_buf[0];
 
  287    m.msg_controllen = CONTROL_BUF_LEN;
 
  288    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m);
 
  289    cmsg->cmsg_level = IPPROTO_IP;
 
  290    cmsg->cmsg_type = IP_PKTINFO;
 
  291    cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct in_pktinfo));
 
  292    struct in_pktinfo* pktinfo =(
struct in_pktinfo *)CMSG_DATA(cmsg);
 
  293    memset(pktinfo, 0, 
sizeof(
struct in_pktinfo));
 
  299    if (pkt->indexSet()) {
 
  300        pktinfo->ipi_ifindex = pkt->getIndex();
 
  305    if (!pkt->getLocalAddr().isV4Zero()) {
 
  306        pktinfo->ipi_spec_dst.s_addr = htonl(pkt->getLocalAddr().toUint32());
 
  309    m.msg_controllen = CMSG_SPACE(
sizeof(
struct in_pktinfo));
 
  312    pkt->updateTimestamp();
 
  316    int result = sendmsg(sockfd, &m, 0);
 
  319                  " with an error: " << strerror(errno));
 
 
The IOAddress class represents an IP addresses (version agnostic)
std::string toText() const
Convert the address to a string.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
static const uint32_t RCVBUFSIZE
Packet reception buffer size.
Represents a single network interface.
std::string getName() const
Returns interface name.
unsigned int getIndex() const
Returns interface index.
bool flag_broadcast_
Flag specifies if selected interface is broadcast capable.
Represents DHCPv4 packet.
static const std::string SOCKET_RECEIVED
Event that marks when a packet is placed in the socket buffer by the kernel.
static const std::string RESPONSE_SENT
Event that marks when a packet is been written to the socket by application.
virtual bool isSocketReceivedTimeSupported() const
Check if the socket received time is supported.
virtual SocketInfo openSocket(Iface &iface, const isc::asiolink::IOAddress &addr, const uint16_t port, const bool receive_bcast, const bool send_bcast)
Open primary and fallback socket.
virtual int send(const Iface &iface, uint16_t sockfd, const Pkt4Ptr &pkt)
Send packet over specified socket.
virtual Pkt4Ptr receive(Iface &iface, const SocketInfo &socket_info)
Receive packet over specified socket.
IfaceMgr exception thrown thrown when socket opening or configuration failed.
IfaceMgr exception thrown thrown when error occurred during reading data from socket.
IfaceMgr exception thrown thrown when error occurred during sending data through socket.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Defines the logger used by the top-level component of kea-lfc.
Holds information about socket.
uint16_t port_
bound address