diff --git a/root/usr/bin/make-srv b/root/usr/bin/make-srv new file mode 100644 index 0000000..e835fae --- /dev/null +++ b/root/usr/bin/make-srv @@ -0,0 +1,181 @@ +#!/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 -target I -port I [I] + +Options: + +=over 4 + +=item -priority I + +=item -weight I + +=head1 DESCRIPTION + +This command prints a DNS SRV record to standard output in +C 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 +IC<.>IC<.>I. For example: +C. You must specify the C<-service> flag. + +The C<-target> flag specifies the target domain name of the record. The +I 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 and I 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, I, and I 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 location. See the C documentation +for help with these fields. + +=head1 LINKS + +=over + +=item * + +RFC 2052: L + +=item * + +C documentation: L + +=back + +=cut +