Blog der Heimetli Software AG

Ein Programm ausführen wenn ein UDP-Paket eintrifft

Das folgende Programm wartet auf ein UDP-Paket an einem angegebenen Port. Sobald dort ein Paket eintrifft, wird ein Script oder Programm ausgeführt.

Aufruf

$ ./udpexecute 7777 /bin/echo works fine!
udpexecute V1.00
works fine!
works fine!
  • 7777 ist das Port
  • /bin/echo wird ausgeführt wenn ein Paket eintrifft
  • works ist das erste Argument für /bin/echo
  • fine! ist das zweite Argument für /bin/echo

Das angegebene Programm muss entweder ein ELF oder ein Script mit einem Shebang sein. echo allein funktioniert nicht, weil es ein Shell-Builtin ist.

Alle Argumente werden unverändert weitergereicht.

Source

Der Code sollte weitgehend selbsterklärend sein für Leute die C kennen, und schon einmal auf Linux entwickelt haben.

/******************************************************************************/
/*                                                                            */
/*                                                       FILE: udpexecute.cpp */
/*                                                                            */
/*  Executes a program when a UDP packet is received                          */
/*  ================================================                          */
/*                                                                            */
/*  V1.00   24-APR-2018   Te                                                  */
/*                                                                            */
/******************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/****************************/
 int CreateSocket( int port )
/****************************/

{
    // Create a socket
    int sock = socket( AF_INET, SOCK_DGRAM, 0 ) ;

    if( sock == -1 )
    {
       fprintf( stderr, "CreateSocket: socket failed\n" ) ;
       return -1 ;
    }

    // Bind it to the local address
    struct sockaddr_in address ;

    memset( &address, 0, sizeof(address) ) ;

    address.sin_family      = AF_INET ;
    address.sin_addr.s_addr = htonl( INADDR_ANY ) ;
    address.sin_port        = htons( port ) ;

    if( bind(sock,(struct sockaddr *)&address,sizeof(address)) == -1 )
    {
       fprintf( stderr, "CreateSocket: bind failed\n" ) ;
       close( sock ) ;
       return -1 ;
    }

    return sock ;
}

/**********************************/
 int main( int argc, char *argv[] )
/**********************************/

{
   fprintf( stderr, "udpexecute V1.00\n" ) ;

   if( argc < 3 )
   {
      fprintf( stderr, "usage: %s port program [args]\n", argv[0] ) ;
      return 1 ;
   }

   int socket = CreateSocket( atoi(argv[1]) ) ;

   if( socket == -1 )
   {
      fprintf( stderr, "error: can't create socket\n" ) ;
      return 2 ;
   }

   struct sockaddr_in address ;
   char   line[256] ;
   int    status ;
   int    size ;

   for( ;; )
   {
       socklen_t length = sizeof( address ) ;
       size = recvfrom( socket, line, sizeof(line), 0, (struct sockaddr *)&address, &length ) ;

       if( size < 1 )
       {
          fprintf( stderr, "error: recvfrom failed\n" ) ;
          break ;
       }

       pid_t pid = fork() ;

       switch( pid )
       {
	  case -1: fprintf( stderr, "fork failed\n" ) ;
		   break ;

	  case  0: execv( argv[2], argv + 2 ) ;
		   fprintf( stderr, "exec failed: %s\n", strerror(errno) ) ;
		   break ;

          default: wait( &status ) ;
		   break ;
       }
   }

   close( socket ) ;

   return 0 ;
}

Build

Builden ist einfach:

g++ -o udpexecute udpexecute.cpp

Download

Source von udpexecute