Unreal 3.2 Protocol Documentation

Last update: 29 November 2006

Table of Contents

1 Introduction

2 Server Negotiation

2.1 PASS - Connection Password

2.2 PROTOCTL - Server Protocol Negotiation

2.3 SERVER - Server Negotiation

2.4 EOS - End Of Synch

2.5 NETINFO - Network Information

3 User Operations

3.1 NICK - User Introduction and Nick Change

3.1.1 Nick Collisions

3.2 MODE, UMODE2 - User Mode Change

3.3 QUIT - User Disconnect

3.4 KILL - Force Disconnect

3.5 SETHOST/CHGHOST - Change virtual host

3.6 SETIDENT/CHGIDENT - Change a user's username

3.7 SETNAME/CHGNAME - Change a user's realname

3.8 WHOIS - User Information

4 Server Operations

4.1 SERVER - Server Introduction

4.2 SQUIT - Server Removal

4.3 SDESC - Server Description

4.4 PING - Live Connection Query

4.5 PONG - Live Connection Reply

4.6 STATS - Server Stats

5 Channel Operations

5.1 SJOIN - Channel Burst

5.2 JOIN - Channel Join

5.3 PART - Channel Part

5.4 KICK - Channel Kick

5.5 MODE - Channel Mode

5.6 INVITE - Invite a user to a channel

5.7 SAJOIN - Channel Force Join

5.8 SAPART - Channel Force Part

5.9 SAMODE - Channel Force Mode

5.10 TOPIC - Chanel Topic

6 Services Commands

6.1 SVSKILL - Force Disconnect by Service

6.2 SVSMODE, SVS2MODE - Force User Mode Change

6.3 SVSSNO, SVS2SNO - Forced SNomask Change

6.4 SVSNICK - Forced Nick Change

6.5 SVSJOIN - Forced Join

6.6 SVSPART - Forced Part

6.7 SVSO - Oper Permissions

6.8 SVSNOOP - Oper Lockdown

6.9 SVSNLINE - RealName Ban

6.10 SVSFLINE - File Ban

7 Messaging

7.1 PRIVMSG, NOTICE - Simple Message Transmission

7.2 SENDUMODE, SMO - Usermode-based Delivery

7.3 SENDSNO - SNomask-based Delivery

7.4 CHATOPS - IRCop Chat

7.5 WALLOPS - Wallop Chat

7.6 GLOBOPS - FailOp Chat

7.7 ADCHAT - Admin Chat

7.8 NACHAT - NetAdmin Chat

8 Ban Control

8.1 TKL - Master Ban Control

8.1.1 GLINE - Network-wide user@host ban

8.1.2 GZLINE - Network-wide IP ban

8.1.3 SQLINE, UNSQLINE - Network-wide Nickname ban

8.1.4 SPAMFILTER - Message Spam Filtration System

9 Base64 Tables

9.1 Table for NICKIP.


1 Introduction

This document describes the UnrealIRCd server-to-server protocol.

A word about clocks.

Unreal is very time-dependant. Users and channels, for example, are timestamped, and if server clocks are not synchronized properly, things can go very wrong very fast. See http://vulnscan.org/UnrealIrcd/faq/#67 for more information on this. Note that there is a slight difference between server time and what is actually reported by the UNIX date command or by the C time() function. Unreal can apply an offset to the real time to create the server time, allowing servers to be virtually synchronized when synchronizing the real clocks is not possible (such as on shell servers). I should make it quite clear that GMT time is used for everything. To be specific, timestamps in unreal are 32-bit integer values (actually, however many bits the time_t type is, which is 32 on 32-bit systems such as x86). This integer value is the number of seconds that have elapsed since Midnight January 1, 1970 GMT (can be referred to as Epoch time in the UNIX world). This means that timezones are no problem, nor is daylight savings time (or whatever your country of choice calls it).


2 Server Negotiation

The first step to establish a server-to-server communication is to negotiate the connection as a server. Negotiation is done using standard IRC commands - no PROTOCTL options are in force until the link is established. The first step is to open a TCP/IP connection to the target server. The target port must be one described by a listen {} block in the remote server's configuration, and that listen block must not have the clientsonly option. After the connection is open, you will be treated as any other connection and be greeted with the "Looking up your hostname..." and "Checking identd..." notices as you would for a client. As these are NOTICE messages and your session as a server isn't established, they should simply be ignored. Use the commands below to introduce a server connection.

2.1 PASS - Connection Password

