xref: /plan9-contrib/sys/src/cmd/ssh2/netssh.h (revision c703450534a39fda5e37abe206338c3e0e4fc8cd)
163afb9a5SDavid du Colombier #include <bio.h>
263afb9a5SDavid du Colombier #include "ssh2.h"		/* ugh */
363afb9a5SDavid du Colombier 
463afb9a5SDavid du Colombier #define MYID "SSH-2.0-Plan9"
563afb9a5SDavid du Colombier 
663afb9a5SDavid du Colombier #pragma varargck type "M" mpint*
763afb9a5SDavid du Colombier 
863afb9a5SDavid du Colombier enum {
963afb9a5SDavid du Colombier 	Server =	0,
1063afb9a5SDavid du Colombier 	Client,
1163afb9a5SDavid du Colombier 
1263afb9a5SDavid du Colombier 	Maxpktpay =	35000,
1363afb9a5SDavid du Colombier 
1463afb9a5SDavid du Colombier 	/* qid.path components: level (2), type (4), conn (7), chan (7) */
1563afb9a5SDavid du Colombier 	Connshift =	7,
1663afb9a5SDavid du Colombier 	MAXCONN =	1 << Connshift,		/* also Maxchan */
1763afb9a5SDavid du Colombier 	Chanmask =	MAXCONN - 1,
1863afb9a5SDavid du Colombier 	Connmask =	Chanmask,
1963afb9a5SDavid du Colombier 
2063afb9a5SDavid du Colombier 	Qtypeshift =	2 * Connshift,		/* conn + chan */
2163afb9a5SDavid du Colombier 
2263afb9a5SDavid du Colombier 	Qroot =		0,
2363afb9a5SDavid du Colombier 	Qclone =	1 << Qtypeshift,
2463afb9a5SDavid du Colombier 	Qctl =		2 << Qtypeshift,
2563afb9a5SDavid du Colombier 	Qdata =		3 << Qtypeshift,
2663afb9a5SDavid du Colombier 	Qlisten =	4 << Qtypeshift,
2763afb9a5SDavid du Colombier 	Qlocal =	5 << Qtypeshift,
2863afb9a5SDavid du Colombier 	Qreqrem =	6 << Qtypeshift,	/* request or remote */
2963afb9a5SDavid du Colombier 	Qstatus =	7 << Qtypeshift,
3063afb9a5SDavid du Colombier 	Qtcp =		8 << Qtypeshift,
3163afb9a5SDavid du Colombier 	Qtypemask =	017 << Qtypeshift,
3263afb9a5SDavid du Colombier 
3363afb9a5SDavid du Colombier 	Levshift =	Qtypeshift + 4,
3463afb9a5SDavid du Colombier 
3563afb9a5SDavid du Colombier 	/* levels of /net/ssh hierarchy */
3663afb9a5SDavid du Colombier 	Top =		0,
3763afb9a5SDavid du Colombier 	Connection,
3863afb9a5SDavid du Colombier 	Subchannel,
3963afb9a5SDavid du Colombier };
4063afb9a5SDavid du Colombier 
4163afb9a5SDavid du Colombier /*
4263afb9a5SDavid du Colombier  * The stylistic anomaly with these names of unbounded length
4363afb9a5SDavid du Colombier  * is a result of following the RFCs in using the same names for
4463afb9a5SDavid du Colombier  * these constants.  I did that to make it easier to search and
4563afb9a5SDavid du Colombier  * cross-reference between the code and the RFCs.
4663afb9a5SDavid du Colombier  */
4763afb9a5SDavid du Colombier enum {					/* SSH2 Protocol Packet Types */
4863afb9a5SDavid du Colombier 	SSH_MSG_DISCONNECT =		1,
4963afb9a5SDavid du Colombier 	SSH_MSG_IGNORE =		2,
5063afb9a5SDavid du Colombier 	SSH_MSG_UNIMPLEMENTED,
5163afb9a5SDavid du Colombier 	SSH_MSG_DEBUG,
5263afb9a5SDavid du Colombier 	SSH_MSG_SERVICE_REQUEST,
5363afb9a5SDavid du Colombier 	SSH_MSG_SERVICE_ACCEPT,
5463afb9a5SDavid du Colombier 
5563afb9a5SDavid du Colombier 	SSH_MSG_KEXINIT =		20,
5663afb9a5SDavid du Colombier 	SSH_MSG_NEWKEYS,
5763afb9a5SDavid du Colombier 
5863afb9a5SDavid du Colombier 	SSH_MSG_KEXDH_INIT =		30,
5963afb9a5SDavid du Colombier 	SSH_MSG_KEXDH_REPLY,
6063afb9a5SDavid du Colombier 
6163afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_REQUEST =	50,
6263afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_FAILURE,
6363afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_SUCCESS,
6463afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_BANNER,
6563afb9a5SDavid du Colombier 
6663afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_PK_OK =	60,
6763afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_PASSWD_CHANGEREQ = 60,
6863afb9a5SDavid du Colombier 
6963afb9a5SDavid du Colombier 	SSH_MSG_GLOBAL_REQUEST =	80,
7063afb9a5SDavid du Colombier 	SSH_MSG_REQUEST_SUCCESS,
7163afb9a5SDavid du Colombier 	SSH_MSG_REQUEST_FAILURE,
7263afb9a5SDavid du Colombier 
7363afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OPEN =		90,
7463afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
7563afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OPEN_FAILURE,
7663afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_WINDOW_ADJUST,
7763afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_DATA,
7863afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_EXTENDED_DATA,
7963afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_EOF,
8063afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_CLOSE,
8163afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_REQUEST,
8263afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_SUCCESS,
8363afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_FAILURE,
8463afb9a5SDavid du Colombier };
8563afb9a5SDavid du Colombier 
8663afb9a5SDavid du Colombier enum {				/* SSH2 reason codes */
8763afb9a5SDavid du Colombier 	SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
8863afb9a5SDavid du Colombier 	SSH_DISCONNECT_PROTOCOL_ERROR,
8963afb9a5SDavid du Colombier 	SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
9063afb9a5SDavid du Colombier 	SSH_DISCONNECT_RESERVED,
9163afb9a5SDavid du Colombier 	SSH_DISCONNECT_MAC_ERROR,
9263afb9a5SDavid du Colombier 	SSH_DISCONNECT_COMPRESSION_ERROR,
9363afb9a5SDavid du Colombier 	SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
9463afb9a5SDavid du Colombier 	SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
9563afb9a5SDavid du Colombier 	SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE,
9663afb9a5SDavid du Colombier 	SSH_DISCONNECT_CONNECTION_LOST,
9763afb9a5SDavid du Colombier 	SSH_DISCONNECT_BY_APPLICATION,
9863afb9a5SDavid du Colombier 	SSH_DISCONNECT_TOO_MANY_CONNECTIONS,
9963afb9a5SDavid du Colombier 	SSH_DISCONNECT_AUTH_CANCELLED_BY_USER,
10063afb9a5SDavid du Colombier 	SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
10163afb9a5SDavid du Colombier 	SSH_DISCONNECT_ILLEGAL_USR_NAME,
10263afb9a5SDavid du Colombier 
10363afb9a5SDavid du Colombier 	SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1,
10463afb9a5SDavid du Colombier 	SSH_OPEN_CONNECT_FAILED,
10563afb9a5SDavid du Colombier 	SSH_OPEN_UNKNOWN_CHANNEL_TYPE,
10663afb9a5SDavid du Colombier 	SSH_OPEN_RESOURCE_SHORTAGE,
10763afb9a5SDavid du Colombier };
10863afb9a5SDavid du Colombier 
10963afb9a5SDavid du Colombier enum {				/* SSH2 type code */
11063afb9a5SDavid du Colombier 	SSH_EXTENDED_DATA_STDERR = 1,
11163afb9a5SDavid du Colombier };
11263afb9a5SDavid du Colombier 
11363afb9a5SDavid du Colombier enum {				/* connection and channel states */
11463afb9a5SDavid du Colombier 	Empty = 0,
11563afb9a5SDavid du Colombier 	Allocated,
11663afb9a5SDavid du Colombier 	Initting,
11763afb9a5SDavid du Colombier 	Listening,
11863afb9a5SDavid du Colombier 	Opening,
11963afb9a5SDavid du Colombier 	Negotiating,
12063afb9a5SDavid du Colombier 	Authing,
12163afb9a5SDavid du Colombier 	Established,
12263afb9a5SDavid du Colombier 	Eof,
12363afb9a5SDavid du Colombier 	Closing,
12463afb9a5SDavid du Colombier 	Closed,
12563afb9a5SDavid du Colombier };
12663afb9a5SDavid du Colombier 
12763afb9a5SDavid du Colombier enum {
12863afb9a5SDavid du Colombier 	NoKeyFile,
12963afb9a5SDavid du Colombier 	NoKey,
13063afb9a5SDavid du Colombier 	KeyWrong,
13163afb9a5SDavid du Colombier 	KeyOk,
13263afb9a5SDavid du Colombier };
13363afb9a5SDavid du Colombier 
13463afb9a5SDavid du Colombier typedef struct Cipher Cipher;
13563afb9a5SDavid du Colombier typedef struct CipherState CipherState;
13663afb9a5SDavid du Colombier typedef struct Conn Conn;
13763afb9a5SDavid du Colombier typedef struct Kex Kex;
13863afb9a5SDavid du Colombier typedef struct MBox MBox;
13963afb9a5SDavid du Colombier typedef struct PKA PKA;
14063afb9a5SDavid du Colombier typedef struct Packet Packet;
14163afb9a5SDavid du Colombier typedef struct Plist Plist;
14263afb9a5SDavid du Colombier typedef struct SSHChan SSHChan;
14363afb9a5SDavid du Colombier 
14463afb9a5SDavid du Colombier #pragma incomplete CipherState
14563afb9a5SDavid du Colombier 
14663afb9a5SDavid du Colombier struct Plist {
14763afb9a5SDavid du Colombier 	Packet	*pack;
14863afb9a5SDavid du Colombier 	uchar	*st;
14963afb9a5SDavid du Colombier 	int	rem;
15063afb9a5SDavid du Colombier 	Plist	*next;
15163afb9a5SDavid du Colombier };
15263afb9a5SDavid du Colombier 
15363afb9a5SDavid du Colombier struct SSHChan {
15463afb9a5SDavid du Colombier 	Rendez	r;			/* awaiting input? */
15563afb9a5SDavid du Colombier 	int	id;
15663afb9a5SDavid du Colombier 	int	otherid;
15763afb9a5SDavid du Colombier 	int	state;
15863afb9a5SDavid du Colombier 	int	waker;
15963afb9a5SDavid du Colombier 	int	conn;
16063afb9a5SDavid du Colombier 	ulong	rwindow;
16163afb9a5SDavid du Colombier 	ulong	twindow;
16263afb9a5SDavid du Colombier 	ulong	sent;
16363afb9a5SDavid du Colombier 	ulong	inrqueue;
16463afb9a5SDavid du Colombier 	char	*ann;
16563afb9a5SDavid du Colombier 	Req	*lreq;
16663afb9a5SDavid du Colombier 
16763afb9a5SDavid du Colombier 	/* File* for each Qid type */
16863afb9a5SDavid du Colombier 	File	*dir;
16963afb9a5SDavid du Colombier 	File	*ctl;
17063afb9a5SDavid du Colombier 	File	*data;
17163afb9a5SDavid du Colombier 	File	*listen;
17263afb9a5SDavid du Colombier 	File	*request;
17363afb9a5SDavid du Colombier 	File	*status;
17463afb9a5SDavid du Colombier 	File	*tcp;
17563afb9a5SDavid du Colombier 
17663afb9a5SDavid du Colombier 	Plist	*dataq;
17763afb9a5SDavid du Colombier 	Plist	*datatl;
17863afb9a5SDavid du Colombier 	Plist	*reqq;
17963afb9a5SDavid du Colombier 	Plist	*reqtl;
18063afb9a5SDavid du Colombier 
18163afb9a5SDavid du Colombier 	Channel	*inchan;
18263afb9a5SDavid du Colombier 	Channel	*reqchan;
18363afb9a5SDavid du Colombier 	QLock	xmtlock;
18463afb9a5SDavid du Colombier 	Rendez	xmtrendez;
18563afb9a5SDavid du Colombier };
18663afb9a5SDavid du Colombier 
18763afb9a5SDavid du Colombier struct Conn {
18863afb9a5SDavid du Colombier 	QLock	l;
18963afb9a5SDavid du Colombier 	Rendez	r;			/* awaiting input? */
19063afb9a5SDavid du Colombier 
19163afb9a5SDavid du Colombier 	Ioproc	*dio;
19263afb9a5SDavid du Colombier 	Ioproc	*cio;
19363afb9a5SDavid du Colombier 	Ioproc	*rio;
19463afb9a5SDavid du Colombier 
19563afb9a5SDavid du Colombier 	int	state;
19663afb9a5SDavid du Colombier 	int	role;
19763afb9a5SDavid du Colombier 	int	id;
19863afb9a5SDavid du Colombier 
19963afb9a5SDavid du Colombier 	char	*remote;
20063afb9a5SDavid du Colombier 	char	*user;
20163afb9a5SDavid du Colombier 	char	*password;
20263afb9a5SDavid du Colombier 
20363afb9a5SDavid du Colombier 	char	*service;
20463afb9a5SDavid du Colombier 	char	*cap;
20563afb9a5SDavid du Colombier 	char	*authkey;
20663afb9a5SDavid du Colombier 	int	nchan;
20763afb9a5SDavid du Colombier 
20863afb9a5SDavid du Colombier 	/* underlying tcp connection */
20963afb9a5SDavid du Colombier 	int	datafd;
21063afb9a5SDavid du Colombier 	int	ctlfd;
21163afb9a5SDavid du Colombier 	int	stifle;		/* flag: no i/o between listen and sshsession */
21263afb9a5SDavid du Colombier 	int	poisoned;
21363afb9a5SDavid du Colombier 	int	tcpconn;
21463afb9a5SDavid du Colombier 
21563afb9a5SDavid du Colombier 	int	rpid;
21663afb9a5SDavid du Colombier 
21763afb9a5SDavid du Colombier 	int	inseq;
21863afb9a5SDavid du Colombier 	int	outseq;
21963afb9a5SDavid du Colombier 	int	kexalg;
22063afb9a5SDavid du Colombier 	int	pkalg;
22163afb9a5SDavid du Colombier 
22263afb9a5SDavid du Colombier 	int	cscrypt;
22363afb9a5SDavid du Colombier 	int	ncscrypt;
22463afb9a5SDavid du Colombier 	int	sccrypt;
22563afb9a5SDavid du Colombier 	int	nsccrypt;
22663afb9a5SDavid du Colombier 
22763afb9a5SDavid du Colombier 	int	csmac;
22863afb9a5SDavid du Colombier 	int	ncsmac;
22963afb9a5SDavid du Colombier 	int	scmac;
23063afb9a5SDavid du Colombier 	int	nscmac;
23163afb9a5SDavid du Colombier 
23263afb9a5SDavid du Colombier 	int	encrypt;
23363afb9a5SDavid du Colombier 	int	decrypt;
23463afb9a5SDavid du Colombier 
23563afb9a5SDavid du Colombier 	int	outmac;
23663afb9a5SDavid du Colombier 	int	inmac;
23763afb9a5SDavid du Colombier 
23863afb9a5SDavid du Colombier 	/* File* for each Qid type */
23963afb9a5SDavid du Colombier 	File	*dir;
24063afb9a5SDavid du Colombier 	File	*clonefile;
24163afb9a5SDavid du Colombier 	File	*ctlfile;
24263afb9a5SDavid du Colombier 	File	*datafile;
24363afb9a5SDavid du Colombier 	File	*listenfile;
24463afb9a5SDavid du Colombier 	File	*localfile;
24563afb9a5SDavid du Colombier 	File	*remotefile;
24663afb9a5SDavid du Colombier 	File	*statusfile;
24763afb9a5SDavid du Colombier 	File	*tcpfile;
24863afb9a5SDavid du Colombier 
24963afb9a5SDavid du Colombier 	Packet	*skexinit;
25063afb9a5SDavid du Colombier 	Packet	*rkexinit;
25163afb9a5SDavid du Colombier 	mpint	*x;
25263afb9a5SDavid du Colombier 	mpint	*e;
25363afb9a5SDavid du Colombier 	int	got_sessid;
25463afb9a5SDavid du Colombier 	uchar	sessid[SHA1dlen];
25563afb9a5SDavid du Colombier 
25663afb9a5SDavid du Colombier 	uchar	c2siv[SHA1dlen*2];
25763afb9a5SDavid du Colombier 	uchar	nc2siv[SHA1dlen*2];
25863afb9a5SDavid du Colombier 	uchar	s2civ[SHA1dlen*2];
25963afb9a5SDavid du Colombier 	uchar	ns2civ[SHA1dlen*2];
26063afb9a5SDavid du Colombier 
26163afb9a5SDavid du Colombier 	uchar	c2sek[SHA1dlen*2];
26263afb9a5SDavid du Colombier 	uchar	nc2sek[SHA1dlen*2];
26363afb9a5SDavid du Colombier 	uchar	s2cek[SHA1dlen*2];
26463afb9a5SDavid du Colombier 	uchar	ns2cek[SHA1dlen*2];
26563afb9a5SDavid du Colombier 
26663afb9a5SDavid du Colombier 	uchar	c2sik[SHA1dlen*2];
26763afb9a5SDavid du Colombier 	uchar	nc2sik[SHA1dlen*2];
26863afb9a5SDavid du Colombier 	uchar	s2cik[SHA1dlen*2];
26963afb9a5SDavid du Colombier 	uchar	ns2cik[SHA1dlen*2];
27063afb9a5SDavid du Colombier 
27163afb9a5SDavid du Colombier 	char	*otherid;
27263afb9a5SDavid du Colombier 	uchar	*inik;
27363afb9a5SDavid du Colombier 	uchar	*outik;
27463afb9a5SDavid du Colombier 	CipherState *s2ccs;
27563afb9a5SDavid du Colombier 	CipherState *c2scs;
27663afb9a5SDavid du Colombier 	CipherState *enccs;
27763afb9a5SDavid du Colombier 	CipherState *deccs;
27863afb9a5SDavid du Colombier 	SSHChan	*chans[MAXCONN];
27963afb9a5SDavid du Colombier 
28063afb9a5SDavid du Colombier 	char	idstring[256];		/* max allowed by SSH spec */
28163afb9a5SDavid du Colombier };
28263afb9a5SDavid du Colombier 
28363afb9a5SDavid du Colombier struct Packet {
28463afb9a5SDavid du Colombier 	Conn	*c;
28563afb9a5SDavid du Colombier 	ulong	rlength;
28663afb9a5SDavid du Colombier 	ulong	tlength;
28763afb9a5SDavid du Colombier 	uchar	nlength[4];
28863afb9a5SDavid du Colombier 	uchar	pad_len;
28963afb9a5SDavid du Colombier 	uchar	payload[Maxpktpay];
29063afb9a5SDavid du Colombier };
29163afb9a5SDavid du Colombier 
29263afb9a5SDavid du Colombier struct Cipher {
29363afb9a5SDavid du Colombier 	char	*name;
29463afb9a5SDavid du Colombier 	int	blklen;
29563afb9a5SDavid du Colombier 	CipherState *(*init)(Conn*, int);
29663afb9a5SDavid du Colombier 	void	(*encrypt)(CipherState*, uchar*, int);
29763afb9a5SDavid du Colombier 	void	(*decrypt)(CipherState*, uchar*, int);
29863afb9a5SDavid du Colombier };
29963afb9a5SDavid du Colombier 
30063afb9a5SDavid du Colombier struct Kex {
30163afb9a5SDavid du Colombier 	char	*name;
30263afb9a5SDavid du Colombier 	int	(*serverkex)(Conn *, Packet *);
30363afb9a5SDavid du Colombier 	int	(*clientkex1)(Conn *, Packet *);
30463afb9a5SDavid du Colombier 	int	(*clientkex2)(Conn *, Packet *);
30563afb9a5SDavid du Colombier };
30663afb9a5SDavid du Colombier 
30763afb9a5SDavid du Colombier struct PKA {
30863afb9a5SDavid du Colombier 	char	*name;
30963afb9a5SDavid du Colombier 	Packet	*(*ks)(Conn *);
31063afb9a5SDavid du Colombier 	Packet	*(*sign)(Conn *, uchar *, int);
31163afb9a5SDavid du Colombier 	int	(*verify)(Conn *, uchar *, int, char *, char *, int);
31263afb9a5SDavid du Colombier };
31363afb9a5SDavid du Colombier 
31463afb9a5SDavid du Colombier struct MBox {
31563afb9a5SDavid du Colombier 	Channel	*mchan;
31663afb9a5SDavid du Colombier 	char	*msg;
31763afb9a5SDavid du Colombier 	int	state;
31863afb9a5SDavid du Colombier };
31963afb9a5SDavid du Colombier 
32063afb9a5SDavid du Colombier extern Cipher cipheraes128, cipheraes192, cipheraes256;
321*c7034505SDavid du Colombier extern Cipher cipheraes128ctr, cipheraes192ctr, cipheraes256ctr;
32263afb9a5SDavid du Colombier extern Cipher cipherblowfish, cipher3des, cipherrc4;
32363afb9a5SDavid du Colombier extern int debug;
32463afb9a5SDavid du Colombier extern int sshkeychan[];
32563afb9a5SDavid du Colombier extern Kex dh1sha1, dh14sha1;
32663afb9a5SDavid du Colombier extern MBox keymbox;
32763afb9a5SDavid du Colombier extern PKA rsa_pka, dss_pka, *pkas[];
32863afb9a5SDavid du Colombier 
32963afb9a5SDavid du Colombier /* pubkey.c */
33063afb9a5SDavid du Colombier int appendkey(char *, char *, RSApub *);
33163afb9a5SDavid du Colombier int findkey(char *, char *, RSApub *);
33263afb9a5SDavid du Colombier RSApub *readpublickey(Biobuf *, char **);
33363afb9a5SDavid du Colombier int replacekey(char *, char *, RSApub *);
33463afb9a5SDavid du Colombier 
33563afb9a5SDavid du Colombier /* dh.c */
33663afb9a5SDavid du Colombier void dh_init(PKA *[]);
33763afb9a5SDavid du Colombier 
33863afb9a5SDavid du Colombier /* transport.c */
33963afb9a5SDavid du Colombier void	add_block(Packet *, void *, int);
34063afb9a5SDavid du Colombier void	add_byte(Packet *, char);
34163afb9a5SDavid du Colombier void	add_mp(Packet *, mpint *);
34263afb9a5SDavid du Colombier int	add_packet(Packet *, void *, int);
34363afb9a5SDavid du Colombier void	add_string(Packet *, char *);
34463afb9a5SDavid du Colombier void	add_uint32(Packet *, ulong);
34563afb9a5SDavid du Colombier void	dump_packet(Packet *);
34663afb9a5SDavid du Colombier int	finish_packet(Packet *);
34763afb9a5SDavid du Colombier mpint	*get_mp(uchar *q);
34863afb9a5SDavid du Colombier uchar	*get_string(Packet *, uchar *, char *, int, int *);
34963afb9a5SDavid du Colombier ulong	get_uint32(Packet *, uchar **);
35063afb9a5SDavid du Colombier void	init_packet(Packet *);
35163afb9a5SDavid du Colombier Packet	*new_packet(Conn *);
35263afb9a5SDavid du Colombier int	undo_packet(Packet *);
353