NAME - A command line client program using Net::DRI towards the .NO EPP registry.


The client supports creation and maintainance of host, contact and domain objects for .NO. It supports various transfer operations, as well as poll operation for the message queue.

It was developed for testing of the .NO extensions to Net::DRI, but can probably be used by users who are comfortable with a simple command line interfaces.


Command line

perl [Connect arguments] [Command arguments]


Mandatory connect arguments
 -C: Client ID, your EPP registrar account name, typical regxxx, 
     where xxx is a number
 -W: Account password, your EPP account password
 -S: Server name, the registry server
 -P: EPP server port
Optional connect arguments
 -f: Log file. The Net::DRI raw XML exchange will be dumped to this file
 -L: Use SSL connection
 -w: New account password, will be set in first EPP login
Command arguments

The command argument specify the EPP operation to perform:

 -o: EPP object.
     One of contact, host, domain, message
 -c: EPP command. 
     One of hello, create, update, info, delete, transfer, transfer_cancel, 
     transfer_execute, count, waiting, retrieve
 -p: EPP parameter argument string, in a format that can be eval'ed into 
     a hash, se parameter string examples below.

About each EPP command sequence

Each command will be performed as follows:

 - Socket connect, session initiation, a greeting is returned
 - an EPP login, which will succeed if the connect arguments are correct, 
   otherwise fail,
   a greeting is returned if login is OK
 - an EPP command, according to the specified command arguments
 - an EPP logout
 - Session termination

A simple connect and greeting test

Basic connect to an EPP server should give you a greeting back if successful. A simple connect to an EPP server and port:

Raw port (no SSL):

   telnet <EPP server> <EPP port>

Encrypted with SSL:

   openssl s_client -host <EPP server> -port <EPP port>

About logging and filtering of the log output

Logging is useful for debugging purposes,

A client side log can be activated by -f option, like:

  '-f xx.log'

Tail on the log-file in a separate window is nice then. Even nicer is to filter the tail through the supplied utility, which will wrap the raw XML to a pretty-printed dump.

The filters '-s' option will skip all the login/logout and greetings which otherwise will dominate the outpot.

  'tail -f xx.log | ./ -s'

About authInfo

Auth-info (pw) can be set and updated only for domain objects, and is needed only for a transfer-execute.

EPP commands and arguments

Hello command


-c hello

A greeting shall be returned, with the menu!

Contact object commands

Contact create

A .NO contact can be one of three types, person, organization or role. For each contact created, the type must be specified via the mandatory type extension.

1 Organization contact

-o contact -c create -p "%p=(name=>'EXAMPLE FIRM AS', street=>['Example building','Example st. 23', '5 etg'], city=>'Trondheim', pc=>'7465', cc=>'NO', voice=>'+47.12345678', fax=>'+47.12345678x01', email=>'', type=>'organization', identity=>{type=>'organizationNumber', value=>'987654321'})"

2 Person contact 1 affiliated with a company

-o contact -c create -p "%p=(name=>'Peter Example Olsen', street=>['First example building','Example st. 1'], city=>'Trondheim', pc=>'7465', cc=>'NO', voice=>'+47.22345671', mobilephone=>'+47.123456781', email=>'', type=>'person', organization=>'EFA12O')"

3 Person contact 2 not affiliated with a company

-o contact -c create -p "%p=(name=>'John Example Johnsen', street=>['Second example building','Example st. 2'], city=>'Trondheim', pc=>'7465', cc=>'NO', voice=>'+47.22345672', mobilephone=>'+47.123456782', email=>'', type=>'person')"

4 Role contact with two contact end a secondary extra email address

-o contact -c create -p "%p=(name=>'Example hostmaster', street=>['Example building','Example st. 23', '5 floor'], city=>'Trondheim', pc=>'7465', cc=>'NO', voice=>'+47.12345678', fax=>'+47.12345678x01', mobilephone=>'+47.123456789', email=>'', type=>'role', rolecontact=>['PEO1P', 'JEO2P'], xemail=>'')"