Syntax: PASS :link password

The PASS command is used to transmit the password required for a server link. It must match the password specified in the remote server's link::password-receive (which can be crypted), otherwise the link will be rejected. This should be the first message sent.

2.2 PROTOCTL - Server Protocol Negotiation

Syntax: PROTOCTL protocol options

The PROTOCTL command sets several protocol options. The tokens supported are listed below.

The syntax examples here follow the conventions for TOKEN and also NS in cases of server-only messages.

2.3 SERVER - Server Negotiation

Note: This message is also used for introducing additional servers, the format of this message in those cases is described later.

Syntax (normal): SERVER server.name 1 :server description

Syntax (with VL): SERVER server.name 1 :Uprotocolversion-protocolflags server description

Syntax (with VL and NS): SERVER server.name 1 :Uprotocolversion-protocolflags-servernumeric server description

The literal 1 in the parameter list is the hopcount parameter. Since you are a direct link, your own hopcount will be 1.

The server.name is the same as that in the remote server's link:: block. When received from unreal servers, this will be the value of that server's me::name. The protocol version is the numeric protocol version (2306 for example), and the protocol flags are the server's compilation flags (described below). These two fields are checked against the deny version {} blocks in the remote server's configuration. A value of 0 for either field prevents deny version{} checking for that field. The server description can be anything. When received from unreal servers, it'll be the value of me::description.

The following version numbers have been used previously:

The compile flags as specified in protocol flags are:

2.4 EOS - End Of Synch (TOKEN: ES)

Syntax: ES

Marks the end of the synching process. This is really optional, but it might be a good idea to send it anyway when you really are done synching. Once you send this, unreal will announce "Client connecting" or "Client exiting" notices (to those with snomask +F) for users (unless your server is U:Lined), and joins will be counted toward channel flood controls (chanmode +f).

Sending EOS only marks your server as synched, but does not do so for servers behind you. EOS would need to be sent on those servers' behalf as well.

2.5 NETINFO - Network Information (TOKEN: AO)

Syntax: AO maxglobal currenttime protocolversion cloakhash 0 0 0 :networkname

