* Force configured destination address
*/
bool force_dst;
+
+ /**
+ * Source IP if destination address is unicast
+ */
+ struct sockaddr_in src;
};
/**
identification_t *identity;
dhcp_option_t *option;
int optlen = 0, remaining;
- host_t *src;
uint32_t id;
memset(dhcp, 0, sizeof(*dhcp));
}
else
{
- /* act as relay agent */
- src = charon->kernel->get_source_addr(charon->kernel, this->dst, NULL);
- if (src)
- {
- memcpy(&dhcp->gateway_address, src->get_address(src).ptr,
- sizeof(dhcp->gateway_address));
- src->destroy(src);
- }
+ memcpy(&dhcp->gateway_address, &this->src.sin_addr,
+ sizeof(dhcp->gateway_address));
}
identity = transaction->get_identity(transaction);
.s_addr = INADDR_ANY,
},
};
+ socklen_t addr_len;
char *iface;
int on = 1, rcvbuf = 0;
struct sock_filter dhcp_filter_code[] = {
return NULL;
}
}
+ if (!is_broadcast(this->dst))
+ {
+ if (connect(this->send, this->dst->get_sockaddr(this->dst),
+ *this->dst->get_sockaddr_len(this->dst)) < 0)
+ {
+ DBG1(DBG_CFG, "unable to connect DHCP send socket: %s",
+ strerror(errno));
+ destroy(this);
+ return NULL;
+ }
+ addr_len = sizeof(this->src);
+ if (getsockname(this->send, &this->src, &addr_len) < 0)
+ {
+ DBG1(DBG_CFG, "unable to determine source address for DHCP: %s",
+ strerror(errno));
+ destroy(this);
+ return NULL;
+ }
+ }
lib->watcher->add(lib->watcher, this->receive, WATCHER_READ,
(watcher_cb_t)receive_dhcp, this);