Contact update

In this example, a role contact update is shown.

Role contact update

Update a role and add an org. affiliation and a new person affiliation, also remove one of the existing person affiliations. Also change some of the address information and the mobile phone number. Keep the rest of the info.

-o contact -c update -p "%p=(srid=>'TOH12R', name=>'New name on Hostmaster', street=>['Changed example building','Changed Example st. 23', '5 floor'], city=>'Trondheim', pc=>'7465', cc=>'NO', mobilephone=>'+47.123433389', organization=>{add=>['TOH1O']}, rolecontact=>{add=>['TOH1P'], del=>['TOH1P']})"

Contact info

If a 'srid' returned on a create is 'TOH169O', it means that the org. handle has the value 'TOH169O-NORID'. Lets do an info on this handle.

Info on an organization contact handle

-o contact -c info -p "%p=(srid=>'TOH169O')"

Contact check

Check on an organization contact handle

-o contact -c check -p "%p=(srid=>'TOH169O')"

You may get an usupported command on this!

Contact delete

Delete on an organization contact handle

-o contact -c delete -p "%p=(srid=>'TOH169O')"

Host object commands

Host create

1 Create an external name server

An external name server is a non .NO name server.

External name servers must be registered without any IP-addresses.

-o host -c create -p "%p=(name=>'')"

2 A .NO name server will require an ipv4-address

-o host -c create -p "%p=(name=>'', v4=>'')"

3 A .NO name server also with an optional contact

-o host -c create -p "%p=(name=>'', v4=>'', contact=>'JEO50P')"

4 Multiple ip-addresses, pass them as an array

-o host -c create -p "%p=(name=>'', v4=>['',''])"

5 A .NO name server with ipv6 address as well
 Will probably be rejected by server policy:

-o host -c create -p "%p=(name=>'', v4=>['',''], v6=>['2001:700:1:0:215:f2ff:fe3e:fe65'])"

Host info

1 Info on a sponsored host object

-o host -c info -p "%p=(name=>'')"

2 info on a host object sponsored (owned) by another registrar

It is possible to query hosts sponsored by other registrars, but you need to specify his registrar id by the 'ownerID'.

-o host -c info -p "%p=(name=>'', ownerid=>'reg9998')"

Host check

Check to see whether a host name is available or registered

-o host -c check -p "%p=(name=>'')"

Host delete

Delete a host

-o host -c delete -p "%p=(name=>'')"

Host update

1 First create a host with two ip-addresses and a contact

-o host -c create -p "%p=(name=>'', v4=>['',''], contact=>'TAH8P')"

2 Do an info to verify

-o host -c info -p "%p=(name=>'')"

3 Now, change/update it
 - The name is changed to a new name specified in key nname
 - 3 new ip-addresses are added, one of the existing is removed, thus 4 
   ip-addresses shall be the final result
 - The contact is deleted and changed to another one.

-o host -c update -p "%p=(name=>'', nname=>'', ipset=>{add=>{v4=>['','','']}, del=>{v4=>''}}, contact=>{del=>'TAH8P', add=>'EFA2P'})"

Domain object commands

Domain check

1 Check to see whether a domain name is available or registered

-o domain -c check -p "%p=(name=>'')"

Domain info

1 Do an info on an existing domain

-o domain -c info -p "%p=(name=>'')"

Domain create

  • on the domain create methods in Net::DRI

    A lot of domain create methods are offered by Net::DRI.

    The client uses one specific create method, namely the domain_create_only().

    • domain_create_only()

      This method assumes that the contacts handles and the nameservers listed are ALREADY created in the registry, and this is closest to Norid's datamodel. Hence, the client uses this method.

    • domain_create()

      This is another method which is a very powerful Net::DRI method.

      This method will do the same as domain_create_only(), but will also accept and handle full contacts and nameserver objects as parameters, meaning that it will check and create various objects as an integral part of the command.

      Support for this variant is not added to the client.

  • on the duration syntax

    The duration parameter must specify one year to be accepted in create, due to the period definition in lib/Net/DRI/DRD/

    Duration syntax: 'duration=>{years=>1}' or 'duration=>{months=>12}'

