Desc: Network protocol info
File: protocol.txt
Date: 22 October 2002
Auth: Russell Kroll <rkroll@exploits.org>

Here's a quick description of how the network protocol works...

This protocol is run over both TCP and UDP, uses English words to perform
operations, and consists of lines terminated by a CR/LF pair.  It is not
case sensitive, but the examples here will be all uppercase to clearly
show what is being sent and received.

As of May 2002, this protocol now has an official port number from IANA,
which is 3493.  The old number (3305) was a relic of the original code's
ancestry, and conflicted with other services.  Version 0.50.0 and up
use 3493 by default.

LISTVARS
========

Form: LISTVARS [<upsname>]

upsname is an identifier given to a UPS on a host.  These are specified
in the ups.conf.  If it is not specified, the server will refer to the
first entry from that file.

Returns: VARS <varlist>
Returns: VARS @<upsname> <varlist>	(when upsname specified)

<varlist> is a space delimited list of all possible variables that
the server process knows about for this UPS.

Requires: MONITOR or higher access

REQ
===

Form: REQ <varname>[@<upsname>]

<varname> is a variable name returned by LISTVARS or a reserved word:

 - Reserved words:

   NUMLOGINS - Number of systems currently monitoring this UPS
               (incremented by LOGIN commands from authorized clients)

<upsname> is an identifier as seen above with LISTVARS.

Returns: ANS <varname> <value>
Returns: ANS <varname>@<upsname> value	(when upsname specified)

<varname> is the variable you requested, repeated just to be sure

<value> is the current value as the server knows it

*** Old versions of upsd also have a few special responses for <value>:

 UNKNOWN
  - upsd doesn't recognize this variable.  
    Replaced with "ERR VAR-UNKNOWN".

 NOT-SUPPORTED
  - this UPS driver doesn't gather data for this variable
    Replaced with "ERR VAR-NOT-SUPPORTED".
   
 DATA-STALE
  - the server hasn't gotten an update for this data recently
    Replaced with "ERR DATA-STALE".

Requires: MONITOR or higher access

LOGOUT
======

Form: LOGOUT

Returns: OK GOODBYE	(recent versions)

TCP mode only.  Used to disconnect gracefully from the server.

Older versions just said "Goodbye...".

LOGIN
=====

Form: LOGIN [<upsname>]

Returns: OK	(upon success)
	 or various errors

Requires: LOGIN or higher access		(legacy)
          "upsmon slave" in upsd.users

Use this to log the fact that a system is drawing power from this UPS.
The upsmon master will wait until the count of attached systems reaches
1 - itself.  This allows the slaves to shut down first.

NOTE: You probably shouldn't send this command unless you are upsmon,
      or a upsmon replacement.

MASTER
======

Form: MASTER [<upsname>]

Returns: OK	(upon success)
	 or various errors

Requires: MASTER or higher access		(legacy)
          "upsmon master" in upsd.users

This function doesn't do much by itself.  It is used by upsmon to make
sure that master-level functions like FSD are available if necessary.

FSD
===

Form: FSD [<upsname>]

Returns: OK FSD-SET	(success)
	 or various errors

Requires: MASTER or higher access

upsmon in master mode is the primary user of this function.  It sets this
"forced shutdown" flag on any UPS when it plans to power it off.  This is
done so that slave systems will know about it and shut down before the
power disappears.

Setting this flag makes "FSD" appear in a STATUS request for this UPS.
Finding "FSD" in a status request should be treated just like a "OB LB".

It should be noted that FSD is currently a latch - once set, there is  
no way to clear it short of restarting upsd or dropping then re-adding
it in the ups.conf.  This may cause issues when upsd is running on a
system that is not shut down due to the UPS event.

PASSWORD
========

Form: PASSWORD <password>

Returns: OK	(upon success)
	 or various errors

Requires: BASE or higher access

Sets the password associated with a connection.  Used for later
authentication for commands that require it.

USERNAME
========

Form: USERNAME <username>

Returns: OK	(upon success)
	 or various errors

Requires: BASE or higher access

Sets the username associated with a connection.  This is also used for
authentication, specifically in conjunction with the upsd.users file.

LISTRW
======

