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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide 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
no message

1 sysadm 1.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