1 Create a normal domain

Create a single domain with a a registrant, a contact set with one type each, and two existing name servers, which is the minimum for .no:

-o domain -c create -p "%p=(name=>'', pw=>'', registrant=>'THO12O', coset=>{tech=>'THO23P', admin=>'TH2345P'}, nsset=>['', ''])"

2 Create an IDN domain

Create a single IDN-domain with a duration of 12 months, a registrant, a contact set with one type each, and two existing name servers, which is the minimum for .NO.

IDN domains are converted to the ACE-form (xn--...) by the client, and the ACE-form is passed as the domain name to the registry.

-o domain -c create -p "%p=(name=>'test-ÆØÅ.no', pw=>'', duration=>{months=>12}, registrant=>'THO12O', coset=>{tech=>'THO23P', admin=>'TH2345P'}, nsset=>['', ''])"

This should be accepted if the handles and name servers exist and the domain don't.

Some domain create variants supported by Net::DRI but rejected by .NO registry policy.

A lot of variants will pass the DRI, but should be rejected by the registry because of local policy.

  • Create a single domain with a pw and a contact set, no name servers

    -o domain -c create -p "%p=(name=>'', pw=>'xxx', registrant=>'THO12O', coset=>{tech=>'THO23P', admin=>'TH2345P'})"

  • Create a single domain with a duration of 12 months, no contact set, but only a nameserver

    -o domain -c create -p "%p=(name=>'', pw=>'', registrant=>'THO12O', nsset=>['', ''])"

  • Create a single domain with a duration of 12 months, no registrant, no contact set, but only a nameserver

    -o domain -c create -p "%p=(name=>'', pw=>'', nsset=>[''])"

  • Create a single domain with a a domain name only:

    -o domain -c create -p "%p=(name=>'', pw=>'')"

Domain delete

Delete domain, optionally specify the two optional Norid dates for removal from DNS and registry:

-o domain -c delete -p "%p=(name=>'', deletefromregistry=>'2008-02-27', deletefromdns=>'2008-01-15')"

Domain update

The domain name cannot be changed, otherwise all parameters may be changed.

1 Update (change) some domain attributes
 - registrant is changed
 - set authInfo to 'abc'
 - add and del on all the multiple objects, coset and nsset, which may be 
   arrays or scalars

-o domain -c update -p "%p=(name=>'', pw=>'abc', duration=>{months=>12}, registrant=>'TOH191O', coset=>{add=>{tech=>['TOH1P'], admin=>['TOH2P']}, del=>{tech=>['TOH1P'], admin=>['TOH2P', 'TOH3P']}}, nsset=>{add=>['', ''], del=>''})"

2 Update of status flags

Update is the only command where the status flags can be set/changed

