|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2007-03-01 00:41 UTC] matth at mystictrd dot com
Description:
------------
A SOCK_DGRAM SOL_UDP socket using socket_bind to an IP address
associated with an interface will not see UDP broadcasts destined to
255.255.255.255. I do not know if this is intended but you can see them
when listening on 0.0.0.0
Reproduce code:
---------------
<?php
//listens for dhcp requests
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
//you must bind to 0.0.0.0 to actually see anything
socket_bind($socket, "10.66.66.1", 67);
while(1)
{
if($src = @socket_recv($socket, $data, 9999, 0))
{
echo "data!\n";
}
}
?>
Expected result:
----------------
When a DHCP request is made we should see "data!" echoed.
Actual result:
--------------
Nothing was read on the interface - it can only see localhost or direct
packets sent to it (destination interface IP address).
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 16:00:01 2025 UTC |
The reason why is if you take a normal DHCP server you can typically listen on multiple interfaces. If one wanted to know what interface is receiving the data you would think to bind on the interfaces IP address. But since you cannot see that type of packet binding to an IP like that you must bind to 0 or 0.0.0.0 which doesn't help with knowing what interface recieved the data since the data does not contain information about interface mac/ip destination from the client. I'm not positive if this is a PHP issue or not but I believe you can do it in C/C++ and that you should be able to do it with PHP. A work around I'm experimenting with goes as: <?php $interface_ip = "10.66.66.1"; $interface_port = 67; //listens for dhcp requests $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); //you must bind to 0.0.0.0 to actually see anything socket_bind($socket, 0, 67); while(1) { if($src = @socket_recvfrom($socket, $data, 9999, 0, $interface_ip, $interface_port)) { echo "data!\n"; } } ?>My first message had a working example but here it is again with more information. The purpose is to see DHCP requests from a DHCP Client. So use a DHCP Client to get an IP address on a system thats on the same network that this script is running on. This first example WON'T see the packets: <?php $ip = "ENTER YOUR IP ADDRESS HERE"; //example: 192.168.0.100 $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_bind($socket, $ip, 67); while(1) { if($src = @socket_recv($socket, $data, 9999, 0)) { echo "data!\n"; } } ?> This second example WILL see the packets: <?php $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_bind($socket, 0, 67); while(1) { if($src = @socket_recv($socket, $data, 9999, 0)) { echo "data!\n"; } } ?> This reference might give you a better idea of what I'm talking about: http://en.wikipedia.org/wiki/Dhcp#DHCP_discoveryHy! I solved the problem: <?php $bc_socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); // for broadcast packets $if_socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); // for answer packets socket_bind($bc_socket, "255.255.255.255", 67); // listen to discover pcks. socket_bind($if_socket, "10.0.0.1", 67); // target interface address socket_set_option($bc_socket, SOL_SOCKET, SO_BROADCAST, 1); socket_set_option($bc_socket, SOL_SOCKET, SO_REUSEADDR, 1); socket_set_option($bc_socket, SOL_SOCKET, SO_DEBUG, 0); socket_set_option($if_socket, SOL_SOCKET, SO_BROADCAST, 1); socket_set_option($if_socket, SOL_SOCKET, SO_REUSEADDR, 1); socket_set_option($if_socket, SOL_SOCKET, SO_DEBUG, 0); while(1) { if($src = @socket_recv($bc_socket, $data, 9999, 0)) { echo "data!\n"; $senddata = "...."; socket_sendto($if_socket, $senddata, strlen($senddata),0, "255.255.255.255", 68); } } ?>