#!/usr/bin/perl # rp2c_cfg_rcvr, Boone, 02/23/11 # Pretend to be an Icom ID-RP2C repeater controller to the config program # # Modifications: # 02/23/11 Boone Initial coding # 02/24/11 Boone Add password set transaction, make variable sets # actually change our stored values, test for non-empty # register string values, not truth: values can be zero, # comments on mac address ranges # 03/01/11 Boone Set responses for d and x registers swap to lower # case on real hardware; adjustments to default values; # rig command line for setting ips/macs; comments # End Modifications # Libraries use Socket; # Initialize $port = 20319; $proto = getprotobyname('udp'); $paddr = sockaddr_in($port, INADDR_ANY); socket(SH, PF_INET, SOCK_DGRAM, $proto) || die "unable to create socket: $!"; bind(SH, $paddr) || die "unable to bind socket: $!"; %fl = ( i1 => '"V0301 "', i2 => '"V0301 "', i3 => '"V0301 "', i4 => '"V0301 "', i5 => '"V0200 "', ); %rd = ( d001 => '20319', d100 => '1', d101 => '1', d102 => '323', d103 => '322', d104 => '0', d105 => '321', d106 => '0', d107 => '0', d108 => '1', d110 => '20000', s000 => '"XXXXXXXX"', s001 => '"RPT000 "', x000 => 'ac100001', # RP2C IP address x002 => 'ffffff00', x003 => '00000000', x004 => '001a92b2', # This range assigned to Icom x005 => '00b2b581', x109 => 'ac100014', x111 => '0000222e', # This range assigned to maintech GmbH x112 => '00000005', x113 => '010001fd', # This range assigned to DVSI (AMBE) x114 => '0100080e', x115 => 'ff010000', x116 => 'ff050000', ); # x004 => '000090c7', # This range assigned to Icom # x005 => '00a004e7', %st = ( x001 => '0000002', ); # Command line foreach $arg (@ARGV) { if (! $ctlip) { $rd{x000} = $arg; # Controller IP next; } if (! $ctlnm) # Controller netmask { $rd{x002} = $arg; next; } if (! $gwip) # Gateway IP { $rd{x109} = $arg; next; } die "don't know what to do with arg $arg"; } # Listen while ($src = recv(SH, $buf, 64, 0)) { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); ($srcport, $srcip) = unpack_sockaddr_in($src); chop($buf); printf(STDERR "%04d-%02d-%02d %02d:%02d:%02d %03d %s:%d recv [%s]\n", $year+1900, $mon+1, $mday, $hour, $min, $sec, length($buf), inet_ntoa($srcip), $srcport, $buf); $resp = &response($buf); if ($resp) { send(SH, $resp, 0, $src); chop($resp); printf(STDERR "%04d-%02d-%02d %02d:%02d:%02d %03d %s:%d send [%s]\n", $year+1900, $mon+1, $mday, $hour, $min, $sec, length($buf), inet_ntoa($srcip), $srcport, $resp); } } # How did I get here!? exit(0); # Build an appropriate response sub response { my $cmd = shift; my $resp; $op = substr($cmd, 1, 1); $subcmd = substr($cmd, 2, 2); $setphrase = substr($cmd, 5); if ($setphrase =~/^[dx]/) { $setphrase =~ y/A-F/a-f/; } ($register, $value) = ($setphrase =~ /([^=]+)=(.*)/); $rest = substr($cmd, 2); $resp = 'br'; if ($op eq '!') # Fake: for injecting comments w/nc { $resp = "Comment injected\n"; } elsif ($op eq 's') # Set/Execute ops; we echo most { if ($subcmd eq 'LI') # Login { $resp .= "LI:OK\r"; } elsif ($subcmd eq 'PC') { $resp .= "PC:ACK\r"; } elsif ($subcmd eq 'RD') # Routing data { $rd{$register} = $value; $resp .= $subcmd; $resp .= ':'; $resp .= $setphrase; $resp .= "\r"; } elsif ($subcmd eq 'SV') # Save to flash { $resp .= "SV:ACK\r"; } elsif ($subcmd eq 'EX') # Execute a function { if ($setphrase eq 'x000') # Reboot { $resp = ''; } else { warn "execute register [$register] not understood"; $resp = ''; } } else # Case we haven't seen before { warn "subcommand [$subcmd] not understood"; $resp = ''; } } elsif ($op eq 'd') # Display ops; we make stuff up { if ($subcmd eq 'FL') # Firmware level { if ($fl{$setphrase} ne "") { $resp .= 'FL:'; $resp .= $setphrase; $resp .= '='; $resp .= $fl{$setphrase}; $resp .= "\r"; } else { warn "firmware level register [$register] not understood"; $resp = ''; } } elsif ($subcmd eq 'RD') # Routing data { if ($rd{$setphrase} ne "") { $resp .= 'RD:'; $resp .= $setphrase; $resp .= '='; $resp .= $rd{$setphrase}; $resp .= "\r"; } else { warn "radio data register [$setphrase] not understood"; $resp = ''; } } elsif ($subcmd eq 'ST') # Status { if ($st{$setphrase} ne "") { $resp .= 'ST:'; $resp .= $setphrase; $resp .= '='; $resp .= $st{$setphrase}; $resp .= "\r"; } else { warn "status register [$setphrase] not understood"; $resp = ''; } } elsif ($subcmd eq 'VS') # Firmware Version { $resp .= "VS:Revision1.2\r"; } else { warn "subcommand [$subcmd] not understood"; $resp = ''; } } else # Case we haven't seen before { warn "opcode [$op] not understood"; $resp = ''; } return($resp); }