pyke369 / pdhcp Goto Github PK
View Code? Open in Web Editor NEWan efficient programmable BOOTP/DHCP client/server/relay
License: MIT License
an efficient programmable BOOTP/DHCP client/server/relay
License: MIT License
Missing options
The UEFI bios in some of our servers asks for these options :
"128", (TFTP Server IP address)
"129", (Call Server IP address.)
"130", (Discrimination string.)
"131", (Remote statistics server IP address.)
"132", (802.1P VLAN ID.)
"133", (802.1Q L2 Priority.)
"134", (Diffserv Code Point.)
"135" (HTTP Proxy for phone-specific applications.)
can you implement it ?
Be aware of the broadcast flag, see RFC2131 (page 24):
A client that cannot receive unicast IP datagrams until its protocol software has been
configured with an IP address SHOULD set the BROADCAST bit in the 'flags' field to 1 in any
DHCPDISCOVER or DHCPREQUEST messages that client sends. The BROADCAST bit will provide
a hint to the DHCP server and BOOTP relay agent to broadcast any messages to the client on the
client's subnet.
We are in a relay setup.
The client (here an UEFI PXE network card) set the BROADCAST bit to 1 in its DHCPDISCOVER message.
The juniper gateway forward the message to the pdhcp server, with the bit set to 1
The server replies, but with the bit unset. Then the juniper gateway send the response as an unicast packet which is ignored.
When using a local pdhcp server, since it's not in relay mode, it replies to the broadcast address, regardless of the BROADCAST bit
For our setup to work, pdhcp must read the BROADCAST bit and set it to the same value when used with a relay setup.
As a bonus, when used in broadcast mode, it should respect the BROADCAST bit too.
Attached are network dumps of a valid query, and of the issue detected, client side, and pdhcp server side
/home/euclide/dev/pdhcp/src/dhcp.cpp:752:41: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if (*frame_size > ((ssize_t)sizeof(frame->options) - (2 + (nvalue[0] / 2))))
^
/home/euclide/dev/pdhcp/src/dhcp.cpp:774:41: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if (*frame_size > (ssize_t)sizeof(frame->options) - (2 + (option->size[1] * items)))
^
/home/euclide/dev/pdhcp/src/dhcp.cpp:798:45: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if (*frame_size > (ssize_t)sizeof(frame->options) - (2 + (option->size[1] * items)))
^
/home/euclide/dev/pdhcp/src/dhcp.cpp:827:45: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if (*frame_size > (ssize_t)sizeof(frame->options) - (2 + nvalue[0]))
^
/home/euclide/dev/pdhcp/src/dhcp.cpp:867:49: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if (*frame_size > (ssize_t)sizeof(frame->options) - (2 + (option->size[1] * items)))
^
/home/euclide/dev/pdhcp/src/dhcp.cpp:884:41: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if (*frame_size > (ssize_t)sizeof(frame->options) - (2 + (option->size[1] * items)))
^
/home/euclide/dev/pdhcp/src/dhcp.cpp:917:41: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if (*frame_size > (ssize_t)sizeof(frame->options) - (2 + (option->size[1] * items)))
^
cc1plus: all warnings being treated as errors```
https://github.com/pyke369/pdhcp/tree/d6ed167c2b94b925cb03fff379886fcb51bf8f86
栈溢出
首先在 service_handler 从网络中接收数据, packet 为 512 字节,然后会传入 dhcp_decode 进行dhcp解码
// service handler
void service_handler(struct ev_loop *loop, struct ev_io *watcher, int events)
{
uint8_t packet[BUFSIZ];
char output[BUFSIZ], message[256];
gettimeofday(&now, NULL);
ssize = sizeof(frame->remote);
frame = (DHCP_FRAME *)packet;
if ((size = recvfrom(service, packet, sizeof(packet), 0, (struct sockaddr *)&frame->remote, &ssize)) > 0)
{
if (dhcp_decode(frame, size, output, sizeof(output), message, sizeof(message)))
{
dhcp_decode 函数中将 packet 当作 DHCP_FRAME 结构体处理,但是DHCP_FRAME 的大小远远大于BUFSIZ, 导致在该函数中会越界写
bool dhcp_decode(DHCP_FRAME *frame, ssize_t frame_size, char *output, ssize_t output_size, char *error, size_t error_size)
{
output[strlen(output) - 1] = '}';
memcpy(frame->key, frame->chaddr, ETH_ALEN); // 直接修改frame+0x901
memcpy(frame->key + ETH_ALEN, (uint8_t *)&(frame->xid), 4); // 修改 frame + 0x907
frame->key[10] = frame->dhcp_type;
frame->expire = time(NULL) + 10;
return true;
}
A programmable DCHP client/server -> A programmable DHCP client/server
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.