continue;
}
- sock = openSocket(iface->getName(), *addr, port);
+ // Using openSocket4 directly instead of using openSocket to
+ // pass boolean arguments that enable broadcast traffic.
+ sock = openSocket4(*iface, *addr, port, true, true);
if (sock < 0) {
isc_throw(SocketConfigError, "failed to open unicast socket");
}
return IOAddress(local_address);
}
-int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
+int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port,
+ bool receive_bcast, bool send_bcast) {
struct sockaddr_in addr4;
memset(&addr4, 0, sizeof(sockaddr));
addr4.sin_family = AF_INET;
addr4.sin_port = htons(port);
- addr4.sin_addr.s_addr = htonl(addr);
- //addr4.sin_addr.s_addr = 0; // anyaddr: this will receive 0.0.0.0 => 255.255.255.255 traffic
- // addr4.sin_addr.s_addr = 0xffffffffu; // broadcast address. This will receive 0.0.0.0 => 255.255.255.255 as well
+ // If we are to receive broadcast messages we have to bind
+ // to "ANY" address.
+ addr4.sin_addr.s_addr = receive_bcast ? INADDR_ANY : htonl(addr);
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
isc_throw(SocketConfigError, "Failed to create UDP6 socket.");
}
+ if (receive_bcast) {
+ // Bind to device so as we receive traffic on a specific interface.
+ if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, iface.getName().c_str(),
+ iface.getName().length() + 1) < 0) {
+ close(sock);
+ isc_throw(SocketConfigError, "Failed to set SO_BINDTODEVICE option"
+ << "on socket " << sock);
+ }
+ }
+
+ if (send_bcast) {
+ // Enable sending to broadcast address.
+ int flag = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) < 0) {
+ close(sock);
+ isc_throw(SocketConfigError, "Failed to set SO_BINDTODEVICE option"
+ << "on socket " << sock);
+ }
+ }
+
if (bind(sock, (struct sockaddr *)&addr4, sizeof(addr4)) < 0) {
close(sock);
isc_throw(SocketConfigError, "Failed to bind socket " << sock << " to " << addr.toText()
/// @param iface reference to interface structure.
/// @param addr an address the created socket should be bound to
/// @param port a port that created socket should be bound to
+ /// @param receive_bcast configure socket to receive broadcast messages
+ /// @param send_bcast configure socket to send broadcast messages.
///
/// @return socket descriptor
- int openSocket4(Iface& iface, const isc::asiolink::IOAddress& addr, uint16_t port);
+ int openSocket4(Iface& iface, const isc::asiolink::IOAddress& addr, uint16_t port,
+ bool receive_bcast = false, bool send_bcast = false);
/// @brief Opens IPv6 socket.
///