コード例 #1
0
ファイル: file.cpp プロジェクト: DizKragnet/pvpgn
/* Send a file.  If the file doesn't exist we still need to respond
 * to the file request.  This will set filelen to 0 and send the server
 * reply message and the client will be happy and not hang.
 */
extern int file_send(t_connection * c, char const * rawname, unsigned int adid, unsigned int etag, unsigned int startoffset, int need_header)
{
    char const * filename;
    t_packet *   rpacket;
    std::FILE *       fp;
    unsigned int filelen;
    int          nbytes;

    if (!c)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
	return -1;
    }
    if (!rawname)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL rawname");
	return -1;
    }

    if (!(rpacket = packet_create(packet_class_file)))
    {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create file packet");
	return -1;
    }
    packet_set_size(rpacket,sizeof(t_server_file_reply));
    packet_set_type(rpacket,SERVER_FILE_REPLY);

    if ((filename = file_get_info(rawname,&filelen,&rpacket->u.server_file_reply.timestamp)))
    {
	if (!(fp = std::fopen(filename,"rb")))
	{
	    /* FIXME: check for lower-case version of filename */
	    eventlog(eventlog_level_error,__FUNCTION__, "stat() succeeded yet could not open file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
	    filelen = 0;
	}
	xfree((void *)filename); /* avoid warning */
    }
    else
    {
	fp = NULL;
	filelen = 0;
	bn_long_set_a_b(&rpacket->u.server_file_reply.timestamp,0,0);
    }

    if (fp)
    {
	if (startoffset<filelen) {
	    std::fseek(fp,startoffset,SEEK_SET);
	} else {
	    eventlog(eventlog_level_warn,__FUNCTION__,"[%d] startoffset is beyond end of file (%u>%u)",conn_get_socket(c),startoffset,filelen);
	    /* Keep the real filesize. Battle.net does it the same way ... */
	    std::fclose(fp);
	    fp = NULL;
	}
    }

    if (need_header)
    {
	/* send the header from the server with the rawname and length. */
	bn_int_set(&rpacket->u.server_file_reply.filelen,filelen);
	bn_int_set(&rpacket->u.server_file_reply.adid,adid);
	bn_int_set(&rpacket->u.server_file_reply.extensiontag,etag);
	/* rpacket->u.server_file_reply.timestamp is set above */
	packet_append_string(rpacket,rawname);
	conn_push_outqueue(c,rpacket);
    }
    packet_del_ref(rpacket);

    /* Now send the data. Since it may be longer than a packet; we use
     * the raw packet class.
     */
    if (!fp)
    {
	eventlog(eventlog_level_warn,__FUNCTION__,"[%d] sending no data for file \"%s\"",conn_get_socket(c),rawname);
	return -1;
    }

    eventlog(eventlog_level_info,__FUNCTION__,"[%d] sending file \"%s\" of length %d",conn_get_socket(c),rawname,filelen);
    for (;;)
    {
	if (!(rpacket = packet_create(packet_class_raw)))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"could not create raw packet");
	    if (std::fclose(fp)<0)
		eventlog(eventlog_level_error,__FUNCTION__,"could not close file \"%s\" after reading (std::fclose: %s)",rawname,std::strerror(errno));
	    return -1;
	}
	if ((nbytes = std::fread(packet_get_raw_data_build(rpacket,0),1,MAX_PACKET_SIZE,fp))<(int)MAX_PACKET_SIZE)
	{
	    if (nbytes>0) /* send out last portion */
	    {
		packet_set_size(rpacket,nbytes);
		conn_push_outqueue(c,rpacket);
	    }
	    packet_del_ref(rpacket);
	    if (std::ferror(fp))
		eventlog(eventlog_level_error,__FUNCTION__,"read failed before EOF on file \"%s\" (std::fread: %s)",rawname,std::strerror(errno));
	    break;
	}
	packet_set_size(rpacket,nbytes);
	conn_push_outqueue(c,rpacket);
	packet_del_ref(rpacket);
    }

    if (std::fclose(fp)<0)
	eventlog(eventlog_level_error,__FUNCTION__,"could not close file \"%s\" after reading (std::fclose: %s)",rawname,std::strerror(errno));
    return 0;
}
コード例 #2
0
ファイル: bnftp.c プロジェクト: Danteoriginal/bnetd
extern int main(int argc, char * argv[])
{
    int                a;
    int                sd;
    struct sockaddr_in saddr;
    t_packet *         packet;
    t_packet *         rpacket;
    t_packet *         fpacket;
    char const *       clienttag=NULL;
    char const *       archtag=NULL;
    char const *       servname=NULL;
    unsigned short     servport=0;
    char const *       hexfile=NULL;
    char               text[MAX_MESSAGE_LEN];
    char const *       reqfile=NULL;
    struct hostent *   host;
    unsigned int       commpos;
    struct termios     in_attr_old;
    struct termios     in_attr_new;
    int                changed_in;
    unsigned int       currsize;
    unsigned int       filelen;
    unsigned int       startoffset;
    int                startoffsetoverride=0;
#define EXIST_ACTION_UNSPEC    -1
#define EXIST_ACTION_ASK        0
#define EXIST_ACTION_OVERWRITE  1
#define EXIST_ACTION_BACKUP     2
#define EXIST_ACTION_RESUME     3 
    int		       exist_action=EXIST_ACTION_UNSPEC;
    struct stat        exist_buf;
    char const *       filename;
    FILE *             fp;
    FILE *             hexstrm=NULL;
    int                fd_stdin;
    t_bnettime         bntime;
    time_t             tm;
    char               timestr[FILE_TIME_MAXLEN];
    unsigned int       screen_width,screen_height;
    int                munged;

    if (argc<1 || !argv || !argv[0])
    {
	fprintf(stderr,"bad arguments\n");
	return STATUS_FAILURE;
    }
    
    for (a=1; a<argc; a++)
	if (servname && isdigit((int)argv[a][0]) && a+1>=argc)
	{
            if (str_to_ushort(argv[a],&servport)<0)
            {
                fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],argv[a]);
                usage(argv[0]);
            }
	}
	else if (!servname && argv[a][0]!='-' && a+2>=argc)
	    servname = argv[a];
        else if (strcmp(argv[a],"-b")==0 || strcmp(argv[a],"--client=SEXP")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_BROODWARS;
        }
        else if (strcmp(argv[a],"-d")==0 || strcmp(argv[a],"--client=DRTL")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_DIABLORTL;
        }
        else if (strcmp(argv[a],"--client=DSHR")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_DIABLOSHR;
        }
        else if (strcmp(argv[a],"-s")==0 || strcmp(argv[a],"--client=STAR")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_STARCRAFT;
        }
        else if (strcmp(argv[a],"--client=SSHR")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_SHAREWARE;
        }
	else if (strcmp(argv[a],"-w")==0 || strcmp(argv[a],"--client=W2BN")==0)
	{
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_WARCIIBNE;
	}
        else if (strcmp(argv[a],"--client=D2DV")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_DIABLO2DV;
        }
        else if (strcmp(argv[a],"--client=D2XP")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_DIABLO2XP;
        }
        else if (strcmp(argv[a],"--client=WAR3")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_WARCRAFT3;
        }
        else if (strncmp(argv[a],"--client=",9)==0)
        {
            fprintf(stderr,"%s: unknown client tag \"%s\"\n",argv[0],&argv[a][9]);
            usage(argv[0]);
        }
	else if (strncmp(argv[a],"--hexdump=",10)==0)
	{
	    if (hexfile)
	    {
		fprintf(stderr,"%s: hexdump file was already specified as \"%s\"\n",argv[0],hexfile);
		usage(argv[0]);
	    }
	    hexfile = &argv[a][10];
	}
        else if (strcmp(argv[a],"--arch=IX86")==0)
        {
            if (archtag)
            {
                fprintf(stderr,"%s: client arch was already specified as \"%s\"\n",argv[0],archtag);
                usage(argv[0]);
            }
            archtag = ARCHTAG_WINX86;
        }
        else if (strcmp(argv[a],"--arch=PMAC")==0)
        {
            if (archtag)
            {
                fprintf(stderr,"%s: client arch was already specified as \"%s\"\n",argv[0],archtag);
                usage(argv[0]);
            }
            archtag = ARCHTAG_MACPPC;
        }
        else if (strcmp(argv[a],"--arch=XMAC")==0)
        {
            if (archtag)
            {
                fprintf(stderr,"%s: client arch was already specified as \"%s\"\n",argv[0],archtag);
                usage(argv[0]);
            }
            archtag = ARCHTAG_OSXPPC;
        }
        else if (strncmp(argv[a],"--arch=",7)==0)
        {
            fprintf(stderr,"%s: unknown arch tag \"%s\"\n",argv[0],&argv[a][9]);
            usage(argv[0]);
        }
	else if (strncmp(argv[a],"--startoffset=",14)==0)
	{
	    if (startoffsetoverride)
	    {
		fprintf(stderr,"%s: startoffset was already specified as %u\n",argv[0],startoffset);
		usage(argv[0]);
	    }
            if (str_to_uint(&argv[a][14],&startoffset)<0)
            {
                fprintf(stderr,"%s: startoffset \"%s\" should be a positive integer\n",argv[0],&argv[a][14]);
                usage(argv[0]);
            }
	    startoffsetoverride = 1;
	}
	else if (strncmp(argv[a],"--exists=",9)==0)
	{
	    if (exist_action!=EXIST_ACTION_UNSPEC)
	    {
		fprintf(stderr,"%s: exists was already specified\n",argv[0]);
		usage(argv[0]);
	    }
	    if (argv[a][9]=='o' || argv[a][9]=='O')
	    	exist_action = EXIST_ACTION_OVERWRITE;
	    else if (argv[a][9]=='a' || argv[a][9]=='A')
	    	exist_action = EXIST_ACTION_ASK;
	    else if (argv[a][9]=='b' || argv[a][9]=='B')
	    	exist_action = EXIST_ACTION_BACKUP;
	    else if (argv[a][9]=='r' || argv[a][9]=='R')
	    	exist_action = EXIST_ACTION_RESUME;
	    else {
		fprintf(stderr,"%s: exists must begin with a,A,o,O,b,B,r or R",argv[0]);
		usage(argv[0]);
	    }
	}
	else if (strncmp(argv[a],"--file=",7)==0)
	{
	    if (reqfile)
	    {
		fprintf(stderr,"%s: file was already specified as \"%s\"\n",argv[0],reqfile);
		usage(argv[0]);
	    }
	    reqfile = &argv[a][7];
	}
	else if (strcmp(argv[a],"-v")==0 || strcmp(argv[a],"--version")==0)
	{
            printf("version "BNETD_VERSION"\n");
            return 0;
	}
	else if (strcmp(argv[a],"-h")==0 || strcmp(argv[a],"--help")==0 || strcmp(argv[a],"--usage")==0)
            usage(argv[0]);
        else if (strcmp(argv[a],"--client")==0 || strcmp(argv[a],"--hexdump")==0)
        {
            fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
            usage(argv[0]);
        }
	else
	{
	    fprintf(stderr,"%s: unknown option \"%s\"\n",argv[0],argv[a]);
	    usage(argv[0]);
	}
    
    if (servport==0)
        servport = BNETD_SERV_PORT;
    if (!clienttag)
        clienttag = CLIENTTAG_STARCRAFT;
    if (!archtag)
        archtag = ARCHTAG_WINX86;
    if (!servname)
	servname = BNETD_DEFAULT_HOST;
    if (exist_action==EXIST_ACTION_UNSPEC)
	exist_action = EXIST_ACTION_ASK;
    
    if (hexfile)
	if (!(hexstrm = fopen(hexfile,"w")))
	    fprintf(stderr,"%s: could not open file \"%s\" for writing the hexdump (fopen: %s)",argv[0],hexfile,strerror(errno));
	else
	    fprintf(hexstrm,"# dump generated by bnftp version "BNETD_VERSION"\n");
    
    if (psock_init()<0)
    {
        fprintf(stderr,"%s: could not inialialize socket functions\n",argv[0]);
        return STATUS_FAILURE;
    }
    
    if (!(host = gethostbyname(servname)))
    {
	fprintf(stderr,"%s: unknown host \"%s\"\n",argv[0],servname);
	return STATUS_FAILURE;
    }
    
    fd_stdin = fileno(stdin);
    if (tcgetattr(fd_stdin,&in_attr_old)>=0)
    {
        in_attr_new = in_attr_old;
        in_attr_new.c_lflag &= ~(ECHO | ICANON); /* turn off ECHO and ICANON */
	in_attr_new.c_cc[VMIN]  = 1; /* require reads to return at least one byte */
        in_attr_new.c_cc[VTIME] = 0; /* no timeout */
        tcsetattr(fd_stdin,TCSANOW,&in_attr_new);
        changed_in = 1;
    }
    else
    {
	fprintf(stderr,"%s: could not get terminal attributes for stdin\n",argv[0]);
	changed_in = 0;
    }
    
    if (client_get_termsize(fd_stdin,&screen_width,&screen_height)<0)
    {
        fprintf(stderr,"%s: could not determine screen size\n",argv[0]);
        if (changed_in)
            tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
        return STATUS_FAILURE;
    }
    
    if ((sd = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP))<0)
    {
	fprintf(stderr,"%s: could not create socket (psock_socket: %s)\n",argv[0],strerror(psock_errno()));
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	return STATUS_FAILURE;
    }
    
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = PSOCK_AF_INET;
    saddr.sin_port   = htons(servport);
    memcpy(&saddr.sin_addr.s_addr,host->h_addr_list[0],host->h_length);
    if (psock_connect(sd,(struct sockaddr *)&saddr,sizeof(saddr))<0)
    {
	fprintf(stderr,"%s: could not connect to server \"%s\" port %hu (psock_connect: %s)\n",argv[0],servname,servport,strerror(psock_errno()));
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	return STATUS_FAILURE;
    }
    
    printf("Connected to %s:%hu.\n",inet_ntoa(saddr.sin_addr),servport);
    
