|< Day Day Up >|
Hack 78 Understanding the IRC Protocol
The IRC protocol is a text-based protocol. Exploit it with just a little knowledge of its features and restrictions.
Because the IRC protocol is text based, you can easily look at it and see what's going on. You can do this either by creating a raw Telnet connection to an IRC server and typing the commands manually or by running a packet sniffer that displays all of the traffic going in and out of your IRC client.
Some IRC clients even let you see what's going on at the protocol level. For example, in mIRC, you can type /debug @output to make a new window that displays all raw lines being sent to and from the IRC server. The output looks something like Figure 13-1.
Figure 13-1. mIRC debug window showing the raw IRC messages
13.2.1 Asynchronous by Nature
The IRC protocol is asynchronous, consisting of a series of events about which you are notified. All these events come through on the same connection, line by line regardless of their content; messages from one channel are interleaved with those of another channel, private messages, server notices, and more.
If you wish the server to send you a list of names on a channel, the server will happily oblige. However, the data will be sent like any other data. If you want to interpret the data and include it in, say, a user list in the IRC client you're programming (or perhaps a user list for a channel bot), you will need to set it up to expect that data. The data must be received one line at a time and be redirected to some sort of data structure that will hold it until the list is complete.
You cannot simply request the list and expect that its content will immediately follow. Some other data might come through first, or there might be a channel message in the middle of the list. On a related note, you should not wait forever for a reply—there is always the possibility that it will never come.
Furthermore, the IRC server will not confirm your actions. If you send a message to a channel, you can only assume that it made it to the channel. The IRC server will not send anything in reply if it did. Therefore, if you're programming some sort of IRC client, you can only assume that whatever you type is going through and display it on screen. If you ask to join a channel, you cannot assume that you have joined it until the server tells you so. This asynchronous nature makes it possible for IRC servers to force IRC clients to join a particular channel, as most IRC clients will be unaware that they haven't actually asked to join that channel.
On a related note, you should be prepared to expect the unexpected from the IRC server. Although it doesn't generally happen, by virtue of the IRC protocol, you could be sent username lists, have your nickname changed without even asking for it, have words put into your mouth, be summoned into random channels, and so on.
As a general rule, you should always listen to the IRC server and accept what it tells you. For example, some servers can be set up to make you automatically join a channel when you connect, and your IRC client must accept this, even if it knows it has never asked to join that channel. Strange events like this rarely happen but become more common when you try to share the same IRC connection among several IRC clients at the same time. JBouncer (http://www.jibble.org/jbouncer) is an IRC proxy that lets you resume proxy sessions—even if other clients are already using them—resulting in multiple replies when you /VERSION the proxy user (see [Hack #85] ).
13.2.2 The Protocol
The IRC protocol is defined in RFC 1459 and updated in RFC 2812. These are both good references and explain the protocol in augmented BNF format. If you don't know what that means, you'll be glad to know a few examples of each message type follow.
prefix command command-parameters\r\n
The prefix is optional and is generally used only in incoming messages. If there is a prefix, the message will start with a colon character (:). It will contain either the name of an IRC server, an IRC nickname, or an IRC nickname and host mask (nick!ident@host). This identifies the source of the message; if there is no prefix, you should assume the message came from your client.
The command-parameters are also optional. In many commands, the parameters will consist of a destination and a message. The message is prefixed with a : to separate it from the rest of the command parameters.
The most common command sent to an IRC server is PRIVMSG. Although it might seem that this command would be limited to private conversations between users, it is in fact used to send messages to channels as well. Its format is:
prefix PRIVMSG destination :message-contents
For example, a message sent to a channel could end up looking like this when it is received:
:Traceyfirstname.lastname@example.org PRIVMSG #game1 :She's dead. Keep laughing.
A message sent to another user would look like this when he receives it:
:AlcarGMemail@example.com PRIVMSG Brisby :And no, Tracey doesn't know Oscar.
Of course, when you send a message, you can make things a bit simpler by not having to specify your own host mask. So to send a message to a channel, your client would simply have to send:
PRIVMSG #game1 :(( Keep laughing?!? YOU INSENSITIVE CLOD!!! ))
Likewise, to send a message to another user (in this case, Gandalf[bot]), you could just do this:
PRIVMSG Gandalf[bot] :Note to Fennec: Where have you been?!?!?!
PRIVMSG JacobRiisfirstname.lastname@example.org :I know where you sleep!!!
Note also that there is no IRC command for an action. These commands are handled by the CTCP command ACTION , and are transported via PRIVMSG commands, as shown in [Hack #85] .
A NOTICE is much like a PRIVMSG, but RFC 2812 absolutely forbids that any automated reply be sent to a NOTICE. This restriction is designed to prevent infinite loops between automatic systems such as IRC bots. The syntax is the same as for PRIVMSG. The NOTICE command is not used very often, although you may see it coming from IRC service commands such as NickServ [Hack #5] and ChanServ [Hack #9].
People may be upset if you send many NOTICE messages to a channel because, depending on the nature of the IRC client, NOTICE messages are seldom displayed or interpreted as nicely as normal PRIVMSG commands.
Every so often, the server may check to see if you're still connected. It does this by sending a PING message. This message should be immediately replied to with a PONG command with the same parameters. Failure to do so could result in a ping timeout, which will result in the server disconnecting you.
|< Day Day Up >|