Berkeley API – Server in C + Client in PHP
- Quinta-feira Jul 16,2009 07:18 PM
- By admin
- In IPv6
If you are a systems administrator responsible for hundreds of servers you may want to monitor them without login in every single server. The solution is quite easy, and the following code (based on my last two posts) can be easily adapted to your needs.
Objective
Remotely access to a box and execute a command without ssh or http on it.
server.c
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
void newConnectionHandler(int sockd){
FILE *stream;
char buffer[100];
int size;
if((size = read(sockd, &buffer, 100)) < 1)
perror("Unable to read from socket");
buffer[size] = 0;
if(strcmp(buffer, "uptime") == 0){
stream = popen("uptime", "r");
sleep(1);
while(fgets(buffer, 2, stream) != NULL)
if(write(sockd, &buffer, strlen(buffer)) < 0)
perror("Unable to write on socket");
pclose(stream);
}
else{
strcpy(buffer, "Unknown command");
if(write(sockd, &buffer, strlen(buffer)) < 0)
perror("Unable to write on socket");
}
close(sockd);
}
int main(int argc, char *argv[])
{
int sockd,newsockd,tmpint;
/* For IPv6
struct sockaddr_in6 socketaddress;
*/
/* For IPv4
struct sockaddr_in socketaddress;
*/
fd_set descriptorslist;
struct timeval timeout;
memset(&socketaddress,0,sizeof(socketaddress));
/* For IPv6
socketaddress.sin6_addr = in6addr_any;
socketaddress.sin6_family = AF_INET6;
socketaddress.sin6_port = htons(8000);
*/
/* For IPv4
socketaddress.sin_addr.s_addr = htonl(INADDR_ANY);
socketaddress.sin_family = AF_INET;
socketaddress.sin_port = htons(8000);
*/
/* For IPv6
if((sockd = socket(AF_INET6, SOCK_STREAM,0))<1){
*/
/* For IPv4
if((sockd = socket(AF_INET, SOCK_STREAM,0))<1){
*/
perror("Unable to create socket");
return 1;
}
// Bind socket sockfd on socketaddress
if(bind(sockd, (struct sockaddr *)&socketaddress, sizeof(socketaddress)) != 0){
perror("Unable to bind socket");
return 1;
}
// Listen on socket, queue up to 10 connections
if(listen(sockd,10) != 0){
perror("Unable to listen on socket ");
return 1;
}
// Clear the socket 'set'
FD_ZERO(&descriptorslist);
// Add sockd to fdread 'set'
FD_SET(sockd, &descriptorslist);
while(1){
switch(select(32, &descriptorslist, NULL, NULL, &timeout)){
case -1:
perror("And error has ocurred");
break;
case 0:
printf("Timeout");
break;
default:
// Default, more than 0, number of descriptors on 'descriptorslist' ready
tmpint = sizeof(socketaddress);
// We fork an handler for the new connection (a new socket is passed as argument)
if(fork() == 0) // The above line is executed on child, where fork() == 0
{
newConnectionHandler(accept(sockd,(struct sockaddr *)&socketaddress, &tmpint));
exit(0);
}
}
}
}
remote.php
<?php
// Create the socket
/* FOR IPv6
if(($sockd = @socket_create(AF_INET6, SOCK_STREAM,SOL_TCP))<1)
*/
/* For IPv4
if(($sockd = @socket_create(AF_INET, SOCK_STREAM,SOL_TCP))<1)
*/
die("Unable to create socket:" . socket_strerror(socket_last_error()));
// Bind socket sockfd on localaddress
if(@socket_bind($sockd, "::1") == FALSE)
die("Unable to bind socket:" . socket_strerror(socket_last_error()));
if(@socket_connect($sockd,"SERVER_IP_HERE", 8000) == FALSE)
die("Unable to connect:" . socket_strerror(socket_last_error()));
$buffer = "1uptime";
if(@socket_write($sockd, $buffer) < strlen($buffer))
die("Unable to connect:" . socket_strerror(socket_last_error()));
unset($buffer);
if(($buffer = socket_read($sockd, 100)) == FALSE)
die("Unable to read from socket:" . socket_strerror(socket_last_error()));
socket_close($sockd);
echo $buffer;
?>