My PHP script uses raw socket to capture icmp packets, but actually it falis. the script is as follows:
<?php
$protocal = getprotobyname("icmp");
$socket = socket_create(AF_INET,SOCK_RAW,$protocal) or die("Cannot create socket");
while(true){
$read = array($socket); $write = NULL; $except = NULL;
$select = socket_select($read, $write, $except, $timeout=1, 300*1000);
if ($select === false){
echo "socket_select error";
continue;
}
elseif($select === 0){
echo "SocketSelect time out";
continue;
}
socket_recvfrom($socket, $recv, 65535, 0, $host, $port);
print($recv);
sleep(1);
}
?>
when I run the script on a host AAA with the ip of 192.168.1.72 on an Ethernet LAN ,and I use "ping 192.168.1.72 -t" cmd on another host BBB , the ping cmd can get echo from host AAA, and it is expected that the above running script on host AAA can capture the icmp request packet from BBB and print some message, however actually the script just print 'SocketSelect time out' repeatly .
can someone help to work out what is wrong with the php script ?
Related
I have a socket server program written in PHP and run by Fedora 21-apache, listening on a port.
<?php
set_time_limit (0);
$address = '1.2.3.4';
$port = "19000";
$con = 1;
$word = "";
$sock = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
$bind = socket_bind($sock, $address, $port) or die("Could not bind to socket\n");
socket_listen($sock);
while ($con == 1)
{
$client = socket_accept($sock);
$input = socket_read($client, 50);
if ($input == 'exit')
{
$close = socket_close($sock);
$con = 0;
}
else {
$input = trim($input) . "," . date('Y-m-d H:i:s') . "\n";
$file= "/home/xyz/data/" . "uls_" . date("Ymd_His") . ".dat";
file_put_contents($file, $input);
}
}
?>
The client is actually a device. Currently there is only one device running.
As per the documentation provided by the device,
"It acts as a TCP client and opens a TCP socket session to the Server. The
device then sends a message and disconnects the socket session. Failed connections force retries"
Now I am able to get data from this client. The problem is that after say 4-5 Hours client is not able to push data.The server socket hangs.
The netstat -taun command shows following.
tcp 0 0 1.2.3.4:19000 0.0.0.0:* LISTEN
tcp 0 0 1.2.3.4:19000 3.4.5.6:20721 ESTABLISHED
Sometimes more than one client connections could be seen.
I can confirm that the client is still running during this time. I tried to connect to this server socket through another client socket script.
The result says, client request made but server socket did not respond.
If restart the web server, and run the server script again, everyrthing works normal for sometime.
Could anyone help me identify the problem.
I ran with the same probleme, i fixed it by closing the resource built by socket_accept()
while ($con == 1)
{
$client = socket_accept($sock);
$input = socket_read($client, 50);
if ($input == 'exit')
{
$close = socket_close($sock);
$con = 0;
}
else {
$input = trim($input) . "," . date('Y-m-d H:i:s') . "\n";
$file= "/home/xyz/data/" . "uls_" . date("Ymd_His") . ".dat";
file_put_contents($file, $input);
}
// #param2 - 1 => block writing in socket ...
socket_shutdown ($client , 1) ;
socket_close ($client ) ;
}
I'm coding a php socket server script which is running on ubuntu.
It works well, clients can connect/disconnect to this server.
But the server is shutting down silently when a client connect to this server that didn't have any client connected for a long time.
I setted up timeout to 0 (unlimited) but the server is stoping without any errors or messages... like this.
root#exfl:/home/projectap/sec/server_core# php socket_server.php
[exfl.kr] Starting AbsolutePitch socket server...
[2014.06.21 16:50:58] Server is listening. PID: 6442
[2014.06.21 17:28:48] Client [192.168.0.1:8795] connected to the server.
root#exfl:/home/projectap/sec/server_core#
I coded for this server like this.
<?php
set_time_limit(0);
error_reporting(E_ALL);
ini_set("memory_limit","2048M");
ini_set("max_execution_time", "0");
if(posix_getpid() == true) {
echo "[exfl.kr] Starting AbsolutePitch socket server...\n";
} else {
echo getTimeToStr()."Server is already running.\n";
}
$cSock = array();
$socketsInformation = array();
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$bind = socket_bind($socket, "0.0.0.0", "24180");
$listen = socket_listen($socket, 5);
echo getTimeToStr()."Server is listening. PID: ".posix_getpid()."\n";
while(true) {
$sockArr = array_merge(array($socket), $cSock);
if(socket_select($sockArr, $tWrite = null, $tExcept = null, null) > 0) {
foreach($sockArr as $sock){
if($sock == $socket){
$tSock = socket_accept($socket);
socket_getpeername($tSock, $sockIp, $sockPort);
array_push($cSock, $tSock);
array_push($socketsInformation, array("SOCKETINDEX"=>(count($cSock)-1), "IP"=>$sockIp, "USERID"=>"", "STATUS"=>"", "AUTH"=>false));
echo getTimeToStr()."Client [".$sockIp.":".$sockPort."] connected to the server.\n";
} else {
...
}
}
}
}
echo getTimeToStr()."Server closed.\n";
...
?>
When the server stops suddenly, it isn't outputing a "Server closed" message..
Please help.
Sorry for my bad English.
You may want to try socket_set_options() with SO_KEEPALIVE. To know more about your options use the socket_get_options page:
https://www.php.net/manual/en/function.socket-get-option.php
To know more about the usage of socket_set_options() use:
https://www.php.net/manual/en/function.socket-set-option.php
Issue at Hand: Intercepting a print request and modifying the data within the job to add content to it.
Solution so far: Here's the solution that has worked for the windows xp machines
1. Redirect the default printer to a raw TCP/IP port say 9100.
2. Write a basic socket server which listens on the port 9100 and accepts connections when they occur.
3. Read from the socket and modify the content before writing to a virtual printer which redirects to actual port that the default printer was on.
Problem: Steps 1 and 2 do not seem to work on windows 7.. Can someone please help..?
Here is the socket server code(very basic)...
<?php
// set some variables
$host = "127.0.0.1";
$port = 9100;
// don't timeout!
set_time_limit(0);
if(($sock = socket_create(AF_INET, SOCK_STREAM, 0)) < 0)
{
echo "failed to create socket: ".socket_strerror($sock)."\n";
exit();
}
if(($ret = socket_bind($sock, $host, $port)) < 0)
{
echo "failed to bind socket: ".socket_strerror($ret)."\n";
exit();
}
if( ( $ret = socket_listen( $sock, 0 ) ) < 0 )
{
echo "failed to listen to socket: ".socket_strerror($ret)."\n";
exit();
}
socket_set_nonblock($sock);
echo "waiting for clients to connect\n";
while (true)
{
$connection = #socket_accept($sock);
if ($connection === false)
{
usleep(100);
}elseif ($connection > 0)
{
//handle_client($sock, $connection);
}else
{
echo "error: ".socket_strerror($connection);
die;
}
}
So at this point, when a print job happens to a default printer, the server should accept the connection but that is not the case. A basic socket client which performs a socket_create, socket_connect and sends a socket_write works fine.. But the same thing does not happen when a print job to the same port is being sent. It works fine on windows XP. Can someone please help?
Found that on windows 7 IPV6 sockets are used by printers by default. If you run a microsoft fixit to prefer IPV4 over IPV6 or create a IPV6 socket it should work. – user2693294
I am writing a port scanner in PHP that supports small ranges (e.g., ports 21-25). The ports and IP to be scanned are sent to the server via AJAX, and then PHP attempts to open a socket on each of the ports. If it succeeds, the port is open, if it times out, the port is closed.
Currently, despite sending all of the AJAX requests at the same time for ports 21-25, each socket is only opened after the last one closes. So, port 21 is checked, the socket is closed, and then port 22 is checked, and so on. What I want is for all ports to be checked concurrently, so I'd be opening several sockets at once.
I've tried:
$fp = #fsockopen($ip,$port,$errno,$errstr,2);
socket_set_nonblock($fp);
But this doesn't work, as I'm setting non-block AFTER the socket has already been opened and is waiting for a response. Is what I'm trying to do possible in PHP?
Use different functions: socket_create() and socket_connect() instead of fsockopen(). This works:
$socks = array();
for ($port = 21; $port <= 25; $port++) {
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sock);
#socket_connect($sock, 'localhost', $port);
$socks[$port] = $sock;
}
$startTime = microtime(true);
while ($socks && microtime(true) - $startTime < 3) {
$null = null;
$write = $socks;
socket_select($null, $write, $null, 1);
foreach ($write as $port => $sock) {
$desc = "$port/tcp";
$errno = socket_get_option($sock, SOL_SOCKET, SO_ERROR);
if ($errno == 0) {
echo "$desc open\n";
} elseif ($errno == SOCKET_ECONNREFUSED) {
echo "$desc closed\n";
} elseif ($errno == SOCKET_ETIMEDOUT) {
echo "$desc filtered\n";
} else {
$errmsg = socket_strerror($errno);
echo "$desc error $errmsg\n";
}
unset($socks[$port]);
socket_close($sock);
}
}
foreach ($socks as $port => $sock) {
$desc = "$port/tcp";
echo "$desc filtered\n";
socket_close($sock);
}
I created a PHP Socket Server with PHP_NORMAL_READ mode. So, a message to the server is read when it ends with \n or \r. I tried it by connecting to the server with multiple telnet instances, and it works great.
However, when I connect to the server with 1 flash application and 1 telnet application (I first start the flash one), the flash one seems to make the server hang - the server is getting stuck somewhere and no longer receiving data from eg. the telnet client.
Because anyone can code a flash client, this has to be fixed server side. The server's code:
<?php
// config
$timelimit = 60; // amount of seconds the server should run for, 0 = run indefintely
$port = 9000; // the port to listen on
$address = $_SERVER['SERVER_ADDR']; // the server's external IP
$backlog = SOMAXCONN; // the maximum of backlog incoming connections that will be queued for processing
// configure custom PHP settings
error_reporting(1); // report all errors
ini_set('display_errors', 1); // display all errors
set_time_limit($timelimit); // timeout after x seconds
ob_implicit_flush(); // results in a flush operation after every output call
//create master IPv4 based TCP socket
if (!($master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) die("Could not create master socket, error: ".socket_strerror(socket_last_error()));
// set socket options (local addresses can be reused)
if (!socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1)) die("Could not set socket options, error: ".socket_strerror(socket_last_error()));
// bind to socket server
if (!socket_bind($master, $address, $port)) die("Could not bind to socket server, error: ".socket_strerror(socket_last_error()));
// start listening
if (!socket_listen($master, $backlog)) die("Could not start listening to socket, error: ".socket_strerror(socket_last_error()));
//display startup information
echo "[".date('Y-m-d H:i:s')."] SERVER CREATED (MAXCONN: ".SOMAXCONN.").\n"; //max connections is a kernel variable and can be adjusted with sysctl
echo "[".date('Y-m-d H:i:s')."] Listening on ".$address.":".$port.".\n";
$time = time(); //set startup timestamp
// init read sockets array
$read_sockets = array($master);
// continuously handle incoming socket messages, or close if time limit has been reached
while ((!$timelimit) or (time() - $time < $timelimit)) {
$changed_sockets = $read_sockets;
socket_select($changed_sockets, $write = null, $except = null, null);
foreach($changed_sockets as $socket) {
if ($socket == $master) {
if (($client = socket_accept($master)) < 0) {
continue;
} else {
array_push($read_sockets, $client);
}
} else {
$data = #socket_read($socket, 1024, PHP_NORMAL_READ); //read a maximum of 1024 bytes until a new line has been sent
if ($data === false) { //the client disconnected
$index = array_search($socket, $read_sockets);
unset($read_sockets[$index]);
socket_close($socket);
} elseif ($data = trim($data)) { //remove whitespace and continue only if the message is not empty
echo "we received: ".$data."\n\n";
//handleData($data, $socket);
}
}
}
}
socket_close($master); //close the socket
echo "[".date('Y-m-d H:i:s')."] SERVER CLOSED.\n";
//function to write to the flash client
function flash_write($socket, $msg) {
socket_write($socket, $msg.chr(0x0));
}
?>
Does anyone know what may cause this? I tried changing the timeout on the socket_select from none to 0 (instant return), but that didn't seem to change anything.
Could you post the source of the flash client? That would show what the problem is?
Are you sure the last thing you send from the flash client is a \n ?
Otherwise the server would block on socket_read() as the flash client socket can be read without blocking (triggered socket_select()), but doesn't send the ending \n.
One thing to help you debug: error_reporting(1) does not enable the display of all errors. Look at the documentation at http://us3.php.net/manual/en/function.error-reporting.php. You need something like error_reporting(E_ALL).