DhcpServer library for mbed-os.
Fork of DhcpServer by
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");
Library in Beta!
This library is in Beta.
このライブラリはβ版です。
DhcpServer.cpp
- Committer:
- dkato
- Date:
- 2018-06-21
- Revision:
- 4:ac6385f9f2db
- Parent:
- 3:bdea854c0ec8
File content as of revision 4:ac6385f9f2db:
#include "mbed.h"
#include "rtos.h"
#include "TCPSocket.h"
#include "TCPServer.h"
#include "SocketAddress.h"
#include "UDPSocket.h"
#include "DhcpServer.h"
/* DHCP message item offsets and length */
#define DHCP_SNAME_LEN 64U
/* DHCP message types */
#define DHCP_DISCOVER 1
#define DHCP_OFFER 2
#define DHCP_REQUEST 3
#define DHCP_DECLINE 4
#define DHCP_ACK 5
#define DHCP_NAK 6
#define DHCP_RELEASE 7
#define DHCP_INFORM 8
/* BootP options */
#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
#define DHCP_OPTION_ROUTER 3
#define DHCP_OPTION_DNS_SERVER 6
/* DHCP options */
#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
#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)
void DhcpServer::dhcp_process(void) {
SocketAddress client;
int cnt;
int tbl_index;
int option;
nsapi_addr_t addr;
const char mac_no_use[6] = {0, 0, 0, 0, 0, 0};
dhcp_server.bind(67);
option = 1;
dhcp_server.setsockopt(0xfff, 0x0020, &option, sizeof(option));
while (true) {
int n = dhcp_server.recvfrom(&client, receivebuff, 500);
if (n > 0) {
addr.version = NSAPI_IPv4;
addr.bytes[0] = 255;
addr.bytes[1] = 255;
addr.bytes[2] = 255;
addr.bytes[3] = 255;
client.set_addr(addr);
client.set_port(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(NetworkInterface *net, const char * name) :
dhcp_server(net), dhcpThread(osPriorityNormal, (1024 * 8)) {
uint32_t i;
uint32_t len;
uint32_t ofs;
receivebuff = new char[500];
sendbuff = new char[300];
memset(sendbuff, 0, 300);
memset(chaddr_tbl, 0, sizeof(chaddr_tbl));
sscanf(net->get_ip_address(), "%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;
dhcpThread.start(callback(this, &DhcpServer::dhcp_process));
}
DhcpServer::~DhcpServer() {
delete [] receivebuff;
delete [] sendbuff;
}
