transmission: update from 2.13 to 2.22
[tomato.git] / release / src / router / bpalogin / transaction.c
blobe3a0b45191a78b027ed6317bb19217f0ebe9f44c
1 /*
2 ** BPALogin - lightweight portable BIDS2 login client
3 ** Copyright (c) 2001-3 Shane Hyde, and others.
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
21 #include "bpalogin.h"
23 void add_trans_data(struct transaction * t,char *p,int count)
25 memcpy(t->data+t->length,p,count);
26 t->length += count;
29 void add_int2field(struct transaction * t,INT2 v)
31 add_trans_data(t,(char *)&v,2);
34 void add_int4field(struct transaction * t,INT4 v)
36 add_trans_data(t,(char *)&v,4);
39 void add_string(struct transaction * t,char *s)
41 add_int2field(t,htons((INT2)(strlen(s)+4)));
42 add_trans_data(t,s,strlen(s));
45 void add_data(struct transaction * t,char *s,int c)
47 add_int2field(t,htons((INT2)(c+4)));
48 add_trans_data(t,s,c);
51 void add_field_string(struct session *s,struct transaction * t,INT2 fn,char * p)
53 //s->debug(2,"Sending parm %d value %s\n",fn,p);
55 add_int2field(t,htons(fn));
56 add_string(t,p);
59 void add_field_data(struct session *s,struct transaction * t,INT2 fn,char * p,int c)
61 //s->debug(2,"Sending parm %d value %s\n",fn,p);
63 add_int2field(t,htons(fn));
64 add_data(t,p,c);
67 void add_field_INT2(struct session *s,struct transaction * t,INT2 fn,INT2 v)
69 //s->debug(2,"Sending parm %d value %d\n",fn,v);
71 add_int2field(t,htons(fn));
72 add_int2field(t,htons(6));
73 add_int2field(t,htons(v));
76 void add_field_INT4(struct session *s,struct transaction * t,INT2 fn,INT4 v)
78 //s->debug(2,"Sending parm %d value %d\n",fn,v);
80 add_int2field(t,htons(fn));
81 add_int2field(t,htons(8));
82 add_int4field(t,htonl(v));
85 void start_transaction(struct transaction * t,INT2 msgtype,INT4 sessionid)
87 t->length = 0;
88 memset(t->data,0,1512);
89 add_int2field(t,htons(msgtype));
90 add_int2field(t,htons(0));
91 add_int4field(t,htonl(sessionid));
94 void dump_transaction(struct session * s,struct transaction * t)
96 return;
97 int i;
98 char * p = t->data;
99 char pkt[1500];
100 char *pktp = &pkt;
101 memset(pkt,0,1500);
102 i = 0;
103 #if 0 // by tallest debug 0210
104 while(i < t->length)
106 s->debug(3,"%d:%02x ",i,(unsigned char)*(p));
108 p++;
109 i++;
111 s->debug(3,"\n");
112 #endif
113 #if 0
114 s->debug(3,"transaction data : ===== start =====");
115 while(i < t->length)
117 sprintf(pktp,"%02x ",(unsigned char)*(p));
119 pktp = pktp+3;
120 p++;
121 i++;
122 if(!(i%32)){
123 s->debug(3,"%s;",pktp-96);
126 if(i == t->length){
127 int j;
128 j = (i%32)*3;
129 s->debug(3,"%s;",pktp-j);
132 //syslog(LOG_DEBUG,"data: %s",pkt);
133 s->debug(3,"transaction data : ===== end =====");
134 #endif
137 void dump_sent_transaction(struct session *s,struct transaction * t)
139 s->debug(3,"Sent transaction:\n");
140 dump_transaction(s,t);
143 void dump_recv_transaction(struct session *s,struct transaction * t)
145 s->debug(3,"Received transaction:\n");
146 dump_transaction(s,t);
149 void send_transaction(struct session *s,int socket,struct transaction * t)
151 int r;
152 INT2 * lll;
154 lll = (INT2 *)(t->data+2);
155 *lll = htons((INT2)t->length);
157 r = send(socket,(void *)t,t->length,0);
158 dump_sent_transaction(s,t);
161 void send_udp_transaction(struct session * s,struct transaction * t)
163 int r;
165 INT2 * lll;
167 lll = (INT2 *)(t->data+2);
168 *lll = htons((INT2)t->length);
170 s->fromaddr.sin_port = htons(s->statusport);
171 r = sendto(s->listensock,(void *)t,t->length,0,(struct sockaddr *)&s->fromaddr,sizeof(s->fromaddr));
172 dump_sent_transaction(s,t);
175 INT2 receive_transaction(struct session *s,int socket,struct transaction * t)
177 INT2 * v;
178 int r = recv(socket,(char *)t,1500,0);
180 t->length = r;
181 dump_recv_transaction(s,t);
183 v = (INT2 *)t;
185 return r>0?ntohs(*v):0;
188 int check_hb_packet(struct session * s,struct transaction * t,int length)
190 INT2 type;
192 type = ntohs(*(INT2 *)t);
193 if(type != T_MSG_STATUS_REQ)
195 s->debug(0,"Incorrect transaction type %d",type);
196 return 0;
199 if(length != 8)
201 s->debug(0,"Incorrect transaction length %d",length);
202 return 0;
204 return 1;
207 INT2 receive_udp_transaction(struct session *s,int socket,struct transaction * t,struct sockaddr_in *addr)
209 struct timeval timeval;
210 fd_set readfds;
211 INT2 * v;
212 int l = sizeof(struct sockaddr_in);
213 int r,i;
215 timeval.tv_sec = s->maxheartbeat;
216 timeval.tv_usec = 0;
217 FD_ZERO(&readfds);
218 FD_SET(socket,&readfds);
220 r = select(socket+1,&readfds,NULL,NULL,&timeval);
222 if(r == -1)
224 return (INT2) 0xfffe;
226 else if(!r)
228 return (INT2) 0xffff;
230 else
232 r = recvfrom(socket,(char *)t,1500,0,(struct sockaddr*)addr,&l);
233 if(r==-1)
234 return (INT2) 0xfffe;
236 //if(s->lastheartbeat + s->minheartbeat > time(NULL))
237 if(s->lastheartbeat + s->minheartbeat > get_time(NULL))
239 s->recenthb++;
240 if(s->recenthb > 3)
242 s->debug(0,"Heartbeats arriving too quickly - discarding\n");
243 return (INT2)0xfffd;
247 else
248 s->recenthb = 0;
250 //s->lastheartbeat = time(NULL);
251 s->lastheartbeat = get_time(NULL);
254 for(i = 0;i<s->tsmcount;i++)
256 if(addr->sin_addr.s_addr == s->tsmlist_in[i].sin_addr.s_addr)
257 break;
259 if(i == s->tsmcount)
261 s->debug(0,"Received a heartbeat from unexpected source %s:%d\n",inet_ntoa(addr->sin_addr),ntohs(addr->sin_port));
262 return (INT2)0xfffd;
265 t->length = r;
267 dump_recv_transaction(s,t);
269 ** Lets make sure this packet is structured correctly
271 if(!check_hb_packet(s,t,r))
273 return (INT2)0xfffd;
276 dump_recv_transaction(s,t);
278 v = (INT2 *)t;
280 return r>0?ntohs(*v):0;
283 char * locate_parm(struct transaction * t,INT2 parm)
285 char * p = t->data,*pp,*lp,*vp;
286 INT2 p1;
287 INT2 l;
288 int i;
290 i = 8;
291 p += 8;
292 while(i < t->length)
294 pp = p;
295 lp = p+2;
296 vp = p+4;
298 l = read_INT2(lp);
299 p1 = read_INT2(pp);
301 if(parm == p1)
303 return vp;
305 p += l;
306 i += l;
308 return NULL;
311 int extract_valueINT2(struct session *s,struct transaction * t,INT2 parm,INT2 *v)
313 INT2 * pp = (INT2 *)locate_parm(t,parm);
314 if(pp)
316 *v = read_INT2(pp);
317 s->debug(2,"Received parm %d value %d\n",parm,*v);
319 return TRUE;
321 return FALSE;
324 int extract_valueINT4(struct session *s,struct transaction * t,INT2 parm,INT4 *v)
326 INT4 * pp = (INT4 *)locate_parm(t,parm);
327 if(pp)
329 *v = read_INT4(pp);
330 s->debug(2,"Received parm %d value %d\n",parm,*v);
332 return TRUE;
334 return FALSE;
337 int extract_valuestring(struct session *s,struct transaction * t,INT2 parm,char * v)
339 char * pp = locate_parm(t,parm);
340 if(pp)
342 INT2 l = read_INT2(pp-2);
343 memcpy(v,pp,l-4);
344 *(v+l-4) = 0;
345 s->debug(2,"Received parm %d value %s\n",parm,v);
347 return TRUE;
349 return FALSE;
352 INT2 read_INT2(void *pp)
354 #ifdef __i386
355 return ntohs(*((INT2*)pp));
356 #else
357 unsigned char * p = (unsigned char *)pp;
358 return (((INT2)(*p))<<8) + ((INT2)(*(p+1)));
359 #endif
362 INT4 read_INT4(void *pp)
364 #ifdef __i386
365 return ntohl(*((INT4*)pp));
366 #else
367 unsigned char * p = (unsigned char *)pp;
368 return (((INT4)(*p))<<24) + (((INT4)(*(p+1)))<<16) + (((INT4)(*(p+2)))<<8) + (((INT4)(*(p+3))));
369 #endif