This tells the other server your current network configuration. The max global is the highest number of concurrent users network-wide that this server has seen. The current time is a timestamp value. Protocolversion is the same as that in the SERVER command. Cloakhash is a hash representing the configured cloak keys. It may be a * if you are implementing services. The network name is that specified in set::network-name. The cloak-prefix is currently not sent here (and thus unreal won't generate warning for mismatching cloak prefixes, but they should be the same anyway).

It is NETINFO, not EOS, that triggers the "Link bla bla bla is now synched" notices, but NETINFO does not imply synching is actually complete (see EOS).


3 User Operations

One important function of servers is it must notify all other servers about all of the users behind it. These commands represent the operations that can result in the change of a user's global state.

3.1 NICK - User Introduction and Nick Change (TOKEN: &)

Syntax (nick change): :oldnick & newnick :timestamp

This format of the NICK message indicates an existing user is changing his or her nickname. If a collision occurs, see the section on Nick Collisions below. The timestamp is the new nickname's timestamp.

Syntax (normal): & nick hopcount timestamp username hostname server service-identifier-token :realname

Syntax (NICKv2): & nick hopcount timestamp username hostname server service-identifier-token +usermodes virtualhost :realname

Syntax (NICKv2+CLK): & nick hopcount timestamp username hostname server service-identifier-token +usermodes virtualhost cloakhost :realname

Syntax (NICKv2+NICKIP): & nick hopcount timestamp username hostname server service-identifier-token +usermodes virtualhost nickipaddr :realname

Syntax (NICKv2+NICKIP+CLK): & nick hopcount timestamp username hostname server service-identifier-token +usermodes virtualhost cloakhost nickipaddr :realname

Note: Because each server normally does its own cloak generation, Unreal does not expect to receive NICK messages with the CLK info, so do not send it. It will send this info to a server it has received a PROTOCTL CLK from however.

This format of the NICK message introduces a new user to the network. If PROTOCTL VHP is enabled, the user's cloaked host is put in the virtualhost field, otherwise it'll be * unless the user is +t. With the addition of CLK, VHP is no longer necessary for determining the cloak host.

3.1.1 Nick Collisions

A nick collision occurs when a server receives a NICK message (or & token) introducing a user that the server already sees on the network. When a collision occurs, one or both of the colliding clients must be disconnected. The timestamp is examined to determine which client loses. The client with the earlier timestamp remains. If both clients have equal timestamps, both are removed. Currently, Unreal handles NICK collisions both passively and agressively:

3.2 MODE, UMODE2 - User Mode Change (TOKEN: G or |)

Syntax (MODE): :user G user modechange

Syntax (UMODE2): :user | modechange

This indicates a usermode change. The modechange can consist of zero or more strings of characters, each prefixed with either a + or -; the only delimiter between them being said + or -. If no + or - is at the beginning of the mode string, a + should be implied.

Some user modes are never sent between servers. Specifically, usermode +s and +O are not sent between servers. Modules can define additional usermodes that also might not be sent between servers. The UMODE2 saves bandwidth by not including the redundant target field for usermode changes, so use it when possible.

3.3 QUIT - User Disconnect (TOKEN: ,)

Syntax: :user , :reason

This command indicates that a user has disconnected. The reason field is filled in with the reason the user disconnected, which will be any of: quit message provided by the user in a /quit command, kill message for local operator kills, "Client exited" if the user does a brutal quit (clean (by TCP's definition) disconnect without sending a QUIT message), or a socket error message if present.

The QUIT message must NOT be prefixed when passing on to other servers. Only local user quit messages are affected by set::prefix-quit.

3.4 KILL - Force Disconnect (TOKEN: .)

Syntax: :source . target :killpath!source (reason)

Used to indicate that an operator has used KILL on a user not on the same server. Anything beyond the last ! in the kill path is used as the reason. The source (reason) part is simply a standard used by Unreal. As each server passes on a KILL message, it usually prepends the bottommost part (up to the first .) of it's name followed by a ! character. When unreal receives a KILL from a directly connected irc operator, it will usually add that oper's vhost (or realhost if -x) as the first hop in the kill path, then follow with it's own name as mentioned before if it is passing to another server.

A server can also send KILLs on it's own. This is done in cases involving nickname collisions, fake senders, bad direction, and other cases of protocol errors. Usually, in these cases, the server puts it's own name as the source, and also prefixes with bottompart! like for any other ircop on that server. For example: @3 . someone :irc!irc.example.com (Nick collision)

3.5 SETHOST/CHGHOST - Change virtual host (TOKEN: AA or AL)

Syntax (SETHOST): :source AA newvhost

Syntax (CHGHOST): :source AL target newvhost

Indicates the change of a user's virtual host. Currently, servers are expected to assume UMODE2 +xt on the target user in both commands. (In the case of SETHOST, the target is the sender.) Servers using PROTOCTL VHP will receive the cloaked host in a SETHOST message when a user activates his cloaked host. A server can also send CHGHOST (from one of it's opered clients) to change a user's hostname. This is generally used by HostServ implementations. To disable a cloaked host, use CHGHOST to set the user's virtual host equal to his real host, or use SVSMODE -xt, but the latter requires services.

3.6 SETIDENT/CHGIDENT - Change a user's username (TOKEN: AD or AZ)

Syntax (SETIDENT): :source AD newusername

Syntax (CHGIDENT): :source AZ target newusername

Indicates the change of a user's username. No usermode change is associated with this. Unreal does not use a distinguished virtual username, so servers should only keep the original username (from the NICK message) if they intend to allow the user to reset the original username. Servers can use CHGIDENT to change a user's username.

3.7 SETNAME/CHGNAME - Change a user's realname (TOKEN: AE or BK)

Syntax (SETNAME): :source AE :newrealname

Syntax (CHGNAME): :source BK target :newrealname

Indicates the change of a user's realname. No usermode change is associated with this. Unreal does not use a distinguished virtual realname, so servers should only keep the original realname (from the NICK message) if they intend to allow the user to reset the original realname. Servers can use CHGNAME to change a user's username. Note that servers must NOT check that the sender be an IRCop in SETNAME - normal users are permitted to use SETNAME.

3.8 WHOIS - User Information (TOKEN: #)

Syntax: :source # [from-server ]nick

Requests the information on a user. This works exactly like the user /whois command - in fact, the source parameter must be a user, or the command will do nothing. from-server is the server to request the information from; if a server recives a WHOIS message without this parameter, it should return its own information on the user, otherwise it should pass the message to the given server. Note that from-server may name a user instead of a server (such as when a user uses /whois nick nick), in which case the the nick should be interpreted as naming the server that user is on. nick may be several users seperated by commas, but may not contain wildcards.

The reply to a WHOIS message uses the same numeric replies as the user command.


4 Server Operations

This is different from server negotiation. Negotiation is when you are first connecting. Server introduction is used for introducing additional servers behind an existing server (aka hubbing). Hubbing is limited as specified by the hub, leaf, and leafdepth parameters in the link block and attempted violation of a hub restriction results in termination of the link. If no hub or leaf directive is given your server is a leaf by default, so any introduction of any server behind you would be an automatic drop. U:Lines don't matter here; services must be configured as a hub in the link block. The reason is U:Line is a permission rule, but hub privilege is a network structure rule.

4.1 SERVER - Server Introduction (TOKEN: ')

Note: This command is also used for negotiation. Be warned that the token for this command is NOT VALID at that time! See section 2.3 for the syntax for negotiation.

Syntax (without PROTOCTL NS): :source SERVER new.server hopcount :description

Syntax (with PROTOCTL NS): @sourcenumeric SERVER new.server hopcount numeric :description

The command indicates that the server named new.server is being introduced by the source (the source is the server which new.server is directly linked to). The hopcount will be the number of links the receiving server would have to cross to reach new.server. In other words, new.server introduced itself with a hopcount of 1, and as the SERVER message is passed along, hopcount is incremented.

As an example, a services server faking a SERVER message for JUPE functionality would use a hopcount of 2.

4.2 SQUIT - Server Removal (TOKEN: -)

Syntax: :source SQUIT server.name :reason

From an IRCop or when server.name is not behind the source, this command requests the removal of the specified server.name. The command in this case is treated very much like KILL in the respect that the message is broadcasted to all servers, except server.name and any servers behind it. When the SQUIT reaches server.name's uplink, that server closes the link to server.name (which would then generate it's own SQUIT on behalf of it's uplink for the servers behind it).

A server can also use SQUIT in the same manner as QUIT to note the removal of a server behind it, or that it itself is quitting. In the former case, server.name is behind source, and the message is forward on to all other servers. In the latter case, source and server.name are equal, the receiving server closes the link and forwards the SQUIT message.

Unreal closes a direct link by simply sending an ERROR message and then closing the TCP connection. This typically causes the other end to generate an SQUIT bearing the message "Client exited" or similar, however, the ERROR will usually cause the server to send a message to all IRCops.

4.3 SDESC - Server Description (TOKEN: AG)

Syntax: :source AG :newdesc

The server to which source is connected to should have it's description updated to newdesc. This does NOT include the VL inforamtion.

4.4 PING - Live Connection Query (TOKEN: 8)

Syntax: 8 source[ :destination]

Used to check if a connection is still live if it has been "quiet" for a certain amount of time. Typically, unreal will send PING requests at intervals determined by the class::pingfreq setting. PINGs originating from the direct uplink will use the token, but it seems PINGs originating from a distant server will not.

The response to a PING is sent with the PONG command.

When receiving a two-parameter PING, the second parameter is the target. If the target isn't you, you can either reply on behalf of that target (using its name instead of yours), or if there is a real connection representing the target, forward the PING to the target.

4.5 PONG - Live Connection Reply (TOKEN: 9)

Syntax: 9 source[ :destination]

Used to respond to a PING query.

Responding to a ping: Once a PING is received, you usually have an amount of time to respond equal to your class::pingfreq. The correct response will always have two parameters. If you received one parameter, then the received parameter becomes the second parameter of your response, and the first parameter is your server name. If you received two parameters, the response returns both parameters in reverse order.

For example, the response to 8 uplink.server is 9 my.name uplink.server, while the response to PING distant.server your.server is 9 your.server distant.server. Unreal typically includes a : prior to the last parameter. This isn't required if that parameter contains no spaces, but it is especially important to not include the colon when reversing the parameters, or else Unreal mistake it for a single-parameter PONG.

If a two-parameter PONG is received, the second parameter names the target. If the target is not you, and a real connection represents that target, you should forward the PONG message via that connection.

4.6 STATS - Server Stats (TOKEN: 2)

Syntax: :source 2 [type [server] [extended-params]]

Requests statistics or configuration information from a server. This command is used to transport cross-server STATS requests from users (eg: /stats o other.server), and should only be sent from a user (not a server). With no parameters, this will cause unreal to simply dump its help output. type is the type of stats to request, server names a server (or a user on that server) to request stats from, and extended-params is used to filter output from STATS G, etc. When received, it is up to the receiver to determine what stats to support and how to reply, but generally numeric replies are used. For the list of unreal's stats types, type /stats in a client for the helptext dump.

Note: Stats set as oper-only (see set::oper-only-stats) will be refused from a server. In this case, it will be necessary to send the stats request from a psuedo-oper (such as a services agent, etc) for services/stats/etc.


5 Channel Operations

These commands deal with the state of channels across the network. Unreal only supports Network Channels, where the first character is a # character.

5.1 SJOIN - Channel Burst (TOKEN: ~)

Syntax: @servernumeric ~ timestamp channel +modes[ modeparams] :memberlist &ban "exempt 'invex

Timestamp is the channel timestamp. Modes should only include those in the last three mode sets listed in CHANMODES. Modeparams is one parameter for each mode character that requires one. Memberlist is a series of users (all of which must at least be behind the server sending the SJOIN), each user is prefixed with one or more characters indicating their status. Owners (+q) are prefixed with *, admins (+a) ~, ops (+o) @, halfops (+h) %, voices (+v) +. Normal users are not prefixed with anything. Ban, ban exception, and invite exception masks are also included, with bans prefixed with &, ban exceptions prefixed with ", and invite exceptions with '. Note that when a &, " or ' is encountered as the first character, further processing of ~, *, @, %, or + characters must not continue because ban, exempt, and invite masks can contain any of those characters. (Plus it's just not right for a ban mask to be marked as a channel admin...)

If the channel didn't already exist it is created with the information given in the SJOIN. Otherwise the timestamp is used to determine how the SJOIN information is handled. As a given, all members are joined into the channel, regardless. The mode information (modes, modeparams, memberlist prefixes, bans, exempts, and invites) is subject to the timestamp rules:

When merging modes, conflicting modes (including +p vs +s, differing +l limits or +k keys, etc) are handled as follows:

5.2 JOIN - Channel Join (TOKEN: C)

Syntax: :source C #channel

Indicates a user has joined a channel. Only one channel is sent this way, and the key is not sent even if the user gave one one joining. If the channel parameter is the special "0" case, the server must interpret the message as a PART for all channels the user is on.

5.3 PART - Channel Part (TOKEN: D)

Syntax: :source D #channel[ :reason]

Indicates a user has left a channel. Only one channel is sent this way. The reason parameter may be left out if no reason was given.

5.4 KICK - Channel Kick (TOKEN: H)

Syntax: :source H #channel user :reason

Orders the forced removal of user from #channel with the given reason. When updating state for this command, it should be the same as if :user PART #channel had been received - the user is removed from #channel's memberlist.

5.5 MODE - Channel Mode (TOKEN: G)

Note: This is the same command as that used for usermode changes.

Syntax: :source G #channel modechange modeparams[ timestamp]

Changes the specified modes on the given channel. If the source is a server and the last parameter is numeric, it is interpreted as timestamp (although it can also be consumed as a parameter for modes. For example: :server.name MODE #channel +l 4 <-- 4 will be a timestamp and the +l parameter). When a mode change is timestamped in this way, the mode is treated as it is with SJOIN: the MODE message is ignored if the timestamp is greater than the channel timestamp. (If the timestamp is equal, the mode is simply added replacing any conflicting modes already in place.)

A services implementation can easily clear all entries in a list mode such as bans with SVSMODE (see below).

5.6 INVITE - Invite a user to a channel (TOKEN: *)

Syntax: :source * target #channel

Sends to target an invitation to join #channel. If the source is a channel operator on #channel, or a U:Lined server, the invitation grants the user the temporary ability to join the channel regardless of any bans or some restricting channel modes (not +O or +A).

5.7 SAJOIN - Channel Force Join (TOKEN: AX)

Syntax: :source AX targetuser #channel

This requests the forced join of targetuser to #channel. This type of forced join overrides bans, and most modes. The server to which targetuser is connected to must actually acknowledge the join for it to occur. Service implementations may ignore this command, as they would only ever receive it if an SAJOIN was targeted at a service client, in which case it should be ignored...

5.8 SAPART - Channel Force Part (TOKEN: AY)

Syntax: :source AY targetuser #channel[ :reason]

This requests the forced part of targetuser from #channel. This is slightly different from a KICK in that the user's removal is announced with PART. The server to which targetuser is connected to must actually acknowledge the part for it to occur. Service implementations may ignore this command, as they would only ever receive it if an SAPART was targeted at a service client, in which case it should be ignored...

The reason field is optional. If provided the acknowledging PART message should prefix the message with "SAPart:".

5.9 SAMODE - Channel Force Mode (TOKEN: o)

Syntax: :source o #channel modechange modeparams

This has the same parameters as for MODE. The only difference is that servers probably will never receive this (but is best to document just in case), and that absolutely NO permission checking is done on anything.

5.10 TOPIC - Channel Topic (TOKEN: ) )

Syntax: :source ) #channel nick timestamp :topic

Changes the channel topic information. This format is used when synching, as well as when a topic is changed normally. Nick is the user who changed the topic (depending on compile options, it can be just nick or a full nick!user@host), timestamp is when the change occured, and topic is the new topic text. Normally, only a newer timestamp will actually change the topic, but a U:Lined server can use an older timestamp as well (such as for TOPICLOCK).


6 Services Commands

These are commands typically employed by a service implementation, in addition to some of the normal commands. All of the commands listed here require the sender to be correctly U:Lined. This means that the services server name must appear within a ulines {} block in the unrealircd.conf configuration for ALL servers in the network. All servers and clients behind a U:Lined server are themselves U:Lined.

6.1 SVSKILL - Force Disconnect by Service (TOKEN: h)

Syntax: :source h target :reason

This command is similar to KILL but differs in several ways. First of all: there is no mutilation of the reason value. The reason given is the exact reason used to generate QUIT messages sent to users. Second, it is silent; no server notice is generated in response to this command. Third, it can only be used by a U:Lined server or client (such as services).

Because this command can be dangerous in the hands of an abusive person, service implementations should avoid granting humans control over the reason parameter. In cases of commands where a person has control over such parameter, either use a regular KILL instead, or otherwise modify the reason so that operators can be held accountable if necessary.

6.2 SVSMODE, SVS2MODE - Force User Mode Change (TOKEN: n or v)

Syntax (SVSMODE): :source n target +usermodes

Syntax (SVS2MODE): :source v target +usermodes

Judging by these commands alone, you'd think they are identical. Both commands force a usermode change to occur. This is typically used by services to set +r on a user who has successfully identified. They differ in that SVS2MODE also sends the mode change to the user, while SVSMODE does not (hidden mode change).

SVSMODE and SVS2MODE also give special treatment to usermode +d. Rather than setting the deaf mode like you might expect, SVS(2)MODE +d allows services to change a user's services stamp (which is given in the NICK message). This could allow services to set the service stamp to an easily identifiable value that could then be used to say "hey, this person identified already". The syntax of this is: +d newservice-identifier-token and can be combined with setting other usermodes as well. The deaf mode can be set by using +d without the service stamp parameter; however, in this case you cannot set the service stamp in the same SVS(2)MODE message.

Note: Do NOT use SVSMODE to remove IRCop status from a user. Use the SVSO command for that instead.

Alternatively, target can name a channel. In this case, the mode change parameter can consist of a - character, followed by any or all of: b, e, I, q, a, o, h, or v. These characters cause the corresponding lists to be cleared of all entries. For example: SVSMODE #channel -b removes ALL bans from #channel, and SVSMODE #channel -qaohv turns ALL users on #channel into normal users (removes all owner, admin, op, halfop, and voice status). In this case, the uplink will acknowledge with a MODE listing the bans, etc that were removed.

To completely clear a channel of all modes: MODE #channel -cfijklmnprstzACGMKLNOQRSTVu (plus any added by third-party module) followed by SVSMODE #channel -beIqaohv.

6.3 SVSSNO, SVS2SNO - Forced SNomask Change (TOKEN: BV or BW)

Syntax (SVSSNO): :source BV target +snomasks

Syntax (SVS2SNO): :source BW target +snomask

Changes a user's snomasks. The difference between SVSSNO and SVS2SNO is the same as with SVSMODE versus SVS2MODE. If the user is not +s, you must add it via SVSMODE +s. For example:

:OperServ v someuser +s
:OperServ BW someuser +ks

6.4 SVSNICK - Forced Nick Change (TOKEN: e)

Syntax: :source e target newnick :newtimestamp

Forces the specified user to change his nick to newnick and also sets the nick timestamp to newtimestamp (so, for example, services could protect identified users from a nick collision by simply setting the nick timestamp to something way less than "now" - though currently this requires actually changing the nick too). SVSNICK requires the server to which the target is connected to acknowledge the nick change. If the user specified by newnick already exists, then target will be disconnected (even if it's something like a case-change).

6.5 SVSJOIN - Forced Join (TOKEN: BX)

Syntax: :source BX target #channel

This is identical to SAJOIN with a few exceptions: 1) It is U:Line-only. 2) No opernotice on use. 3) Bans and restricting modes are respected, a prior INVITE message must be sent to cause bans to be ignored.