Form: LISTRW [<upsname>]

Returns: RW <read-write variable list>
         RW @<upsname> <read-write variable list> (when upsname specified)

Requires: MONITOR or higher access

Lists all variables that allow modification of their values within the
driver.

VARTYPE
=======

Form: VARTYPE <varname>[@<upsname>]

Returns: TYPE <vartype> <extravalue>

Requires: MONITOR or higher access

<vartype> is one of ENUM or STRING.

ENUM: Enumerated type, <extravalue> is how many possibilities exist
STRING: Character string, <extravalue> is how long it may be

Lists the type of a read-write variable.

VARDESC
=======

Form: VARDESC <varname>

Returns: DESC "<variable description>"

Requires: MONITOR or higher access

<variable description> is a short explanation of what a variable means.

ENUM
====

Form: ENUM <varname>[@<upsname>]

Returns: multi-line return:

ENUM <varname>
OPTION "<optval>" [SELECTED]		may repeat multiple times
END

Requires: MONITOR or higher access

<optval> is a valid option for <varname>.  SELECTED will be included if
<varname> is currently set to <optval> in the hardware.

Shows the possible values for an enumerated type R/W variable.

SET
===

Form: SET <varname>[@upsname] <value>

<value> is an acceptable sequence for the variable <varname>.

Requires: "SET" action granted in upsd.users

Sets the R/W variable <varname> to <value>, assuming it is allowed.

INSTCMD
=======

Form: INSTCMD <command>[@<upsname>]

Requires: "INSTCMD" action granted in upsd.users
          "<command>" instcmd granted in upsd.users

<command> is an instant command name.  See LISTINSTCMD and shared.h.

LISTINSTCMD
===========

Form: LISTINSTCMD [<upsname>]

Returns: INSTCMDS [@<upsname>] <cmd1> <cmd2> ... <cmdn>

Requires: MONITOR access

Shows all the instant commands available on a given UPS.

INSTCMDDESC
===========

Form: INSTCMDDESC <cmdname>

Requires: MONITOR access

Returns: DESC "<description>"

Shows the description for a given instant command suitable for showing
to users.

STARTTLS
========

Form: STARTTLS

Requires: TCP connection (impossible over UDP)

Returns: OK STARTTLS
	 or various errors

This tells upsd to switch to TLS mode internally, so all future
communications will be encrypted.  You must also change to TLS mode in
the client after receiving the OK, or the connection will be useless.	

Other commands
==============

HELP - lists the commands supported by this server
VER  - shows the version of the server currently in use

These two are not intended to be used directly by programs.  Humans can
make use of this program by using telnet for TCP or netcat for UDP.  Try
either "telnet localhost 3493" for TCP or "nc -u localhost 3493" for UDP
and it should talk to you.

Error responses
===============

ERR <message>

 VAR-NOT-SUPPORTED
  - this UPS doesn't support the requested variable

 VAR-UNKNOWN
  - upsd doesn't recognize the requested variable

 ACCESS-DENIED
  - This client has been denied access to this function.

 PASSWORD-REQUIRED
  - The client must set a password before attempting this action.

 PASSWORD-INCORRECT
  - The password supplied previously is not the correct one associated 
    with this action on the server.

 UNKNOWN-UPS
  - The client tried to associate a command with a UPS that is 
    not recognized by the server.

 ALREADY-LOGGED-IN
  - The client has already done LOGIN.

 ALREADY-SET-PASSWORD
  - The client has already done PASSWORD.

 UNKNOWN-COMMAND
  - The client sent a command that this server doesn't understand.

 UNKNOWN-INSTCMD
  - The client sent an instant command that this server doesn't
    understand.

 CMD-NOT-SUPPORTED
  - The client tried to start an instant cmd (INSTCMD) that the
    UPS equipment doesn't support.

Errors related to message passing (future, some unimplemented)
--------------------------------------------------------------

NO-RESPONSE: The UPS driver did not respond to a command before a timeout.

UNKNOWN-REPLY: The UPS driver gave the server a bogus response.

NOT-IMPLEMENTED: The UPS driver doesn't have this command impemented.

COMMAND-FAILED: The UPS driver tried, but failed to execute this
                command.
