napster messages
================

by drscholl@users.sourceforge.net
February 17, 2000

0.  Forward

This is meant to be an open specification.  If you find errors or know of
additional functionality not described hereafter, please send me email.  It
benefits the entire community to have a complete and accurate protocol
specification.  Not only does it allow for clients to be developed for any
platform, but also decreases the strain on the server having to parse out
bad client messages.

Disclaimer: the following information was gathered by analyzing the protocol
between the linux nap client and may not resemble the official windows client
protocol.

1.  Client-Server protocol

each message to/from the server is in the form of
<length><type><data>
where <length> and <type> are 2 bytes each.  <length> specifies the length in
bytes of the <data> portion of the message.  Be aware that <length> and <type>
appear to be in little-endian format (least significant byte goes first).  For
example, in the C language you would encode the number 1 as
	const unsigned char num[2] = { 0x01, 0x00 };
and 256 would be encoded as
	const unsigned char num[2] = { 0x00, 0x01 };
[The above is for illustrative purposes only, there are much quicker ways to
actually encode a number. -ed]

Note that in many cases, strings are passed as double-quoted entries.  For
example, filenames and client id strings are always sent as
	"random band - generic cowboy song.mp3"
or
	"nap v0.8"
Where required, double quotes are used in the description of the messages
below.