6.6 SVSPART - Forced Part (TOKEN: BT)

Syntax: :source BT target #channel :reason

Also identical to SAPART with a few exceptions: no static prefix on the optional part reason, and no global notice, and requires a U:Line. Usage recommendation of SVSPART versus KICK is the same as for SVSKILL versus KILL.

6.7 SVSO - Oper Permissions (TOKEN: BB)

Syntax: :source BB target flagchanges

This allows a service to add or remove IRCop permission flags for a user. Flagchanges is formatted similar to that of MODE with the exception that operflags are used instead of usermodes. If the change string consists only of -, then all oper permissions, usermodes, and snomasks are removed (as if the user had himself typed MODE nick -Oo).

If you are granting IRCop permissions to a user who is not currently an IRCop, you should follow up with an SVSMODE +o or SVSMODE +O as appropriate. For example:

:OperServ BB somenick +o
:OperServ BW somenick +cefknoqsSv
:OperServ AL somenick local.oper.somethinghere.net
:OperServ v somenick +Ohs 

6.8 SVSNOOP - Oper Lockdown (TOKEN: f)

Syntax: :source f (op)server.name

The (op) parameter is either a + or - indicating if NOOP mode should be activated (+) or deactivated (-). When NOOP mode is activated, all IRCops on the server are deopered (including local operators) and the /oper command is disabled. IRCop privileges can still be granted through use of SVSO. On UnrealIRCd, it is not necessary to masskill all IRCops on the nooped server, as they are deopered automatically.