#ifdef CLIENTDEBUG
    eventlog_set(stderr);
#endif
    
    if (!(packet = packet_create(packet_class_init)))
    {
	fprintf(stderr,"%s: could not create packet\n",argv[0]);
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	return STATUS_FAILURE;
    }
    bn_byte_set(&packet->u.client_initconn.class,CLIENT_INITCONN_CLASS_FILE);
    if (hexstrm)
    {
	fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		sd,
		packet_get_class_str(packet),(unsigned int)packet_get_class(packet),
		packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),
		packet_get_size(packet));
	hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));
    }
    client_blocksend_packet(sd,packet);
    packet_del_ref(packet);
    
    if (!(rpacket = packet_create(packet_class_file)))
    {
	fprintf(stderr,"%s: could not create packet\n",argv[0]);
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	return STATUS_FAILURE;
    }
    
    if (!(fpacket = packet_create(packet_class_raw)))
    {
	fprintf(stderr,"%s: could not create packet\n",argv[0]);
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	packet_del_ref(rpacket);
	return STATUS_FAILURE;
    }
    
    if (!reqfile) /* if not specified on the command line then prompt for it */
    {
    	munged = 1;
    	commpos = 0;
    	text[0] = '\0';
	
    	for (;;)
    	{
	    switch (client_get_comm("filename: ",text,sizeof(text),&commpos,1,munged,screen_width))
	    {
	    case -1: /* cancel or error */
	    	printf("\n");
	    	if (changed_in)
		    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	    	packet_del_ref(fpacket);
	    	packet_del_ref(rpacket);
	    	return STATUS_FAILURE;
		
	    case 0: /* timeout */
	    	munged = 0;
	    	continue;
		
	    case 1:
	    	munged = 0;
	    	if (text[0]=='\0')
		    continue;
	    	printf("\n");
	    }
	    break;
    	}
	reqfile = text;
    }
    
    if (stat(reqfile,&exist_buf)==0) /* check if the file exists */
    {
	char text2[MAX_MESSAGE_LEN];
	    
    	munged = 1;
	commpos = 0;
	text2[0] = '\0';
	
  	while (exist_action==EXIST_ACTION_ASK)
	{
	    switch (client_get_comm("File exists [O]verwrite, [B]ackup or [R]esume?: ",text2,sizeof(text2),&commpos,1,munged,screen_width))
	    {
	    case -1: /* cancel or error */
	    	printf("\n");
	    	if (changed_in)
		    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	    	packet_del_ref(fpacket);
	    	packet_del_ref(rpacket);
	    	return STATUS_FAILURE;
		
	    case 0: /* timeout */
	    	munged = 0;
	    	continue;
		
	    case 1:
	    	munged = 0;
	    	if (text2[0]=='\0')
		    continue;
	    	printf("\n");
		break;
	    }
	    
	    switch (text2[0])
	    {
	    case 'o':
	    case 'O':
		exist_action = EXIST_ACTION_OVERWRITE;
		break;
	    case 'b':
	    case 'B':
		exist_action = EXIST_ACTION_BACKUP;
		break;
	    case 'r':
	    case 'R':
		exist_action = EXIST_ACTION_RESUME;
		break;
	    default:
		printf("Please answer with o,O,b,B,r or R.\n");
		munged = 1;
		continue;
	    }
	    break;
	}
	
	switch (exist_action)
	{
	case EXIST_ACTION_OVERWRITE:
	    if (!startoffsetoverride)
	    	startoffset = 0;
	    break;
	case EXIST_ACTION_BACKUP:
	    {
		char *       bakfile;
		unsigned int bnr;
		int          renamed=0;
		
		if (!(bakfile = malloc(strlen(reqfile)+1+2+1))) /* assuming we go up to bnr 99 we need reqfile+'.'+'99'+'\0' */
		{
		    fprintf(stderr,"%s: unable to allocate memory for backup filename.\n",argv[0]);
		    if (changed_in)
			tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
		    packet_del_ref(fpacket);
		    packet_del_ref(rpacket);
		    return STATUS_FAILURE;
		}
		
		for (bnr=0; bnr<100; bnr++)
		{
		    sprintf(bakfile,"%s.%d",reqfile,bnr);
		    if (stat(bakfile,&exist_buf)==0)
			continue; /* backup exists */
		    /* backup does not exist */
		    if (rename(reqfile,bakfile)<0) /* just rename the existing file to the backup */
			fprintf(stderr,"%s: could not create backup file \"%s\" (rename: %s)\n",argv[0],bakfile,strerror(errno));
		    else
		    {
			renamed = 1;
			printf("Renaming \"%s\" to \"%s\".\n",reqfile,bakfile);
		    }
		    break;
		}
		free(bakfile);
		if (!renamed)
		{
		    fprintf(stderr,"%s: could not create backup for \"%s\".\n",argv[0],reqfile);
		    if (changed_in)
			tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
		    packet_del_ref(fpacket);
		    packet_del_ref(rpacket);
		    return STATUS_FAILURE;
		}
	    	if (!startoffsetoverride)
	    	    startoffset = 0;
	    }
	    break;
	case EXIST_ACTION_RESUME:
	    if (!startoffsetoverride)
	    	startoffset = exist_buf.st_size;
	    break;	    	
	}	
    }
    else
	if (!startoffsetoverride)
	    startoffset = 0;
    
    if (changed_in)
	tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
    
    if (!(packet = packet_create(packet_class_file)))
    {
	fprintf(stderr,"%s: could not create packet\n",argv[0]);
	packet_del_ref(fpacket);
	packet_del_ref(rpacket);
	return STATUS_FAILURE;
    }
    packet_set_size(packet,sizeof(t_client_file_req));
    packet_set_type(packet,CLIENT_FILE_REQ);
    bn_int_tag_set(&packet->u.client_file_req.archtag,archtag);
    bn_int_tag_set(&packet->u.client_file_req.clienttag,clienttag);
    bn_int_set(&packet->u.client_file_req.adid,0);
    bn_int_set(&packet->u.client_file_req.extensiontag,0);
    bn_int_set(&packet->u.client_file_req.startoffset,startoffset);
    bn_long_set_a_b(&packet->u.client_file_req.timestamp,0x00000000,0x00000000);
    packet_append_string(packet,reqfile);
    if (hexstrm)
    {
	fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		sd,
		packet_get_class_str(packet),(unsigned int)packet_get_class(packet),
		packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),
		packet_get_size(packet));
	hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));
    }
    printf("\nRequesting info...");
    fflush(stdout);
    client_blocksend_packet(sd,packet);
    packet_del_ref(packet);
    
    do
    {
	if (client_blockrecv_packet(sd,rpacket)<0)
	{
	    fprintf(stderr,"%s: server closed connection\n",argv[0]);
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
	if (hexstrm)
	{
	    fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		     sd,
		     packet_get_class_str(rpacket),(unsigned int)packet_get_class(rpacket),
		     packet_get_type_str(rpacket,packet_dir_from_server),packet_get_type(rpacket),
		     packet_get_size(rpacket));
	    hexdump(hexstrm,packet_get_raw_data(rpacket,0),packet_get_size(rpacket));
	}
    }
    while (packet_get_type(rpacket)!=SERVER_FILE_REPLY);
    
    filelen = bn_int_get(rpacket->u.server_file_reply.filelen);
    bn_long_to_bnettime(rpacket->u.server_file_reply.timestamp,&bntime);
    tm = bnettime_to_time(bntime);
    strftime(timestr,FILE_TIME_MAXLEN,FILE_TIME_FORMAT,localtime(&tm));
    filename = packet_get_str_const(rpacket,sizeof(t_server_file_reply),MAX_FILENAME_STR);
    
    if (exist_action==EXIST_ACTION_RESUME)
    {
	if (!(fp = fopen(reqfile,"ab")))
	{
	    fprintf(stderr,"%s: could not open file \"%s\" for appending (fopen: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
    }
    else
    {
	if (!(fp = fopen(reqfile,"wb")))
	{
	    fprintf(stderr,"%s: could not open file \"%s\" for writing (fopen: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
    }
    
    printf("\n name: \"");
    str_print_term(stdout,filename,0,0);
    printf("\"\n changed: %s\n length: %u bytes\n",timestr,filelen);
    fflush(stdout);
    
    if (startoffset>0) {
	filelen -= startoffset; /* for resuming files */
	printf("Resuming at position %u (%u bytes remaining).\n",startoffset,filelen);
    }
    
    printf("\nSaving to \"%s\"...",reqfile);

    for (currsize=0; currsize+MAX_PACKET_SIZE<=filelen; currsize+=MAX_PACKET_SIZE)
    {
	printf(".");
	fflush(stdout);
	
	if (client_blockrecv_raw_packet(sd,fpacket,MAX_PACKET_SIZE)<0)
	{
	    printf("error\n");
	    fprintf(stderr,"%s: server closed connection\n",argv[0]);
	    if (fclose(fp)<0)
		fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
	if (hexstrm)
	{
	    fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		     sd,
		     packet_get_class_str(fpacket),(unsigned int)packet_get_class(fpacket),
		     packet_get_type_str(fpacket,packet_dir_from_server),packet_get_type(fpacket),
		     packet_get_size(fpacket));
	    hexdump(hexstrm,packet_get_raw_data(fpacket,0),packet_get_size(fpacket));
	}
	if (fwrite(packet_get_raw_data_const(fpacket,0),1,MAX_PACKET_SIZE,fp)<MAX_PACKET_SIZE)
	{
	    printf("error\n");
	    fprintf(stderr,"%s: could not write to file \"%s\" (fwrite: %s)\n",argv[0],reqfile,strerror(errno));
	    if (fclose(fp)<0)
		fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
    }
    filelen -= currsize;
    if (filelen)
    {
	printf(".");
	fflush(stdout);
	
	if (client_blockrecv_raw_packet(sd,fpacket,filelen)<0)
	{
	    printf("error\n");
	    fprintf(stderr,"%s: server closed connection\n",argv[0]);
	    if (fclose(fp)<0)
		fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
	if (hexstrm)
	{
	    fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		     sd,
		     packet_get_class_str(fpacket),(unsigned int)packet_get_class(fpacket),
		     packet_get_type_str(fpacket,packet_dir_from_server),packet_get_type(fpacket),
		     packet_get_size(fpacket));
	    hexdump(hexstrm,packet_get_raw_data(fpacket,0),packet_get_size(fpacket));
	}
	if (fwrite(packet_get_raw_data_const(fpacket,0),1,filelen,fp)<filelen)
	{
	    printf("error\n");
	    fprintf(stderr,"%s: could not write to file \"%s\"\n",argv[0],reqfile);
	    if (fclose(fp)<0)
		fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
    }
    
    packet_del_ref(fpacket);
    packet_del_ref(rpacket);
    
    if (hexstrm)
    {
	fprintf(hexstrm,"# end of dump\n");
	if (fclose(hexstrm)<0)
	    fprintf(stderr,"%s: could not close hexdump file \"%s\" after writing (fclose: %s)",argv[0],hexfile,strerror(errno));
    }
    
    if (fclose(fp)<0)
    {
	fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	return STATUS_FAILURE;
    }
    
    printf("done\n");
    return STATUS_FAILURE;
}
コード例 #3
0
static int _client_anongame_infos(t_connection * c, t_packet const * const packet)
{
    t_packet * rpacket;

    if (bn_int_get(packet->u.client_findanongame_inforeq.count) > 1) {
	/* reply with 0 entries found */
	int	temp = 0;

	if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
	    eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
	    return -1;
	}

	packet_set_size(rpacket, sizeof(t_server_findanongame_inforeply));
	packet_set_type(rpacket, SERVER_FINDANONGAME_INFOREPLY);
	bn_byte_set(&rpacket->u.server_findanongame_inforeply.option, CLIENT_FINDANONGAME_INFOS);
	bn_int_set(&rpacket->u.server_findanongame_inforeply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
	bn_byte_set(&rpacket->u.server_findanongame_inforeply.noitems, 0);
	packet_append_data(rpacket, &temp, 1);

	conn_push_outqueue(c,rpacket);
	packet_del_ref(rpacket);
    } else {
	int i;
	int client_tag;
	int server_tag_count	= 0;
	int client_tag_unk;
	int server_tag_unk;
	bn_int temp;
	char noitems;
	char * tmpdata;
	int tmplen;
	t_clienttag clienttag	= conn_get_clienttag(c);
	char last_packet	= 0x00;
	char other_packet	= 0x01;
	char langstr[5];
	t_gamelang gamelang = conn_get_gamelang(c);
	bn_int_tag_get((bn_int const *)&gamelang, langstr, 5);

	/* Send seperate packet for each item requested
	 * sending all at once overloaded w3xp
	 * [Omega] */
	for (i=0;i<bn_byte_get(packet->u.client_findanongame_inforeq.noitems);i++){
	    noitems = 0;

	    if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
		eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
		return -1;
	    }

	    /* Starting the packet stuff */
	    packet_set_size(rpacket, sizeof(t_server_findanongame_inforeply));
	    packet_set_type(rpacket, SERVER_FINDANONGAME_INFOREPLY);
	    bn_byte_set(&rpacket->u.server_findanongame_inforeply.option, CLIENT_FINDANONGAME_INFOS);
	    bn_int_set(&rpacket->u.server_findanongame_inforeply.count, 1);

	    std::memcpy(&temp,(packet_get_data_const(packet,10+(i*8),4)),sizeof(int));
	    client_tag=bn_int_get(temp);
	    std::memcpy(&temp,packet_get_data_const(packet,14+(i*8),4),sizeof(int));
	    client_tag_unk=bn_int_get(temp);

	    switch (client_tag){
		case CLIENT_FINDANONGAME_INFOTAG_URL:
		    bn_int_set((bn_int*)&server_tag_unk,0xBF1F1047);
		    packet_append_data(rpacket, "LRU\0" , 4);
		    packet_append_data(rpacket, &server_tag_unk , 4);
		    // FIXME: Maybe need do do some checks to avoid prefs empty strings.
			tmpdata = anongame_infos_data_get_url(clienttag, conn_get_versionid(c), &tmplen);
		    packet_append_data(rpacket, tmpdata, tmplen);
		    noitems++;
		    server_tag_count++;
		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s)  tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_URL",client_tag_unk);
		    break;
		case CLIENT_FINDANONGAME_INFOTAG_MAP:
		    bn_int_set((bn_int*)&server_tag_unk,0x70E2E0D5);
		    packet_append_data(rpacket, "PAM\0" , 4);
		    packet_append_data(rpacket, &server_tag_unk , 4);
			tmpdata = anongame_infos_data_get_map(clienttag, conn_get_versionid(c), &tmplen);
		    packet_append_data(rpacket, tmpdata, tmplen);
		    noitems++;
		    server_tag_count++;
		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s)  tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_MAP",client_tag_unk);
		    break;
		case CLIENT_FINDANONGAME_INFOTAG_TYPE:
		    bn_int_set((bn_int*)&server_tag_unk,0x7C87DEEE);
		    packet_append_data(rpacket, "EPYT" , 4);
		    packet_append_data(rpacket, &server_tag_unk , 4);
			tmpdata = anongame_infos_data_get_type(clienttag, conn_get_versionid(c), &tmplen);
		    packet_append_data(rpacket, tmpdata, tmplen);
		    noitems++;
		    server_tag_count++;
		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_TYPE",client_tag_unk);
		    break;
		case CLIENT_FINDANONGAME_INFOTAG_DESC:
		    bn_int_set((bn_int*)&server_tag_unk,0xA4F0A22F);
		    packet_append_data(rpacket, "CSED" , 4);
		    packet_append_data(rpacket,&server_tag_unk,4);
			tmpdata = anongame_infos_data_get_desc(langstr, clienttag, conn_get_versionid(c), &tmplen);
		    packet_append_data(rpacket, tmpdata, tmplen);
		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_DESC",client_tag_unk);
		    noitems++;
		    server_tag_count++;
		    break;
		case CLIENT_FINDANONGAME_INFOTAG_LADR:
		    bn_int_set((bn_int*)&server_tag_unk,0x3BADE25A);
		    packet_append_data(rpacket, "RDAL" , 4);
		    packet_append_data(rpacket, &server_tag_unk , 4);
			tmpdata = anongame_infos_data_get_ladr(langstr, clienttag, conn_get_versionid(c), &tmplen);
		    packet_append_data(rpacket, tmpdata, tmplen);
		    noitems++;
		    server_tag_count++;
		    eventlog(eventlog_level_debug,__FUNCTION__,"client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)",i,"CLIENT_FINDANONGAME_INFOTAG_LADR",client_tag_unk);
		    break;
		default:
		     eventlog(eventlog_level_debug,__FUNCTION__,"unrec client_tag request tagid=(0x%01x) tag=(0x%04x)",i,client_tag);

	    }
	    //Adding a last padding null-byte
	    if (server_tag_count == bn_byte_get(packet->u.client_findanongame_inforeq.noitems))
		packet_append_data(rpacket, &last_packet, 1); /* only last packet in group gets 0x00 */
	    else
		packet_append_data(rpacket, &other_packet, 1); /* the rest get 0x01 */

	    //Go,go,go
	    bn_byte_set(&rpacket->u.server_findanongame_inforeply.noitems, noitems);
	    conn_push_outqueue(c,rpacket);
	    packet_del_ref(rpacket);
	}
    }
    return 0;
}
コード例 #4
0
/* tournament notice disabled at this time, but responce is sent to cleint */
static int _client_anongame_tournament(t_connection * c, t_packet const * const packet)
{
    t_packet * rpacket;

    t_account * account = conn_get_account(c);
    t_clienttag clienttag = conn_get_clienttag(c);

    unsigned int start_prelim	= tournament_get_start_preliminary();
    unsigned int end_signup	= tournament_get_end_signup();
    unsigned int end_prelim	= tournament_get_end_preliminary();
    unsigned int start_r1	= tournament_get_start_round_1();

    if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
	eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
	return -1;
    }

    packet_set_size(rpacket, sizeof(t_server_anongame_tournament_reply));
    packet_set_type(rpacket, SERVER_FINDANONGAME_TOURNAMENT_REPLY);
    bn_byte_set(&rpacket->u.server_anongame_tournament_reply.option, 7);
    bn_int_set(&rpacket->u.server_anongame_tournament_reply.count,
    bn_int_get(packet->u.client_anongame_tournament_request.count));

    if ( !start_prelim || (end_signup <= now && tournament_user_signed_up(account) < 0) ||
	    tournament_check_client(clienttag) < 0) { /* No Tournament Notice */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0);
	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
    }
    else if (start_prelim>=now) { /* Tournament Notice */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		1);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0000); /* random */
	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(start_prelim));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		start_prelim-now);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x00);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
    }
    else if (end_signup>=now) { /* Tournament Signup Notice - Play Game Active */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		2);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0828); /* random */
	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(end_signup));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		end_signup-now);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		tournament_get_stat(account, 1));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		tournament_get_stat(account, 2));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		tournament_get_stat(account, 3));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x08);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
    }
    else if (end_prelim>=now) { /* Tournament Prelim Period - Play Game Active */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		3);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0828); /* random */
	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(end_prelim));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		end_prelim-now);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		tournament_get_stat(account, 1));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		tournament_get_stat(account, 2));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		tournament_get_stat(account, 3));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x08);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
    }
    else if (start_r1>=now && (tournament_get_game_in_progress()) ) { /* Prelim Period Over - Shows user stats (not all prelim games finished) */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		4);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0000); /* random */
	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(start_r1));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		start_r1-now);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0); /* 00 00 */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		tournament_get_stat(account, 1));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		tournament_get_stat(account, 2));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		tournament_get_stat(account, 3));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x08);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
    }
    else if (!(tournament_get_in_finals_status(account))) { /* Prelim Period Over - user did not make finals - Shows user stats */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		5);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0);
	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		tournament_get_stat(account, 1));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		tournament_get_stat(account, 2));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		tournament_get_stat(account, 3));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x04);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
    }
    /* cycle through [type-6] & [type-7] packets
     *
     * use [type-6] to show client "eliminated" or "continue"
     *     timestamp , countdown & round number (of next round) must be set if clinet continues
     *
     * use [type-7] to make cleint wait for 44FF packet option 1 to start game (A guess, not tested)
     *
     * not sure if there is overall winner packet sent at end of last final round
     */

    else if ( (0) ) { /* User in finals - Shows user stats and start of next round*/
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		6);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0x0000);
	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		_tournament_time_convert(start_r1));
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0x01);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		start_r1-now);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0x0000); /* 00 00 */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		4); /* round number */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		0); /* 0 = continue , 1= eliminated */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x04); /* number of rounds in finals */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
    }
    else if ( (0) ) { /* user waiting for match to be made */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.type,		7);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown4,		0);
	bn_int_set(	&rpacket->u.server_anongame_tournament_reply.timestamp,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown5,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.countdown,		0);
	bn_short_set(	&rpacket->u.server_anongame_tournament_reply.unknown2,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.wins,		1); /* round number */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.losses,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.ties,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.unknown3,		0x04); /* number of finals */
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.selection,		2);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.descnum,		0);
	bn_byte_set(	&rpacket->u.server_anongame_tournament_reply.nulltag,		0);
    }

    conn_push_outqueue(c,rpacket);
    packet_del_ref(rpacket);
    return 0;
}
コード例 #5
0
ファイル: capture.c プロジェクト: linuxmaniac/sngrep
int
capture_ws_check_packet(packet_t *packet)
{
    int ws_off = 0;
    u_char ws_fin;
    u_char ws_opcode;
    u_char ws_mask;
    uint8_t ws_len;
    u_char ws_mask_key[4];
    u_char *payload, *newpayload;
    uint32_t size_payload;
    int i;

    /**
     * WSocket header definition according to RFC 6455
     *     0                   1                   2                   3
     *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     *    +-+-+-+-+-------+-+-------------+-------------------------------+
     *    |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     *    |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     *    |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     *    | |1|2|3|       |K|             |                               |
     *    +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     *    |     Extended payload length continued, if payload len == 127  |
     *    + - - - - - - - - - - - - - - - +-------------------------------+
     *    |                               |Masking-key, if MASK set to 1  |
     *    +-------------------------------+-------------------------------+
     *    | Masking-key (continued)       |          Payload Data         |
     *    +-------------------------------- - - - - - - - - - - - - - - - +
     *    :                     Payload Data continued ...                :
     *    + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     *    |                     Payload Data continued ...                |
     *    +---------------------------------------------------------------+
     */

    // Get payload from packet(s)
    size_payload = packet_payloadlen(packet);
    payload = packet_payload(packet);

    // Check we have payload
    if (size_payload == 0)
        return 0;

    // Flags && Opcode
    ws_fin = (*payload & WH_FIN) >> 4;
    ws_opcode = *payload & WH_OPCODE;
    ws_off++;

    // Only interested in Ws text packets
    if (ws_opcode != WS_OPCODE_TEXT)
        return 0;

    // Masked flag && Payload len
    ws_mask = (*(payload + ws_off) & WH_MASK) >> 4;
    ws_len = (*(payload + ws_off) & WH_LEN);
    ws_off++;

    // Skip Payload len
    switch (ws_len) {
            // Extended
        case 126:
            ws_off += 2;
            break;
        case 127:
            ws_off += 8;
            break;
        default:
            return 0;
    }

    // Get Masking key if mask is enabled
    if (ws_mask) {
        memcpy(ws_mask_key, (payload + ws_off), 4);
        ws_off += 4;
    }

    // Skip Websocket headers
    size_payload -= ws_off;
    if ((int32_t) size_payload <= 0)
        return 0;

    newpayload = sng_malloc(size_payload);
    memcpy(newpayload, payload + ws_off, size_payload);
    // If mask is enabled, unmask the payload
    if (ws_mask) {
        for (i = 0; i < size_payload; i++)
            newpayload[i] = newpayload[i] ^ ws_mask_key[i % 4];
    }
    // Set new packet payload into the packet
    packet_set_payload(packet, newpayload, size_payload);
    // Free the new payload
    sng_free(newpayload);

    if (packet->type == PACKET_SIP_TLS) {
        packet_set_type(packet, PACKET_SIP_WSS);
    } else {
        packet_set_type(packet, PACKET_SIP_WS);
    }
    return 1;
}
コード例 #6
0
static int _client_anongame_get_icon(t_connection * c, t_packet const * const packet)
{
    t_packet * rpacket;

    //BlacKDicK 04/20/2003 Need some huge re-work on this.
    {
	struct
	{
	    char	 icon_code[4];
	    unsigned int portrait_code;
	    char	 race;
	    bn_short	 required_wins;
	    char	 client_enabled;
        } tempicon;

	//FIXME: Add those to the prefs and also merge them on accoun_wrap;
	// FIXED BY DJP 07/16/2003 FOR 110 CHANGE ( TOURNEY & RACE WINS ) + Table_witdh
	short icon_req_race_wins;
	short icon_req_tourney_wins;
        int race[]={W3_RACE_RANDOM,W3_RACE_HUMANS,W3_RACE_ORCS,W3_RACE_UNDEAD,W3_RACE_NIGHTELVES,W3_RACE_DEMONS};
        char race_char[6] ={'R','H','O','U','N','D'};
        char icon_pos[5] ={'2','3','4','5','6',};
        char table_width = 6;
        char table_height= 5;
        int i,j;
        char rico;
        unsigned int rlvl,rwins;
	t_clienttag clienttag;
	t_account * acc;

        char user_icon[5];
        char const * uicon;

	clienttag = conn_get_clienttag(c);
	acc = conn_get_account(c);
	/* WAR3 uses a different table size, might change if blizzard add tournament support to RoC */
	if (clienttag==CLIENTTAG_WARCRAFT3_UINT) {
    	    table_width = 5;
	    table_height= 4;
	}

        eventlog(eventlog_level_info,__FUNCTION__,"[%d] got FINDANONGAME Get Icons packet",conn_get_socket(c));

	if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
	    eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
	    return -1;
	}

	packet_set_size(rpacket, sizeof(t_server_findanongame_iconreply));
        packet_set_type(rpacket, SERVER_FINDANONGAME_ICONREPLY);
        bn_int_set(&rpacket->u.server_findanongame_iconreply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
        bn_byte_set(&rpacket->u.server_findanongame_iconreply.option, CLIENT_FINDANONGAME_GET_ICON);
        if ((uicon = account_get_user_icon(acc,clienttag)))
        {
	    std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, uicon,4);
        }
        else
        {
	    account_get_raceicon(acc,&rico,&rlvl,&rwins,clienttag);
	    std::sprintf(user_icon,"%1d%c3W",rlvl,rico);
            std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon,user_icon,4);
        }

	bn_byte_set(&rpacket->u.server_findanongame_iconreply.table_width, table_width);
        bn_byte_set(&rpacket->u.server_findanongame_iconreply.table_size, table_width*table_height);
        for (j=0;j<table_height;j++){
	    icon_req_race_wins = anongame_infos_get_ICON_REQ(j+1,clienttag);
	    for (i=0;i<table_width;i++){
		tempicon.race=i;
	        tempicon.icon_code[0] = icon_pos[j];
	        tempicon.icon_code[1] = race_char[i];
	        tempicon.icon_code[2] = '3';
	        tempicon.icon_code[3] = 'W';
	        tempicon.portrait_code = (account_icon_to_profile_icon(tempicon.icon_code,acc,clienttag));
	        if (i<=4){
	    	    //Building the icon for the races
	    	    bn_short_set(&tempicon.required_wins,icon_req_race_wins);
	    	    if (account_get_racewins(acc,race[i],clienttag)>=icon_req_race_wins) {
			tempicon.client_enabled=1;
	    	    }else{
			tempicon.client_enabled=0;
		    }
	    	}else{
	        //Building the icon for the tourney
		icon_req_tourney_wins = anongame_infos_get_ICON_REQ_TOURNEY(j+1);
	        bn_short_set(&tempicon.required_wins,icon_req_tourney_wins);
	        if (account_get_racewins(acc,race[i],clienttag)>=icon_req_tourney_wins) {
		    tempicon.client_enabled=1;
	        }else{
		    tempicon.client_enabled=0;}
	        }
	        packet_append_data(rpacket, &tempicon, sizeof(tempicon));
	    }
	}
        //Go,go,go
        conn_push_outqueue(c,rpacket);
        packet_del_ref(rpacket);
    }
    return 0;
}
コード例 #7
0
ファイル: handle_d2cs.c プロジェクト: BackupTheBerlios/pvpgn
static int on_d2cs_charloginreq(t_connection * c, t_packet const * packet)
{
	t_connection *	client;
	char const *	charname;
	char const *	portrait;
	char const *	clienttag;
	char *	temp;
	unsigned int	sessionnum;
	t_realm * 	realm;
	char const *	realmname;
	unsigned int	pos, reply;
	t_packet *	rpacket;
	
	if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_charloginreq)) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size");
		return -1;
	}
	sessionnum=bn_int_get(packet->u.d2cs_bnetd_charloginreq.sessionnum);
	pos=sizeof(t_d2cs_bnetd_charloginreq);
	if (!(charname=packet_get_str_const(packet,pos,CHAR_NAME_LEN))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name");
		return -1;
	}
	pos+=strlen(charname)+1;
	if (!(portrait=packet_get_str_const(packet,pos,CHAR_PORTRAIT_LEN))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character portrait");
		return -1;
	}
	if (!(client=connlist_find_connection_by_sessionnum(sessionnum))) {
		eventlog(eventlog_level_error,__FUNCTION__,"user %d not found",sessionnum);
		reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
	} else if (!(clienttag=clienttag_uint_to_str(conn_get_clienttag(client)))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got NULL clienttag");
		reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
	} else if (!(realm=conn_get_realm(client))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got NULL realm");
		reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
	} else {
		char revtag[8];

		realmname = realm_get_name(realm);
		temp=xmalloc(strlen(clienttag)+strlen(realmname)+1+strlen(charname)+1+
			strlen(portrait)+1);
		reply = BNETD_D2CS_CHARLOGINREPLY_SUCCEED;
		strcpy(revtag,clienttag);
		strreverse(revtag);
		sprintf(temp,"%4s%s,%s,%s",revtag,realmname,charname,portrait);
		conn_set_charname(client,charname);
		conn_set_realminfo(client,temp);
		xfree(temp);
		eventlog(eventlog_level_debug,__FUNCTION__,
			"loaded portrait for character %s",charname);
	}
	if ((rpacket=packet_create(packet_class_d2cs_bnetd))) {
		packet_set_size(rpacket,sizeof(t_bnetd_d2cs_charloginreply));
		packet_set_type(rpacket,BNETD_D2CS_CHARLOGINREPLY);
		bn_int_set(&rpacket->u.bnetd_d2cs_charloginreply.h.seqno,
			bn_int_get(packet->u.d2cs_bnetd_charloginreq.h.seqno));
		bn_int_set(&rpacket->u.bnetd_d2cs_charloginreply.reply,reply);
		conn_push_outqueue(c,rpacket);
		packet_del_ref(rpacket);
	}
	return 0;
}
コード例 #8
0
ファイル: capture.c プロジェクト: linuxmaniac/sngrep
void
parse_packet(u_char *info, const struct pcap_pkthdr *header, const u_char *packet)
{
    // Capture info
    capture_info_t *capinfo = (capture_info_t *) info;
    // UDP header data
    struct udphdr *udp;
    // UDP header size
    uint16_t udp_off;
    // TCP header data
    struct tcphdr *tcp;
    // TCP header size
    uint16_t tcp_off;
    // Packet data
    u_char data[MAX_CAPTURE_LEN];
    // Packet payload data
    u_char *payload = NULL;
    // Whole packet size
    uint32_t size_capture = header->caplen;
    // Packet payload size
    uint32_t size_payload =  size_capture - capinfo->link_hl;
    // Captured packet info
    packet_t *pkt;

    // Ignore packets while capture is paused
    if (capture_paused())
        return;

    // Check if we have reached capture limit
    if (capture_cfg.limit && sip_calls_count() >= capture_cfg.limit) {
        // If capture rotation is disabled, just skip this packet
        if (!capture_cfg.rotate) {
            return;
        }
    }

    // Check maximum capture length
    if (header->caplen > MAX_CAPTURE_LEN)
        return;

    // Copy packet payload
    memcpy(data, packet, header->caplen);

    // Check if we have a complete IP packet
    if (!(pkt = capture_packet_reasm_ip(capinfo, header, data, &size_payload, &size_capture)))
        return;

    // Only interested in UDP packets
    if (pkt->proto == IPPROTO_UDP) {
        // Get UDP header
        udp = (struct udphdr *)((u_char *)(data) + (size_capture - size_payload));
        udp_off = sizeof(struct udphdr);

        // Set packet ports
        pkt->src.port = htons(udp->uh_sport);
        pkt->dst.port = htons(udp->uh_dport);

        // Remove UDP Header from payload
        size_payload -= udp_off;

        if ((int32_t)size_payload < 0)
            size_payload = 0;

        // Remove TCP Header from payload
        payload = (u_char *) (udp) + udp_off;

        // Complete packet with Transport information
        packet_set_type(pkt, PACKET_SIP_UDP);
        packet_set_payload(pkt, payload, size_payload);

    } else if (pkt->proto == IPPROTO_TCP) {
        // Get TCP header
        tcp = (struct tcphdr *)((u_char *)(data) + (size_capture - size_payload));
        tcp_off = (tcp->th_off * 4);

        // Set packet ports
        pkt->src.port = htons(tcp->th_sport);
        pkt->dst.port = htons(tcp->th_dport);

        // Get actual payload size
        size_payload -= tcp_off;

        if ((int32_t)size_payload < 0)
            size_payload = 0;

        // Get payload start
        payload = (u_char *)(tcp) + tcp_off;

        // Complete packet with Transport information
        packet_set_type(pkt, PACKET_SIP_TCP);
        packet_set_payload(pkt, payload, size_payload);

        // Create a structure for this captured packet
        if (!(pkt = capture_packet_reasm_tcp(pkt, tcp, payload, size_payload)))
            return;

#if defined(WITH_GNUTLS) || defined(WITH_OPENSSL)
        // Check if packet is TLS
        if (capture_cfg.keyfile) {
            tls_process_segment(pkt, tcp);
        }
#endif

        // Check if packet is WS or WSS
        capture_ws_check_packet(pkt);
    } else {
        // Not handled protocol
        packet_destroy(pkt);
        return;
    }

    // Avoid parsing from multiples sources.
    // Avoid parsing while screen in being redrawn
    capture_lock();
    // Check if we can handle this packet
    if (capture_packet_parse(pkt) == 0) {
#ifdef USE_EEP
        // Send this packet through eep
        capture_eep_send(pkt);
#endif
        // Store this packets in output file
        dump_packet(capture_cfg.pd, pkt);
        // If storage is disabled, delete frames payload
        if (capture_cfg.storage == 0) {
            packet_free_frames(pkt);
        }
        // Allow Interface refresh and user input actions
        capture_unlock();
        return;
    }

    // Not an interesting packet ...
    packet_destroy(pkt);
    // Allow Interface refresh and user input actions
    capture_unlock();
}
コード例 #9
0
ファイル: handle_d2cs.c プロジェクト: BackupTheBerlios/pvpgn
static int on_d2cs_accountloginreq(t_connection * c, t_packet const * packet)
{
	unsigned int	sessionkey;
	unsigned int	sessionnum;
	unsigned int	salt;
	char const *	account;
	char const *	tname;
	t_connection	* client;
	int		reply;
	t_packet	* rpacket;
	struct
	{
		bn_int   salt;
		bn_int   sessionkey;
		bn_int   sessionnum;
		bn_int   secret;
		bn_int	 passhash[5];
	} temp;
	t_hash       secret_hash;
	char const * pass_str;
	t_hash	     passhash;
	t_hash	     try_hash;

	if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_accountloginreq)) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size");
		return -1;
	}
	if (!(account=packet_get_str_const(packet,sizeof(t_d2cs_bnetd_accountloginreq),USER_NAME_MAX))) {
		eventlog(eventlog_level_error,__FUNCTION__,"missing or too long account name");
		return -1;
	}
	sessionkey=bn_int_get(packet->u.d2cs_bnetd_accountloginreq.sessionkey);
	sessionnum=bn_int_get(packet->u.d2cs_bnetd_accountloginreq.sessionnum);
	salt=bn_int_get(packet->u.d2cs_bnetd_accountloginreq.seqno);
	if (!(client=connlist_find_connection_by_sessionnum(sessionnum))) {
		eventlog(eventlog_level_error,__FUNCTION__,"sessionnum %d not found",sessionnum);
		reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
	} else if (sessionkey!=conn_get_sessionkey(client)) {
		eventlog(eventlog_level_error,__FUNCTION__,"sessionkey %d not match",sessionkey);
		reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
	} else if (!(tname=conn_get_username(client))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got NULL username");
		reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
	} else if (strcasecmp(account,tname)) {
		eventlog(eventlog_level_error,__FUNCTION__,"username %s not match",account);
		reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
	} else {
		bn_int_set(&temp.salt,salt);
		bn_int_set(&temp.sessionkey,sessionkey);
		bn_int_set(&temp.sessionnum,sessionnum);
		bn_int_set(&temp.secret,conn_get_secret(client));
		pass_str=account_get_pass(conn_get_account(client));
		if (hash_set_str(&passhash,pass_str)<0) {
			reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
		} else {
			hash_to_bnhash((t_hash const *)&passhash,temp.passhash);
			bnet_hash(&secret_hash,sizeof(temp),&temp);
			bnhash_to_hash(packet->u.d2cs_bnetd_accountloginreq.secret_hash,&try_hash);
			if (hash_eq(try_hash,secret_hash)==1) {
				eventlog(eventlog_level_debug,__FUNCTION__,"user %s loggedin on d2cs",
					account);
				reply=BNETD_D2CS_ACCOUNTLOGINREPLY_SUCCEED;
			} else {
				eventlog(eventlog_level_error,__FUNCTION__,"user %s hash not match",
					account);
				reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
			}
		}
	}
	if ((rpacket=packet_create(packet_class_d2cs_bnetd))) {
		packet_set_size(rpacket,sizeof(t_bnetd_d2cs_accountloginreply));
		packet_set_type(rpacket,BNETD_D2CS_ACCOUNTLOGINREPLY);
		bn_int_set(&rpacket->u.bnetd_d2cs_accountloginreply.h.seqno,
			bn_int_get(packet->u.d2cs_bnetd_accountloginreq.h.seqno));
		bn_int_set(&rpacket->u.bnetd_d2cs_accountloginreply.reply,reply);
		conn_push_outqueue(c,rpacket);
		packet_del_ref(rpacket);
	}
	return 0;
}
コード例 #10
0
ファイル: capture_eep.c プロジェクト: digitainc/sngrep
packet_t *
capture_eep_receive_v3()
{

    struct hep_generic hg;
    hep_chunk_ip4_t src_ip4, dst_ip4;
#ifdef USE_IPV6
    hep_chunk_ip6_t src_ip6, dst_ip6;
#endif
    hep_chunk_t payload_chunk;
    hep_chunk_t authkey_chunk;
    uint8_t family, proto;
    char password[100];
    int password_len;
    unsigned char *payload = 0;
    uint32_t len, pos;
    char buffer[MAX_CAPTURE_LEN] ;
    //! Source and Destination Address
    address_t src, dst;
    //! EEP client data
    struct sockaddr eep_client;
    socklen_t eep_client_len;
    //! Packet header
    struct pcap_pkthdr header;
    //! New created packet pointer
    packet_t *pkt;

    /* Receive EEP generic header */
    if (recvfrom(eep_cfg.server_sock, buffer, MAX_CAPTURE_LEN, 0, &eep_client, &eep_client_len) == -1)
        return NULL;

    /* Copy initial bytes to EEP Generic header */
    memcpy(&hg, buffer, sizeof(struct hep_generic));

    /* header check */
    if (memcmp(hg.header.id, "\x48\x45\x50\x33", 4) != 0)
        return NULL;

    /* IP proto */
    family = hg.ip_family.data;
    /* Proto ID */
    proto = hg.ip_proto.data;

    len = ntohs(hg.header.length) - sizeof(struct hep_generic);
    pos = sizeof(struct hep_generic);

    /* IPv4 */
    if (family == AF_INET) {
        /* SRC IP */
        memcpy(&src_ip4, (void*) buffer + pos, sizeof(struct hep_chunk_ip4));
        inet_ntop(AF_INET, &src_ip4.data, src.ip, sizeof(src.ip));
        pos += sizeof(struct hep_chunk_ip4);

        /* DST IP */
        memcpy(&dst_ip4, (void*) buffer + pos, sizeof(struct hep_chunk_ip4));
        inet_ntop(AF_INET, &dst_ip4.data, dst.ip, sizeof(src.ip));
        pos += sizeof(struct hep_chunk_ip4);
    }
#ifdef USE_IPV6
    /* IPv6 */
    else if(family == AF_INET6) {
        /* SRC IPv6 */
        memcpy(&src_ip6, (void*) buffer + pos, sizeof(struct hep_chunk_ip6));
        inet_ntop(AF_INET6, &src_ip6.data, src.ip, sizeof(src.ip));
        pos += sizeof(struct hep_chunk_ip6);

        /* DST IP */
        memcpy(&src_ip6, (void*) buffer + pos, sizeof(struct hep_chunk_ip6));
        inet_ntop(AF_INET6, &dst_ip6.data, dst.ip, sizeof(dst.ip));
        pos += sizeof(struct hep_chunk_ip6);
    }
#endif

    /* SRC PORT */
    src.port = ntohs(hg.src_port.data);
    /* DST PORT */
    dst.port = ntohs(hg.dst_port.data);
    /* TIMESTAMP*/
    header.ts.tv_sec = ntohl(hg.time_sec.data);
    header.ts.tv_usec = ntohl(hg.time_usec.data);
    /* Protocol TYPE */
    /* Capture ID */

    /* auth key */
    if (eep_cfg.capt_srv_password != NULL) {
        memcpy(&authkey_chunk, (void*) buffer + pos, sizeof(authkey_chunk));
        pos += sizeof(authkey_chunk);

        password_len = ntohs(authkey_chunk.length) - sizeof(authkey_chunk);
        memcpy(password, (void*) buffer + pos, password_len);
        pos += password_len;

        // Validate the password
        if (strncmp(password, eep_cfg.capt_srv_password, password_len) != 0)
            return NULL;
    }

    /* Payload */
    memcpy(&payload_chunk, (void*) buffer + pos, sizeof(payload_chunk));
    pos += sizeof(payload_chunk);

    // Calculate payload size
    header.caplen = header.len = ntohs(payload_chunk.length) - sizeof(payload_chunk);

    // Receive packet payload
    payload = sng_malloc(header.caplen);
    memcpy(payload, (void*) buffer + pos, header.caplen);

    // Create a new packet
    pkt = packet_create((family == AF_INET)?4:6, proto, src, dst, 0);
    packet_add_frame(pkt, &header, payload);
    packet_set_type(pkt, PACKET_SIP_UDP);
    packet_set_payload(pkt, payload, header.caplen);

    /* FREE */
    sng_free(payload);
    return pkt;
}
コード例 #11
0
ファイル: capture_eep.c プロジェクト: digitainc/sngrep
packet_t *
capture_eep_receive_v2()
{
    uint8_t family, proto;
    unsigned char *payload = 0;
    uint32_t pos;
    char buffer[MAX_CAPTURE_LEN] ;
    //! Source Address
    address_t src;
    //! Destination address
    address_t dst;
    //! Packet header
    struct pcap_pkthdr header;
    //! New created packet pointer
    packet_t *pkt;
    //! EEP client data
    struct sockaddr eep_client;
    socklen_t eep_client_len;
    struct hep_hdr hdr;
    struct hep_timehdr hep_time;
    struct hep_iphdr hep_ipheader;
#ifdef USE_IPV6
    struct hep_ip6hdr hep_ip6header;
#endif

    // Initialize buffer
    memset(buffer, 0, MAX_CAPTURE_LEN);

    /* Receive EEP generic header */
    if (recvfrom(eep_cfg.server_sock, buffer, MAX_CAPTURE_LEN, 0, &eep_client, &eep_client_len) == -1)
        return NULL;

    /* Copy initial bytes to HEPv2 header */
    memcpy(&hdr, buffer, sizeof(struct hep_hdr));

    // Check HEP version
    if (hdr.hp_v != 2)
        return NULL;

    /* IP proto */
    family = hdr.hp_f;
    /* Proto ID */
    proto = hdr.hp_p;

    pos = sizeof(struct hep_hdr);

    /* IPv4 */
    if (family == AF_INET) {
        memcpy(&hep_ipheader, (void*) buffer + pos, sizeof(struct hep_iphdr));
        inet_ntop(AF_INET, &hep_ipheader.hp_src, src.ip, sizeof(src.ip));
        inet_ntop(AF_INET, &hep_ipheader.hp_dst, dst.ip, sizeof(dst.ip));
        pos += sizeof(struct hep_iphdr);
    }
#ifdef USE_IPV6
    /* IPv6 */
    else if(family == AF_INET6) {
        memcpy(&hep_ip6header, (void*) buffer + pos, sizeof(struct hep_ip6hdr));
        inet_ntop(AF_INET6, &hep_ip6header.hp6_src, src.ip, sizeof(src.ip));
        inet_ntop(AF_INET6, &hep_ip6header.hp6_dst, dst.ip, sizeof(dst.ip));
        pos += sizeof(struct hep_ip6hdr);
    }
#endif

    /* PORTS */
    src.port = ntohs(hdr.hp_sport);
    dst.port = ntohs(hdr.hp_dport);

    /* TIMESTAMP*/
    memcpy(&hep_time, (void*) buffer + pos, sizeof(struct hep_timehdr));
    pos += sizeof(struct hep_timehdr);
    header.ts.tv_sec = hep_time.tv_sec;
    header.ts.tv_usec = hep_time.tv_usec;

    /* Protocol TYPE */
    /* Capture ID */

    // Calculate payload size (Total size - headers size)
    header.caplen = header.len = ntohs(hdr.hp_l) - pos;

    // Copy packet payload
    payload = sng_malloc(header.caplen + 1);
    memcpy(payload, (void*) buffer + pos, header.caplen);

    // Create a new packet
    pkt = packet_create((family == AF_INET) ? 4 : 6, proto, src, dst, 0);
    packet_add_frame(pkt, &header, payload);
    packet_set_transport_data(pkt, src.port, dst.port);
    packet_set_type(pkt, PACKET_SIP_UDP);
    packet_set_payload(pkt, payload, header.caplen);

    /* FREE */
    sng_free(payload);
    return pkt;

}
コード例 #12
0
ファイル: capture_gnutls.c プロジェクト: jmillan/sngrep
int
tls_process_segment(packet_t *packet, struct tcphdr *tcp)
{
    struct SSLConnection *conn;
    const u_char *payload = packet_payload(packet);
    uint32_t size_payload = packet_payloadlen(packet);
    uint8_t *out;
    uint32_t outl = packet->payload_len;
    out = sng_malloc(outl);
    struct in_addr ip_src, ip_dst;
    uint16_t sport = packet->src.port;
    uint16_t dport = packet->dst.port;

    // Convert addresses
    inet_pton(AF_INET, packet->src.ip, &ip_src);
    inet_pton(AF_INET, packet->dst.ip, &ip_dst);

    // Try to find a session for this ip
    if ((conn = tls_connection_find(ip_src, sport))) {
        // Update last connection direction
        conn->direction = tls_connection_dir(conn, ip_src, sport);

        // Check current connection state
        switch (conn->state) {
            case TCP_STATE_SYN:
                // First SYN received, this package must be SYN/ACK
                if (tcp->th_flags & TH_SYN & ~TH_ACK)
                    conn->state = TCP_STATE_SYN_ACK;
                break;
            case TCP_STATE_SYN_ACK:
                // We expect an ACK packet here
                if (tcp->th_flags & ~TH_SYN & TH_ACK)
                    conn->state = TCP_STATE_ESTABLISHED;
                break;
            case TCP_STATE_ACK:
            case TCP_STATE_ESTABLISHED:
                // Process data segment!
                if (tls_process_record(conn, payload, size_payload, &out, &outl) == 0) {
                    if ((int32_t) outl > 0) {
                        packet_set_payload(packet, out, outl);
                        packet_set_type(packet, PACKET_SIP_TLS);
                        return 0;
                    }
                }
                break;
            case TCP_STATE_FIN:
            case TCP_STATE_CLOSED:
                // We can delete this connection
                tls_connection_destroy(conn);
                break;
        }
    } else {
        if (tcp->th_flags & TH_SYN & ~TH_ACK) {
            // New connection, store it status and leave
            tls_connection_create(ip_src, sport, ip_dst, dport);
        }
    }

    sng_free(out);
    return 0;
}
コード例 #13
0
ファイル: message.c プロジェクト: Danteoriginal/bnetd
static int message_bnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags)
{
    if (!packet)
    {
	eventlog(eventlog_level_error,"message_bnet_format","got NULL packet");
	return -1;
    }
    
    if (text && text[0]=='\0')
        text = " "; /* empty messages crash some clients, just send whitespace */
    
    packet_set_size(packet,sizeof(t_server_message));
    packet_set_type(packet,SERVER_MESSAGE);
    bn_int_set(&packet->u.server_message.unknown1,SERVER_MESSAGE_UNKNOWN1);
    bn_int_nset(&packet->u.server_message.player_ip,SERVER_MESSAGE_PLAYER_IP_DUMMY);
    bn_int_set(&packet->u.server_message.unknown3,SERVER_MESSAGE_UNKNOWN3);
    
    switch (type)
    {
    case message_type_adduser:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
    bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_ADDUSER);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * playerinfo;
    	char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, dst)))
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    if (!(playerinfo = conn_get_playerinfo(me)))
			playerinfo = "";
	    packet_append_string(packet,playerinfo);
	}
	break;
    case message_type_join:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
    bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_JOIN);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * playerinfo;
	    char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, dst)))
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    if (!(playerinfo = conn_get_playerinfo(me)))
			playerinfo = "";
	    packet_append_string(packet,playerinfo); /* FIXME: should we just send "" here instead of playerinfo? */
	}
	break;
    case message_type_part:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
    bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_PART);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, dst)))
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    packet_append_string(packet,"");
	}
	break;
    case message_type_whisper:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
	if (dstflags&MF_X)
	    return -1; /* player is ignored */
    bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_WHISPER);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, dst)))
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    packet_append_string(packet,text);
	}
	break;
    case message_type_talk:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
	if (dstflags&MF_X)
	    return -1; /* player is ignored */
 	bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_TALK);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, me))) /* FIXME: second should be dst but cache gets in the way */
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    packet_append_string(packet,text);
	}
	break;
    case message_type_broadcast:
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
	if (dstflags&MF_X)
	    return -1; /* player is ignored */
    bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_BROADCAST);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, dst)))
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    packet_append_string(packet,text);
	}
	break;
    case message_type_channel:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
        bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNEL);
	{
	    t_channel const * channel;
	    
	    if (!(channel = conn_get_channel(me)))
		bn_int_set(&packet->u.server_message.flags,0);
	    else
		bn_int_set(&packet->u.server_message.flags,cflags_to_bncflags(channel_get_flags(channel)));
	}
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * tname;
	    
	    if(!(tname = conn_get_chatname(me)))
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatname(me,tname);
	    packet_append_string(packet,text);
	}
	break;
    case message_type_userflags:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
        bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_USERFLAGS);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * playerinfo;
	    char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, dst)))
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    if (!(playerinfo = conn_get_playerinfo(me)))
			playerinfo = "";
