xref: /plan9/sys/src/cmd/ssh2/netssh.h (revision 63afb9a5d3f910047231762bcce0ee49fed3d07c)
1*63afb9a5SDavid du Colombier #include <bio.h>
2*63afb9a5SDavid du Colombier #include "ssh2.h"		/* ugh */
3*63afb9a5SDavid du Colombier 
4*63afb9a5SDavid du Colombier #define MYID "SSH-2.0-Plan9"
5*63afb9a5SDavid du Colombier 
6*63afb9a5SDavid du Colombier #pragma varargck type "M" mpint*
7*63afb9a5SDavid du Colombier 
8*63afb9a5SDavid du Colombier enum {
9*63afb9a5SDavid du Colombier 	Server =	0,
10*63afb9a5SDavid du Colombier 	Client,
11*63afb9a5SDavid du Colombier 
12*63afb9a5SDavid du Colombier 	Maxpktpay =	35000,
13*63afb9a5SDavid du Colombier 
14*63afb9a5SDavid du Colombier 	/* qid.path components: level (2), type (4), conn (7), chan (7) */
15*63afb9a5SDavid du Colombier 	Connshift =	7,
16*63afb9a5SDavid du Colombier 	MAXCONN =	1 << Connshift,		/* also Maxchan */
17*63afb9a5SDavid du Colombier 	Chanmask =	MAXCONN - 1,
18*63afb9a5SDavid du Colombier 	Connmask =	Chanmask,
19*63afb9a5SDavid du Colombier 
20*63afb9a5SDavid du Colombier 	Qtypeshift =	2 * Connshift,		/* conn + chan */
21*63afb9a5SDavid du Colombier 
22*63afb9a5SDavid du Colombier 	Qroot =		0,
23*63afb9a5SDavid du Colombier 	Qclone =	1 << Qtypeshift,
24*63afb9a5SDavid du Colombier 	Qctl =		2 << Qtypeshift,
25*63afb9a5SDavid du Colombier 	Qdata =		3 << Qtypeshift,
26*63afb9a5SDavid du Colombier 	Qlisten =	4 << Qtypeshift,
27*63afb9a5SDavid du Colombier 	Qlocal =	5 << Qtypeshift,
28*63afb9a5SDavid du Colombier 	Qreqrem =	6 << Qtypeshift,	/* request or remote */
29*63afb9a5SDavid du Colombier 	Qstatus =	7 << Qtypeshift,
30*63afb9a5SDavid du Colombier 	Qtcp =		8 << Qtypeshift,
31*63afb9a5SDavid du Colombier 	Qtypemask =	017 << Qtypeshift,
32*63afb9a5SDavid du Colombier 
33*63afb9a5SDavid du Colombier 	Levshift =	Qtypeshift + 4,
34*63afb9a5SDavid du Colombier 
35*63afb9a5SDavid du Colombier 	/* levels of /net/ssh hierarchy */
36*63afb9a5SDavid du Colombier 	Top =		0,
37*63afb9a5SDavid du Colombier 	Connection,
38*63afb9a5SDavid du Colombier 	Subchannel,
39*63afb9a5SDavid du Colombier };
40*63afb9a5SDavid du Colombier 
41*63afb9a5SDavid du Colombier /*
42*63afb9a5SDavid du Colombier  * The stylistic anomaly with these names of unbounded length
43*63afb9a5SDavid du Colombier  * is a result of following the RFCs in using the same names for
44*63afb9a5SDavid du Colombier  * these constants.  I did that to make it easier to search and
45*63afb9a5SDavid du Colombier  * cross-reference between the code and the RFCs.
46*63afb9a5SDavid du Colombier  */
47*63afb9a5SDavid du Colombier enum {					/* SSH2 Protocol Packet Types */
48*63afb9a5SDavid du Colombier 	SSH_MSG_DISCONNECT =		1,
49*63afb9a5SDavid du Colombier 	SSH_MSG_IGNORE =		2,
50*63afb9a5SDavid du Colombier 	SSH_MSG_UNIMPLEMENTED,
51*63afb9a5SDavid du Colombier 	SSH_MSG_DEBUG,
52*63afb9a5SDavid du Colombier 	SSH_MSG_SERVICE_REQUEST,
53*63afb9a5SDavid du Colombier 	SSH_MSG_SERVICE_ACCEPT,
54*63afb9a5SDavid du Colombier 
55*63afb9a5SDavid du Colombier 	SSH_MSG_KEXINIT =		20,
56*63afb9a5SDavid du Colombier 	SSH_MSG_NEWKEYS,
57*63afb9a5SDavid du Colombier 
58*63afb9a5SDavid du Colombier 	SSH_MSG_KEXDH_INIT =		30,
59*63afb9a5SDavid du Colombier 	SSH_MSG_KEXDH_REPLY,
60*63afb9a5SDavid du Colombier 
61*63afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_REQUEST =	50,
62*63afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_FAILURE,
63*63afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_SUCCESS,
64*63afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_BANNER,
65*63afb9a5SDavid du Colombier 
66*63afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_PK_OK =	60,
67*63afb9a5SDavid du Colombier 	SSH_MSG_USERAUTH_PASSWD_CHANGEREQ = 60,
68*63afb9a5SDavid du Colombier 
69*63afb9a5SDavid du Colombier 	SSH_MSG_GLOBAL_REQUEST =	80,
70*63afb9a5SDavid du Colombier 	SSH_MSG_REQUEST_SUCCESS,
71*63afb9a5SDavid du Colombier 	SSH_MSG_REQUEST_FAILURE,
72*63afb9a5SDavid du Colombier 
73*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OPEN =		90,
74*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
75*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OPEN_FAILURE,
76*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_WINDOW_ADJUST,
77*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_DATA,
78*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_EXTENDED_DATA,
79*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_EOF,
80*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_CLOSE,
81*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_REQUEST,
82*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_SUCCESS,
83*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_FAILURE,
84*63afb9a5SDavid du Colombier };
85*63afb9a5SDavid du Colombier 
86*63afb9a5SDavid du Colombier enum {				/* SSH2 reason codes */
87*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
88*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_PROTOCOL_ERROR,
89*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
90*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_RESERVED,
91*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_MAC_ERROR,
92*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_COMPRESSION_ERROR,
93*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
94*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
95*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE,
96*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_CONNECTION_LOST,
97*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_BY_APPLICATION,
98*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_TOO_MANY_CONNECTIONS,
99*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_AUTH_CANCELLED_BY_USER,
100*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
101*63afb9a5SDavid du Colombier 	SSH_DISCONNECT_ILLEGAL_USR_NAME,
102*63afb9a5SDavid du Colombier 
103*63afb9a5SDavid du Colombier 	SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1,
104*63afb9a5SDavid du Colombier 	SSH_OPEN_CONNECT_FAILED,
105*63afb9a5SDavid du Colombier 	SSH_OPEN_UNKNOWN_CHANNEL_TYPE,
106*63afb9a5SDavid du Colombier 	SSH_OPEN_RESOURCE_SHORTAGE,
107*63afb9a5SDavid du Colombier };
108*63afb9a5SDavid du Colombier 
109*63afb9a5SDavid du Colombier enum {				/* SSH2 type code */
110*63afb9a5SDavid du Colombier 	SSH_EXTENDED_DATA_STDERR = 1,
111*63afb9a5SDavid du Colombier };
112*63afb9a5SDavid du Colombier 
113*63afb9a5SDavid du Colombier enum {				/* connection and channel states */
114*63afb9a5SDavid du Colombier 	Empty = 0,
115*63afb9a5SDavid du Colombier 	Allocated,
116*63afb9a5SDavid du Colombier 	Initting,
117*63afb9a5SDavid du Colombier 	Listening,
118*63afb9a5SDavid du Colombier 	Opening,
119*63afb9a5SDavid du Colombier 	Negotiating,
120*63afb9a5SDavid du Colombier 	Authing,
121*63afb9a5SDavid du Colombier 	Established,
122*63afb9a5SDavid du Colombier 	Eof,
123*63afb9a5SDavid du Colombier 	Closing,
124*63afb9a5SDavid du Colombier 	Closed,
125*63afb9a5SDavid du Colombier };
126*63afb9a5SDavid du Colombier 
127*63afb9a5SDavid du Colombier enum {
128*63afb9a5SDavid du Colombier 	NoKeyFile,
129*63afb9a5SDavid du Colombier 	NoKey,
130*63afb9a5SDavid du Colombier 	KeyWrong,
131*63afb9a5SDavid du Colombier 	KeyOk,
132*63afb9a5SDavid du Colombier };
133*63afb9a5SDavid du Colombier 
134*63afb9a5SDavid du Colombier typedef struct Cipher Cipher;
135*63afb9a5SDavid du Colombier typedef struct CipherState CipherState;
136*63afb9a5SDavid du Colombier typedef struct Conn Conn;
137*63afb9a5SDavid du Colombier typedef struct Kex Kex;
138*63afb9a5SDavid du Colombier typedef struct MBox MBox;
139*63afb9a5SDavid du Colombier typedef struct PKA PKA;
140*63afb9a5SDavid du Colombier typedef struct Packet Packet;
141*63afb9a5SDavid du Colombier typedef struct Plist Plist;
142*63afb9a5SDavid du Colombier typedef struct SSHChan SSHChan;
143*63afb9a5SDavid du Colombier 
144*63afb9a5SDavid du Colombier #pragma incomplete CipherState
145*63afb9a5SDavid du Colombier 
146*63afb9a5SDavid du Colombier struct Plist {
147*63afb9a5SDavid du Colombier 	Packet	*pack;
148*63afb9a5SDavid du Colombier 	uchar	*st;
149*63afb9a5SDavid du Colombier 	int	rem;
150*63afb9a5SDavid du Colombier 	Plist	*next;
151*63afb9a5SDavid du Colombier };
152*63afb9a5SDavid du Colombier 
153*63afb9a5SDavid du Colombier struct SSHChan {
154*63afb9a5SDavid du Colombier 	Rendez	r;			/* awaiting input? */
155*63afb9a5SDavid du Colombier 	int	id;
156*63afb9a5SDavid du Colombier 	int	otherid;
157*63afb9a5SDavid du Colombier 	int	state;
158*63afb9a5SDavid du Colombier 	int	waker;
159*63afb9a5SDavid du Colombier 	int	conn;
160*63afb9a5SDavid du Colombier 	ulong	rwindow;
161*63afb9a5SDavid du Colombier 	ulong	twindow;
162*63afb9a5SDavid du Colombier 	ulong	sent;
163*63afb9a5SDavid du Colombier 	ulong	inrqueue;
164*63afb9a5SDavid du Colombier 	char	*ann;
165*63afb9a5SDavid du Colombier 	Req	*lreq;
166*63afb9a5SDavid du Colombier 
167*63afb9a5SDavid du Colombier 	/* File* for each Qid type */
168*63afb9a5SDavid du Colombier 	File	*dir;
169*63afb9a5SDavid du Colombier 	File	*ctl;
170*63afb9a5SDavid du Colombier 	File	*data;
171*63afb9a5SDavid du Colombier 	File	*listen;
172*63afb9a5SDavid du Colombier 	File	*request;
173*63afb9a5SDavid du Colombier 	File	*status;
174*63afb9a5SDavid du Colombier 	File	*tcp;
175*63afb9a5SDavid du Colombier 
176*63afb9a5SDavid du Colombier 	Plist	*dataq;
177*63afb9a5SDavid du Colombier 	Plist	*datatl;
178*63afb9a5SDavid du Colombier 	Plist	*reqq;
179*63afb9a5SDavid du Colombier 	Plist	*reqtl;
180*63afb9a5SDavid du Colombier 
181*63afb9a5SDavid du Colombier 	Channel	*inchan;
182*63afb9a5SDavid du Colombier 	Channel	*reqchan;
183*63afb9a5SDavid du Colombier 	QLock	xmtlock;
184*63afb9a5SDavid du Colombier 	Rendez	xmtrendez;
185*63afb9a5SDavid du Colombier };
186*63afb9a5SDavid du Colombier 
187*63afb9a5SDavid du Colombier struct Conn {
188*63afb9a5SDavid du Colombier 	QLock	l;
189*63afb9a5SDavid du Colombier 	Rendez	r;			/* awaiting input? */
190*63afb9a5SDavid du Colombier 
191*63afb9a5SDavid du Colombier 	Ioproc	*dio;
192*63afb9a5SDavid du Colombier 	Ioproc	*cio;
193*63afb9a5SDavid du Colombier 	Ioproc	*rio;
194*63afb9a5SDavid du Colombier 
195*63afb9a5SDavid du Colombier 	int	state;
196*63afb9a5SDavid du Colombier 	int	role;
197*63afb9a5SDavid du Colombier 	int	id;
198*63afb9a5SDavid du Colombier 
199*63afb9a5SDavid du Colombier 	char	*remote;
200*63afb9a5SDavid du Colombier 	char	*user;
201*63afb9a5SDavid du Colombier 	char	*password;
202*63afb9a5SDavid du Colombier 
203*63afb9a5SDavid du Colombier 	char	*service;
204*63afb9a5SDavid du Colombier 	char	*cap;
205*63afb9a5SDavid du Colombier 	char	*authkey;
206*63afb9a5SDavid du Colombier 	int	nchan;
207*63afb9a5SDavid du Colombier 
208*63afb9a5SDavid du Colombier 	/* underlying tcp connection */
209*63afb9a5SDavid du Colombier 	int	datafd;
210*63afb9a5SDavid du Colombier 	int	ctlfd;
211*63afb9a5SDavid du Colombier 	int	stifle;		/* flag: no i/o between listen and sshsession */
212*63afb9a5SDavid du Colombier 	int	poisoned;
213*63afb9a5SDavid du Colombier 	int	tcpconn;
214*63afb9a5SDavid du Colombier 
215*63afb9a5SDavid du Colombier 	int	rpid;
216*63afb9a5SDavid du Colombier 
217*63afb9a5SDavid du Colombier 	int	inseq;
218*63afb9a5SDavid du Colombier 	int	outseq;
219*63afb9a5SDavid du Colombier 	int	kexalg;
220*63afb9a5SDavid du Colombier 	int	pkalg;
221*63afb9a5SDavid du Colombier 
222*63afb9a5SDavid du Colombier 	int	cscrypt;
223*63afb9a5SDavid du Colombier 	int	ncscrypt;
224*63afb9a5SDavid du Colombier 	int	sccrypt;
225*63afb9a5SDavid du Colombier 	int	nsccrypt;
226*63afb9a5SDavid du Colombier 
227*63afb9a5SDavid du Colombier 	int	csmac;
228*63afb9a5SDavid du Colombier 	int	ncsmac;
229*63afb9a5SDavid du Colombier 	int	scmac;
230*63afb9a5SDavid du Colombier 	int	nscmac;
231*63afb9a5SDavid du Colombier 
232*63afb9a5SDavid du Colombier 	int	encrypt;
233*63afb9a5SDavid du Colombier 	int	decrypt;
234*63afb9a5SDavid du Colombier 
235*63afb9a5SDavid du Colombier 	int	outmac;
236*63afb9a5SDavid du Colombier 	int	inmac;
237*63afb9a5SDavid du Colombier 
238*63afb9a5SDavid du Colombier 	/* File* for each Qid type */
239*63afb9a5SDavid du Colombier 	File	*dir;
240*63afb9a5SDavid du Colombier 	File	*clonefile;
241*63afb9a5SDavid du Colombier 	File	*ctlfile;
242*63afb9a5SDavid du Colombier 	File	*datafile;
243*63afb9a5SDavid du Colombier 	File	*listenfile;
244*63afb9a5SDavid du Colombier 	File	*localfile;
245*63afb9a5SDavid du Colombier 	File	*remotefile;
246*63afb9a5SDavid du Colombier 	File	*statusfile;
247*63afb9a5SDavid du Colombier 	File	*tcpfile;
248*63afb9a5SDavid du Colombier 
249*63afb9a5SDavid du Colombier 	Packet	*skexinit;
250*63afb9a5SDavid du Colombier 	Packet	*rkexinit;
251*63afb9a5SDavid du Colombier 	mpint	*x;
252*63afb9a5SDavid du Colombier 	mpint	*e;
253*63afb9a5SDavid du Colombier 	int	got_sessid;
254*63afb9a5SDavid du Colombier 	uchar	sessid[SHA1dlen];
255*63afb9a5SDavid du Colombier 
256*63afb9a5SDavid du Colombier 	uchar	c2siv[SHA1dlen*2];
257*63afb9a5SDavid du Colombier 	uchar	nc2siv[SHA1dlen*2];
258*63afb9a5SDavid du Colombier 	uchar	s2civ[SHA1dlen*2];
259*63afb9a5SDavid du Colombier 	uchar	ns2civ[SHA1dlen*2];
260*63afb9a5SDavid du Colombier 
261*63afb9a5SDavid du Colombier 	uchar	c2sek[SHA1dlen*2];
262*63afb9a5SDavid du Colombier 	uchar	nc2sek[SHA1dlen*2];
263*63afb9a5SDavid du Colombier 	uchar	s2cek[SHA1dlen*2];
264*63afb9a5SDavid du Colombier 	uchar	ns2cek[SHA1dlen*2];
265*63afb9a5SDavid du Colombier 
266*63afb9a5SDavid du Colombier 	uchar	c2sik[SHA1dlen*2];
267*63afb9a5SDavid du Colombier 	uchar	nc2sik[SHA1dlen*2];
268*63afb9a5SDavid du Colombier 	uchar	s2cik[SHA1dlen*2];
269*63afb9a5SDavid du Colombier 	uchar	ns2cik[SHA1dlen*2];
270*63afb9a5SDavid du Colombier 
271*63afb9a5SDavid du Colombier 	char	*otherid;
272*63afb9a5SDavid du Colombier 	uchar	*inik;
273*63afb9a5SDavid du Colombier 	uchar	*outik;
274*63afb9a5SDavid du Colombier 	CipherState *s2ccs;
275*63afb9a5SDavid du Colombier 	CipherState *c2scs;
276*63afb9a5SDavid du Colombier 	CipherState *enccs;
277*63afb9a5SDavid du Colombier 	CipherState *deccs;
278*63afb9a5SDavid du Colombier 	SSHChan	*chans[MAXCONN];
279*63afb9a5SDavid du Colombier 
280*63afb9a5SDavid du Colombier 	char	idstring[256];		/* max allowed by SSH spec */
281*63afb9a5SDavid du Colombier };
282*63afb9a5SDavid du Colombier 
283*63afb9a5SDavid du Colombier struct Packet {
284*63afb9a5SDavid du Colombier 	Conn	*c;
285*63afb9a5SDavid du Colombier 	ulong	rlength;
286*63afb9a5SDavid du Colombier 	ulong	tlength;
287*63afb9a5SDavid du Colombier 	uchar	nlength[4];
288*63afb9a5SDavid du Colombier 	uchar	pad_len;
289*63afb9a5SDavid du Colombier 	uchar	payload[Maxpktpay];
290*63afb9a5SDavid du Colombier };
291*63afb9a5SDavid du Colombier 
292*63afb9a5SDavid du Colombier struct Cipher {
293*63afb9a5SDavid du Colombier 	char	*name;
294*63afb9a5SDavid du Colombier 	int	blklen;
295*63afb9a5SDavid du Colombier 	CipherState *(*init)(Conn*, int);
296*63afb9a5SDavid du Colombier 	void	(*encrypt)(CipherState*, uchar*, int);
297*63afb9a5SDavid du Colombier 	void	(*decrypt)(CipherState*, uchar*, int);
298*63afb9a5SDavid du Colombier };
299*63afb9a5SDavid du Colombier 
300*63afb9a5SDavid du Colombier struct Kex {
301*63afb9a5SDavid du Colombier 	char	*name;
302*63afb9a5SDavid du Colombier 	int	(*serverkex)(Conn *, Packet *);
303*63afb9a5SDavid du Colombier 	int	(*clientkex1)(Conn *, Packet *);
304*63afb9a5SDavid du Colombier 	int	(*clientkex2)(Conn *, Packet *);
305*63afb9a5SDavid du Colombier };
306*63afb9a5SDavid du Colombier 
307*63afb9a5SDavid du Colombier struct PKA {
308*63afb9a5SDavid du Colombier 	char	*name;
309*63afb9a5SDavid du Colombier 	Packet	*(*ks)(Conn *);
310*63afb9a5SDavid du Colombier 	Packet	*(*sign)(Conn *, uchar *, int);
311*63afb9a5SDavid du Colombier 	int	(*verify)(Conn *, uchar *, int, char *, char *, int);
312*63afb9a5SDavid du Colombier };
313*63afb9a5SDavid du Colombier 
314*63afb9a5SDavid du Colombier struct MBox {
315*63afb9a5SDavid du Colombier 	Channel	*mchan;
316*63afb9a5SDavid du Colombier 	char	*msg;
317*63afb9a5SDavid du Colombier 	int	state;
318*63afb9a5SDavid du Colombier };
319*63afb9a5SDavid du Colombier 
320*63afb9a5SDavid du Colombier extern Cipher cipheraes128, cipheraes192, cipheraes256;
321*63afb9a5SDavid du Colombier extern Cipher cipherblowfish, cipher3des, cipherrc4;
322*63afb9a5SDavid du Colombier extern int debug;
323*63afb9a5SDavid du Colombier extern int sshkeychan[];
324*63afb9a5SDavid du Colombier extern Kex dh1sha1, dh14sha1;
325*63afb9a5SDavid du Colombier extern MBox keymbox;
326*63afb9a5SDavid du Colombier extern PKA rsa_pka, dss_pka, *pkas[];
327*63afb9a5SDavid du Colombier 
328*63afb9a5SDavid du Colombier /* pubkey.c */
329*63afb9a5SDavid du Colombier int appendkey(char *, char *, RSApub *);
330*63afb9a5SDavid du Colombier int findkey(char *, char *, RSApub *);
331*63afb9a5SDavid du Colombier RSApub *readpublickey(Biobuf *, char **);
332*63afb9a5SDavid du Colombier int replacekey(char *, char *, RSApub *);
333*63afb9a5SDavid du Colombier 
334*63afb9a5SDavid du Colombier /* dh.c */
335*63afb9a5SDavid du Colombier void dh_init(PKA *[]);
336*63afb9a5SDavid du Colombier 
337*63afb9a5SDavid du Colombier /* transport.c */
338*63afb9a5SDavid du Colombier void	add_block(Packet *, void *, int);
339*63afb9a5SDavid du Colombier void	add_byte(Packet *, char);
340*63afb9a5SDavid du Colombier void	add_mp(Packet *, mpint *);
341*63afb9a5SDavid du Colombier int	add_packet(Packet *, void *, int);
342*63afb9a5SDavid du Colombier void	add_string(Packet *, char *);
343*63afb9a5SDavid du Colombier void	add_uint32(Packet *, ulong);
344*63afb9a5SDavid du Colombier void	dump_packet(Packet *);
345*63afb9a5SDavid du Colombier int	finish_packet(Packet *);
346*63afb9a5SDavid du Colombier mpint	*get_mp(uchar *q);
347*63afb9a5SDavid du Colombier uchar	*get_string(Packet *, uchar *, char *, int, int *);
348*63afb9a5SDavid du Colombier ulong	get_uint32(Packet *, uchar **);
349*63afb9a5SDavid du Colombier void	init_packet(Packet *);
350*63afb9a5SDavid du Colombier Packet	*new_packet(Conn *);
351*63afb9a5SDavid du Colombier int	undo_packet(Packet *);
352