6.9 SVSNLINE - RealName Ban (TOKEN: BR)

Syntax: :source BR op reason :realname mask

Op is either + (add) or - (remove). In the case of +, reason is a space-escaped string (all space chars are encoded as _). If -, reason is ignored.

6.10 SVSFLINE - File Ban (TOKEN: BC)

Syntax (add): :source BC + filemask :reason

Syntax (remove): :source BC - filemask

Syntax (clear): :source BC *

Adds or removes a DCCDENY item for the specified filemask on all servers. These DCCDENYs are hard dccdenies - the /dccallow command cannot override it. The last form removes all dccdenies added via SVSFLINE.


7 Messaging

What good is Internet Relay CHAT if users cannot CHAT? This section addresses the commands through which arbitrary user messages are sent.

7.1 PRIVMSG, NOTICE - Simple Message Transmission (Token: ! or B)

PRIVMSG Syntax: :source ! target :message

NOTICE Syntax: :source B target :message

Sends a messages to the given target. The target either names a single client, or identifies a list of clients in which the message is to be sent to. The available targets include:

Unreal does not support the #hostmask format.

7.2 SENDUMODE, SMO - Usermode-based Delivery (TOKEN: AP or AU)

Syntax: @servernumeric AU umode :message

Sends the specified message to all users with the given mode. Only one usermode may be given. This is a server-only command if you can't tell from the sender prefix :) .

