You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

181 lines
3.6 KiB

#!/usr/bin/perl
# $Header: /u/cvsroot/env/b/make-srv,v 1.3 2002/10/30 17:26:42 mayoff Exp $
use strict;
use Getopt::Long;
use Pod::Usage;
my $priority = 0;
my $weight = 0;
my $service;
my $port;
my $target;
my $help = 0;
my $result = GetOptions(
'help|?' => \$help,
'service=s' => \$service,
'priority=i' => \$priority,
'weight=i' => \$weight,
'port=i' => \$port,
'target=s' => \$target
) || pod2usage(2);
pod2usage(1) if $help;
pod2usage(3) if (!defined($service) || !defined($port) || !defined($target));
my $data = tinydns_escape(
pack("nnn", $priority, $weight, $port)
. dotted_sequence_to_label_sequence($target));
print ":$service:33:$data\n";
exit 0;
sub tinydns_escape {
my ($data) = @_;
$data =~ s{[\000-\037:\\\177-\377]}{
sprintf("\\%03o", unpack('C', $&))
}ge;
return $data;
}
sub dotted_sequence_to_label_sequence {
my ($dotted) = @_;
my @chars = split(//, $dotted);
my $l = scalar(@chars);
my $out = '';
my $label = '';
my $i = 0;
while (1) {
my $c;
if ($i < $l) {
$c = $chars[$i];
$i++;
}
else {
$c = '.';
}
if ($c eq '.') {
my $ll = length($label);
if ($ll > 63) {
die "$dotted contains a label of length $ll, but max length is 63";
}
if ($ll > 0) {
$out .= pack('C', $ll);
$out .= $label;
$label = '';
}
last if ($i >= $l);
next;
}
if ($c eq '\\') {
if ($i < $l) {
$c = $chars[$i];
$i++;
if ($c ge '0' && $c le '7') {
my $o = $c;
if ($i < $l) {
$c = $chars[$i];
if ($c ge '0' && $c le '7') {
$i++;
$o .= $c;
if ($i < $l) {
$c = $chars[$i];
if ($c ge '0' && $c le '7') {
$i++;
$o .= $c;
}
}
}
}
$c = pack('C', oct($o));
}
}
}
$label .= $c;
}
$out .= "\000";
return $out;
}
__END__
=head1 NAME
make-srv - Make an SRV record for tinydns
=head1 SYNOPSIS
make-srv -service I<service> -target I<target> -port I<port> [I<options>]
Options:
=over 4
=item -priority I<priority>
=item -weight I<weight>
=head1 DESCRIPTION
This command prints a DNS SRV record to standard output in
C<tinydns-data> format. This record is defined by RFC 2052.
The C<-service> flag specifies the domain name for which
the SRV record is defined. This name should have the format
I<service>C<.>I<protocol>C<.>I<domain>. For example:
C<http.tcp.dqd.com>. You must specify the C<-service> flag.
The C<-target> flag specifies the target domain name of the record. The
I<target> must be a domain name with an associated A record. (This
command doesn't verify that, but the RFC says it's a requirement.) You
must specify the C<-target> flag.
The C<-port> flag specifies the port number of the record. You must
specify the C<-port> flag.
The C<-priority> and C<-weight> flags specify the priority and weight of
the record. These flags are optional; I<priority> and I<weight> are
zero by default.
Example:
$ make-srv -service http.tcp.dqd.com -target zot.dqd.com -port 80
:http.tcp.dqd.com:33:\000\000\000\000\000P\003zot\003dqd\003com\000
You may add the I<ttl>, I<timestamp>, and I<lo> fields to the end of the
line yourself if necessary. For example,
:http.tcp.dqd.com:33:\000\000\000\000\000P\003zot\003dqd\003com\000:::in
is the same SRV record as in the example above, but will be visible only
to clients in the C<in> location. See the C<tinydns-data> documentation
for help with these fields.
=head1 LINKS
=over
=item *
RFC 2052: L<http://www.ietf.org/rfc/rfc2052.txt>
=item *
C<tinydns-data> documentation: L<http://cr.yp.to/djbdns/tinydns-data.html>
=back
=cut