Asterisk name and location lookup AGI

Display name or location ('Lc') of caller on your IP / VoIP or soft SIP phones;

Location of caller displayed on VoIP phone

Description

Use the Asterisk Gateway Interface to lookup telephone numbers and put the subscribers name or location in the display-name;
Whenever '${CALLERID(NUM)}' (telephone number) is a number and '${CALLERID(NAME)}' (display-name) is empty, this AGI will try to lookup the name in a database.
If this fails it will try a web lookup (the website is for Dutch telephone numbers, so you need to change the source if you want lookups in other countries).
If this also fails, the software will try to lookup the area- and then the country code. The software comes with more than 20000 area codes from all over the world. This is vastly superior to IP address based geolocation. Geolocation databases are notoriously inaccurate and outdated.
If you don't know who is calling you, at least you know where they're calling from. Locations are prefixed with the string 'Lc ';
AGI lookup Flow
Note: Asterisk can be made to block anonymous calls, making it unlikely not to have a valid telephone number.
Note: If the software can't even find the country, there is probably something wrong with your setup or configuration.
Note: If the telephone number is in the phones' internal address book, the phone may display the address book info instead.
You can test the area and country lookup here.

AGI Basics

Asterisk sends the following information to the lookup program;

agi_network:
agi_request:
agi_channel:
agi_language:
agi_type:
agi_uniqueid:
agi_version:
agi_callerid:
agi_calleridname:
agi_callingpres:
agi_callingani2:
agi_callington:
agi_callingtns:
agi_dnid:
agi_rdnis:
agi_context:
agi_extension:
agi_priority:
agi_enhanced:
agi_accountcode:
agi_threadid:

Followed by an empty line.

The fields that we are interested in are 'agi_callerid' (telephone number) and 'agi_calleridname' (display-name). If calleridname is empty and callerid is a number the AGI software will try to do a name lookup, and if successful send this to Asterisk;

SET VARIABLE NAME "John Doe"

If all goes well Asterisk will then respond with;

200 result=1

Implementation