Some additional information about use of quotes inside of quotes:
> The answer is, no, it doesn't do escaping of quotes.  If you try searching
> for the phrase 'a "quoted" string' on the windows client, you get no songs
> found, and "invalid search request" printed in yellow in your console
> window.  (don't know what code that is, sorry.)
>
> and no wonder-- a little birdie told me that the client sends this:
>
> FILENAME CONTAINS "a "quoted" string" MAX_RESULTS 100

[contributed by Ben Byer <bbyer@rice.edu>.  -ed]

Note that unlike the IRC protocol, each line does NOT end in \r\n.  The
<length> field specifies exactly how much data you should read.

2.  Message Types

The following section describes the format of the <data> section for each
specific message type.  Each field is denoted with <>.  The fields in a
message are separated by a single space character (ASCII 32).  Where
appropriate, examples of the <data> section for each message are given.

<type> can be one of the following (converted to big-endian):

0	error message [SERVER]

	<message>

2	client login message [CLIENT]

	<username> <password> <port> "<client-info>" <link-type>

	<port> is the port the client is listening on for data transfer.  if
		this value is 0, it means that the client is behind a firewall
		and can only push files outward.  it is expected that requests
		for downloads be made using the 500 message (see below)
	<client-info> is a string containing the client version info
	<link-type> is an integer indicating the client's bandwidth
		0  unknown
		1  14.4 kbps
		2  28.8 kpbs
		3  33.6 kbps
		4  56.7 kbps
		5  64K ISDN
		6  128K ISDN
		7  Cable
		8  DSL
		9  T1
		10 T3 or greater
		
	Example:

	foo badpass 6699 "nap v0.8" 3

3	login ack [SERVER]

	<email>

	the server sends this message to the client after a succesful
	login (2).  If the nick is registered, the <email> address given at
	registration time is returned.  If the nick is not registered, a
	dummy value is returned.

4	??? [CLIENT]

	<n>

	the latest napster v2.0beta5a sends this prior to login.

6	alternate login format [CLIENT]

	this message is used when logging in for the first time after
	registering (0x07) a nick

	<nick> <pass> <port> "<client-info>" <linkspeed> <email-address>

	note: this message is similar to the 0x02 message, with the addition	
	of <email-address> on the end

	Example:

	foo foo 6699 "nap v0.8" 3 email@here.com

7	client registration message [CLIENT]

	<nick>

	this message is sent to create an account

	response to this message is one of 8, 9 or 10

8	registration success [SERVER]

	the server sends this when the clients request to register a new
	nickname has succeeded.

9	nickname already registered [SERVER]

	the server sends this message when the nickname the client has
	requested has already been registered by another user

10	invalid nickname [SERVER]

	this server sends this message when the client attempts register
	an invalid nickname [what defines an invalid nickname? -ed]

11	??? [CLIENT]

	[returns "parameters are unparsable" -ed]

14	login options [CLIENT]

	NAME:%s ADDRESS:%s CITY:%s STATE:%s PHONE:%s AGE:%s INCOME:%s EDUCATION:%s

100	client notification of shared file [CLIENT]

	"<filename>" <md5> <size> <bitrate> <frequency> <time>

	<md5> see section "MD5"
	<size> is bytes
	<bitrate> is kbps
	<frequency> is hz
	<time> is seconds
	
	Example:

	"generic band - generic song.mp3" b92870e0d41bc8e698cf2f0a1ddfeac7 443332 128 44100 60

102	remove file [CLIENT]

	<filename>

	client requests to remove file from shared library

200	client search request [CLIENT]

    [FILENAME CONTAINS "artist name"] MAX_RESULTS <max> [FILENAME CONTAINS
"song"] [LINESPEED <compare> <link-type>] [BITRATE <compare> "<br>"] [FREQ
<compare> "<freq>"]

        The artist name and the song name are, obviously, treated
                the same by the server; confirm this for yourself
                on the windows client.

        max is a number; if it is greater than 100, the server will
                only return 100 results.

        <compare> is one of the following:
                "AT LEAST" "AT BEST" "EQUAL TO"

        <link-type> see 0x02 (client login) for a description

        <br> is a number, in kbps

        <freq> is a sample frequency, in Hz

        The windows client filters by ping time inside the client.
                It pretty much has to, and it's easy to see the
                result by setting ping time to at best 100 ms or
                so, and max search terms to 50.  You'll get back
                like 3 results, but the client will still tell you
                that it found "50 results".

        Examples:
                FILENAME CONTAINS "Sneaker Pimps" MAX_RESULTS 75 FILENAME
                         CONTAINS "tesko suicide" BITRATE "AT LEAST" "128"

                MAX_RESULTS 100 FILENAME CONTAINS "Ventolin" LINESPEED
                        "EQUAL TO" 10

	[Thanks to Ben Byer <bbyer@rice.edu> for this contribution.  -ed]

201	search response [SERVER]

	"<filename>" <md5> <size> <bitrate> <frequency> <length> <nick> <ip> <link-type>

	<md5> see secton "MD5"
	<size> is file size in bytes
	<bitrate> is mp3 bit rate in kbps
	<frequency> is sample rate in hz
	<length> is the play length of the mp3 in seconds
	<nick> the person sharing the file
	<ip> is an unsigned long integer representing the ip address of the
		user with this file
	<link-type> see message client login (2) message for a description

	Example:

	"random band - random song.mp3" 7d733c1e7419674744768db71bff8bcd 2558199 128 44100 159 lefty 3437166285 4

202	end of search response from server [SERVER]

	no data.

203	download request [CLIENT]

	<nick> "<filename>"

	client requests to download <filename> from <nick>.  client expects
	to make an outgoing connection to <nick> on their specified data
	port.

	Example:

	mred "C:\Program Files\Napster\generic cowboy song.mp3"

	SEE ALSO: 500 alternate download request

204	download ack [SERVER]

	<nick> <ip> <port> "<filename>" <md5> <linespeed>

	server sends this message in response to a 203 request.

	<nick> is the user who has the file
	<ip> is an unsigned long integer representing the ip address
	<port> is the port <nick> is listening on
	<filename> is the file to retrieve
	<md5> is the md5 sum
	<linespeed> is the user's connection speed (see login(2))

	Example:

	lefty 4877911892 6699 "generic band - generic song.mp3" 10fe9e623b1962da85eea61df7ac1f69 3

205	private message to/from another user [CLIENT, SERVER]

	<nick> <message>

	note the same type is used for a client sending a msg or recieving one

	[Commentary: this message causes problems if you consider linking
	servers together.  With the current one server situation, the server
	just rewrites the message it receives with the name of the client that
	sent it and passes it to the recipient client.  However, in the case
	where the recipient and sender are not on the same server, there is
	loss of information without encapsulating it.  It would have been
	better to put both the sender and recipient because if the servers
	are ever linked they will have to make a new message type for this
	situation.  -ed]

206	get error [SERVER]

	<nick> <filename>

	the server sends this message when the file that the user has
	requested to download is unavailable (such as the user is not logged
	in).

207	add hotlist entry [CLIENT]

	<user>

	client is requesting notification when <user> logs in or out.

209	user signon [SERVER]

	<user> <speed>

	server is notifying client that a user in their hotlist, <user>,
	has signed on the server with link <speed>

210	user signoff [SERVER]

	<user>

	server is notifying client that a user on their hotlist, <user>, has
	signed off the server.

	this message is also sent by the server when the client attempts to
	browse a nonexistent client.  [why don't they just use 404 for
	this? -ed]

211	browse a user's files [CLIENT]

	<nick>

	the client sends this message when it wants to get a list of the files
	shared by a specific client

212	browse response [SERVER]

	<nick> "<filename>" <md5> <size> <bitrate> <frequency> <time>

	<nick> is the user contributing the file
	<filename> is the mp3 file contributed
	<md5> is the has of the mp3 file
	<size> is the file size in bytes
	<bitrate> is the mp3 bitrate in kbps
	<frequence> is the sampling frequency in Hz
	<time> is the play time in seconds

	Example:

	foouser "generic band - generic song.mp3" b92870e0d41bc8e698cf2f0a1ddfeac7 443332 128 44100 60

213	end of browse list [SERVER]

	<nick>

	indicates no more entries in the browse list for <user>

214	server stats [CLIENT, SERVER]

	client: no data
	server: <users> <# files> <size>

	<size> is approximate total library size in gigabytes
	this message is sent by the server occasionaly without request

	Example:

	553 64692 254

215	request resume [CLIENT]

	<checksum> <filesize>

	client is requesting a list of all users which have the file with
	the characteristics.  the server responds with a list of 216 messages
	for each match, followed by a 217 message to terminate the list

216	resume search response [SERVER]

	<user> <ip> <port> <filename> <checksum> <size> <speed>

	this message contains the matches for the resume request (215).  the
	list is terminated by a 217 message.

217	end of resume search list [SERVER]

	no data.

	this messag terminates a list of 216 messages initiated by a 215
	client request

218	downloading file [CLIENT]

	no body.

	client sends this message to the server to indicate they are in the
	process of downloading a file.  this adds 1 to the download count
	which the server maintains.

219	download complete [CLIENT]

	no body.

	client sends this message to the server to indicate they have
	completed the file for which a prior 218 message was sent.  this
	subtracts one from the download count the server maintains

220	uploading file [CLIENT]

	no body.

	client sends this message to indicate they are uploading a file.
	this adds one to the upload count maintained by the server.

221	upload complete [CLIENT]

	no body.

	client sends this message when they are finished uploading a file.
	this subtracts one from the upload count maintained by the server.

300	??? [CLIENT]

	<port>

	[anyone know what this command is for? -ed]

301	hotlist ack [SERVER]

	<user>

	server is notifying client that <user> has successfully be added to
	their hotlist

302	hotlist error [SERVER]

	<user>

	server is notifying client that it was unable to add <user> to their
	hotlist.  [can you only add registered nicks to your hotlist? -ed]

303	remove user from hotlist [CLIENT]

	<user>

	client is notifying the server that it no longer wishes to request
	notifications about <user> when they sign on or off the server.  no
	response is sent in return.

400	join channel [CLIENT]

	<channel-name>

	the client sends this command to join a channel

401	part channel [CLIENT]

	<channel-name>

	the client sends this command to part a channel

402	send public message [CLIENT]

	<channel> <message>

403	public message [SERVER]

	<channel> <nick> <text>

	this message is sent by the server when a client sends a public message
	to a channel.

	Example:

	80's espinozaf hello...hola

404	user/channel does not exist [SERVER]

	<error-message>

	This message is sent to the client when the client has requested an
	operation on another client or channel which is invalid.

	Examples:

	User nosuchuser is not currently online.
	Channel #nosuchchannel does not exist!
	permission denied
	ping failed, shtien is not online

405	join acknowledge [SERVER]

	<channel>

	the server sends this message to the client to acknowlege that it
	has joined the requested channel (400)
	
406	join message [SERVER]

	<channel> <user> <sharing> <link-type>

	<user> has joined <channel>

	Example:

	80's WilmaFlinstone 12 2

407	user parted channel [SERVER]

	<channel> <nick> <sharing> <linespeed>

	Example:

	80's DLongley 23 7

408	channel user list entry [SERVER]

	this message is identical to the join (406) message.  the server will
	send the list of users in the channel prior to the client join command
	in this message.  joins that occur after the client has joined will
	be noted by a 406 message.

409	end of channel user list [SERVER]

	<channel>

	this message is sent by the server to indicate it has sent all informati	about the users in a channel

410	channel topic [CLIENT, SERVER]

	<channel> <topic>

	sent when joining a channel or a new topic is set.  a client requesting
	topic change also uses this message.

	[why didn't they put a field to indicate WHO changed the topic?  as
	it is now you can only tell that it was changed.  -ed]

500	alternate download request [CLIENT]

	<nick> "<filename>"

	requests that <nick> make an outgoing connection to the requesters
	client and send <filename>.  this message is for use when the
	person sharing the file can only make an outgoing tcp connection
	because of firewalls blocking incoming messages.  this message should
	be used to request files from users who have specified their data
	port as 0 in their login message

501	alternate download ack [SERVER]

	<nick> <ip> <port> "<filename>" <md5> <speed>

	this message is sent to the uploader when their data port is set to
	0 to indicate they are behind a firewall and need to push all data
	outware.  the uploader is responsible for connecting to the
	downloader to transfer the file.

600	request user's link speed [CLIENT]

	<nick>

601	link speed response [SERVER]

	<nick> <linespeed>

603	whois request [CLIENT]

	<nick>

604	whois response [SERVER]

	<nick> "<user-level>" <time> "<channels>" <status> <shared>
	<downloads> <uploads> <link-type> "<client-info>" [ <total uploads>
	<total_downloads> <ip> <connecting port> <data port> <email> ]

	<user-level> is one of "User" or "Admin"
	<time> is seconds this user has been connected
	<channels> is the list of channels the client is a member of, each
		separated by a space (ASCII 32)
	<status> is one of "Active." or "Inactive." if they are on or offline
	<shared> is number of files user has available for download
	<downloads> is the current number of downloads in progress
	<uploads> is the current number of uploads in progress
	<link-type> see 0x02 (client login) above
	<client-info> see 0x02 (client login) above

	The following fields are displayed for user level moderator and
	above:

	<total uploads>
	<total downloads>
	<ip>			note: can be "unavailable"
	<connecting port>
	<data port>
	<email>			note: can be unavailable

	Example:

	lefty "User" 1203 "80's " "Active" 0 0 0 3 "nap v0.8"

605	whowas response [SERVER]

	<user> <level> <last-seen>

	if the user listed in a 603 request is not currently online, the
	server sends this message.

	<user> is the user for which information was requested
	<level> is the user's last known userlevel (user/mod/admin)
	<last-seen> is the last time at which this user was seen, measured
		as seconds since 12:00am on January 1, 1970 (UNIX time_t).

606	change user level [CLIENT]

	<nick> <level>

	changes the privileges for <nick> to <level>.  client must be admin
	level to execute this request

	[I have not verified this message since I don't have admin status
	on any of the servers.  -ed]

607	upload request [CLIENT]

	<nick> "<filename>"

	this message is used to notify the client that user <nick> has
	requested upload of <filename>

	Example:

	lefty "generic band - generic song.mp3"

608	accept upload request [CLIENT]

	<nick> "<filename>"

	client is notifying server that upload of <filename> to <nick> is
	accepted, and that the requesting client may begin download

	Example:

	lefty "generic band - generic song.mp3"

610	kill (disconnect) a user [CLIENT]

	<nick>

	client request to disconnect a user.  client must be "Admin" level to
	execute this command

611	nuke a user [CLIENT]

	<nick>

	client request to delete account for <nick>

612	ban user [CLIENT]

613	set data port for user [CLIENT]

614	unban user [CLIENT]

615	show bans for server [CLIENT]

	client requests the list of banned ips for the current server

616	ip ban notification [SERVER]

	<ip> <nick> "<reason>" <time>

	<ip> is the string version of the ip banned
	<nick> is the user setting the ban
	<reason> is the reason given
	<time> is the time_t when the ban was set

	This message is sent in response to the 615 client request, one
	for each ban.

	Example:
	
	207.172.245. valkyrie "" 947304224

617	list channels [CLIENT, SERVER]

	no data.

	client requests a list of channels on the server.  server responds
	with 618/617

	server indicates end of channel list using this message.

618	channel list entry [SERVER]

	<channel-name> <number-of-users> <topic>

	this is the server response to a 617 client request, one for each
	channel.

	Example:

	Help 50 OpenNap help channel

619	queue limit [CLIENT]

	<nick> "<filename>" <n>

	a client may limit the number of downloads from a particular client.
	once the limit for a particular user has been reached, the uploading
	client can send this message to notify the downloader that they
	have hit the limit and can't have any more simultaneous downloads.
	<nick> is the user who hit the limit, <filename> is the file they
	were trying to download when they hit the limit, and <n> is the
	number of simultaneous downloads allowed.

	Example:

	joebob "C:\MP3\Generic Band - Generic Song.mp3" 3

620	queue limit [SERVER]

	<nick> "<filename>" <filesize> <digit>

	This message is sent by the server in response to the 619 client
	request, when one user needs to notify another that they have
	reached the maximum allowed simultaneous downloads.  When the server
	recieves the 619 request from the uploading client, it sends the 620
	message to the downloading client.  The only difference in format is
	the addition of the <nick> field in the 620 message which specifies
	the username of the uploading agent which is notifying the
	downloader that the queue is full.

	Example:

	joebob "C:\MP3\Generic Band - Generic Song.mp3" 1234567 3

621	message of the day [CLIENT, SERVER]

	<text>

	Server: each 621 message contains a single line of text

	Client: client sends a 621 command with no data to request the
	motd be sent.  The server will usually send this automatically after
	a user logs in, so this command allows a user to reread it upon
	request.

622	muzzle a user [CLIENT]

	<nick> [ <reason> ]

	client requests that <nick> not be allowed to send public messages

623	unmuzzle a user [CLIENT]

	<nick>

	client requests that the enforced silence on <nick> be lifted

624	un-nuke a user [CLIENT]

625	change a user's linespeed [CLIENT]

626	data port error [CLIENT]

	<user>

	client is informing server that it was unable to connect to the data
	port for <user>

627	operator message [CLIENT, SERVER]

	client: <text>
	server: <nick> <text>

	client request to send a message to all admins/moderators

628	global message [CLIENT, SERVER]

	client: <text>
	server: <nick> <text>

	client request send a message to all users

629	banned users [SERVER]

	<nick>

	when displaying the ban list for the server, this message is used
	to indicate banned nicknames.

700	change link speed [CLIENT]

	<speed>

	client is notifying server that its correct link speed is <speed>,
	in the range 0-10 (see the login message for details).

701	change user password [CLIENT]

	<password>

	client wishes to change their password

702	change email address [CLIENT]

	<email address>

	client wishes to change their email address

703	change data port [CLIENT]

	<port>

	client is changing the data port being listened on for file
	transfers

751	ping user [CLIENT, SERVER]

	<user>

	client is attempting to determine if <user>'s connection is alive

752	pong response [CLIENT, SERVER]

	<user>

	this message is sent in response to the the 751 (PING) requeset

753	???

	[returns permission denied.  -ed]

800	reload config [CLIENT]

	<config variable>

	resets configuration parameter to its default value

801	server version [CLIENT]

	no data.

	client request's a server's version

810	set config [CLIENT]

	<config string>

	request a change in server configuration variables

820	clear channel

	<channel>

	[what does this do? -ed]

821	???
822	???
823	???

824	emote [CLIENT]

	<text>

825	user list entry [SERVER]

	<channel> <user> <files shared> <speed>

	an 825 message is sent for each user in the channel specified by the
	830 message

	Example:

	Help testor3 0 3

	[This appears to be exactly the same format as the 408 message.  -ed]

826	???
827	???

830	list users in channel [CLIENT, SERVER]

	<channel>

	client requests a list of all users in <channel>.  server responds
	with a 825 response for each user, followed by an 830 response with
	no data [why didn't they just use the 409 message? -ed]

3.  MD5

It looks like the vast majority of the files are hashed using the first
299,008 bytes of the file.  There have been some cases where the hash
matches at 300,032 bytes, but no correlation has been drawn as to when that
happens.  The speculation at this point is that it might have to do with
the existence of a ID3v2 tag, or perhaps the file was sampled at 48kHz...?

The current method seems to be: skip id3v2, seek to frame sync and hash.

Note: the linux nap client (versions 0.7 - 0.9) seem to hash exactly 300,000
bytes, which is NOT what the official windows client does.

4.  Client-Client Protocol

File transfer occur directly between clients without passing through the
server.  There are four transfer modes, upload, download, firewalled upload,
firewalled download.  The normal method of transfer is that the client
wishing to download a file makes a TCP connection to the client holding the
file on their data port.  However, in the case where the client sharing the
file is behind a firewall, it is necessary for them to "push" the data by
making a TCP connection to the downloader's data port.

4.1  Normal Downloading

Regardless of which mode, the downloading client will first issue either a 
search(200) or browse(211) command to the server.  This returns a list of
files and information on the client sharin the file.  To request a download,
a get(203) request is sent to the server.  The server will respond with
a get ack(204) containing more detailed information.

This is the point at which the different methods diverge.  If the 204 get
ack says that the remote clients data port is 0, you must send a 500 request
to the server requesting that the remote client send the data to you.  In
this case you wait for the remote client to connect to your own data port.

In the case where the sharing client is not firewalled, you make a TCP
connection to the data port specified in the 204 message from the server.
The remote client should accept the connection and immediately send one
ASCII char, `1' (ASCII 49).  Once you read this char, you send a request
for the file you wish to download.  First send the string "GET" in a single
packet, then send
	<mynick> "<filename>" <offset>
where <mynick> is your napster user name, <filename> is the file you wish to
download, and <offset> if the byte offst in the file to begin the transfer
at (if you are downloading for the first time, and not resuming a prior
transfer, you should uses 0 to start at the beginning of the file).

The remote client will then return the file size, or an error message such
as "INVALID REQUEST" or "FILE NOT SHARED".  Note that the file size is not
terminated in any special way, and the best way to figure out the size is to
keep reading until you hit a character that is not a digit (it will usually
be 0xff which is the start of the MP3 frame sync header, but if a ID3v2
tag is present it might look different).  Immediately following the file
size is where the data stream for the file begins.

Once the data transfer is initiated, the downloader should notify the server
that they are downloading a file by sending the 218 message.  Once the
transfer is complete, you send a 219 message to indicate you have finished
the download.  Note that this is cummalitive, so that if you are downloading
multiple files, you send one 218/219 pair for EACH concurrent download--this
is how the server knows how many transfers you have going on.  Likewise,
the uploader should send one 220 messge for each upload, and one 221 when
each upload has finished.

4.2  Firwalled Downloading

As described above, when the file needs to be pushed from a client behind a
firewall, the downloader sends a 500 message to the server.  This causes a
501 message to be sent to the uploader, which is similar to the 204 message
for a normal download.

Once the uploader receives the 501 message from the server, they should make
a TCP connection to the downloader's data port (given in the 501 message).
Upon connection, the downloader's client will sent one byte, the ASCII
character `1'.  The uploader should then send the string "SEND" in a single
packet, and then the information:
	<mynick> "<filename>" <size>
where <mynick> is the uploader's napster user name, <filename> is the file
being sent, and <size> is the size of the file in bytes.

Upon receipt, the downloading client will either send the byte offset at
whcih the transfer should start, or an error message such as
"INVALID REQUEST".  The byte offset should be sent as a single packet
in plain ASCII digits.  Just as with above in section 4.1, a 0 byte offset
indicates the transfer should begin at the start of the file.

Each client should notify the server that they are uploading or downloading
with the 218/219 (downloading) or 220/221 (uploading) command pairs (see
section 4.1 for more detailed information).

5.  Where to get more help?

Join the napdev mailing list by sending email to napdev-subscribe@onelist.com
or by visiting the community page http://www.onelist.com/community/napdev/.
This list is designed for open source napster developers to share information
about the specification or applications.

6.  Acknowledgements

A big THANKS goes to the following people who contributed valuable information
to this specification:

Ben Byer <bbyer@rice.edu>
JT <jtraub@dragoncat.net>
Evan Martin <eeyem@u.washington.edu>
Colten Edwards (aka panasync@efnet) <edwards@bitchx.dimension6.com>