#if 0 /* FIXME: which is correct? does it depend on the client type? */
	    packet_append_string(packet,"");
#else
	    packet_append_string(packet,playerinfo);
#endif
	}
	break;
    case message_type_whisperack:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
    bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_WHISPERACK);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, dst)))
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    packet_append_string(packet,text);
	}
	break;
    case message_type_channelfull: /* FIXME */
        bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELFULL);
	bn_int_set(&packet->u.server_message.flags,0);
	bn_int_set(&packet->u.server_message.latency,0);
	packet_append_string(packet,"");
	packet_append_string(packet,"");
	break;
    case message_type_channeldoesnotexist:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
        bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELDOESNOTEXIST);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * tname;
	    
	    tname = conn_get_chatname(me);
	    packet_append_string(packet,tname);
	    conn_unget_chatname(me,tname);
	    packet_append_string(packet,text);
	}
	break;
    case message_type_channelrestricted: /* FIXME */
        bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELRESTRICTED);
	bn_int_set(&packet->u.server_message.flags,0);
	bn_int_set(&packet->u.server_message.latency,0);
	packet_append_string(packet,"");
	packet_append_string(packet,"");
	break;
    case message_type_info:
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
        bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_INFO);
	bn_int_set(&packet->u.server_message.flags,0);
	bn_int_set(&packet->u.server_message.latency,0);
	packet_append_string(packet,"");
	packet_append_string(packet,text);
	break;
    case message_type_error:
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
    bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_ERROR);
	bn_int_set(&packet->u.server_message.flags,0);
	bn_int_set(&packet->u.server_message.latency,0);
	packet_append_string(packet,"");
	packet_append_string(packet,text);
	break;
    case message_type_emote:
	if (!me)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type));
	    return -1;
	}
	if (!text)
	{
	    eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type));
	    return -1;
	}
	if (dstflags&MF_X)
	    return -1; /* player is ignored */
    bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_EMOTE);
	bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
	bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
	{
	    char const * tname;
	    
	    if(!(tname = conn_get_chatcharname(me, me))) /* FIXME: second should be dst but cache gets in the way */
	    	return -1;
	    packet_append_string(packet,tname);
	    conn_unget_chatcharname(me,tname);
	    packet_append_string(packet,text);
	}
	break;
    default:
	eventlog(eventlog_level_error,"message_bnet_format","got bad message type %d",(int)type);
	return -1;
    }
    
    return 0;
}