Dhcp server sample.
Dependents: GR-PEACH_WebCamera_AP
mbedボードをDHCPサーバとして使用するためのライブラリです。mbedボードとPCを直結する際などに使用してください。
このクラスは5つのIPアドレスを割り当てられることができます。
IPアドレスの上位3バイトはサーバーアドレスと同じで、下の1バイトは、10-14が割り当てられます。
例えば、サーバーアドレスが"192.168.0.1"の場合、IPアドレスは"192.168.0.10"~"192.168.0.14"が割り当てられます。
EthernetInterfaceでconnectを実行した後に、DhcpServerを使用してください。
EthernetInterface eth; eth.init("192.168.0.1", "255.255.255.0", "192.168.0.1"); eth.connect(); DhcpServer dhcp_server("HostName", eth.getIPAddress());
Library in Beta!
This library is in Beta.
このライブラリはβ版です。
Diff: DhcpServer.cpp
- Revision:
- 0:1c2747611cab
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DhcpServer.cpp Fri Mar 25 05:00:52 2016 +0000 @@ -0,0 +1,189 @@ +#include "mbed.h" +#include "rtos.h" +#include "lwip/netif.h" +#include "TCPSocketConnection.h" +#include "TCPSocketServer.h" +#include "Endpoint.h" +#include "UDPSocket.h" +#include "dhcp.h" +#include "DhcpServer.h" + +#define CONNECT_NUM (5) +#define IP_ADDER_START (10) + +#define OFS_XID (4) +#define OFS_YIADDR (16) +#define OFS_SIADDR (20) +#define OFS_CHADDR (28) +#define OFS_SNAME (44) +#define OFS_COOKIE (236) +#define OFS_OPTIONS (240) + +static char receivebuff[500]; +static char sendbuff[300] = {0}; +static UDPSocket dhcp_server; +static Thread * dhcpThread = NULL; +static char chaddr_tbl[CONNECT_NUM][6] = {0}; +static const char mac_no_use[6] = {0, 0, 0, 0, 0, 0}; + + +static void dhcp_task_static(void const *argument) { + Endpoint client; + int cnt; + int tbl_index; + + dhcp_server.bind(67); + dhcp_server.set_broadcasting(true); + + while (true) { + int n = dhcp_server.receiveFrom(client, receivebuff, sizeof(receivebuff)); + if (n > 0) { + client.set_address("255.255.255.255", 68); + + sendbuff[OFS_XID + 0] = receivebuff[OFS_XID + 0]; + sendbuff[OFS_XID + 1] = receivebuff[OFS_XID + 1]; + sendbuff[OFS_XID + 2] = receivebuff[OFS_XID + 2]; + sendbuff[OFS_XID + 3] = receivebuff[OFS_XID + 3]; + + tbl_index = -1; + for (cnt = 0; cnt < CONNECT_NUM; cnt++) { + if (memcmp(&receivebuff[OFS_CHADDR], chaddr_tbl[cnt], 6) == 0) { + tbl_index = cnt; + break; + } + } + if (tbl_index == -1) { + sendbuff[OFS_YIADDR + 0] = 0; + sendbuff[OFS_YIADDR + 1] = 0; + sendbuff[OFS_YIADDR + 2] = 0; + sendbuff[OFS_YIADDR + 3] = 0; + } else { + sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0]; + sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1]; + sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2]; + sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index; + } + + sendbuff[OFS_CHADDR + 0] = receivebuff[OFS_CHADDR + 0]; + sendbuff[OFS_CHADDR + 1] = receivebuff[OFS_CHADDR + 1]; + sendbuff[OFS_CHADDR + 2] = receivebuff[OFS_CHADDR + 2]; + sendbuff[OFS_CHADDR + 3] = receivebuff[OFS_CHADDR + 3]; + sendbuff[OFS_CHADDR + 4] = receivebuff[OFS_CHADDR + 4]; + sendbuff[OFS_CHADDR + 5] = receivebuff[OFS_CHADDR + 5]; + + if (receivebuff[OFS_OPTIONS + 2] == DHCP_DISCOVER) { + sendbuff[OFS_OPTIONS + 2] = DHCP_OFFER; + if (tbl_index == -1) { + for (cnt = 0; cnt < CONNECT_NUM; cnt++) { + if (memcmp( chaddr_tbl[cnt], mac_no_use, 6) == 0) { + tbl_index = cnt; + break; + } + } + } + if (tbl_index != -1) { + chaddr_tbl[tbl_index][0] = receivebuff[OFS_CHADDR + 0]; + chaddr_tbl[tbl_index][1] = receivebuff[OFS_CHADDR + 1]; + chaddr_tbl[tbl_index][2] = receivebuff[OFS_CHADDR + 2]; + chaddr_tbl[tbl_index][3] = receivebuff[OFS_CHADDR + 3]; + chaddr_tbl[tbl_index][4] = receivebuff[OFS_CHADDR + 4]; + chaddr_tbl[tbl_index][5] = receivebuff[OFS_CHADDR + 5]; + sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0]; + sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1]; + sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2]; + sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index; + } + dhcp_server.sendTo(client, sendbuff, 300); + } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_REQUEST) { + if (tbl_index != -1) { + sendbuff[OFS_OPTIONS + 2] = DHCP_ACK; + } else { + sendbuff[OFS_OPTIONS + 2] = DHCP_NAK; + } + dhcp_server.sendTo(client, sendbuff, 300); + } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_RELEASE) { + if (tbl_index != -1) { + memset(chaddr_tbl[tbl_index], 0, 6); + } + } else { + // do nothing + } + } + } +} + +DhcpServer::DhcpServer(char * name, char * ipadder) { + int i; + int len; + int ofs; + + sscanf(ipadder, "%d.%d.%d.%d", (int *)&sendbuff[OFS_SIADDR + 0], (int *)&sendbuff[OFS_SIADDR + 1], + (int *)&sendbuff[OFS_SIADDR + 2], (int *)&sendbuff[OFS_SIADDR + 3]); + + len = strlen(name); + for (i = 0; (i < len) && (i < DHCP_SNAME_LEN); i++) { + sendbuff[OFS_SNAME + i] = name[i]; + } + + sendbuff[0] = 0x02; + sendbuff[1] = 0x01; + sendbuff[2] = 0x06; + sendbuff[3] = 0x00; + + sendbuff[OFS_COOKIE + 0] = 0x63; + sendbuff[OFS_COOKIE + 1] = 0x82; + sendbuff[OFS_COOKIE + 2] = 0x53; + sendbuff[OFS_COOKIE + 3] = 0x63; + + ofs = OFS_OPTIONS; + sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE; + sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE_LEN; + sendbuff[ofs++] = 0; + + sendbuff[ofs++] = DHCP_OPTION_SERVER_ID; + sendbuff[ofs++] = 0x04; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3]; + + sendbuff[ofs++] = DHCP_OPTION_LEASE_TIME; + sendbuff[ofs++] = 0x04; + sendbuff[ofs++] = 0x00; + sendbuff[ofs++] = 0x01; + sendbuff[ofs++] = 0x4e; + sendbuff[ofs++] = 0x20; + + sendbuff[ofs++] = DHCP_OPTION_SUBNET_MASK; + sendbuff[ofs++] = 0x04; + sendbuff[ofs++] = 0xff; + sendbuff[ofs++] = 0xff; + sendbuff[ofs++] = 0xff; + sendbuff[ofs++] = 0xf0; + + sendbuff[ofs++] = DHCP_OPTION_ROUTER; + sendbuff[ofs++] = 0x04; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3]; + + sendbuff[ofs++] = DHCP_OPTION_DNS_SERVER; + sendbuff[ofs++] = 0x04; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2]; + sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3]; + + sendbuff[ofs++] = 0xff; + + if (dhcpThread == NULL) { + dhcpThread = new Thread(&dhcp_task_static, NULL, osPriorityNormal, (1024 * 8)); + } +} + +DhcpServer::~DhcpServer() { + if (dhcpThread != NULL) { + delete dhcpThread; + } +}