#!/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