The message will be displayed as coming from the receiving client's own server. It may be appropriate to add a "*** Notice (or other leader here) -- from blah:" if you wish to clarify where the message is from.

7.3 SENDSNO - SNomask-based Delivery (TOKEN: Ss)

Syntax: @servernumeric Ss snomask :message

Sends the specified message to all users with the given snomask. Only one snomask may be given. This is a server-only command if you can't tell from the sender prefix :) .

The message will be displayed as coming from the receiving client's own server. It may be appropriate to add a "*** Notice (or other leader here) -- from blah:" if you wish to clarify where the message is from.

7.4 CHATOPS - IRCop Chat (TOKEN: p)

Syntax: :source p :message

Sends the message to all IRCops on all servers.

7.5 WALLOPS - Wallop Chat (TOKEN: =)

Syntax: :source = :message

Sends the message to all users with usermode +w, whether they are ircops or not.

7.6 GLOBOPS - FailOp Chat (TOKEN: ])

Syntax: :source ] :message

Send the message to all IRCops with usermode +g.

7.7 ADCHAT - Admin Chat (TOKEN: x)

Syntax: :source x :message

Send the message to all Server and Network Admins (usermode +A).

7.8 NACHAT - NetAdmin Chat (TOKEN: AC)

Syntax: :source AC :message