The flag values to use by the DRI user is the following (from

  my %s=('delete'   => 'clientDeleteProhibited',
         'renew'    => 'clientRenewProhibited',
         'update'   => 'clientUpdateProhibited',
         'transfer' => 'clientTransferProhibited',
         'publish'  => 'clientHold');

Example update when a couple of flags are set, and two already set are removed:

-o domain -c update -p "%p=(name=>'', status=>{add=>['delete','publish'], del=>['update', 'transfer']})"

Domain renew

Rule from we must have : curexp+duration < now + maxdelta maxdelta = the permitted period which is 1 year (set in

So basicly curexpiry must have a value between today (=now) and up to one year ahead in time. Values outside that generates a DRI-error.

1 Renew with minimum parameters

DRI requires curexpiry, which should match the expiry date of the domain being renewed:

-o domain -c renew -p "%p=(name=>'Æ', curexpiry=>'2007-12-11')"

2 Renew with max. parameters. We specify duration as well to two months

-o domain -c renew -p "%p=(name=>'Æ', curexpiry=>'2007-12-11', duration=>{months=>2})"

Domain withdraw

This is a .NO specific extension command.

Withdraw will transfer the domain to REG0, thus a registrar can push the responsibility for a domain into the bucket.

-o domain -c withdraw -p "%p=(name=>'')"

If the sponsor for a domain is REG0, any registrar can do a transfer on it to take over the responsibility.

Domain transfer commands

Domain transfers are used if the registrant wants to change his registrar. He must then ask a new registrar to transfer his domains from the current registrar to the new one.

authInfo is known, can use it in a direct 'transfer execute'

If the registrant knows the authInfo, he passes it to the new registrar, who can do a transfer 'op=execute' containing the authInfo, and the transfer will be performed.

 - The execute must be authorized by the token. 
 - An optional duration can specify a renew period for the domain (1-12 months).

-o domain -c transfer_execute -p "%p=(name=>'', pw=>'abc', duration=>{months=>'6'})"

If the password is correct, the domain should be transferred.

authInfo not known, must request one-time token

If the registrant does not know the authInfo, the new registrar must initiate a transfer by sending a transfer request without authInfo. This will trig the registry to generate a one-time password (a token) and send it to the registrant, which in turn must pass the token to his new registrar. The new registrar can then send a transfer execute containing the token, and then the transfer will be performed.

1 Domain transfer request

Initate a transfer request to ask for a token. The DRI-method used is domain_transfer_start(). The token will be sent to the primary email address registered on the registrant unless a special alternative address is selected.

-o domain -c transfer -p "%p=(name=>'')"

Optionally, use the notify address to specify that the token shall be sent to another email address. It must match one of the registered email addresses:

-o domain -c transfer -p "%p=(name=>'', notify=>{email=>''})"

Optionally, specify that the token shall be sent by SMS to a mobilePhone number as notify address. It must match the registered mobilePhone number.

-o domain -c transfer -p "%p=(name=>'', notify=>{mobilephone=>'+47123456789'})"

2 Domain transfer query

After a transfer request is received, the token is sent to the registrant. Until a transfer execute is received the domain will remain in a pending state.

The status of pending transfers can be queried.

-o domain -c transfer_query -p "%p=(name=>'')"

3 Cancel a pending transfer

A pending transfer can be cancelled. The token will be deleted and the pending state information will be restored to the normal state.

-o domain -c transfer_cancel -p "%p=(name=>'')

4 Execute a pending transfer
 - Execute must be authorized by the token. 
 - An optional duration can specify a renew period for the domain (1-12 months).

-o domain -c transfer_execute -p "%p=(name=>'', token=>'MySecretToken', duration=>{months=>'9'})"

If the token is correct, the domain should be transferred.

Polling the message queue

Poll messages

1 message_waiting()

This method performs a poll request and returns true if one or more messages are waiting in the queue.

-o message -c waiting -p "%p=()"

2 message_count()

This method performs a poll request and returns the 'msgQ count' value from the response, if any.

-o message -c count -p "%p=()"

3 message_retrieve()

This method performs a poll request, and with get_info() you can grab all the message details.

-o message -c retrieve -p "%p=()"

4 message_delete()

This is the poll ack message, which will remove message (with id=12) from the server message queue.

-o message -c delete -p "%p=(id=>12)"


Copyright (c) 2008 UNINETT Norid AS, <>, Trond Haugen <> All rights reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

See the LICENSE file that comes with this distribution for more details.


Trond Haugen, <>

1 POD Error

The following errors were encountered while parsing the POD:

Around line 1621:

Non-ASCII character seen before =encoding in 'E<34>%p=(name=>'test-ÆØÅ.no','. Assuming ISO8859-1