--- /dev/null
+#!/usr/bin/env perl
+#
+# Make outgoing calls via enum NAPTR records.
+#
+# Add to your extensions.conf like so:
+# exten => _*164X.,n,AGI(enum.agi, +${EXTEN:4})
+#
+# Requires Net::DNS and Asterisk::AGI perl modules.
+#
+# Mahlon E. Smith <mahlon@martini.nu>
+#
+# ---------------------------------------------------------
+
+use strict;
+use warnings;
+
+use Net::DNS;
+use Asterisk::AGI;
+
+my (
+ @resolvers,
+ $A,
+ %AGI,
+ $num,
+ $resources
+);
+
+# in order of preference
+@resolvers = qw/ e164.org e164.arpa /;
+
+# setup AGI environment
+$A = Asterisk::AGI->new();
+%AGI = $A->ReadParse;
+
+unless ( $num = $ARGV[0] ) {
+ $A->verbose( "No number to parse! Exiting.", 4 );
+ exit;
+}
+$ARGV[0] =~ s/\s+//g;
+$num =~ s/[^\d]//g;
+$num = join '.', split //, reverse $num;
+
+foreach ( @resolvers ) {
+ last if $resources;
+ $A->verbose("Finding resource at $_ for $ARGV[0]...", 4);
+ $resources = get_resources( $num, $_ );
+}
+unless ( $resources ) {
+ $A->verbose( "No valid resources found for $ARGV[0].", 4 );
+ exit;
+}
+
+foreach ( sort { $resources->{$a}->{'preference'} <=> $resources->{$b}->{'preference'} }
+ keys %$resources ) {
+ my $resource = $resources->{$_}->{'resource'};
+ if ( $A->exec( 'Dial', "$resource|60|r" ) ) {
+ last;
+ $A->hangup;
+ }
+}
+
+exit;
+
+sub get_resources
+{
+ my ( $num, $resolver ) = @_;
+ my $resource;
+
+ my $res = Net::DNS::Resolver->new;
+ my $query = $res->query( "$num.$_", 'NAPTR' );
+
+ unless ( $query ) {
+ $A->verbose("ENUM query failed at $_ for $ARGV[0]: " . $res->errorstring, 4);
+ return;
+ }
+
+ # build hash of potential resources to use
+ my %records;
+ my $count = 0;
+ foreach my $rr ( $query->answer ) {
+ next unless $rr->type eq 'NAPTR';
+ next unless $rr->service =~ /(sip|iax)/i;
+ $count++;
+
+ $resource = $ARGV[0];
+ my ( $pattern, $replacement ) = (split '!', $rr->regexp)[1,2];
+ print "$pattern, $replacement\n";
+ unless ( $resource =~ s/$pattern/$replacement/ ) {
+ $A->verbose("Unable to apply regexp to $ARGV[0]", 4);
+ }
+ $resource =~ s/^(\w+):/\U$1\//;
+ $records{$count} = { preference => $rr->preference, resource => $resource };
+ }
+
+ return \%records;
+}