The stdin - stdout AGI interface of some Asterisk versions may be a bit buggy, so the most of the examples below use Fast AGI (AGI over TCP/IP) instead;
Xinetd is used as a server: The lookup program communicates with Xinetd and Xinetd with Asterisk. It is also possible to use a systemd socket instead of (x)inetd. (It shouldn't be too hard to write a standalone daemon though).
Below various ways that the communication between Asterisk and this lookup AGI can be implemented. Emphasis is on the second method;

Asterisk lookup AGI implementation

Errors are logged to syslog.
Note: In the setup described here, this AGI runs as user asterisk. It is possible to run it as an other (system) user.
Note: It may be possible to use this AGI with FreePBX. I don't use FreePBX myself, so you're on your own here.

Files

Phone books

Default file format

These are the following files;

numbers.db
Contains names and telephone numbers of your contacts.
areas.db
Contains area codes and names of cities, counties or provinces.
regions.db
Contains country codes.

areas.db, numbers.db and regions.db are binary files. Records are 56 bytes;

Number:
19 byte US-ASCII NULL terminated string (20 including terminating NULL).
Number length:
4 byte signed integer.
Name:
31 byte UTF-8 NULL terminated string (32 including terminating NULL).
Note: When compiled with 'make wide' this 71 bytes (72 including terminating NULL).

Records are fixed length with zero padding.
Number length is zero in numbers.db and the length of the number in areas.db and regions.db.
Sort order is Number.

Compact file format

With compact files numbers and names or locations are split into separate files:

numbers.lst
contains the names as UTF-8 NULL terminated strings without any padding. So records are variable length, which is more efficient.
numbers.idx
contains the numbers, their length and position (offset in bytes) of the corresponding name in 'numbers.lst'. It also contains the length of the name, excluding the terminating NULL.

The same applies to areas and regions. With the compact file format there are 'araeas.idx' and 'areas.lst' and 'regions.idx' and 'regions.lst'.
Number length is always zero in 'numbers.idx'. And the length of the number in 'areas.idx' and regions.idx.
Sort order is Number.

In 'numbers.idx', 'araeas.idx' and 'regions.idx' records have a fixed length of 32 bytes with zero padding;

Number
19 byte US-ASCII null terminated string (20 including terminating NULL).
Number length
4 byte signed integer.
Name offset
4 byte signed integer.
Position of name in bytes from start of .lst file.
Name length
4 byte signed integer.
Length of name or location, excluding the terminating NULL.
Field sizes

Numbers are never more then 15 digits. And most phones can't display much more then 20 chars. So these sizes should be plenty, except when using non-Latin scripts;
With UTF-8 a character may be more then one byte. E.G. Two bytes for Greek and Cyrillic. And three bytes for Asian scripts. When compiled with 'make wide', the maximum name or location size is 71 instead of 31 bytes. This makes the total .db record size 96 bytes.
Note that the use of 32-bit signed integers limits the file sizes to 2 GB.
More about the phone book below.

Config files

agi-namelookup.conf

If web lookups are disabled, this is set in /etc/namelookup-agi/agi-namelookup.conf;

weblookup=off

If compact files are enabled, this is set in /etc/namelookup-agi/agi-namelookup.conf;

compact=on

If agi-namelookup.conf doesn't exist, web lookups default to on and compact files to off.

agi-nameblock.db

agi-nameblock.db lists names which are considered invalid. When '${CALLERID(NAME)}' (display-name) is set to one of these the software will consider this field empty and do a lookup anyway.
agi-nameblock.db is a binary file. Records are 32 bytes. Each record is a lower case 31 byte UTF-8 NULL terminated string with zero padding.
Sort order is unsigned ascending byte value.
If the file agi-nameblock.db doesn't exist, the list defaults to 'anonymous', 'privacy manager' and 'unknown'.
Note: Matches are not case sensitive. So if 'anonymous' is blocked, 'Anonymous' and 'ANONYMOUS' are also blocked.
Note: When compiled with 'make wide', the record size is 72 instead of 32 bytes.
More about the block list below.

Log file

namelookup.log
Normally these are five fields separated by tabs;

ISO date<Tab>Lookup type<Tab>Number<Tab>Name<Tab>Asterisk result code<Lf>
Lookup types
ArLkArea code (city, county or province) lookup
DbLkDatabase lookup
RgLkRegion (country) lookup
WbLkWeb lookup

Only successful lookups are logged.

Debug (-d) logging

debug is for stdin - stdout tests. Here the last field is replaced by 'Debug'. And the input from the test is also written to the log file.
Logging is done to the default directory. It also uses config- and database files in the default directory.

Syslog

The software logs to syslog too;

Syslog entries
Log entryMeaning
namelookup.agi[PID]: connect from localhost (127.0.0.1) Connect to inetd.
namelookup[PID]: Version: Version Number Start of namelookup.agi
namelookup[PID]: Lookup nr: Number Telephone number to be lookup up.
namelookup[PID]: Name from VP: Name Name set by VoIP provider.
namelookup[PID]: Invalid: Name Name set by VoIP provider is not a valid name.
namelookup[PID]: dblookup: Name Name or area found in database.
namelookup[PID]: weblookup: Name Name found on web.

Plus various errors that may occur.
'Timeout expired' usually means that the website lookup takes too long. Other errors are more serious.

Installation

Required

Download and install

~$ make
cc -O2 -Wall  -o agiblk2db block2db.c
cc -O2 -Wall  -o agiconf agiconf.c -lncursesw
cc -O2 -Wall  -o agidx2ph idx2ph.c
cc -O2 -Wall  -o aginum2db num2db.c
cc -O2 -Wall  -o agiph2idx ph2idx.c
cc -O2 -Wall -o csv2tsv csv2tsv.c
cc -O2 -Wall -o namelookup namelookup.c
cc -O2 -Wall  -o namelookup.agi agi-namelookup.c

Alternatively you can do 'make wide' instead. This sets a define ('-D') 'ANL_WITH_WIDE_NAMES'. This will increase the maximum name- or location size from 31 to 71 bytes, which makes the software more suitable for non-Latin scripts;

~$ make wide
cc -O2 -Wall -DANL_WITH_WIDE_NAMES -o agiblk2db block2db.c
cc -O2 -Wall -DANL_WITH_WIDE_NAMES -o agiconf agiconf.c -lncursesw
cc -O2 -Wall -DANL_WITH_WIDE_NAMES -o agidx2ph idx2ph.c
cc -O2 -Wall -DANL_WITH_WIDE_NAMES -o aginum2db num2db.c
cc -O2 -Wall -DANL_WITH_WIDE_NAMES -o agiph2idx ph2idx.c
cc -O2 -Wall -o csv2tsv csv2tsv.c
cc -O2 -Wall -o namelookup namelookup.c
cc -O2 -Wall -DANL_WITH_WIDE_NAMES -o namelookup.agi agi-namelookup.c

Next, as root run 'make install'. This runs install.sh

Target directories are created if they do no exist.
If you re-run install later, only newer versions of the above files are installed.

Configuration

Agiconf

Agiconf is a ncurses configuration tool. It can generate agi-namelookup.conf, and agi-nameblock.db, numbers.db, areas.db, and regions.db (or their compact file format equivalents). It's called from the install script, but you can (re)run it later if you want.

The main menu has the following items;

  1. Select Country
  2. Configuration
  3. Convert Blocklist
  4. Convert Phonebook
  5. Select Areas
  6. Select Regions

Select Country

This sets trunk prefix and international call prefix;

AGIConf Select Country

Configuration

If you are not interested in Dutch web lookups, you can disable them here.
You can also choose to use compact files.

Convert Blocklist

Convert agi-nameblock.txt to agi-nameblock.db.
The software first looks for agi-nameblock.txt in /etc/namelookup-agi/, then the default directory and then in your home directory.
Note: You can do this conversion later if you want.

Convert Phonebook

Convert numbers.tsv to numbers.db or numbers.idx and numbers.lst
The software first looks for numbers.tsv in /etc/namelookup-agi/, then the default directory and then in your home directory.
Note: You can do this conversion later if you want.

Select Areas

The default behaviour is to just lookup countries. If you want to lookup cities and areas as well you can enable this on a per country basis. Or all if you like and then select language and resolution on a per country basis.
So instead of 'Germany' it might say 'DE Düsseldorf'.

AGIConf Select Areas

Note: With area code lookups enabled, the software will display the two letter ISO country code instead of the country name.
Note: If the software can't find the area code, it will display the country name instead of the city or area name.

Select Regions

This has an option called 'With federal states'. With this enabled, instead of 'USA' or 'Canada', it will display the federal state as well. E.G.: 'US New Jersey' or 'CA Manitoba'.

Agiconf HTML man page here.

Fast AGI

Inetd

In /etc/services, under local services, add:

agi		4573/tcp			# Asterisk Gateway Interface

In /etc/inetd.conf, add;

agi	stream	tcp	nowait	asterisk	/usr/sbin/tcpd	/usr/local/sbin/namelookup.agi

Or, if you want an other user then 'asterisk', E.G. 'namelookup';
Note: This is not supported by the install script.

agi	stream	tcp	nowait	namelookup	/usr/sbin/tcpd	/usr/local/sbin/namelookup.agi

Restart inetd. E.G.:

~# /etc/init.d/xinetd reload

Or the systemd equivalent thereof;

~# systemctl reload xinetd

Systemd socket

You can use a systemd socket instead of (x)inetd.
Hypothetically, the following should work.
I don't use systemd myself, so if this doesn't work, you are on your own!

In /etc/services, under local services, add:

agi		4573/tcp			# Asterisk Gateway Interface

In /etc/systemd/system/agi@.service;

[Unit]
Description=AGI service
After=network.target agi.socket
Requires=agi.socket

[Service]
Type=simple
TimeoutStopSec=10
User=asterisk
Group=asterisk
StandardInput=socket
StandardOutput=socket
StandardError=journal
ExecStart=/usr/local/sbin/namelookup.agi
Restart=no

[Install]
WantedBy=default.target

Replace 'asterisk' by 'namelookup' if you want to run as user namelookup.
Note: This is not supported by the install script.

In /etc/systemd/system/agi.socket;

[Unit]
Description=AGI socket
PartOf=agi.service

[Socket]
ListenStream=4573
Accept=true
ReusePort=true
Writable=true

[Install]
WantedBy=sockets.target

Next;

~# systemctl reload
~# systemctl enable agi.socket
~# systemctl start agi.socket

Check with;

~# systemctl status agi.socket

Note: This is not fully tested!

Check for listening socket

Agi should now show up in a netstat;

~$ netstat -a | grep agi
tcp6       0      0 [::]:agi                [::]:*                  LISTEN

You can further test things with telnet. As shown with the location lookup example below;

~$ telnet localhost agi
Trying ::1...
Connected to localhost.
Escape character is '^]'.
agi_callerid: 0201234567

SET VARIABLE NAME "Lc Amsterdam"
Connection closed by foreign host.

You need to cut and paste ('agi_callerid: 0201234567') quickly because the program has a timeout of just a few seconds. And don't forget the blank line (an extra <Enter>). And after the AGI response, press <Enter> again. This will stop the program.
Note: The above example is for within the Netherlands. Outside the Netherlands the same lookup would include the NL country code (31): agi_callerid: 0031201234567 (assuming the international call prefix is '00').

Asterisk

If you have got all of the above to work, you can start configuring Asterisk.
In /etc/asterisk/extensions.conf: Just before the internal dial command that dials your phone(s) on incoming calls:

	same => n,Set(NAME=${CALLERID(NAME)})
	same => n,Set(AGISIGHUP=no)
	same => n,AGI(agi://127.0.0.1)
	same => n,Set(CALLERID(NAME)=${NAME})

Variable NAME is set to the Caller-Id name.
'Set(AGISIGHUP=no)' keeps Asterisk from sending a 'HANGUP'.
If the lookup is successful, the AGI will send the string 'SET VARIABLE NAME' followed by the name.
This value is then assigned to Caller-Id name.

Note: In a non-FastAGI (non-TCP/IP), stdin - stdout version this would have been;

	same => n,Set(NAME=${CALLERID(NAME)})
	same => n,Set(AGISIGHUP=no)
	same => n,AGI(/usr/local/sbin/namelookup.agi)
	same => n,Set(CALLERID(NAME)=${NAME})

If you want to, you can combine this with the Privacy Manager;

exten => Your_Extention,1,GotoIf($["${CALLERID(num)}" = "anonymous"]?anon:nona)
	same => n(anon),Set(CALLERID(num)=)
	same => n(nona),Answer()
	same => n,PrivacyManager()
	same => n,GotoIf($["${PRIVACYMGRSTATUS}" = "FAILED"]?pmfail:num)
	same => n(num),Set(NAME=${CALLERID(NAME)})
	same => n,Set(AGISIGHUP=no)
	same => n,AGI(agi://127.0.0.1)
	same => n,Set(CALLERID(NAME)=${NAME})
	same => n,Dial(Your_Internal_Dial_Command)
	same => n,Hangup()
	same => n(pmfail),Playback(im-sorry)
	same => n,Playback(vm-goodbye)
	same => n,Hangup()

Note: You can, of course, use a hostname instead of an IP address. And IPv6 is supported as well.

Next, reload extensions.conf:

asterisk -rx "dialplan reload"

Security

Firewall port 4573.
Limit access in /etc/hosts.allow and /etc/hosts.deny.

Log file rotation

In /etc/logrotate.d/asterisk-namelookup;

/var/local/log/asterisk/namelookup.log {
        monthly
        missingok
        rotate 4
        compress
        delaycompress
        notifempty
        create 660 asterisk asterisk
}

Modify to suit your needs.

Block list

If your VOIP provider set a name for you, there is no need to do a lookup. However, if this name is invalid the software needs to do a lookup anyway. The file 'agi-nameblock.db' lists names that are considered invalid.
agi-nameblock.db is a binary file. It can be derived from 'agi-nameblock.txt'. The script 'block2db.sh' sorts agi-nameblock.txt to alphabetical order and uses 'agiblk2db' to convert the data to agi-nameblock.db.
agi-nameblock.txt is an UTF-8 text file. It contains one invalid name per line.
Example;

anonymous
privacy manager
unknown

Maximum length is 31 bytes (32 including newline). Except when compiled with 'make wide', in which case the maximum length is 71 bytes (72 including newline).
Note: If you use block2db.sh to do the conversion, all entries in agi-nameblock.txt need to be lower case.

Alternatively, you can use agiconf to do the conversion. Agiconf will also convert any upper case to lower case. This includes non-ASCII; It will convert 'Ö' to 'ö' and 'Ω' to 'ω'.
Note: Agiconv will only convert non-ASCII to lower case in an UTF-8 environment!
I recommend strongly against using Agiconv in a non UTF-8 environment. Agiconv was never tested in a non UTF-8 environment on a big-endian machine and may not work under such conditions!

If agi-nameblock.db does not exist, the list of invalid names defaults to 'anonymous', 'privacy manager' and 'unknown'.

Phone book

Phone book format

Phone books come in all sorts of formats. There are two fields they always have in common: Name and Telephone number.
I use a phone book with the following format as a base for all other formats:

Name <Tab> Telephone number <Line Feed>

This I then convert to whatever format is required for soft phones and SIP-phones.

Default phone book file format

The script 'ph2num.sh' converts the file 'phonebook.txt' with this format to;

Telephone number <Tab> Name <Line Feed>

And saves this as 'numbers.tsv'. It also sets the sort order to Telephone number.
It then uses 'aginum2db' to convert this to binary format.
The binary phone book is saved as 'numbers.db'.
Below the file format.

Byte  0       1        2        3        4        5        6        7
   ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
 0 │ Number                                                                │  7
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 8 │                                                                       │ 15
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
16 │                            0      │ Number length                     │ 23
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
24 │ Name                                                                  │ 31
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
32 │                                                                       │ 39
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
40 │                                                                       │ 47
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
48 │                                                                0      │ 55
   └────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
    48       49       50       51       52       53       54       55

Records have a fixed length of 56 bytes with zero padding. Except when compiled with 'make wide', in which case is 96 bytes;

Byte  0       1        2        3        4        5        6        7
   ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
 0 │ Number                                                                │  7
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 8 │                                                                       │ 15
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
16 │                            0      │ Number length                     │ 23
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
24 │ Name                                                                  │ 31
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
32 │                                                                       │ 39
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
40 │                                                                       │ 47
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
48 │                                                                       │ 55
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
56 │                                                                       │ 63
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
64 │                                                                       │ 71
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
72 │                                                                       │ 79
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
80 │                                                                       │ 87
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
88 │                                                                0      │ 95
   └────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
    88       89       90       91       92       93       94       95

Number and name are NULL-terminated character strings. Number length is a 32-bit signed integer.
Number length is always zero in 'numbers.db'. And the length of the number in 'areas.db' and 'regions.db'.
Note: When number length is zero, namelookup.agi will try to match the complete telephone number. And when number length is not zero, namelookup.agi will only try to match the first number-length number of digits of the telephone number.

Compact phone book file format

With compact files numbers and names are split into separate files. Below the numbers.idx format;

Byte  0       1        2        3        4        5        6        7
   ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
 0 │ Number                                                                │  7
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 8 │                                                                       │ 15
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
16 │                            0      │ Number length                     │ 23
   ├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
24 │ Name offset                       │ Name length                       │ 31
   └────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘

Records are fixed length (32 bytes) with zero padding.
Number is a NULL-terminated character string. The other fields are 32-bit signed integers.
Number length is always zero in 'numbers.idx'. And the length of the number in 'areas.idx' and 'regions.idx'.
Note: When number length is zero, namelookup.agi will try to match the complete telephone number. And when number length is not zero, namelookup.agi will only try to match the first number-length number of digits of the telephone number.
'agiph2idx' converts the default format to compact. 'agidx2ph' converts the compact format to default. And agiconf can generate and install both formats.

Phone book contents

Normally a phone book is for dialling out. But this phone book is meant for recognising incoming phone calls.
A dial-out phone book may contain toll-free numbers.
A dial-in phone book needs to contain the phone numbers by which companies identify them selves instead.

Phone numbers are just digits: 0123456789. So no spaces, brackets, pluses or hyphens. Format is 'trunk_prefix area_code subscribers_number' or 'international_call_prefix country_code area_code subscribers_number'.
Examples:

Most countries

General phone number
Trunk prefix: 0
International call prefix: 00
Country code: 12
Area code: 34
Subscribers NR: 56789

Phone number is: 03456789 or: 00123456789
Assuming of course that the trunk prefix is '0' and the international call prefix is '00'.

USA

Some places use a different trunk prefix or international call prefix. In the USA for instance, it's '1' resp '011';

USA phone number
Trunk prefix: 1
International call prefix: 011
Country code: 12
Area code: 34
Subscribers NR: 56789

Phone number is: 13456789 or: 011123456789

Other properties

Names are UTF-8 text.
Sort order is ALPHABETIC sort of phone numbers.
Phone numbers have to be UNIQUE: They may occur only ONCE! The same name may occur multiple times though;
A phone number has one name.
A person may have more then one number.

Phone book installation

cp numbers.db /var/local/lib/phonebook/
cd /var/local/lib/phonebook/
chmod 640 numbers.db
chown root:asterisk numbers.db

Alternatively you can use agiconf. If you want to agiconf converts numbers.tsv to numbers.db, sorts to alphabetical order and installs the file with the right permissions.
Note: Generally speaking, Agiconf will insert the right trunk- and international call prefix. An exception is the conversion from 'numbers.tsv' to 'numbers.db'. Here the correct trunk- and international call prefixes should already be in the TSV file!
A list of countries their trunk prefix and international call prefix here.
Most organisations list their phone number as;
+ Country_code (trunk_prefix) area_code subscribers_number
However, according to ITU standard E.123 this should be;
+ Country_code area_code subscribers_number
And some list their number as;
(trunk_prefix area_code) subscribers_number
Which can be very confusing indeed!

Web lookups

For unrecognised numbers the program does a web lookup. If successful, the result gets saved in 'namelookup.log'. These are marked with the string WbLk (Web Lookup). You can add these to your phone book.

W3m configuration

W3m can be configured globally be editing /etc/w3m/config Alternatively, copy this file to /var/local/log/asterisk/.w3m/ and then edit this copy ('/var/local/log/asterisk/' is both the home- and default directory of namelookup.agi).

The following are the charset settings;

display_charset UTF-8
document_charset UTF-8
system_charset UTF-8

And these are the proxy settings;

use_proxy 1
http_proxy http://proxy.example.org:1234
https_proxy http://proxy.example.org:1234
gopher_proxy http://proxy.example.org:1234
ftp_proxy http://proxy.example.org:1234
no_proxy localhost,example.org

Disable Web lookups

If you want to you can DISABLE web lookups; Create a file /etc/namelookup-agi/agi-namelookup.conf with the following line;

weblookup=off

Agiconf can do this for you.

Area and country code lookups

If the number is not in the phone book, web lookups are disabled or the web lookup fails and area code lookups are enabled (for this country), the software will try to do a area code lookup.

Format is 'trunk_prefix area_code' or 'international_call_prefix country_code area_code'.
Example:

Trunk prefix: 0
International call prefix: 00
Country code: 12
Area code: 34

Area code is: 034 or: 001234

Use the first format for area codes in your own country and the second for foreign area codes.
Assuming of course that the trunk prefix is '0' and the international call prefix is '00'.
Note: Agiconf can set the correct trunk- and international call prefix for you.
For more information see: Asterisk location lookup AGI country and area code files

Country code lookups

If the number hasn't been found yet, the software will do a country lookup.

Format is 'international_call_prefix country_code'.
Example:

International call prefix: 00
Country code: 12

Format is: 0012
Assuming that the international call prefix is '00'.
Note: Agiconf can set the correct international call prefix for you.

Options

Namelookup.agi options;

namelookup.agi [-d] [-h] [-l altlog ] [-u althome ] [-v]
-d
Enable debug.
With debug the program reads from stdin and logs to the default directory. It also uses config- and database files in the default directory.
-h
Print help and exit.
-l Alternate log file
Use this log file instead of default (/var/local/log/asterisk/namelookup.log).
-u Alternate home directory
Use this home directory instead of default (/var/local/log/asterisk/).
This is where w3m will create the directory '.w3m/' when web lookups are enabled.
-v
Print version and exit.

You could create a system user 'namelookup' with home directory '/var/local/lib/namelookup/' and log directory '/var/local/log/namelookup/' and then use these instead of the defaults;

namelookup.agi -l /var/local/log/namelookup/namelookup.log -u /var/local/lib/namelookup

The install script doesn't support this, so it's a bit more DIY.
Note: If you don't use FastAGI but the stdin - stdout interface instead, the AGI process owner is always the same as the Asterisk process owner!