DhcpServer library for mbed-os.

Fork of DhcpServer by Daiki Kato

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(&eth, "HostName");


Library in Beta!

This library is in Beta.
このライブラリはβ版です。

Committer:
dkato
Date:
Thu Jun 21 10:37:18 2018 +0000
Revision:
4:ac6385f9f2db
Parent:
3:bdea854c0ec8
Supports mbed-os 5.9.1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:1c2747611cab 1 #include "mbed.h"
dkato 0:1c2747611cab 2 #include "rtos.h"
dkato 2:4a34731d231e 3 #include "TCPSocket.h"
dkato 2:4a34731d231e 4 #include "TCPServer.h"
dkato 2:4a34731d231e 5 #include "SocketAddress.h"
dkato 0:1c2747611cab 6 #include "UDPSocket.h"
dkato 0:1c2747611cab 7 #include "DhcpServer.h"
dkato 0:1c2747611cab 8
dkato 4:ac6385f9f2db 9 /* DHCP message item offsets and length */
dkato 4:ac6385f9f2db 10 #define DHCP_SNAME_LEN 64U
dkato 4:ac6385f9f2db 11
dkato 4:ac6385f9f2db 12 /* DHCP message types */
dkato 4:ac6385f9f2db 13 #define DHCP_DISCOVER 1
dkato 4:ac6385f9f2db 14 #define DHCP_OFFER 2
dkato 4:ac6385f9f2db 15 #define DHCP_REQUEST 3
dkato 4:ac6385f9f2db 16 #define DHCP_DECLINE 4
dkato 4:ac6385f9f2db 17 #define DHCP_ACK 5
dkato 4:ac6385f9f2db 18 #define DHCP_NAK 6
dkato 4:ac6385f9f2db 19 #define DHCP_RELEASE 7
dkato 4:ac6385f9f2db 20 #define DHCP_INFORM 8
dkato 4:ac6385f9f2db 21
dkato 4:ac6385f9f2db 22 /* BootP options */
dkato 4:ac6385f9f2db 23 #define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
dkato 4:ac6385f9f2db 24 #define DHCP_OPTION_ROUTER 3
dkato 4:ac6385f9f2db 25 #define DHCP_OPTION_DNS_SERVER 6
dkato 4:ac6385f9f2db 26
dkato 4:ac6385f9f2db 27 /* DHCP options */
dkato 4:ac6385f9f2db 28 #define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
dkato 4:ac6385f9f2db 29
dkato 4:ac6385f9f2db 30 #define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
dkato 4:ac6385f9f2db 31 #define DHCP_OPTION_MESSAGE_TYPE_LEN 1
dkato 4:ac6385f9f2db 32
dkato 4:ac6385f9f2db 33 #define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
dkato 4:ac6385f9f2db 34
dkato 4:ac6385f9f2db 35
dkato 0:1c2747611cab 36 #define IP_ADDER_START (10)
dkato 0:1c2747611cab 37
dkato 0:1c2747611cab 38 #define OFS_XID (4)
dkato 0:1c2747611cab 39 #define OFS_YIADDR (16)
dkato 0:1c2747611cab 40 #define OFS_SIADDR (20)
dkato 0:1c2747611cab 41 #define OFS_CHADDR (28)
dkato 0:1c2747611cab 42 #define OFS_SNAME (44)
dkato 0:1c2747611cab 43 #define OFS_COOKIE (236)
dkato 0:1c2747611cab 44 #define OFS_OPTIONS (240)
dkato 0:1c2747611cab 45
dkato 2:4a34731d231e 46 void DhcpServer::dhcp_process(void) {
dkato 2:4a34731d231e 47 SocketAddress client;
dkato 0:1c2747611cab 48 int cnt;
dkato 0:1c2747611cab 49 int tbl_index;
dkato 2:4a34731d231e 50 int option;
dkato 2:4a34731d231e 51 nsapi_addr_t addr;
dkato 2:4a34731d231e 52 const char mac_no_use[6] = {0, 0, 0, 0, 0, 0};
dkato 0:1c2747611cab 53
dkato 0:1c2747611cab 54 dhcp_server.bind(67);
dkato 2:4a34731d231e 55 option = 1;
dkato 2:4a34731d231e 56 dhcp_server.setsockopt(0xfff, 0x0020, &option, sizeof(option));
dkato 0:1c2747611cab 57
dkato 0:1c2747611cab 58 while (true) {
dkato 2:4a34731d231e 59 int n = dhcp_server.recvfrom(&client, receivebuff, 500);
dkato 0:1c2747611cab 60 if (n > 0) {
dkato 2:4a34731d231e 61 addr.version = NSAPI_IPv4;
dkato 2:4a34731d231e 62 addr.bytes[0] = 255;
dkato 2:4a34731d231e 63 addr.bytes[1] = 255;
dkato 2:4a34731d231e 64 addr.bytes[2] = 255;
dkato 2:4a34731d231e 65 addr.bytes[3] = 255;
dkato 2:4a34731d231e 66 client.set_addr(addr);
dkato 2:4a34731d231e 67 client.set_port(68);
dkato 0:1c2747611cab 68
dkato 0:1c2747611cab 69 sendbuff[OFS_XID + 0] = receivebuff[OFS_XID + 0];
dkato 0:1c2747611cab 70 sendbuff[OFS_XID + 1] = receivebuff[OFS_XID + 1];
dkato 0:1c2747611cab 71 sendbuff[OFS_XID + 2] = receivebuff[OFS_XID + 2];
dkato 0:1c2747611cab 72 sendbuff[OFS_XID + 3] = receivebuff[OFS_XID + 3];
dkato 0:1c2747611cab 73
dkato 0:1c2747611cab 74 tbl_index = -1;
dkato 0:1c2747611cab 75 for (cnt = 0; cnt < CONNECT_NUM; cnt++) {
dkato 0:1c2747611cab 76 if (memcmp(&receivebuff[OFS_CHADDR], chaddr_tbl[cnt], 6) == 0) {
dkato 0:1c2747611cab 77 tbl_index = cnt;
dkato 0:1c2747611cab 78 break;
dkato 0:1c2747611cab 79 }
dkato 0:1c2747611cab 80 }
dkato 0:1c2747611cab 81 if (tbl_index == -1) {
dkato 0:1c2747611cab 82 sendbuff[OFS_YIADDR + 0] = 0;
dkato 0:1c2747611cab 83 sendbuff[OFS_YIADDR + 1] = 0;
dkato 0:1c2747611cab 84 sendbuff[OFS_YIADDR + 2] = 0;
dkato 0:1c2747611cab 85 sendbuff[OFS_YIADDR + 3] = 0;
dkato 0:1c2747611cab 86 } else {
dkato 0:1c2747611cab 87 sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 88 sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 89 sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 90 sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index;
dkato 0:1c2747611cab 91 }
dkato 0:1c2747611cab 92
dkato 0:1c2747611cab 93 sendbuff[OFS_CHADDR + 0] = receivebuff[OFS_CHADDR + 0];
dkato 0:1c2747611cab 94 sendbuff[OFS_CHADDR + 1] = receivebuff[OFS_CHADDR + 1];
dkato 0:1c2747611cab 95 sendbuff[OFS_CHADDR + 2] = receivebuff[OFS_CHADDR + 2];
dkato 0:1c2747611cab 96 sendbuff[OFS_CHADDR + 3] = receivebuff[OFS_CHADDR + 3];
dkato 0:1c2747611cab 97 sendbuff[OFS_CHADDR + 4] = receivebuff[OFS_CHADDR + 4];
dkato 0:1c2747611cab 98 sendbuff[OFS_CHADDR + 5] = receivebuff[OFS_CHADDR + 5];
dkato 0:1c2747611cab 99
dkato 0:1c2747611cab 100 if (receivebuff[OFS_OPTIONS + 2] == DHCP_DISCOVER) {
dkato 0:1c2747611cab 101 sendbuff[OFS_OPTIONS + 2] = DHCP_OFFER;
dkato 0:1c2747611cab 102 if (tbl_index == -1) {
dkato 0:1c2747611cab 103 for (cnt = 0; cnt < CONNECT_NUM; cnt++) {
dkato 0:1c2747611cab 104 if (memcmp( chaddr_tbl[cnt], mac_no_use, 6) == 0) {
dkato 0:1c2747611cab 105 tbl_index = cnt;
dkato 0:1c2747611cab 106 break;
dkato 0:1c2747611cab 107 }
dkato 0:1c2747611cab 108 }
dkato 0:1c2747611cab 109 }
dkato 0:1c2747611cab 110 if (tbl_index != -1) {
dkato 0:1c2747611cab 111 chaddr_tbl[tbl_index][0] = receivebuff[OFS_CHADDR + 0];
dkato 0:1c2747611cab 112 chaddr_tbl[tbl_index][1] = receivebuff[OFS_CHADDR + 1];
dkato 0:1c2747611cab 113 chaddr_tbl[tbl_index][2] = receivebuff[OFS_CHADDR + 2];
dkato 0:1c2747611cab 114 chaddr_tbl[tbl_index][3] = receivebuff[OFS_CHADDR + 3];
dkato 0:1c2747611cab 115 chaddr_tbl[tbl_index][4] = receivebuff[OFS_CHADDR + 4];
dkato 0:1c2747611cab 116 chaddr_tbl[tbl_index][5] = receivebuff[OFS_CHADDR + 5];
dkato 0:1c2747611cab 117 sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 118 sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 119 sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 120 sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index;
dkato 0:1c2747611cab 121 }
dkato 2:4a34731d231e 122 dhcp_server.sendto(client, sendbuff, 300);
dkato 0:1c2747611cab 123 } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_REQUEST) {
dkato 0:1c2747611cab 124 if (tbl_index != -1) {
dkato 0:1c2747611cab 125 sendbuff[OFS_OPTIONS + 2] = DHCP_ACK;
dkato 0:1c2747611cab 126 } else {
dkato 0:1c2747611cab 127 sendbuff[OFS_OPTIONS + 2] = DHCP_NAK;
dkato 0:1c2747611cab 128 }
dkato 2:4a34731d231e 129 dhcp_server.sendto(client, sendbuff, 300);
dkato 0:1c2747611cab 130 } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_RELEASE) {
dkato 0:1c2747611cab 131 if (tbl_index != -1) {
dkato 0:1c2747611cab 132 memset(chaddr_tbl[tbl_index], 0, 6);
dkato 0:1c2747611cab 133 }
dkato 0:1c2747611cab 134 } else {
dkato 0:1c2747611cab 135 // do nothing
dkato 0:1c2747611cab 136 }
dkato 0:1c2747611cab 137 }
dkato 0:1c2747611cab 138 }
dkato 0:1c2747611cab 139 }
dkato 0:1c2747611cab 140
dkato 3:bdea854c0ec8 141 DhcpServer::DhcpServer(NetworkInterface *net, const char * name) :
dkato 2:4a34731d231e 142 dhcp_server(net), dhcpThread(osPriorityNormal, (1024 * 8)) {
dkato 2:4a34731d231e 143 uint32_t i;
dkato 2:4a34731d231e 144 uint32_t len;
dkato 2:4a34731d231e 145 uint32_t ofs;
dkato 0:1c2747611cab 146
dkato 2:4a34731d231e 147 receivebuff = new char[500];
dkato 2:4a34731d231e 148 sendbuff = new char[300];
dkato 2:4a34731d231e 149 memset(sendbuff, 0, 300);
dkato 2:4a34731d231e 150 memset(chaddr_tbl, 0, sizeof(chaddr_tbl));
dkato 2:4a34731d231e 151
dkato 2:4a34731d231e 152 sscanf(net->get_ip_address(), "%d.%d.%d.%d", (int *)&sendbuff[OFS_SIADDR + 0], (int *)&sendbuff[OFS_SIADDR + 1],
dkato 0:1c2747611cab 153 (int *)&sendbuff[OFS_SIADDR + 2], (int *)&sendbuff[OFS_SIADDR + 3]);
dkato 0:1c2747611cab 154
dkato 0:1c2747611cab 155 len = strlen(name);
dkato 0:1c2747611cab 156 for (i = 0; (i < len) && (i < DHCP_SNAME_LEN); i++) {
dkato 0:1c2747611cab 157 sendbuff[OFS_SNAME + i] = name[i];
dkato 0:1c2747611cab 158 }
dkato 0:1c2747611cab 159
dkato 0:1c2747611cab 160 sendbuff[0] = 0x02;
dkato 0:1c2747611cab 161 sendbuff[1] = 0x01;
dkato 0:1c2747611cab 162 sendbuff[2] = 0x06;
dkato 0:1c2747611cab 163 sendbuff[3] = 0x00;
dkato 0:1c2747611cab 164
dkato 0:1c2747611cab 165 sendbuff[OFS_COOKIE + 0] = 0x63;
dkato 0:1c2747611cab 166 sendbuff[OFS_COOKIE + 1] = 0x82;
dkato 0:1c2747611cab 167 sendbuff[OFS_COOKIE + 2] = 0x53;
dkato 0:1c2747611cab 168 sendbuff[OFS_COOKIE + 3] = 0x63;
dkato 0:1c2747611cab 169
dkato 0:1c2747611cab 170 ofs = OFS_OPTIONS;
dkato 0:1c2747611cab 171 sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE;
dkato 0:1c2747611cab 172 sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE_LEN;
dkato 0:1c2747611cab 173 sendbuff[ofs++] = 0;
dkato 0:1c2747611cab 174
dkato 0:1c2747611cab 175 sendbuff[ofs++] = DHCP_OPTION_SERVER_ID;
dkato 0:1c2747611cab 176 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 177 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 178 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 179 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 180 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
dkato 0:1c2747611cab 181
dkato 0:1c2747611cab 182 sendbuff[ofs++] = DHCP_OPTION_LEASE_TIME;
dkato 0:1c2747611cab 183 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 184 sendbuff[ofs++] = 0x00;
dkato 0:1c2747611cab 185 sendbuff[ofs++] = 0x01;
dkato 0:1c2747611cab 186 sendbuff[ofs++] = 0x4e;
dkato 0:1c2747611cab 187 sendbuff[ofs++] = 0x20;
dkato 0:1c2747611cab 188
dkato 0:1c2747611cab 189 sendbuff[ofs++] = DHCP_OPTION_SUBNET_MASK;
dkato 0:1c2747611cab 190 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 191 sendbuff[ofs++] = 0xff;
dkato 0:1c2747611cab 192 sendbuff[ofs++] = 0xff;
dkato 0:1c2747611cab 193 sendbuff[ofs++] = 0xff;
dkato 0:1c2747611cab 194 sendbuff[ofs++] = 0xf0;
dkato 0:1c2747611cab 195
dkato 0:1c2747611cab 196 sendbuff[ofs++] = DHCP_OPTION_ROUTER;
dkato 0:1c2747611cab 197 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 198 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 199 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 200 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 201 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
dkato 0:1c2747611cab 202
dkato 0:1c2747611cab 203 sendbuff[ofs++] = DHCP_OPTION_DNS_SERVER;
dkato 0:1c2747611cab 204 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 205 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 206 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 207 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 208 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
dkato 0:1c2747611cab 209
dkato 0:1c2747611cab 210 sendbuff[ofs++] = 0xff;
dkato 0:1c2747611cab 211
dkato 2:4a34731d231e 212 dhcpThread.start(callback(this, &DhcpServer::dhcp_process));
dkato 0:1c2747611cab 213 }
dkato 0:1c2747611cab 214
dkato 0:1c2747611cab 215 DhcpServer::~DhcpServer() {
dkato 2:4a34731d231e 216 delete [] receivebuff;
dkato 2:4a34731d231e 217 delete [] sendbuff;
dkato 0:1c2747611cab 218 }