Send the message to all Network Admins (usermode +N).


8 Ban Control

Sometimes, you have the misfortune of encountering a user who has no purpose but to serve as an annoyance to your server or network. These commands transmit network-wide ban information amongst each other.

8.1 TKL - Master Ban Control (TOKEN: BD)

The TKL command seems to have one oddity about it: the real ban source is included in the TKL command rather than in the sender prefix. Most likely this is done for synching reasons (so that the *line ban can be credited to the proper person even if he/she is offline). For this reason, the command syntax is given without any sender prefix at all. It is still permissible to use one, however.

8.1.1 GLINE - Network-wide user@host ban

Add Syntax (TKL): BD + G userpart hostpart source expiretimestamp settimestamp :reason

Remove Syntax (TKL): BD - G userpart hostpart source

Adds and Removes Network-wide user@host bans, known as G:Lines. The GLINE command itself must not be used. The userpart and hostpart are the user portion and hostname portion of the ban mask. The expiretimestamp is 0 if the G:Line should not expire, otherwise it will expire at the given time. It is an absolute time, not relative, thus it's imperitive to have reasonably synchrnoized clocks or bans may be removed too early or even immediately!

8.1.2 GZLINE - Network-wide IP ban

Add Syntax (TKL): BD + Z * ipmask source expiretimestamp settimestamp :reason

