UDP broadcasts are usually not forwarded by routers, especially not to the Internet, so this should stay within the local network. On some (nowadays many) local networks, the router is smart enough to add a local DNS entry so the RPi can be reached by its hostname. On other networks, this may not be available, so there, this UDP broadcast simply serves for me to discover the IP that the RPi has been assigned.
I see. I've been trying to figure out everything that's going on with your udplisten.pl. I've made some changes primarily to introduce time measurement in a way that I could use for the higher-level abstractions of DateTime. Also, I couldn't understand where the newline after mypi was coming in, but I think that's what Data::Dumper gives the string in dumpstr. Regarding this syntax:
my $FULLMSG = !!$opts{m};
I searched for an operator !! in perlop, and not finding it have to believe it's a double application of !, essentially "Not-not". It seems to have the effect of making LHS the same as RHS, whether RHS is defined or not. That was torturous to say; do I have it right?
Update: The background for this is that I prefer a headless setup of my RPis, purely over the network, which is why my notes include instructions on how to enable WiFi and the ssh server. There is a small security risk in not changing the password from the default before the first boot, perhaps I will update my notes in that regard. Update 2: Done. Also, BitBucket wasn't rendering some of the Markdown correctly, which should now be fixed, so those crontab lines you quoted should be readable on the site now (when in doubt, refer to the source). /Update
The revision in Markdown did help me make an effective crontab command with this as the result:
$ crontab -l
# Edit this file to introduce tasks to be run by cron.
...
# m h dom mon dow command
*/17 * * * * hostname | socat -s - UDP-DATAGRAM:255.255.255.255:12340
+,broadcast 2>/dev/null
$
Source:
#!/usr/bin/env perl
use warnings;
use strict;
use 5.010;
no feature 'switch';
=head1 SYNOPSIS
Waits for message(s) on a UDP port and when a message is received,
prints the IP address from which each message was received.
udplisten.pl [-m] [-c COUNT] [-a] [-p PORT] [-e EXPR] [-b RXSZ]
OPTIONS:
-m - Output the entire message, not just the IP address
-c COUNT - Exit after receiving this many messages (default=1)
-a - Continuously output all messages (overrides -c)
-p PORT - UDP port number (default=12340)
-e EXPR - Output only messages which match this Perl expression
-b RXSZ - Receive length (default=1024)
=head1 DETAILS
The message can be transmitted, for example, via the following
L<crontab(5)> entry (note: C<sudo apt-get install socat>):
* * * * * echo "HELLO xyZ129" | socat - UDP-DATAGRAM:255.255.255.255
+:12340,broadcast
The string used can be completely random; the idea is for it to be uni
+que
to your device so you can identify it, for example:
udplisten.pl -e '/HELLO xyZ129/'
Two alternate ways to listen are via L<netcat(1)> or L<socat(1)>
(note these will receive and print I<any> messages on that port):
netcat -ul 12340 # may need to use -p12340 instead
socat -u udp-recv:12340 -
Don't forget to open the port for incoming UDP traffic on your local f
+irewall,
for example for L<UFW|https://wiki.ubuntu.com/UncomplicatedFirewall>:
ufw allow in 12340/udp
B<Note> that the choice of port number above is completely random.
At the time of writing, this port appears to be unused
(L<http://www.iana.org/assignments/port-numbers>),
but if you've got other things on your network that use this port, cho
+ose a different one.
You're also free to, for example, use different ports for different de
+vices.
=head1 AUTHOR, COPYRIGHT, AND LICENSE
Copyright (c) 2016 Hauke Daempfling (haukex@zero-g.net)
at the Leibniz Institute of Freshwater Ecology and Inland Fisheries (I
+GB),
Berlin, Germany, L<http://www.igb-berlin.de/>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see L<http://www.gnu.org/licenses/>.
=cut
use Getopt::Std 'getopts';
use Pod::Usage 'pod2usage';
use IO::Socket::INET ();
use Data::Dumper;
use DateTime;
use DateTime::Format::Duration;
sub HELP_MESSAGE { pod2usage( -output => shift ); return }
sub VERSION_MESSAGE { say {shift} q$udplisten.pl v2.00$; return }
$Getopt::Std::STANDARD_HELP_VERSION = 1;
getopts( 'mc:ap:e:b:', \my %opts ) or pod2usage;
my $FULLMSG = !!$opts{m};
my $COUNT = $opts{c} // 1;
pod2usage("Bad count") unless $COUNT && $COUNT =~ /^\d+$/ && $COUNT >
+0;
my $ALLMSGS = !!$opts{a};
my $PORT = $opts{p} // 12340;
pod2usage("Bad port") unless $PORT && $PORT =~ /^\d+$/ && $PORT > 0;
my $EXPR = $opts{e};
my $RXSZ = $opts{b} // 1024;
pod2usage("Bad receive length") unless $RXSZ && $RXSZ =~ /^\d+$/ && $R
+XSZ > 0;
pod2usage("Extra arguments") if @ARGV;
my $sock = IO::Socket::INET->new(
LocalPort => $PORT,
Proto => 'udp',
) or die "error in socket creation: $!";
my $count = 0;
my $dt;
my $start = DateTime->now;
say "Start time is: ", $start->hms;
my $later;
RXLOOP: while (1) {
defined $sock->recv( my $rx, $RXSZ )
or die "error during recv: $!";
my $peeraddr = $sock->peerhost;
my $match = 1;
if ( defined $EXPR ) {
local $_ = $rx;
eval "\$match = do { package CodeEval; $EXPR }; 1"
or die "Perl expression failed: " . ( $@ || "Unknown error" );
}
next RXLOOP unless $match;
say "rx is $rx";
say $FULLMSG ? "From $peeraddr: " . dumpstr($rx) : "$peeraddr";
$dt = DateTime->now;
say "Time is: ", $dt->hms;
$later = $dt;
last RXLOOP if !$ALLMSGS && ++$count >= $COUNT;
}
$sock->close;
my $d =
DateTime::Format::Duration->new(
pattern => '%Y years, %m months, %e days, '
. '%H hours, %M minutes, %S seconds' );
my $duration_object = $later - $start;
say $d->format_duration($duration_object);
sub dumpstr {
chomp( my $s =
Data::Dumper->new( [ '' . shift ] )->Terse(1)->Useqq(1)->Dump );
return $s;
}
Slightly-redacted output:
$ ./2.udplisten.pl -m -c 2
Start time is: 23:30:43
rx is mypi
From 192.168.red.acted: "mypi\n"
Time is: 23:34:01
rx is mypi
From 192.168.red.acted: "mypi\n"
Time is: 23:51:01
0 years, 00 months, 0 days, 00 hours, 20 minutes, 18 seconds
$
so, everything's looking pretty good, but I wanted to complete step 4 in your rpi setup, with some attempt to understand it along the way:
man rsyslog
On my first attempt, I just tacked it on the end:
# patch 4/20/2022
-*.*;auth,authpriv.none -/var/log/syslog
+*.*;cron,auth,authpriv.none -/var/log/syslog
, and restarted:
sudo systemctl restart rsyslog
, but rsyslog did not want to parse these lines:
Apr 20 16:41:59 mypi systemd[1]: Stopped System Logging Service.
Apr 20 16:41:59 mypi systemd[1]: Starting System Logging Service...
Apr 20 16:41:59 mypi rsyslogd: error during parsing file /etc/rsyslog.
+conf, on or before line 94: errors occured in file '/etc/rsyslog.conf
+' around line 94 [v8.1901.0 try https://www.rsyslog.com/e/2207 ]
Apr 20 16:41:59 mypi rsyslogd: error during parsing file /etc/rsyslog.
+conf, on or before line 95: invalid character '+' - is there an inval
+id escape sequence somewhere? [v8.1901.0 try https://www.rsyslog.com/
+e/2207 ]
Apr 20 16:41:59 mypi systemd[1]: Started System Logging Service.
, so I recalled that I didn't see any notation for a leading + or -, and went with this instead in /etc/rsyslog.conf:
###############
#### RULES ####
###############
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
#*.*;auth,authpriv.none -/var/log/syslog
*.*;cron,auth,authpriv.none -/var/log/syslog
#cron.* /var/log/cron.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
lpr.* -/var/log/lpr.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
, and that looks more like it, the parser having no objections. The man page for rsyslog had promised an html page, which I was enjoined to find. When running
cat /var/log/syslog
after a successful start, this url was posted as output: www.rsyslog.com, where I finally learned what the r is for in rsyslog. (rocket-fast)
So, yay, at the pace of a tortoise I think I've got task 4 covered. Thank you for your comments.
Gruss aus Amiland,
|