/[LeafOK_CVS]/pvpgn-1.7.4/src/client/client_connect.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/client/client_connect.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
Error occurred while calculating annotation data.
no message

1 /*
2 * Copyright (C) 1998,1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #include "common/setup_before.h"
19 #include <stdio.h>
20 #ifdef STDC_HEADERS
21 # include <stdlib.h>
22 #endif
23 #ifdef HAVE_MEMORY_H
24 # include <memory.h>
25 #endif
26 #include "compat/memset.h"
27 #include "compat/memcpy.h"
28 #include <ctype.h>
29 #ifdef HAVE_STRING_H
30 # include <string.h>
31 #endif
32 #include <errno.h>
33 #include "compat/strerror.h"
34 #ifdef TIME_WITH_SYS_TIME
35 # include <sys/time.h>
36 # include <time.h>
37 #else
38 # ifdef HAVE_SYS_TIME_H
39 # include <sys/time.h>
40 # else
41 # include <time.h>
42 # endif
43 #endif
44 #ifdef HAVE_UNISTD_H
45 # include <unistd.h>
46 #endif
47 #include "compat/gethostname.h"
48 #ifdef HAVE_SYS_TYPES_H
49 # include <sys/types.h>
50 #endif
51 #ifdef HAVE_SYS_SOCKET_H
52 # include <sys/socket.h>
53 #endif
54 #include "compat/socket.h"
55 #ifdef HAVE_SYS_PARAM_H
56 # include <sys/param.h>
57 #endif
58 #ifdef HAVE_NETINET_IN_H
59 # include <netinet/in.h>
60 #endif
61 #include "compat/netinet_in.h"
62 #ifdef HAVE_ARPA_INET_H
63 # include <arpa/inet.h>
64 #endif
65 #include "compat/inet_ntoa.h"
66 #ifdef HAVE_NETDB_H
67 # include <netdb.h>
68 #endif
69 #include "compat/psock.h"
70 #include "common/packet.h"
71 #include "common/init_protocol.h"
72 #include "common/udp_protocol.h"
73 #include "common/bnet_protocol.h"
74 #include "common/file_protocol.h"
75 #include "common/tag.h"
76 #include "common/bn_type.h"
77 #include "common/field_sizes.h"
78 #include "common/bnethash.h"
79 #include "common/bnethashconv.h"
80 #include "common/util.h"
81 #ifdef CLIENTDEBUG
82 # include "common/eventlog.h"
83 #endif
84 #include "client.h"
85 #include "udptest.h"
86 #include "common/bnettime.h"
87 #include "common/proginfo.h"
88 #include "client_connect.h"
89 #include "common/setup_after.h"
90
91
92 #define COMPNAMELEN 128
93
94 #ifdef CLIENTDEBUG
95 # define dprintf printf
96 #else
97 # define dprintf if (0) printf
98 #endif
99
100
101 static int key_interpret(char const * cdkey, unsigned int * productid, unsigned int * keyvalue1, unsigned int * keyvalue2)
102 {
103 /* FIXME: implement... have example code from Eurijk! */
104 *productid = 0;
105 *keyvalue1 = 0;
106 *keyvalue2 = 0;
107 return 0;
108 }
109
110
111 static int get_defversioninfo(char const * progname, char const * clienttag, unsigned int * versionid, unsigned int * gameversion, char const * * exeinfo, unsigned int * checksum)
112 {
113 if (strcmp(clienttag,CLIENTTAG_DIABLORTL)==0)
114 {
115 *versionid = CLIENT_VERSIONID_DRTL;
116 *gameversion = CLIENT_GAMEVERSION_DRTL;
117 *exeinfo = CLIENT_EXEINFO_DRTL;
118 *checksum = CLIENT_CHECKSUM_DRTL;
119 return 0;
120 }
121
122 if (strcmp(clienttag,CLIENTTAG_STARCRAFT)==0)
123 {
124 *versionid = CLIENT_VERSIONID_STAR;
125 *gameversion = CLIENT_GAMEVERSION_STAR;
126 *exeinfo = CLIENT_EXEINFO_STAR;
127 *checksum = CLIENT_CHECKSUM_STAR;
128 return 0;
129 }
130
131 if (strcmp(clienttag,CLIENTTAG_SHAREWARE)==0)
132 {
133 *versionid = CLIENT_VERSIONID_SSHR;
134 *gameversion = CLIENT_GAMEVERSION_SSHR;
135 *exeinfo = CLIENT_EXEINFO_SSHR;
136 *checksum = CLIENT_CHECKSUM_SSHR;
137 return 0;
138 }
139
140 if (strcmp(clienttag,CLIENTTAG_BROODWARS)==0)
141 {
142 *versionid = CLIENT_VERSIONID_SEXP;
143 *gameversion = CLIENT_GAMEVERSION_SEXP;
144 *exeinfo = CLIENT_EXEINFO_SEXP;
145 *checksum = CLIENT_CHECKSUM_SEXP;
146 return 0;
147 }
148
149 if (strcmp(clienttag,CLIENTTAG_WARCIIBNE)==0)
150 {
151 *versionid = CLIENT_VERSIONID_W2BN;
152 *gameversion = CLIENT_GAMEVERSION_W2BN;
153 *exeinfo = CLIENT_EXEINFO_W2BN;
154 *checksum = CLIENT_CHECKSUM_W2BN;
155 return 0;
156 }
157
158 if (strcmp(clienttag,CLIENTTAG_DIABLO2DV)==0)
159 {
160 *versionid = CLIENT_VERSIONID_D2DV;
161 *gameversion = CLIENT_GAMEVERSION_D2DV;
162 *exeinfo = CLIENT_EXEINFO_D2DV;
163 *checksum = CLIENT_CHECKSUM_D2DV;
164 return 0;
165 }
166
167 if (strcmp(clienttag,CLIENTTAG_DIABLO2XP)==0)
168 {
169 *versionid = CLIENT_VERSIONID_D2XP;
170 *gameversion = CLIENT_GAMEVERSION_D2XP;
171 *exeinfo = CLIENT_EXEINFO_D2XP;
172 *checksum = CLIENT_CHECKSUM_D2XP;
173 return 0;
174 }
175
176 if (strcmp(clienttag,CLIENTTAG_WARCRAFT3)==0 ||
177 strcmp(clienttag,CLIENTTAG_WAR3XP)==0)
178 {
179 *versionid = CLIENT_VERSIONID_WAR3;
180 *gameversion = CLIENT_GAMEVERSION_WAR3;
181 *exeinfo = CLIENT_EXEINFO_WAR3;
182 *checksum = CLIENT_CHECKSUM_WAR3;
183 return 0;
184 }
185
186 *versionid = 0;
187 *gameversion = 0;
188 *exeinfo = "";
189 *checksum = 0;
190
191 fprintf(stderr,"%s: unsupported clienttag \"%s\"\n",progname,clienttag);
192 // aaron: dunno what we should return in case of this.. but returning nothing was definetly wrong
193 return -1;
194 }
195
196
197 extern int client_connect(char const * progname, char const * servname, unsigned short servport, char const * cdowner, char const * cdkey, char const * clienttag, struct sockaddr_in * saddr, unsigned int * sessionkey, unsigned int * sessionnum, char const * archtag)
198 {
199 struct hostent * host;
200 char const * username;
201 int sd;
202 t_packet * packet;
203 t_packet * rpacket;
204 char compname[COMPNAMELEN];
205 int lsock;
206 unsigned short lsock_port;
207 unsigned int versionid;
208 unsigned int gameversion;
209 char const * exeinfo;
210 unsigned int checksum;
211
212 if (!progname)
213 {
214 fprintf(stderr,"got NULL progname\n");
215 return -1;
216 }
217 if (!saddr)
218 {
219 fprintf(stderr,"%s: got NULL saddr\n",progname);
220 return -1;
221 }
222 if (!sessionkey)
223 {
224 fprintf(stderr,"%s: got NULL sessionkey\n",progname);
225 return -1;
226 }
227 if (!sessionnum)
228 {
229 fprintf(stderr,"%s: got NULL sessionnum\n",progname);
230 return -1;
231 }
232
233 if (psock_init()<0)
234 {
235 fprintf(stderr,"%s: could not inialialize socket functions\n",progname);
236 return -1;
237 }
238
239 if (!(host = gethostbyname(servname)))
240 {
241 fprintf(stderr,"%s: unknown host \"%s\"\n",progname,servname);
242 return -1;
243 }
244 if (host->h_addrtype!=PSOCK_AF_INET)
245 fprintf(stderr,"%s: host \"%s\" is not in IPv4 address family\n",progname,servname);
246
247 if (gethostname(compname,COMPNAMELEN)<0)
248 {
249 fprintf(stderr,"%s: could not get host name (gethostname: %s)\n",progname,pstrerror(errno));
250 return -1;
251 }
252 #ifdef HAVE_GETLOGIN
253 if (!(username = getlogin()))
254 #endif
255 {
256 username = "unknown";
257 dprintf("%s: could not get login name, using \"%s\" (getlogin: %s)\n",progname,username,pstrerror(errno));
258 }
259
260 if ((sd = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP))<0)
261 {
262 fprintf(stderr,"%s: could not create socket (psock_socket: %s)\n",progname,pstrerror(psock_errno()));
263 return -1;
264 }
265
266 memset(saddr,0,sizeof(*saddr));
267 saddr->sin_family = PSOCK_AF_INET;
268 saddr->sin_port = htons(servport);
269 memcpy(&saddr->sin_addr.s_addr,host->h_addr_list[0],host->h_length);
270 if (psock_connect(sd,(struct sockaddr *)saddr,sizeof(*saddr))<0)
271 {
272 fprintf(stderr,"%s: could not connect to server \"%s\" port %hu (psock_connect: %s)\n",progname,servname,servport,pstrerror(psock_errno()));
273 goto error_sd;
274 }
275
276 printf("Connected to %s:%hu.\n",inet_ntoa(saddr->sin_addr),servport);
277
278 #ifdef CLIENTDEBUG
279 eventlog_set(stderr);
280 #endif
281
282 if ((lsock = client_udptest_setup(progname,&lsock_port))>=0)
283 dprintf("Got UDP data on port %hu\n",lsock_port);
284
285 if (!(packet = packet_create(packet_class_init)))
286 {
287 fprintf(stderr,"%s: could not create packet\n",progname);
288 goto error_lsock;
289 }
290 bn_byte_set(&packet->u.client_initconn.class,CLIENT_INITCONN_CLASS_BNET);
291 client_blocksend_packet(sd,packet);
292 packet_del_ref(packet);
293
294 /* reuse this same packet over and over */
295 if (!(rpacket = packet_create(packet_class_bnet)))
296 {
297 fprintf(stderr,"%s: could not create packet\n",progname);
298 goto error_lsock;
299 }
300
301 get_defversioninfo(progname,clienttag,&versionid,&gameversion,&exeinfo,&checksum);
302
303 if (strcmp(clienttag,CLIENTTAG_DIABLOSHR)==0 ||
304 strcmp(clienttag,CLIENTTAG_DIABLORTL)==0)
305 {
306 if (!(packet = packet_create(packet_class_bnet)))
307 {
308 fprintf(stderr,"%s: could not create packet\n",progname);
309 goto error_rpacket;
310 }
311 packet_set_size(packet,sizeof(t_client_unknown_1b));
312 packet_set_type(packet,CLIENT_UNKNOWN_1B);
313 bn_short_set(&packet->u.client_unknown_1b.unknown1,CLIENT_UNKNOWN_1B_UNKNOWN3);
314 bn_short_nset(&packet->u.client_unknown_1b.port,lsock_port);
315 bn_int_nset(&packet->u.client_unknown_1b.ip,0); /* FIXME */
316 bn_int_set(&packet->u.client_unknown_1b.unknown2,CLIENT_UNKNOWN_1B_UNKNOWN3);
317 bn_int_set(&packet->u.client_unknown_1b.unknown3,CLIENT_UNKNOWN_1B_UNKNOWN3);
318 client_blocksend_packet(sd,packet);
319 packet_del_ref(packet);
320 }
321
322 if (!(packet = packet_create(packet_class_bnet)))
323 {
324 fprintf(stderr,"%s: could not create packet\n",progname);
325 goto error_rpacket;
326 }
327 packet_set_size(packet,sizeof(t_client_countryinfo_109));
328 packet_set_type(packet,CLIENT_COUNTRYINFO_109);
329 bn_int_set(&packet->u.client_countryinfo_109.protocol,CLIENT_COUNTRYINFO_109_PROTOCOL);
330 bn_int_tag_set(&packet->u.client_countryinfo_109.archtag,archtag);
331 bn_int_tag_set(&packet->u.client_countryinfo_109.clienttag,clienttag);
332 //AARON
333
334 bn_int_set(&packet->u.client_countryinfo_109.versionid,versionid);
335 bn_int_set(&packet->u.client_countryinfo_109.gamelang,CLIENT_COUNTRYINFO_109_GAMELANG);
336 bn_int_set(&packet->u.client_countryinfo_109.localip,CLIENT_COUNTRYINFO_109_LOCALIP);
337 {
338 int bias;
339
340 bias = local_tzbias();
341
342 bn_int_set(&packet->u.client_countryinfo_109.bias,(unsigned int)bias); /* rely on 2's complement */
343 dprintf("my tzbias = %d (0x%08hx)\n",bias,(unsigned int)bias);
344 }
345 /* FIXME: determine from locale */
346 bn_int_set(&packet->u.client_countryinfo_109.lcid,CLIENT_COUNTRYINFO_109_LANGID_USENGLISH);
347 bn_int_set(&packet->u.client_countryinfo_109.langid,CLIENT_COUNTRYINFO_109_LANGID_USENGLISH);
348 packet_append_string(packet,CLIENT_COUNTRYINFO_109_LANGSTR_USENGLISH);
349 /* FIXME: determine from locale+timezone... from domain name... nothing really would
350 work. Maybe add some command-line options */
351 packet_append_string(packet,CLIENT_COUNTRYINFO_109_COUNTRYNAME_USA);
352 client_blocksend_packet(sd,packet);
353 packet_del_ref(packet);
354
355 do
356 if (client_blockrecv_packet(sd,rpacket)<0)
357 {
358 fprintf(stderr,"%s: server closed connection\n",progname);
359 goto error_rpacket;
360 }
361 while (packet_get_type(rpacket)!=SERVER_AUTHREQ_109 &&
362 packet_get_type(rpacket)!=SERVER_AUTHREPLY_109);
363
364 if (packet_get_type(rpacket)==SERVER_AUTHREQ_109) /* hmm... server wants to check the version number */
365 {
366 dprintf("Got AUTHREQ_109\n");
367 *sessionkey = bn_int_get(rpacket->u.server_authreq_109.sessionkey);
368 *sessionnum = bn_int_get(rpacket->u.server_authreq_109.sessionnum);
369 /* FIXME: also get filename and equation */
370
371 if (!(packet = packet_create(packet_class_bnet)))
372 {
373 fprintf(stderr,"%s: could not create packet\n",progname);
374 goto error_rpacket;
375 }
376 packet_set_size(packet,sizeof(t_client_authreq_109));
377 packet_set_type(packet,CLIENT_AUTHREQ_109);
378 bn_int_set(&packet->u.client_authreq_109.ticks,time(NULL));
379
380 {
381 t_cdkey_info cdkey_info;
382
383 bn_int_set(&packet->u.client_authreq_109.gameversion,gameversion);
384
385 bn_int_set(&packet->u.client_authreq_109.cdkey_number,1); /* only one */
386 memset(&cdkey_info,'0',sizeof(cdkey_info));
387 /* FIXME: put the input cdkey here */
388 packet_append_data(packet,&cdkey_info,sizeof(cdkey_info));
389 packet_append_string(packet,exeinfo);
390 packet_append_string(packet,cdowner);
391 }
392 bn_int_set(&packet->u.client_authreq_109.spawn,0x0000);
393 bn_int_set(&packet->u.client_authreq_109.checksum,checksum);
394 client_blocksend_packet(sd,packet);
395 packet_del_ref(packet);
396
397 /* now wait for reply */
398 do
399 if (client_blockrecv_packet(sd,rpacket)<0)
400 {
401 fprintf(stderr,"%s: server closed connection\n",progname);
402 goto error_rpacket;
403 }
404 while (packet_get_type(rpacket)!=SERVER_AUTHREPLY_109);
405 //FIXME: check if AUTHREPLY_109 is success or fail
406 if (bn_int_get(rpacket->u.server_authreply_109.message)!=SERVER_AUTHREPLY_109_MESSAGE_OK)
407 {
408 fprintf(stderr,"AUTHREPLY_109 failed - closing connection\n");
409 goto error_rpacket;
410 }
411 }
412 else
413 fprintf(stderr,"We didn't get a sessionkey, don't expect login to work!");
414 dprintf("Got AUTHREPLY_109\n");
415
416 if (!(packet = packet_create(packet_class_bnet)))
417 {
418 fprintf(stderr,"%s: could not create packet\n",progname);
419 goto error_rpacket;
420 }
421 packet_set_size(packet,sizeof(t_client_iconreq));
422 packet_set_type(packet,CLIENT_ICONREQ);
423 client_blocksend_packet(sd,packet);
424 packet_del_ref(packet);
425
426 do
427 if (client_blockrecv_packet(sd,rpacket)<0)
428 {
429 fprintf(stderr,"%s: server closed connection\n",progname);
430 goto error_rpacket;
431 }
432 while (packet_get_type(rpacket)!=SERVER_ICONREPLY);
433 dprintf("Got ICONREPLY\n");
434
435 if (strcmp(clienttag,CLIENTTAG_STARCRAFT)==0 ||
436 strcmp(clienttag,CLIENTTAG_BROODWARS)==0 ||
437 strcmp(clienttag,CLIENTTAG_WARCIIBNE)==0)
438 {
439 if (!(packet = packet_create(packet_class_bnet)))
440 {
441 fprintf(stderr,"%s: could not create packet\n",progname);
442 goto error_rpacket;
443 }
444
445 {
446 struct
447 {
448 bn_int sessionkey;
449 bn_int ticks;
450 bn_int productid;
451 bn_int keyvalue1;
452 bn_int keyvalue2;
453 } temp;
454 t_hash key_hash;
455 unsigned int ticks;
456 unsigned int keyvalue1,keyvalue2,productid;
457
458 if (key_interpret(cdkey,&productid,&keyvalue1,&keyvalue2)<0)
459 {
460 fprintf(stderr,"%s: specified key is not valid, sending junk\n",progname);
461 productid = 0;
462 keyvalue1 = 0;
463 keyvalue2 = 0;
464 }
465
466 ticks = 0; /* FIXME: what to use here? */
467 bn_int_set(&temp.ticks,ticks);
468 bn_int_set(&temp.sessionkey,*sessionkey);
469 bn_int_set(&temp.productid,productid);
470 bn_int_set(&temp.keyvalue1,keyvalue1);
471 bn_int_set(&temp.keyvalue2,keyvalue2);
472 bnet_hash(&key_hash,sizeof(temp),&temp);
473
474 packet_set_size(packet,sizeof(t_client_cdkey2));
475 packet_set_type(packet,CLIENT_CDKEY2);
476 bn_int_set(&packet->u.client_cdkey2.spawn,CLIENT_CDKEY2_SPAWN_FALSE); /* FIXME: add option */
477 bn_int_set(&packet->u.client_cdkey2.keylen,strlen(cdkey));
478 bn_int_set(&packet->u.client_cdkey2.productid,productid);
479 bn_int_set(&packet->u.client_cdkey2.keyvalue1,keyvalue1);
480 bn_int_set(&packet->u.client_cdkey2.sessionkey,*sessionkey);
481 bn_int_set(&packet->u.client_cdkey2.ticks,ticks);
482 hash_to_bnhash((t_hash const *)&key_hash,packet->u.client_cdkey2.key_hash); /* avoid warning */
483 packet_append_string(packet,cdowner);
484 client_blocksend_packet(sd,packet);
485 packet_del_ref(packet);
486 }
487
488 do
489 if (client_blockrecv_packet(sd,rpacket)<0)
490 {
491 fprintf(stderr,"%s: server closed connection\n",progname);
492 goto error_rpacket;
493 }
494 while (packet_get_type(rpacket)!=SERVER_CDKEYREPLY2);
495 dprintf("Got CDKEYREPLY2 (%u)\n",bn_int_get(rpacket->u.server_cdkeyreply2.message));
496 }
497
498 packet_destroy(rpacket);
499 return sd;
500
501 /* error cleanup */
502
503 error_rpacket:
504
505 packet_destroy(rpacket);
506
507 error_lsock:
508
509 if (lsock>=0)
510 psock_close(lsock);
511
512 error_sd:
513
514 psock_close(sd);
515
516 return -1;
517 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1