Remove Syntax (TKL): BD - Z * ipmask source

Adds and Removes Network-wide IP bans, known as Global Z:Lines. The GZLINE command itself must not be used. Ipmask permits CIDR notation as well as wildcard masks.

8.1.3 SQLINE, UNSQLINE - Network-wide Nickname ban (TOKEN: c or d)

Add Syntax (TKL): BD + Q hold nickmask source expiretimestamp settimestamp :reason

Add Syntax (SQLINE): :source c nickmask :reason

Remove Syntax (TKL): BD - Q hold nickmask source

Remove Syntax (UNSQLINE): :source d nickmask

In the TKL syntax, the hold parameter is either a * to mark the qline as a nick ban, or an H to mark it as a services hold. A services hold does not trigger qline rejection notice, and is typically used by NickServ to reserve registered nicks until they are released by the owner. The (UN)SQLINE syntax can only be used by a server, but any user can be used as the source for the TKL syntax. Unlike G and GZ lines, Q:Lines do not cause existing matching users to be disconnected or otherwise affected.

The TKL syntax is preferred, since it is more flexible, but (UN)SQLINE is permitted for compatibility.

8.1.4 SPAMFILTER - Message Spam Filtration System

Proper use of spamfilter in TKL commands requires use of PROTOCTL TKLEXT, which increases the number of parameters allowed in TKL.

Add Syntax (TKL): BD + F target(s) action source 0 settimestamp tklduration tklreason :regex

Remove Syntax (TKL): BD - F target(s) action source 0 settimestap :regex

Adds and Removes network-wide spamfilters. The SPAMFILTER command itself must not be used. See http://vulnscan.org/UnrealIrcd/unreal32docs.html#feature_spamfilter for a list of valid targets. For actions, a single character is used to identify the action to be taken:

9 Base64 Tables

Historically, unreal used different base64 tables for sending NICK and SJOIN timestamps and sending NICKIP data. Currently, base64 is used only to encode NICKIP.

9.1 Table for NICKIP.

In this table, the IP is encoded in network byte order. In terms of IPs, this means the first byte of the address really is first. Each "digit" in the base64 encoded IP corresponds to 6 bits of the IP address.

An IPv4 address is 32 bits, so 6 base64 "digits" are needed. Since base64 requires values to come in multiples of 4 "digits", padding characters (=) need to be added if a value comes up short. In the case of IPv4 addresses, two are needed.

IPv6 addresses are 128-bit. They therefore need 22 base64 "digits" plus 2 pad characters.

 0 A            17 R            34 i            51 z
 1 B            18 S            35 j            52 0
 2 C            19 T            36 k            53 1
 3 D            20 U            37 l            54 2
 4 E            21 V            38 m            55 3
 5 F            22 W            39 n            56 4
 6 G            23 X            40 o            57 5
 7 H            24 Y            41 p            58 6
 8 I            25 Z            42 q            59 7
 9 J            26 a            43 r            60 8
10 K            27 b            44 s            61 9
11 L            28 c            45 t            62 +
12 M            29 d            46 u            63 /
13 N            30 e            47 v
14 O            31 f            48 w         (pad) =
15 P            32 g            49 x
16 Q            33 h            50 y