#!/usr/bin/perl use strict; # # Upon start, starts sending UDP messages to $dest_ip on $data_port # The initial data packets are: # DATA1: 1234567890\n # DATA2: ABCDEFGHIJ\n # DATA3: abcdefghij\n # Then checks port $cmd_port for any commands. # If a command is received on $cmd_port, # cmd = DIGITS ; DATA1 is replaced by "111111111111\n" # DATA2 is replaced by "222222222222\n" # DATA3 is replaced by "333333333333\n" # cmd = LETTERS; DATA1 is replaced by "AAAAAAAAAAAA\n" # DATA2 is replaced by "BBBBBBBBBBBB\n" # DATA3 is replaced by "CCCCCCCCCCCC\n" # cmd = DEFAULT; DATA1 is replaced by "1234567890\n" # DATA2 is replaced by "ABCDEFGHIJ\n" # DATA3 is replaced by "abcdefghij\n" # cmd = STOP; Data broadcast is stopped # cmd = EXIT; This program terminates # cmd = RESUME; Previously stopped broadcast is resumed # # any other value for cmd is ignored # Commands can be sent to this process by the program "cmd.pl" # # and loops forever # Sent packets can ve verified by # "tcpdump dst port 7777" # on remote host my $dest_ip = "139.179.10.6"; my $data_port = 7777; my $cmd_port = 7778; # use IO::Socket; use IO::Select; ##use Socket; my ($hostname, $sockaddr, $name, $aliases, $proto, $type, $len, $myaddr); my ($broadaddr, $me, $them); my @dest_addr = split(/\./, $dest_ip); chop($hostname = `hostname`); # prepare socket for outbound data transfer $sockaddr = "S n a4 x8"; ($name,$aliases,$proto) = getprotobyname('udp'); ($name,$aliases,$type,$len,$myaddr) = gethostbyname($hostname); my @my_ip = unpack("C4", $myaddr); my $my_ip_addr = join(".", @my_ip); print "$my_ip_addr $hostname\n"; $broadaddr=pack("C4",@dest_addr); $me = pack($sockaddr,&AF_INET, 0, $myaddr); $them = pack($sockaddr,&AF_INET, $data_port, $broadaddr); socket(S, &AF_INET, &SOCK_DGRAM, $proto) || die $!; setsockopt(S,&SOL_SOCKET,&SO_BROADCAST,1) || die $1; bind(S, $me) || die $!; # prepare socket for inbound command transfer (if any) # Use IO::Select to check if there is any data to read in the socket # IO::Select (see cpan.org) provides a library for NON-BLOCKING I/O my $s = new IO::Select; my $ip1 = IO::Socket::INET->new(LocalPort => $cmd_port, Proto=>'udp', LocalAddr => $my_ip_addr) or die "error creating UDP server for $my_ip_addr $@\n"; $s -> add($ip1); # sockets to check for pending data # # default $data my $default_data = " 1234567890 ABCDEFGHIJ abcdefghij\n", my $letter_data = "AAAAAAAAAAA BBBBBBBBBBB CCCCCCCCCCC\n"; my $digit_data = "11111111111 22222222222 33333333333\n"; my $data = $default_data; my ($server, $remote_port, $remote_ipaddr, $cmd, $local_port, $local_ipaddr); my @available_clients; my $seq_no = 0; my $actual_data; my $stop_broadcast = 0; # Broadcast on by default while (1) { # LOOP INDEFINITELY if ($stop_broadcast == 0) { $actual_data = "SeqNo: $seq_no-".$data; send(S,$actual_data,0,$them) || die $!; $seq_no++; sleep (1); } # # Check if any command has arrived @available_clients = $s -> can_read(0); foreach $server ( @available_clients) { $server -> recv($cmd, 1024); # # You cna use the following functions to gather info on host that # has sent the command ##($remote_port, $remote_ipaddr) = sockaddr_in($server -> peername); ##($local_port, $local_ipaddr) = sockaddr_in($server -> sockname); $data = $letter_data if ($cmd =~ /^LETTERS/); $data = $digit_data if ($cmd =~ /^DIGITS/); $data = $default_data if ($cmd =~ /^DEFAULT/); $stop_broadcast = 1 if ($cmd =~ /^STOP/); $stop_broadcast = 0 if ($cmd =~ /^RESUME/); exit if ($cmd =~ /^EXIT/); } # Give up some cycles if not in broadcast mode sleep (2) if ($stop_broadcast == 1); }