|
@@ -32,16 +32,18 @@
|
|
|
#include <misc/ethernet_proto.h>
|
|
#include <misc/ethernet_proto.h>
|
|
|
#include <misc/ipv4_proto.h>
|
|
#include <misc/ipv4_proto.h>
|
|
|
#include <misc/udp_proto.h>
|
|
#include <misc/udp_proto.h>
|
|
|
|
|
+#include <system/BLog.h>
|
|
|
|
|
|
|
|
#include <dhcpclient/BDHCPClient.h>
|
|
#include <dhcpclient/BDHCPClient.h>
|
|
|
|
|
|
|
|
|
|
+#include <generated/blog_channel_BHDCPClient.h>
|
|
|
|
|
+
|
|
|
#define COMPONENT_SOURCE 1
|
|
#define COMPONENT_SOURCE 1
|
|
|
#define COMPONENT_SINK 2
|
|
#define COMPONENT_SINK 2
|
|
|
|
|
|
|
|
#define DHCP_SERVER_PORT 67
|
|
#define DHCP_SERVER_PORT 67
|
|
|
#define DHCP_CLIENT_PORT 68
|
|
#define DHCP_CLIENT_PORT 68
|
|
|
|
|
|
|
|
-#define ETH_HEADER_LEN sizeof(struct ethernet_header)
|
|
|
|
|
#define IPUDP_OVERHEAD (sizeof(struct ipv4_header) + sizeof(struct udp_header))
|
|
#define IPUDP_OVERHEAD (sizeof(struct ipv4_header) + sizeof(struct udp_header))
|
|
|
|
|
|
|
|
static void error_handler (BDHCPClient *o, int component, const void *data)
|
|
static void error_handler (BDHCPClient *o, int component, const void *data)
|
|
@@ -50,11 +52,11 @@ static void error_handler (BDHCPClient *o, int component, const void *data)
|
|
|
|
|
|
|
|
switch (component) {
|
|
switch (component) {
|
|
|
case COMPONENT_SOURCE: {
|
|
case COMPONENT_SOURCE: {
|
|
|
- DEBUG("source error");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "source error");
|
|
|
} break;
|
|
} break;
|
|
|
|
|
|
|
|
case COMPONENT_SINK: {
|
|
case COMPONENT_SINK: {
|
|
|
- DEBUG("sink error");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "sink error");
|
|
|
} break;
|
|
} break;
|
|
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -62,26 +64,26 @@ static void error_handler (BDHCPClient *o, int component, const void *data)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static int bind_to_device (int sock, const char *ifname)
|
|
|
|
|
|
|
+static void dhcp_handler (BDHCPClient *o, int event)
|
|
|
{
|
|
{
|
|
|
- struct ifreq ifr;
|
|
|
|
|
- memset(&ifr, 0, sizeof(ifr));
|
|
|
|
|
- snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname);
|
|
|
|
|
- if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
|
|
|
|
|
- return 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ DebugObject_Access(&o->d_obj);
|
|
|
|
|
|
|
|
- return 1;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static int set_broadcast (int sock)
|
|
|
|
|
-{
|
|
|
|
|
- int broadcast = 1;
|
|
|
|
|
- if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *)&broadcast, sizeof(broadcast)) < 0) {
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+ switch (event) {
|
|
|
|
|
+ case BDHCPCLIENTCORE_EVENT_UP:
|
|
|
|
|
+ ASSERT(!o->up)
|
|
|
|
|
+ o->up = 1;
|
|
|
|
|
+ o->handler(o->user, BDHCPCLIENT_EVENT_UP);
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
|
|
+ case BDHCPCLIENTCORE_EVENT_DOWN:
|
|
|
|
|
+ ASSERT(o->up)
|
|
|
|
|
+ o->up = 0;
|
|
|
|
|
+ o->handler(o->user, BDHCPCLIENT_EVENT_DOWN);
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
|
|
+ default:
|
|
|
|
|
+ ASSERT(0);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- return 1;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static int get_iface_info (const char *ifname, uint8_t *out_mac, int *out_mtu, int *out_ifindex)
|
|
static int get_iface_info (const char *ifname, uint8_t *out_mac, int *out_mtu, int *out_ifindex)
|
|
@@ -90,7 +92,7 @@ static int get_iface_info (const char *ifname, uint8_t *out_mac, int *out_mtu, i
|
|
|
|
|
|
|
|
int s = socket(AF_INET, SOCK_DGRAM, 0);
|
|
int s = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
if (!s) {
|
|
if (!s) {
|
|
|
- DEBUG("socket failed");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "socket failed");
|
|
|
goto fail0;
|
|
goto fail0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -98,11 +100,11 @@ static int get_iface_info (const char *ifname, uint8_t *out_mac, int *out_mtu, i
|
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname);
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname);
|
|
|
if (ioctl(s, SIOCGIFHWADDR, &ifr)) {
|
|
if (ioctl(s, SIOCGIFHWADDR, &ifr)) {
|
|
|
- DEBUG("ioctl(SIOCGIFHWADDR) failed");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "ioctl(SIOCGIFHWADDR) failed");
|
|
|
goto fail1;
|
|
goto fail1;
|
|
|
}
|
|
}
|
|
|
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
|
|
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
|
|
|
- DEBUG("hardware address not ethernet");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "hardware address not ethernet");
|
|
|
goto fail1;
|
|
goto fail1;
|
|
|
}
|
|
}
|
|
|
memcpy(out_mac, ifr.ifr_hwaddr.sa_data, 6);
|
|
memcpy(out_mac, ifr.ifr_hwaddr.sa_data, 6);
|
|
@@ -111,7 +113,7 @@ static int get_iface_info (const char *ifname, uint8_t *out_mac, int *out_mtu, i
|
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname);
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname);
|
|
|
if (ioctl(s, SIOCGIFMTU, &ifr)) {
|
|
if (ioctl(s, SIOCGIFMTU, &ifr)) {
|
|
|
- DEBUG("ioctl(SIOCGIFMTU) failed");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "ioctl(SIOCGIFMTU) failed");
|
|
|
goto fail1;
|
|
goto fail1;
|
|
|
}
|
|
}
|
|
|
*out_mtu = ifr.ifr_mtu;
|
|
*out_mtu = ifr.ifr_mtu;
|
|
@@ -120,7 +122,7 @@ static int get_iface_info (const char *ifname, uint8_t *out_mac, int *out_mtu, i
|
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname);
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifname);
|
|
|
if (ioctl(s, SIOCGIFINDEX, &ifr)) {
|
|
if (ioctl(s, SIOCGIFINDEX, &ifr)) {
|
|
|
- DEBUG("ioctl(SIOCGIFINDEX) failed");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "ioctl(SIOCGIFINDEX) failed");
|
|
|
goto fail1;
|
|
goto fail1;
|
|
|
}
|
|
}
|
|
|
*out_ifindex = ifr.ifr_ifindex;
|
|
*out_ifindex = ifr.ifr_ifindex;
|
|
@@ -135,25 +137,27 @@ fail0:
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-int BDHCPClient_Init (BDHCPClient *o, const char *ifname, BReactor *reactor, BDHCPClientCore_handler handler, void *user)
|
|
|
|
|
|
|
+int BDHCPClient_Init (BDHCPClient *o, const char *ifname, BReactor *reactor, BDHCPClient_handler handler, void *user)
|
|
|
{
|
|
{
|
|
|
// init arguments
|
|
// init arguments
|
|
|
o->reactor = reactor;
|
|
o->reactor = reactor;
|
|
|
|
|
+ o->handler = handler;
|
|
|
|
|
+ o->user = user;
|
|
|
|
|
|
|
|
// get interface information
|
|
// get interface information
|
|
|
uint8_t if_mac[6];
|
|
uint8_t if_mac[6];
|
|
|
int if_mtu;
|
|
int if_mtu;
|
|
|
int if_index;
|
|
int if_index;
|
|
|
if (!get_iface_info(ifname, if_mac, &if_mtu, &if_index)) {
|
|
if (!get_iface_info(ifname, if_mac, &if_mtu, &if_index)) {
|
|
|
- DEBUG("failed to get interface information");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "failed to get interface information");
|
|
|
goto fail0;
|
|
goto fail0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- DEBUG("if_mac=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8" if_mtu=%d if_index=%d",
|
|
|
|
|
|
|
+ BLog(BLOG_INFO, "if_mac=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8" if_mtu=%d if_index=%d",
|
|
|
if_mac[0], if_mac[1], if_mac[2], if_mac[3], if_mac[4], if_mac[5], if_mtu, if_index);
|
|
if_mac[0], if_mac[1], if_mac[2], if_mac[3], if_mac[4], if_mac[5], if_mtu, if_index);
|
|
|
|
|
|
|
|
if (if_mtu < IPUDP_OVERHEAD) {
|
|
if (if_mtu < IPUDP_OVERHEAD) {
|
|
|
- DEBUG("MTU is too small for UDP/IP !?!");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "MTU is too small for UDP/IP !?!");
|
|
|
goto fail0;
|
|
goto fail0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -161,27 +165,15 @@ int BDHCPClient_Init (BDHCPClient *o, const char *ifname, BReactor *reactor, BDH
|
|
|
|
|
|
|
|
// init socket
|
|
// init socket
|
|
|
if (BSocket_Init(&o->sock, o->reactor, BADDR_TYPE_PACKET, BSOCKET_TYPE_DGRAM) < 0) {
|
|
if (BSocket_Init(&o->sock, o->reactor, BADDR_TYPE_PACKET, BSOCKET_TYPE_DGRAM) < 0) {
|
|
|
- DEBUG("BSocket_Init failed");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "BSocket_Init failed");
|
|
|
goto fail0;
|
|
goto fail0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // set socket broadcast
|
|
|
|
|
- if (!set_broadcast(o->sock.socket)) {
|
|
|
|
|
- DEBUG("set_broadcast failed");
|
|
|
|
|
- goto fail1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // bind socket to device
|
|
|
|
|
- if (!bind_to_device(o->sock.socket, ifname)) {
|
|
|
|
|
- DEBUG("bind_to_device failed");
|
|
|
|
|
- goto fail1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
// bind socket
|
|
// bind socket
|
|
|
BAddr bind_addr;
|
|
BAddr bind_addr;
|
|
|
BAddr_InitPacket(&bind_addr, hton16(ETHERTYPE_IPV4), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_HOST, if_mac);
|
|
BAddr_InitPacket(&bind_addr, hton16(ETHERTYPE_IPV4), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_HOST, if_mac);
|
|
|
if (BSocket_Bind(&o->sock, &bind_addr) < 0) {
|
|
if (BSocket_Bind(&o->sock, &bind_addr) < 0) {
|
|
|
- DEBUG("BSocket_Bind failed");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "BSocket_Bind failed");
|
|
|
goto fail1;
|
|
goto fail1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -206,7 +198,7 @@ int BDHCPClient_Init (BDHCPClient *o, const char *ifname, BReactor *reactor, BDH
|
|
|
|
|
|
|
|
// init buffer
|
|
// init buffer
|
|
|
if (!SinglePacketBuffer_Init(&o->send_buffer, DHCPIpUdpEncoder_GetOutput(&o->send_encoder), DatagramSocketSink_GetInput(&o->send_sink), BReactor_PendingGroup(o->reactor))) {
|
|
if (!SinglePacketBuffer_Init(&o->send_buffer, DHCPIpUdpEncoder_GetOutput(&o->send_encoder), DatagramSocketSink_GetInput(&o->send_sink), BReactor_PendingGroup(o->reactor))) {
|
|
|
- DEBUG("SinglePacketBuffer_Init failed");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed");
|
|
|
goto fail2;
|
|
goto fail2;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -223,16 +215,19 @@ int BDHCPClient_Init (BDHCPClient *o, const char *ifname, BReactor *reactor, BDH
|
|
|
|
|
|
|
|
// init buffer
|
|
// init buffer
|
|
|
if (!SinglePacketBuffer_Init(&o->recv_buffer, DatagramSocketSource_GetOutput(&o->recv_source), DHCPIpUdpDecoder_GetInput(&o->recv_decoder), BReactor_PendingGroup(o->reactor))) {
|
|
if (!SinglePacketBuffer_Init(&o->recv_buffer, DatagramSocketSource_GetOutput(&o->recv_source), DHCPIpUdpDecoder_GetInput(&o->recv_decoder), BReactor_PendingGroup(o->reactor))) {
|
|
|
- DEBUG("SinglePacketBuffer_Init failed");
|
|
|
|
|
|
|
+ BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed");
|
|
|
goto fail3;
|
|
goto fail3;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// init dhcp
|
|
// init dhcp
|
|
|
- if (!BDHCPClientCore_Init(&o->dhcp, PacketCopier_GetInput(&o->send_copier), PacketCopier_GetOutput(&o->recv_copier), if_mac, o->reactor, handler, user)) {
|
|
|
|
|
- DEBUG("BDHCPClientCore_Init failed");
|
|
|
|
|
|
|
+ if (!BDHCPClientCore_Init(&o->dhcp, PacketCopier_GetInput(&o->send_copier), PacketCopier_GetOutput(&o->recv_copier), if_mac, o->reactor, (BDHCPClientCore_handler)dhcp_handler, o)) {
|
|
|
|
|
+ BLog(BLOG_ERROR, "BDHCPClientCore_Init failed");
|
|
|
goto fail4;
|
|
goto fail4;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // set not up
|
|
|
|
|
+ o->up = 0;
|
|
|
|
|
+
|
|
|
DebugObject_Init(&o->d_obj);
|
|
DebugObject_Init(&o->d_obj);
|
|
|
|
|
|
|
|
return 1;
|
|
return 1;
|
|
@@ -279,20 +274,28 @@ void BDHCPClient_Free (BDHCPClient *o)
|
|
|
|
|
|
|
|
void BDHCPClient_GetClientIP (BDHCPClient *o, uint32_t *out_ip)
|
|
void BDHCPClient_GetClientIP (BDHCPClient *o, uint32_t *out_ip)
|
|
|
{
|
|
{
|
|
|
|
|
+ ASSERT(o->up)
|
|
|
|
|
+
|
|
|
BDHCPClientCore_GetClientIP(&o->dhcp, out_ip);
|
|
BDHCPClientCore_GetClientIP(&o->dhcp, out_ip);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void BDHCPClient_GetClientMask (BDHCPClient *o, uint32_t *out_mask)
|
|
void BDHCPClient_GetClientMask (BDHCPClient *o, uint32_t *out_mask)
|
|
|
{
|
|
{
|
|
|
|
|
+ ASSERT(o->up)
|
|
|
|
|
+
|
|
|
BDHCPClientCore_GetClientMask(&o->dhcp, out_mask);
|
|
BDHCPClientCore_GetClientMask(&o->dhcp, out_mask);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int BDHCPClient_GetRouter (BDHCPClient *o, uint32_t *out_router)
|
|
int BDHCPClient_GetRouter (BDHCPClient *o, uint32_t *out_router)
|
|
|
{
|
|
{
|
|
|
|
|
+ ASSERT(o->up)
|
|
|
|
|
+
|
|
|
return BDHCPClientCore_GetRouter(&o->dhcp, out_router);
|
|
return BDHCPClientCore_GetRouter(&o->dhcp, out_router);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int BDHCPClient_GetDNS (BDHCPClient *o, uint32_t *out_dns_servers, size_t max_dns_servers)
|
|
int BDHCPClient_GetDNS (BDHCPClient *o, uint32_t *out_dns_servers, size_t max_dns_servers)
|
|
|
{
|
|
{
|
|
|
|
|
+ ASSERT(o->up)
|
|
|
|
|
+
|
|
|
return BDHCPClientCore_GetDNS(&o->dhcp, out_dns_servers, max_dns_servers);
|
|
return BDHCPClientCore_GetDNS(&o->dhcp, out_dns_servers, max_dns_servers);
|
|
|
}
|
|
}
|