Example #1
0
rt_data_t* dr_load_routing_info( db_func_t *dr_dbf, db1_con_t* db_hdl,
							str *drd_table, str *drl_table, str* drr_table )
{
	int    int_vals[4];
	char * str_vals[5];
	str tmp;
	db_key_t columns[7];
	db1_res_t* res;
	db_row_t* row;
	rt_info_t *ri;
	rt_data_t *rdata;
	tmrec_t   *time_rec;
	unsigned int id;
	str s_id;
	int i,n;

	res = 0;
	ri = 0;
	rdata = 0;

	/* init new data structure */
	if ( (rdata=build_rt_data())==0 ) {
		LM_ERR("failed to build rdata\n");
		goto error;
	}

	/* read the destinations */
	if (dr_dbf->use_table( db_hdl, drd_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drd_table->len,drd_table->s);
		goto error;
	}

	columns[0] = &dst_id_drd_col;
	columns[1] = &address_drd_col;
	columns[2] = &strip_drd_col;
	columns[3] = &prefix_drd_col;
	columns[4] = &type_drd_col;
	columns[5] = &attrs_drd_col;

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 6, 0, 0 ) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 6, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_WARN("table \"%.*s\" empty\n", drd_table->len,drd_table->s );
	}
	LM_DBG("%d records found in %.*s\n",
		RES_ROW_N(res), drd_table->len,drd_table->s);
	n = 0;
	do {
		for(i=0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;
			/* DST_ID column */
			check_val( ROW_VALUES(row), DB1_INT, 1, 0);
			int_vals[0] = VAL_INT   (ROW_VALUES(row));
			/* ADDRESS column */
			check_val( ROW_VALUES(row)+1, DB1_STRING, 1, 1);
			str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1);
			/* STRIP column */
			check_val( ROW_VALUES(row)+2, DB1_INT, 1, 0);
			int_vals[1] = VAL_INT   (ROW_VALUES(row)+2);
			/* PREFIX column */
			check_val( ROW_VALUES(row)+3, DB1_STRING, 0, 0);
			str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+3);
			/* TYPE column */
			check_val( ROW_VALUES(row)+4, DB1_INT, 1, 0);
			int_vals[2] = VAL_INT(ROW_VALUES(row)+4);
			/* ATTRS column */
			check_val( ROW_VALUES(row)+5, DB1_STRING, 0, 0);
			str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+5);

			/* add the destinaton definition in */
			if ( add_dst( rdata, int_vals[0], str_vals[0], int_vals[1],
					str_vals[1], int_vals[2], str_vals[2])<0 ) {
				LM_ERR("failed to add destination id %d -> skipping\n",
					int_vals[0]);
				continue;
			}
			n++;
		}
		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) {
				LM_ERR( "fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	if (n==0) {
		LM_WARN("no valid "
			"destinations set -> ignoring the routing rules\n");
		return rdata;
	}

	/* read the gw lists, if any */
	if (dr_dbf->use_table( db_hdl, drl_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drl_table->len,drl_table->s);
		goto error;
	}

	columns[0] = &id_drl_col;
	columns[1] = &gwlist_drl_col;

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 2, 0, 0 ) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 2, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("table \"%.*s\" empty\n", drl_table->len,drl_table->s );
	} else {
		LM_DBG("%d records found in %.*s\n",
			RES_ROW_N(res), drl_table->len,drl_table->s);
		do {
			for(i=0; i < RES_ROW_N(res); i++) {
				row = RES_ROWS(res) + i;
				/* ID column */
				check_val( ROW_VALUES(row), DB1_INT, 1, 0);
				int_vals[0] = VAL_INT   (ROW_VALUES(row));
				/* GWLIST column */
				check_val( ROW_VALUES(row)+1, DB1_STRING, 1, 1);
				str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1);

				if (add_tmp_gw_list(int_vals[0], str_vals[0])!=0) {
					LM_ERR("failed to add temporary GW list\n");
					goto error;
				}
			}
			if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
				if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) {
					LM_ERR( "fetching rows (1)\n");
					goto error;
				}
			} else {
				break;
			}
		} while(RES_ROW_N(res)>0);
	}
	dr_dbf->free_result(db_hdl, res);
	res = 0;

	/* read the routing rules */
	if (dr_dbf->use_table( db_hdl, drr_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drr_table->len, drr_table->s);
		goto error;
	}

	columns[0] = &rule_id_drr_col;
	columns[1] = &group_drr_col;
	columns[2] = &prefix_drr_col;
	columns[3] = &time_drr_col;
	columns[4] = &priority_drr_col;
	columns[5] = &routeid_drr_col;
	columns[6] = &dstlist_drr_col;

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 7, 0, 0) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 7, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_WARN("table \"%.*s\" is empty\n", drr_table->len, drr_table->s);
	}

	LM_DBG("%d records found in %.*s\n", RES_ROW_N(res),
		drr_table->len, drr_table->s);

	n = 0;
	do {
		for(i=0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;
			/* RULE_ID column */
			check_val( ROW_VALUES(row), DB1_INT, 1, 0);
			int_vals[0] = VAL_INT (ROW_VALUES(row));
			/* GROUP column */
			check_val( ROW_VALUES(row)+1, DB1_STRING, 1, 1);
			str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1);
			/* PREFIX column - it may be null or empty */
			check_val( ROW_VALUES(row)+2, DB1_STRING, 0, 0);
			if ((ROW_VALUES(row)+2)->nul || VAL_STRING(ROW_VALUES(row)+2)==0){
				tmp.s = NULL;
				tmp.len = 0;
			} else {
				str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+2);
				tmp.s = str_vals[1];
				tmp.len = strlen(str_vals[1]);
			}
			/* TIME column */
			check_val( ROW_VALUES(row)+3, DB1_STRING, 1, 1);
			str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+3);
			/* PRIORITY column */
			check_val( ROW_VALUES(row)+4, DB1_INT, 1, 0);
			int_vals[2] = VAL_INT   (ROW_VALUES(row)+4);
			/* ROUTE_ID column */
			check_val( ROW_VALUES(row)+5, DB1_STRING, 1, 0);
			str_vals[3] = (char*)VAL_STRING(ROW_VALUES(row)+5);
			/* DSTLIST column */
			check_val( ROW_VALUES(row)+6, DB1_STRING, 1, 1);
			str_vals[4] = (char*)VAL_STRING(ROW_VALUES(row)+6);
			/* parse the time definition */
			if ((time_rec=parse_time_def(str_vals[2]))==0) {
				LM_ERR("bad time definition <%s> for rule id %d -> skipping\n",
					str_vals[2], int_vals[0]);
				continue;
			}
			/* lookup for the script route ID */
			if (str_vals[3][0] && str_vals[3][0]!='0') {
				int_vals[3] =  route_lookup(&main_rt, str_vals[3]);
				if (int_vals[3]==-1) {
					LM_WARN("route <%s> does not exist\n",str_vals[3]);
					int_vals[3] = 0;
				}
			} else {
				int_vals[3] = 0;
			}
			/* is gw_list a list or a list id? */
			if (str_vals[4][0]=='#') {
				s_id.s = str_vals[4]+1;
				s_id.len = strlen(s_id.s);
				if ( str2int( &s_id, &id)!=0 ||
				(str_vals[4]=get_tmp_gw_list(id))==NULL ) {
					LM_ERR("invalid reference to a GW list <%s> -> skipping\n",
						str_vals[4]);
					continue;
				}
			}
			/* build the routing rule */
			if ((ri = build_rt_info( int_vals[2], time_rec, int_vals[3],
					str_vals[4], rdata->pgw_l))== 0 ) {
				LM_ERR("failed to add routing info for rule id %d -> "
					"skipping\n", int_vals[0]);
				tmrec_free( time_rec );
				continue;
			}
			/* add the rule */
			if (add_rule( rdata, str_vals[0], &tmp, ri)!=0) {
				LM_ERR("failed to add rule id %d -> skipping\n", int_vals[0]);
				free_rt_info( ri );
				continue;
			}
			n++;
		}
		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) {
				LM_ERR( "fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	free_tmp_gw_list();

	if (n==0) {
		LM_WARN("no valid routing rules -> discarding all destinations\n");
		free_rt_data( rdata, 0 );
	}

	return rdata;
error:
	if (res)
		dr_dbf->free_result(db_hdl, res);
	if (rdata)
		free_rt_data( rdata, 1 );
	rdata = NULL;
	return 0;
}
Example #2
0
query_status_t deal_with_fl_packet(struct qserver *server, char *rawpkt, int pktlen)
{
	struct fl_status* status = (struct fl_status*)server->master_query_tag;
	char* pkt = rawpkt;
	char buf[16];
	char* str;
	unsigned cnt;
	unsigned short tmp_short;

	if(server->server_name == NULL)
	{
		server->ping_total += time_delta( &packet_recv_time, &server->packet_time1);
		server->n_requests++;
	}

	if(pktlen < 5) goto out_too_short;

	if( 0 == memcmp(pkt, "\xFF\xFF\xFF\xFE", 4) )
	{
		// fragmented packet
		unsigned char pkt_index, pkt_max;
		unsigned int pkt_id;
		SavedData *sdata;

		if(pktlen < 9) goto out_too_short;

		// format:
		// int Header
		// int RequestId
		// byte PacketNumber
		// byte NumPackets
		// Short SizeOfPacketSplits

		// Header
		pkt += 4;

		// RequestId
		pkt_id = ntohl( *(long *)pkt );
		debug( 3, "RequestID: %d", pkt_id );
		pkt += 4;

		// The next two bytes are:
		// 1. the max packets sent ( byte )
		// 2. the index of this packet starting from 0 ( byte )
		// 3. Size of the split ( short )
		if(pktlen < 10) goto out_too_short;

		// PacketNumber
		pkt_index = ((unsigned char)*pkt);

		// NumPackates
		pkt_max = ((unsigned char)*(pkt+1));

		// SizeOfPacketSplits
		debug( 3, "packetid[2]: 0x%hhx => idx: %hhu, max: %hhu", *pkt, pkt_index, pkt_max );
		pkt+=4;
		pktlen -= 12;

		// pkt_max is the total number of packets expected
		// pkt_index is a bit mask of the packets received.
		if ( server->saved_data.data == NULL )
		{
			sdata = &server->saved_data;
		}
		else
		{
			sdata = (SavedData*) calloc( 1, sizeof(SavedData));
			sdata->next = server->saved_data.next;
			server->saved_data.next = sdata;
		}

		sdata->pkt_index = pkt_index;
		sdata->pkt_max = pkt_max;
		sdata->pkt_id = pkt_id;
		sdata->datalen = pktlen;
		sdata->data= (char*)malloc( pktlen );
		if ( NULL == sdata->data )
		{
			malformed_packet(server, "Out of memory");
			return MEM_ERROR;
		}

		memcpy( sdata->data, pkt, sdata->datalen );

		// combine_packets will call us recursively
		return combine_packets( server );
	}
	else if ( 0 != memcmp(pkt, "\xFF\xFF\xFF\xFF", 4) )
	{
		malformed_packet(server, "invalid packet header");
		return PKT_ERROR;
	}

	pkt += 4;
	pktlen -= 4;

	pktlen -= 1;
	debug( 2, "FL type = 0x%x", *pkt );
	switch(*pkt++)
	{
	case FL_CHALLENGERESPONSE:
		if(pktlen < 4) goto out_too_short;
		memcpy(&status->challenge, pkt, 4);
		// do not count challenge as retry
		if(!status->have_challenge && server->retry1 != n_retries)
		{
			++server->retry1;
			if(server->n_retries)
			{
				--server->n_retries;
			}
		}
		status->have_challenge = 1;
		debug(3, "challenge %x", status->challenge);
		break;

	case FL_INFORESPONSE:
		if(pktlen < 1) goto out_too_short;
		status->type = *pkt;
		if ( *pkt > 1 && ( get_server_rules || get_player_info ) )
		{
			 server->next_rule = ""; // trigger calling send_fl_rule_request_packet
		}
		snprintf(buf, sizeof(buf), "%hhX", *pkt);
		add_rule(server, "protocol", buf, 0);
		pktlen--;
		pkt++;

		// ServerName
		str = memchr(pkt, '\0', pktlen);
		if(!str) goto out_too_short;
		server->server_name = strdup(pkt);
		pktlen -= str-pkt+1;
		pkt += str-pkt+1;

		// MapName
		str = memchr(pkt, '\0', pktlen);
		if(!str) goto out_too_short;
		server->map_name = strdup(pkt);
		pktlen -= str-pkt+1;
		pkt += str-pkt+1;

		// ModName
		str = memchr(pkt, '\0', pktlen);
		if(!str) goto out_too_short;
		server->game = strdup(pkt);
		add_rule(server, "modname", pkt, 0);
		pktlen -= str-pkt+1;
		pkt += str-pkt+1;

		// GameMode
		str = memchr(pkt, '\0', pktlen);
		if(!str) goto out_too_short;
		add_rule(server, "gamemode", pkt, 0);
		pktlen -= str-pkt+1;
		pkt += str-pkt+1;

		// GameDescription
		str = memchr(pkt, '\0', pktlen);
		if(!str) goto out_too_short;
		add_rule(server, "gamedescription", pkt, 0);
		pktlen -= str-pkt+1;
		pkt += str-pkt+1;

		// GameVersion
		str = memchr(pkt, '\0', pktlen);
		if(!str) goto out_too_short;
		add_rule(server, "gameversion", pkt, 0);
		pktlen -= str-pkt+1;
		pkt += str-pkt+1;

		if( pktlen < 13 )
		{
			goto out_too_short;
		}

		// GamePort
		tmp_short = ((unsigned short)pkt[0] <<8 ) | ((unsigned short)pkt[1]);
		change_server_port( server, tmp_short, 0 );
		pkt += 2;

		// Num Players
		server->num_players = (unsigned char)*pkt++;

		// Max Players
		server->max_players = (unsigned char)*pkt++;

		// Dedicated
		add_rule(server, "dedicated", ( 'd' == *pkt++) ? "1" : "0", 0);

		// OS
		switch( *pkt )
		{
		case 'l':
			add_rule(server, "sv_os", "linux", 0);
			break;

		case 'w':
			add_rule(server, "sv_os", "windows", 0);
			break;

		default:
			buf[0] = *pkt;
			buf[1] = '\0';
			add_rule(server, "sv_os", buf, 0);
			break;
		}
		pkt++;

		// Passworded
		add_rule(server, "passworded", ( *pkt++ ) ? "1" : "0" , 0);

		// Anticheat
		add_rule(server, "passworded", ( *pkt++ ) ? "1" : "0" , 0);

		// FrameTime
		sprintf( buf, "%hhu", *pkt++ );
		add_rule(server, "frametime", buf , 0);

		// Round
		sprintf( buf, "%hhu", *pkt++ );
		add_rule(server, "round", buf , 0);

		// RoundMax
		sprintf( buf, "%hhu", *pkt++ );
		add_rule(server, "roundmax", buf , 0);

		// RoundSeconds
		tmp_short = ((unsigned short)pkt[0] <<8 ) | ((unsigned short)pkt[1]);
		sprintf( buf, "%hu", tmp_short );
		add_rule(server, "roundseconds", buf , 0);
		pkt += 2;

		status->have_info = 1;

		server->retry1 = n_retries;

		server->next_player_info = server->num_players;

		break;

	case FL_RULESRESPONSE:
		if(pktlen < 2) goto out_too_short;

		cnt = ((unsigned char)pkt[0] << 8 ) + ((unsigned char)pkt[1]);
		pktlen -= 2;
		pkt += 2;

		debug(3, "num_rules: %d", cnt);

		for(;cnt && pktlen > 0; --cnt)
		{
			char* key, *value;
			str = memchr(pkt, '\0', pktlen);
			if(!str) break;
			key = pkt;
			pktlen -= str-pkt+1;
			pkt += str-pkt+1;

			str = memchr(pkt, '\0', pktlen);
			if(!str) break;
			value = pkt;
			pktlen -= str-pkt+1;
			pkt += str-pkt+1;

			add_rule(server, key, value, NO_FLAGS);
		}

		if(cnt)
		{
			malformed_packet(server, "packet contains too few rules, missing %d", cnt);
			server->missing_rules = 1;
		}
		if(pktlen)
		malformed_packet(server, "garbage at end of rules, %d bytes left", pktlen);

		status->have_rules = 1;

		server->retry1 = n_retries;

		break;

	case FL_PLAYERRESPONSE:

		if(pktlen < 1) goto out_too_short;

		cnt = (unsigned char)pkt[0];
		pktlen -= 1;
		pkt += 1;

		debug(3, "num_players: %d", cnt);

		for(;cnt && pktlen > 0; --cnt)
		{
			unsigned idx;
			const char* name;
			struct player* p;

			// Index
			idx = *pkt++;
			--pktlen;

			// PlayerName
			str = memchr(pkt, '\0', pktlen);
			if(!str) break;
			name = pkt;
			pktlen -= str-pkt+1;
			pkt += str-pkt+1;

			if(pktlen < 8) goto out_too_short;

			debug(3, "player index %d", idx);
			p = add_player(server, server->n_player_info);
			if(p)
			{
				union
				{
					int i;
					float fl;
				} temp;

				p->name = strdup(name);

				// Score
				p->frags = ntohl( *(unsigned int *)pkt );

				// TimeConnected
				temp.i = ntohl( *(unsigned int *)(pkt+4) );
				p->connect_time = temp.fl;

				// Ping
				p->ping = 0;
				p->ping = ntohs( *(unsigned int *)(pkt+8) );
				//((unsigned char*)&p->ping)[0] = pkt[9];
				//((unsigned char*)&p->ping)[1] = pkt[8];

				// ProfileId
				//p->profileid = ntohl( *(unsigned int *)pkt+10 );

				// Team
				p->team = *(pkt+14);
//fprintf( stderr, "Player: '%s', Frags: %u, Time: %u, Ping: %hu, Team: %d\n", p->name, p->frags,  p->connect_time, p->ping, p->team );
			}
			pktlen -= 15;
			pkt += 15;
		}

#if 0 // seems to be a rather normal condition
		if(cnt)
		{
			malformed_packet(server, "packet contains too few players, missing %d", cnt);
		}
#endif
		if(pktlen)
		malformed_packet(server, "garbage at end of player info, %d bytes left", pktlen);

		status->have_player = 1;

		server->retry1 = n_retries;

		break;

	default:
		malformed_packet(server, "invalid packet id %hhx", *--pkt);
		return PKT_ERROR;
	}

	if(
		(!get_player_info || (get_player_info && status->have_player)) &&
		(!get_server_rules || (get_server_rules && status->have_rules))
	)
	{
		server->next_rule = NULL;
	}

	return DONE_AUTO;

out_too_short:
	malformed_packet(server, "packet too short");

	return PKT_ERROR;
}
Example #3
0
void fuzzy_system::add_rule(fuzzy_set& antecedent, fuzzy_set& consequent)
{
    add_rule(make_unique<fuzzy_set_wrapper>(antecedent),
             make_unique<fuzzy_set_wrapper>(consequent));
}
Example #4
0
int
unpack_msgpack(struct qserver *server, unsigned char *s, unsigned char *l)
{
	uint16_t elements;
	unsigned char type, type_len;
	char *var, *str_val;
	uint8_t uint8_val;

	type_len = *s;
	s++;
	debug(3, "type/len: 0x%02hhx\n", type_len);
	if (0x80 == (type_len & 0x80)) {
		type = (type_len & 0x80);
		elements = (type_len & 0x0f);
		debug(3, "map type: 0x%02hhx, elements: %d\n", type, elements);

	} else if (type_len == 0xde) {
		// map 16
		if (!unpack_msgpack_uint16(server, &elements, &s, l, 1))
			return 0;
	} else {
		// There is a map 32 but we don't support it
		malformed_packet(server, "invalid map type 0x%02hhx", type_len);
		return 0;
	}

	while(elements) {
		type = *s;
		if (!unpack_msgpack_string(server, &var, &s, l))
			return 0;

		debug(4, "Map[%s]\n", var);

		if (0 == strcmp(var, "SN")) {
			// Server Name
			if (!unpack_msgpack_string(server, &str_val, &s, l))
				return 0;
			server->server_name = str_val;

		} else if (0 == strcmp(var, "MAP")) {
			// Map
			if (!unpack_msgpack_string(server, &str_val, &s, l))
				return 0;
			server->map_name = str_val;

		} else if (0 == strcmp(var, "MP")) {
			// Max Players
			if (!unpack_msgpack_pos_fixnum(server, &uint8_val, &s, l, 0))
				return 0;
			server->max_players = uint8_val;

		} else if (0 == strcmp(var, "NP")) {
			// Number of Players
			if (!unpack_msgpack_pos_fixnum(server, &uint8_val, &s, l, 0))
				return 0;
			server->num_players = uint8_val;

		} else if (0 == strcmp(var, "RL")) {
			// Gametype
			if (!unpack_msgpack_string(server, &str_val, &s, l))
				return 0;

			server->game = str_val;
			add_rule(server, "gametype", str_val, NO_FLAGS);

		} else if (0 == strcmp(var, "SFT")) {
			// Current Frametime in ms
			if (!unpack_msgpack_pos_fixnum(server, &uint8_val, &s, l, 0))
				return 0;

		} else {
			debug(4, "Unknown setting '%s'\n", var);
			s++;
		}

		free(var);
		elements--;
	}

	return 1;
}
Example #5
0
query_status_t deal_with_ts2_packet( struct qserver *server, char *rawpkt, int pktlen )
{
	char *s, *end;
	int ping, connect_time, mode = 0;
	char name[256];
	debug( 2, "processing..." );

	server->n_servers++;
	server->n_requests++;
	server->ping_total += time_delta( &packet_recv_time, &server->packet_time1 );

	if ( 0 == pktlen )
	{
		// Invalid password
		return REQ_ERROR;
	}

	rawpkt[pktlen]= '\0';
	end = &rawpkt[pktlen];

	s = rawpkt;
	s = strtok( rawpkt, "\015\012" );

	while ( NULL != s )
	{
		if ( 0 == mode )
		{
			// Rules
			char *key = s;
			char *value = strchr( key, '=' );
			if ( NULL != value )
			{
				// Server Rule
				*value = '\0';
				value++;
				if ( 0 == strcmp( "server_name", key ) )
				{
					server->server_name = strdup( value );
				}
				else if ( 0 == strcmp( "server_udpport", key ) )
				{
					change_server_port( server, atoi( value ), 0 );
					add_rule( server, key, value, NO_FLAGS );
				}
				else if ( 0 == strcmp( "server_maxusers", key ) )
				{
					server->max_players = atoi( value );
				}
				else if ( 0 == strcmp( "server_currentusers", key ) )
				{
					server->num_players = atoi( value);
				}
				else
				{
					add_rule( server, key, value, NO_FLAGS);
				}
			}
			else if ( 0 == strcmp( "OK", s ) )
			{
				// end of rules request
				server->saved_data.pkt_index--;
				mode++;
			}
			else if ( 0 == strcmp( "[TS]", s ) )
			{
				// nothing to do
			}
			else if ( 0 == strcmp( "ERROR, invalid id", s ) )
			{
				// bad server
				server->server_name = DOWN;
				server->saved_data.pkt_index = 0;
			}
		}
		else if ( 1 == mode )
		{
			// Player info
			if ( 3 == sscanf( s, "%*d %*d %*d %*d %*d %*d %*d %d %d %*d %*d %*d %*d \"0.0.0.0\" \"%255[^\"]", &ping, &connect_time, name ) )
			{
				// Player info
				struct player *player = add_player( server, server->n_player_info );
				if ( NULL != player )
				{
					player->name = strdup( name );
					player->ping = ping;
					player->connect_time = connect_time;
				}
			}
			else if ( 0 == strcmp( "OK", s ) )
			{
				// end of rules request
				server->saved_data.pkt_index--;
				mode++;
			}
			else if ( 0 == strcmp( "[TS]", s ) )
			{
				// nothing to do
			}
			else if ( 0 == strcmp( "ERROR, invalid id", s ) )
			{
				// bad server
				server->server_name = DOWN;
				server->saved_data.pkt_index = 0;
			}
		}
		s = strtok( NULL, "\015\012" );
	}

	gettimeofday( &server->packet_time1, NULL );

	if ( 0 == server->saved_data.pkt_index )
	{
		server->map_name = strdup( "N/A" );
		return DONE_FORCE;
	}

	return INPROGRESS;
}
Example #6
0
int
init_acl(const char *path)
{
    // initialize ipset
    ipset_init_library();

    ipset_init(&white_list_ipv4);
    ipset_init(&white_list_ipv6);
    ipset_init(&black_list_ipv4);
    ipset_init(&black_list_ipv6);

    cork_dllist_init(&black_list_rules);
    cork_dllist_init(&white_list_rules);

    struct ip_set *list_ipv4  = &black_list_ipv4;
    struct ip_set *list_ipv6  = &black_list_ipv6;
    struct cork_dllist *rules = &black_list_rules;

    FILE *f = fopen(path, "r");
    if (f == NULL) {
        LOGE("Invalid acl path.");
        return -1;
    }

    char buf[257];
    while (!feof(f))
        if (fgets(buf, 256, f)) {
            // Trim the newline
            int len = strlen(buf);
            if (len > 0 && buf[len - 1] == '\n') {
                buf[len - 1] = '\0';
            }

            char *line = trimwhitespace(buf);

            // Skip comments
            if (line[0] == '#') {
                continue;
            }

            if (strlen(line) == 0) {
                continue;
            }

            if (strcmp(line, "[black_list]") == 0
                || strcmp(line, "[bypass_list]") == 0) {
                list_ipv4 = &black_list_ipv4;
                list_ipv6 = &black_list_ipv6;
                rules     = &black_list_rules;
                continue;
            } else if (strcmp(line, "[white_list]") == 0
                       || strcmp(line, "[proxy_list]") == 0) {
                list_ipv4 = &white_list_ipv4;
                list_ipv6 = &white_list_ipv6;
                rules     = &white_list_rules;
                continue;
            } else if (strcmp(line, "[reject_all]") == 0
                       || strcmp(line, "[bypass_all]") == 0) {
                acl_mode = WHITE_LIST;
                continue;
            } else if (strcmp(line, "[accept_all]") == 0
                       || strcmp(line, "[proxy_all]") == 0) {
                acl_mode = BLACK_LIST;
                continue;
            }

            char host[257];
            int cidr;
            parse_addr_cidr(line, host, &cidr);

            struct cork_ip addr;
            int err = cork_ip_init(&addr, host);
            if (!err) {
                if (addr.version == 4) {
                    if (cidr >= 0) {
                        ipset_ipv4_add_network(list_ipv4, &(addr.ip.v4), cidr);
                    } else {
                        ipset_ipv4_add(list_ipv4, &(addr.ip.v4));
                    }
                } else if (addr.version == 6) {
                    if (cidr >= 0) {
                        ipset_ipv6_add_network(list_ipv6, &(addr.ip.v6), cidr);
                    } else {
                        ipset_ipv6_add(list_ipv6, &(addr.ip.v6));
                    }
                }
            } else {
                rule_t *rule = new_rule();
                accept_rule_arg(rule, line);
                init_rule(rule);
                add_rule(rules, rule);
            }
        }

    fclose(f);

    return 0;
}
Example #7
0
// main function
int main(int argc, char *argv[])
{
  char ch, *p, *argv0, *faddr, *taddr, buf[BUFSIZ];
  int s, fid, tid, from, to, pipe_nr;
  uint16_t rulenum;

  int usage_type;

  float time, dummy[PARAMETERS_UNUSED], bandwidth, delay, lossrate;
  FILE *fd;
  timer_handle *timer;
  int loop_count=0;

  int direction=DIRECTION_BOTH;

  struct timeval tp_begin, tp_end;
  
  int i, my_id;
  in_addr_t IP_addresses[MAX_NODES];
  char IP_char_addresses[MAX_NODES*IP_ADDR_SIZE];
  int node_number;

  int j, offset_num, rule_count, next_hop_id, rule_num;
  float time_period, next_time;
  qomet_param param_table[MAX_RULE_NUM];
  qomet_param param_over_read;
  unsigned int over_read;
  char broadcast_address[IP_ADDR_SIZE];

  usage_type = 1;
  
  // initializing the param_table
  memset(param_table, 0, sizeof(qomet_param)*MAX_RULE_NUM);
  memset(&param_over_read, 0, sizeof(qomet_param));
  over_read = 0;
  rule_count = 0;
  next_time = 0.0;
  next_hop_id = 0;
  rule_num = -1;

  // init variables to invalid values
  argv0 = argv[0];
  fd = NULL;

  faddr = taddr = NULL;
  fid = tid = pipe_nr = -1;
  rulenum = 65535;

  my_id = -1;
  node_number = -1;
  time_period = -1;
  strncpy(broadcast_address, "255.255.255.255", IP_ADDR_SIZE);

    // -----------------codes are added by ntrtrung---------------------//
  //---------------------------------Init UDP client--------------//
  int server_fd_do_action;
  int server_do_action_connected;
  server_do_action_connected = 0;
  server_fd_do_action = init_udp_client();
  if(server_fd_do_action >0)
	server_do_action_connected = 1;
  else
	printf("\nCannot Init UDP Client\n");
  //----------------------------------------------------------------------//
  
  if(argc<2)
    {
      WARNING("No arguments provided");
      usage(argv0);
      exit(1);
    }

  // parse command-line options
  while((ch = getopt(argc, argv, "q:f:F:t:T:r:p:d:i:s:m:b:")) != -1)
    {
      switch(ch)
	{
	  //QOMET output file
	case 'q':
	  if((fd = fopen(optarg, "r")) == NULL) 
	    {
	      WARNING("Could not open QOMET output file '%s'", optarg);
	      exit(1);
	    }
	  break;

	  /////////////////////////////////////////////
	  // Usage (1) parameters
	  /////////////////////////////////////////////
	  // from_node_id
	case 'f':
	  fid = strtol(optarg, &p, 10);
	  if((*optarg == '\0') || (*p != '\0'))
	    {
	      WARNING("Invalid from_node_id '%s'", optarg);
	      exit(1);
	    }
	  break;

	  // IP address of from_node
	case 'F':
	  faddr = optarg;
	  break;

	  // to_node_id
	case 't':
	  tid = strtol(optarg, &p, 10);
	  if((*optarg == '\0') || (*p != '\0'))
	    {
	      WARNING("Invalid to_node_id '%s'", optarg);
	      exit(1);
	    }
	  break;

	  // IP address of to_node
	case 'T':
	  taddr = optarg;
	  break;

	  // rule number for dummynet configuration
	case 'r':
	  rulenum = strtol(optarg, &p, 10);
	  if((*optarg == '\0') || (*p != '\0'))
	    {
	      WARNING("Invalid rule_number '%s'", optarg);
	      exit(1);
	    }
	  break;

	  // pipe number for dummynet configuration
	case 'p':
	  pipe_nr = strtol(optarg, &p, 10);
	  if((*optarg == '\0') || (*p != '\0'))
	    {
	      WARNING("Invalid pipe_number '%s'", optarg);
	      exit(1);
	    }
	  break;

	  // direction option for dummynet configuration
	case 'd':
	  if(strcmp(optarg, "in")==0)
	    {
	      direction = DIRECTION_IN;
	    }
	  else if(strcmp(optarg, "out")==0)
	    {
	      direction = DIRECTION_OUT;
	    }
	  else
	    {
	      WARNING("Invalid direction '%s'", optarg);
	      exit(1);
	    }
	  break;

	  /////////////////////////////////////////////
	  // Usage (2) parameters
	  /////////////////////////////////////////////
	  // current node ID
	case 'i':
	  my_id = strtol(optarg, NULL, 10);
	  break;

	  // settings file
	case 's':
	  usage_type = 2;
	  if((node_number = read_settings(optarg, IP_addresses, MAX_NODES)) < 1)
	    {
	      WARNING("Settings file '%s' is invalid", optarg);
	      exit(1);
	    }
	  for(i = 0; i < node_number; i++)
	    snprintf(IP_char_addresses + i * IP_ADDR_SIZE, IP_ADDR_SIZE, 
		     "%hu.%hu.%hu.%hu",
		     *(((uint8_t *)&IP_addresses[i]) + 0),
		     *(((uint8_t *)&IP_addresses[i]) + 1),
		     *(((uint8_t *)&IP_addresses[i]) + 2),
		     *(((uint8_t *)&IP_addresses[i]) + 3));
	  break;

	  // time interval between settings
	case 'm':
	  // check if conversion was performed (we assume a time
	  // period of 0 is also invalid)
	  if ((time_period = strtod(optarg,NULL)) == 0)
	    {
	      WARNING("Invalid time period");
	      exit(1);
	    }
	  break;

	case 'b':
	  strncpy(broadcast_address, optarg, IP_ADDR_SIZE);
	  break;

	  // help output
	case '?':
	default:
	  usage(argv0);
	  exit(1);
	}
    }

  if((my_id<FIRST_NODE_ID) || (my_id>=node_number+FIRST_NODE_ID))
  {
    WARNING("Invalid ID '%d'. Valid range is [%d, %d]", my_id,
	    FIRST_NODE_ID, node_number+FIRST_NODE_ID-1);
    exit(1);
  }

  // update argument-related counter and pointer
  argc -= optind;
  argv += optind;

  // check that all the required arguments were provided
  if(fd == NULL)
    {
      WARNING("No QOMET data file was provided");
      usage(argv0);
      exit(1);
    }
  
  if((usage_type == 1) &&
     ((fid == -1) || (faddr == NULL) ||
      (tid == -1) || (taddr == NULL) || (pipe_nr == -1) || (rulenum == 65535)))
    {
      WARNING("Insufficient arguments were provided for usage (1)");
      usage(argv0);
      fclose(fd);
      exit(1);
    }
  else if ((my_id == -1) || (node_number == -1) || (time_period == -1))
    {
      WARNING("Insufficient arguments were provided for usage (2)");
      usage(argv0);
      fclose(fd);
      exit(1);
    }


  // initialize timer
  DEBUG("Initialize timer...");
  if((timer = timer_init()) == NULL)
    {
      WARNING("Could not initialize timer");
      exit(1);
    }

  // open control socket
  DEBUG("Open control socket...");
  if((s = get_socket()) < 0)
    {
      WARNING("Could not open control socket (requires root priviledges)\n");
      exit(1);
    }

  // add pipe to dummynet in normal manner
  if(usage_type==1)
    {
      // get rule
      //get_rule(s, 123);

      INFO("Add rule #%d with pipe #%d from %s to %s", 
	   rulenum, pipe_nr, faddr, taddr);
      if(add_rule(s, rulenum, pipe_nr, faddr, taddr, direction) < 0)
	{
	  WARNING("Could not add rule #%d with pipe #%d from %s to %s", 
		  rulenum, pipe_nr, faddr, taddr);
	  exit(1);
	}

      // get rule
      //get_rule(s, 123);

      //exit(2);
    }
  else // usage (2) => sets of rules must be added
    {
      // add rule & pipe for unicast traffic _to_ j
      for(j = FIRST_NODE_ID; j < node_number + FIRST_NODE_ID; j++)
	{
	  if(j == my_id)
	    continue;

	  offset_num = j; 

	  INFO("Node %d: Add rule #%d with pipe #%d to destination %s", 
	       my_id, MIN_PIPE_ID_OUT+offset_num, MIN_PIPE_ID_OUT+offset_num, 
	       IP_char_addresses+(j-FIRST_NODE_ID)*IP_ADDR_SIZE);
	  if(add_rule(s, MIN_PIPE_ID_OUT+offset_num, MIN_PIPE_ID_OUT+offset_num,
		      "any", IP_char_addresses+(j-FIRST_NODE_ID)*IP_ADDR_SIZE, 
		      DIRECTION_OUT) < 0)
	    {
	      WARNING("Node %d: Could not add rule #%d with pipe #%d to \
destination %s", my_id, MIN_PIPE_ID_OUT + offset_num, 
		      MIN_PIPE_ID_OUT + offset_num, 
		      IP_char_addresses + (j-FIRST_NODE_ID) * IP_ADDR_SIZE);
	      exit(1);
	    }
	}// end for loop


      // add rule & pipe for broadcast traffic _from_ j
      for(j = FIRST_NODE_ID; j < node_number + FIRST_NODE_ID; j++)
	{
	  if(j == my_id)
	    continue;

	  offset_num = j; 

	  INFO("Node %d: Add rule #%d with pipe #%d to destination %s",
	       my_id, MIN_PIPE_ID_IN_BCAST + offset_num, 
	       MIN_PIPE_ID_IN_BCAST + offset_num, broadcast_address);
	  if(add_rule(s, MIN_PIPE_ID_IN_BCAST + offset_num, 
		      MIN_PIPE_ID_IN_BCAST + offset_num, 
		      IP_char_addresses+(j-FIRST_NODE_ID)*IP_ADDR_SIZE,
		      broadcast_address, DIRECTION_IN) < 0)
	    {
	      WARNING("Node %d: Could not add rule #%d with pipe #%d from %s to \
destination %s", my_id, MIN_PIPE_ID_IN_BCAST + offset_num, 
		      MIN_PIPE_ID_IN_BCAST + offset_num, 
		      IP_char_addresses+(j-FIRST_NODE_ID)*IP_ADDR_SIZE, broadcast_address);
	      exit(1);
	    }
	}
    }

  // get the time at the beginning of the experiment
  gettimeofday(&tp_begin, NULL);

  // do this only for usage (1)
  if(usage_type==1)
    {
#ifdef OLSR_ROUTING
      // get the next hop ID to find correct configuration lines
      if( (next_hop_id = get_next_hop_id(tid, direction)) == ERROR )
	{
	  WARNING("Time=%.2f: Couldn't locate the next hop for destination node %i, direction=%i", time, tid, direction);
	  exit(1);
	} 
      else
	INFO("Time=%.2f: Next_hop=%i for destination=%i", time, 
	     next_hop_id, tid);
#else
      next_hop_id = tid;
#endif
    }

  // read input data from QOMET output file
  INFO("Reading QOMET data from file...");
  
  
  //--------codes are added by ntrtrung--------//
  next_time = 0;
  float this_time,last_time_for_do_action,last_time_for_broad_envi;
  last_time_for_do_action=-1;
  last_time_for_broad_envi=-1;
  //--------codes are added by ntrtrung--------//
  
  while(fgets(buf, BUFSIZ, fd) != NULL)
    {
      if(sscanf(buf, "%f %d %f %f %f %d %f %f %f %f %f %f "
		"%f %f %f %f %f %f %f", &time, &from, &dummy[0],
		&dummy[1], &dummy[2], &to, &dummy[3], &dummy[4],
		&dummy[5],  &dummy[6], &dummy[7], &dummy[8],
		&dummy[9], &dummy[10], &dummy[11], &bandwidth, 
		&lossrate, &delay, &dummy[12]) != PARAMETERS_TOTAL)
	{
	  INFO("Skipped non-parametric line");
	  continue;
	}
	//--------codes are added by ntrtrung--------//
     this_time = time;
	 if(server_do_action_connected == 1)
	 {
		if(this_time != last_time_for_do_action && server_fd_do_action > 0)
		{
			if( SendDataToServer(&this_time,server_fd_do_action,DO_ACTION_SERVER_PORT) == -1)
			{
				server_do_action_connected = 0;
			}
			else
		 	   printf("\ntime is sent to do action server:%f \n",this_time);
			if( SendDataToServer(&this_time,server_fd_do_action,BROAD_ENVI_SERVER_PORT) == -1)
			{
				server_do_action_connected = 0;
			}
			else
			   printf("\ntime is sent to broad envi server:%f \n",this_time);

			last_time_for_do_action = this_time;
		}
	 }
	
	 //--------codes are added by ntrtrung--------//
	 
	 
      if(usage_type==1)
	{
	  // check whether the from_node and to_node from the file
	  // match the user selected ones
	  if((from == fid) && (to == next_hop_id))
	    {
	      
#ifdef PREDEFINED_EXPERIMENT
	      bandwidth=BANDWIDTH;
	      delay=DELAY;
	      lossrate=PACKET_LOSS_RATE;
#endif
	      // print current configuration info
	      INFO("* Wireconf configuration (time=%.2f s): bandwidth=%.2fbit/s \
loss_rate=%.4f delay=%.4f ms", time, bandwidth, lossrate, delay);
	      
	      // if this is the first operation we reset the timer
	      // Note: it is assumed time always equals 0.0 for the first line
	      if(time == 0.0)
		timer_reset(timer);
	      else 
		{
		  // wait for for the next timer event
		  if(timer_wait(timer, time * 1000000) < 0)
		    {
		      WARNING("Timer deadline missed at time=%.2f s", time);
		      //exit(1); // NOT NEEDED ANYMORE!!!!
		    }
		}
	      
#ifdef OLSR_ROUTING
	      // get the next hop ID to find correct configuration lines
	      if((next_hop_id = get_next_hop_id(tid, direction)) == ERROR)
		{
		  WARNING("Time=%.2f: Couldn't locate the next hop for destination node %i,direction=%i", time, tid, direction);
		  exit(1);
		}
	      else
		INFO("Time=%.2f: Next_hop=%i for destination=%i", time, next_hop_id, tid);
#endif

	      // prepare adjusted values:
	      // 1. if packet size is known bandwidth could be adjusted:
	      //   multiplication factor 1.0778 was computed for 400 byte datagrams
	      //   because of 28 bytes header (428/400=1.07)
	      //   however we consider bandwidth at Ethernet level, therefore we
	      //   don't multiply here but when plotting results
	      //   Note: ip_dummynet.h says that bandwidth is in bytes/tick
	      //         but we seem to obtain correct values using bits/second
	      bandwidth = (int)round(bandwidth);// * 2.56);
	      
	      // 2. no adjustment necessary for delay expressed in ms
	      delay = (int) round(delay);//(delay / 2);
	      
	      // 3. loss rate probability must be extended to 
	      //    2^31-1 (=0x7fffffff) range, equivalent to 100% loss
	      lossrate = (int)round(lossrate * 0x7fffffff);
	      
	      // do configure pipe
	      configure_pipe(s, pipe_nr, bandwidth, delay, lossrate);
	      
	      // increase loop counter
	      loop_count++;
	      
#ifdef PREDEFINED_EXPERIMENT
	      if(loop_count>LOOP_COUNT)
		break;
#endif
	    }
	}
      else // usage (2) => manage multiple rules
	{
	  // add rules regarding next deadline to parameter table
	  if(time == next_time)
Example #8
0
rt_data_t* dr_load_routing_info( db_func_t *dr_dbf, db_con_t* db_hdl,
		str *drd_table, str *drc_table, str* drr_table, int persistent_state)
{
	int    int_vals[5];
	char * str_vals[6];
	str tmp;
	db_key_t columns[10];
	db_res_t* res;
	db_row_t* row;
	rt_info_t *ri;
	rt_data_t *rdata;
	tmrec_t   *time_rec;
	int i,n;
	int no_rows = 10;
	int db_cols;
	struct socket_info *sock;
	str s_sock, host;
	int proto, port;

	res = 0;
	ri = 0;
	rdata = 0;

	/* init new data structure */
	if ( (rdata=build_rt_data())==0 ) {
		LM_ERR("failed to build rdata\n");
		goto error;
	}

	if (db_check_table_version(dr_dbf, db_hdl, drd_table, 6/*version*/ )!= 0)
		goto error;

	/* read the destinations */
	if (dr_dbf->use_table( db_hdl, drd_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drd_table->len,drd_table->s);
		goto error;
	}

	columns[0] = &id_drd_col;
	columns[1] = &gwid_drd_col;
	columns[2] = &address_drd_col;
	columns[3] = &strip_drd_col;
	columns[4] = &prefix_drd_col;
	columns[5] = &type_drd_col;
	columns[6] = &attrs_drd_col;
	columns[7] = &probe_drd_col;
	columns[8] = &sock_drd_col;
	if (persistent_state) {
		columns[9] = &state_drd_col;
		db_cols = 10;
	} else {
		db_cols = 9;
	}

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, db_cols, 0, 0 ) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		no_rows = estimate_available_rows( 4+32+15+4+32+4+128+4+32+4, db_cols);
		if (no_rows==0) no_rows = 10;
		if(dr_dbf->fetch_result(db_hdl, &res, no_rows )<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, db_cols, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	LM_DBG("%d records found in %.*s\n",
		RES_ROW_N(res), drd_table->len,drd_table->s);

	n = 0;
	do {
		for(i=0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;
			/* DB ID column */
			check_val( id_drd_col, ROW_VALUES(row), DB_INT, 1, 0);
			int_vals[INT_VALS_ID_DRD_COL] = VAL_INT(ROW_VALUES(row));
			/* GW ID column */
			check_val( gwid_drd_col, ROW_VALUES(row)+1, DB_STRING, 1, 1);
			str_vals[STR_VALS_GWID_DRD_COL] = (char*)VAL_STRING(ROW_VALUES(row)+1);
			/* ADDRESS column */
			check_val( address_drd_col, ROW_VALUES(row)+2, DB_STRING, 1, 1);
			str_vals[STR_VALS_ADDRESS_DRD_COL] = (char*)VAL_STRING(ROW_VALUES(row)+2);
			/* STRIP column */
			check_val( strip_drd_col, ROW_VALUES(row)+3, DB_INT, 1, 0);
			int_vals[INT_VALS_STRIP_DRD_COL] = VAL_INT   (ROW_VALUES(row)+3);
			/* PREFIX column */
			check_val( prefix_drd_col, ROW_VALUES(row)+4, DB_STRING, 0, 0);
			str_vals[STR_VALS_PREFIX_DRD_COL] = (char*)VAL_STRING(ROW_VALUES(row)+4);
			/* TYPE column */
			check_val( type_drd_col, ROW_VALUES(row)+5, DB_INT, 1, 0);
			int_vals[INT_VALS_TYPE_DRD_COL] = VAL_INT(ROW_VALUES(row)+5);
			/* ATTRS column */
			check_val( attrs_drd_col, ROW_VALUES(row)+6, DB_STRING, 0, 0);
			str_vals[STR_VALS_ATTRS_DRD_COL] = (char*)VAL_STRING(ROW_VALUES(row)+6);
			/*PROBE_MODE column */
			check_val( probe_drd_col, ROW_VALUES(row)+7, DB_INT, 1, 0);
			int_vals[INT_VALS_PROBE_DRD_COL] = VAL_INT(ROW_VALUES(row)+7);
			/*SOCKET column */
			check_val( sock_drd_col, ROW_VALUES(row)+8, DB_STRING, 0, 0);
			if ( !VAL_NULL(ROW_VALUES(row)+8) &&
			(s_sock.s=(char*)VAL_STRING(ROW_VALUES(row)+8))[0]!=0 ) {
				s_sock.len = strlen(s_sock.s);
				if (parse_phostport( s_sock.s, s_sock.len, &host.s, &host.len,
				&port, &proto)!=0){
					LM_ERR("GW <%s>(%d): socket description <%.*s> "
						"is not valid -> ignoring socket\n",
						str_vals[STR_VALS_GWID_DRD_COL],
						int_vals[INT_VALS_ID_DRD_COL], s_sock.len,s_sock.s);
					sock = NULL;
				} else {
					sock = grep_sock_info( &host, port, proto);
					if (sock == NULL) {
						LM_ERR("GW <%s>(%d): socket <%.*s> is not local to"
						" OpenSIPS (we must listen on it) -> ignoring socket\n",
						str_vals[STR_VALS_GWID_DRD_COL],
						int_vals[INT_VALS_ID_DRD_COL], s_sock.len,s_sock.s);
					}
				}
			} else {
				sock = NULL;
			}
			/*STATE column */
			if (persistent_state) {
				check_val( state_drd_col, ROW_VALUES(row)+9, DB_INT, 1, 0);
				int_vals[INT_VALS_STATE_DRD_COL] = VAL_INT(ROW_VALUES(row)+9);
			} else {
				int_vals[INT_VALS_STATE_DRD_COL] = 0; /* by default enabled */
			}

			/* add the destinaton definition in */
			if ( add_dst( rdata, str_vals[STR_VALS_GWID_DRD_COL],
						str_vals[STR_VALS_ADDRESS_DRD_COL],
						int_vals[INT_VALS_STRIP_DRD_COL],
						str_vals[STR_VALS_PREFIX_DRD_COL],
						int_vals[INT_VALS_TYPE_DRD_COL],
						str_vals[STR_VALS_ATTRS_DRD_COL],
						int_vals[INT_VALS_PROBE_DRD_COL],
						sock,
						int_vals[INT_VALS_STATE_DRD_COL] )<0 ) {
				LM_ERR("failed to add destination <%s>(%d) -> skipping\n",
					str_vals[STR_VALS_GWID_DRD_COL],int_vals[INT_VALS_ID_DRD_COL]);
				continue;
			}
			n++;
		}
		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
				LM_ERR( "fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	/* read the carriers, if any */
	if (dr_dbf->use_table( db_hdl, drc_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drc_table->len,drc_table->s);
		goto error;
	}

	columns[0] = &id_drc_col;
	columns[1] = &cid_drc_col;
	columns[2] = &flags_drc_col;
	columns[3] = &gwlist_drc_col;
	columns[4] = &attrs_drc_col;
	if (persistent_state) {
		columns[5] = &state_drc_col;
		db_cols = 6;
	} else {
		db_cols = 5;
	}

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, db_cols, 0, 0 ) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		no_rows = estimate_available_rows( 4+4+32+64+64, db_cols);
		if (no_rows==0) no_rows = 10;
		if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, db_cols, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("table \"%.*s\" empty\n", drc_table->len,drc_table->s );
	} else {
		LM_DBG("%d records found in %.*s\n",
			RES_ROW_N(res), drc_table->len,drc_table->s);
		do {
			for(i=0; i < RES_ROW_N(res); i++) {
				row = RES_ROWS(res) + i;
				/* ID column */
				check_val( id_drc_col, ROW_VALUES(row), DB_INT, 1, 0);
				int_vals[INT_VALS_ID_DRC_COL] = VAL_INT(ROW_VALUES(row));
				/* CARRIER_ID column */
				check_val( cid_drc_col, ROW_VALUES(row)+1, DB_STRING, 1, 1);
				str_vals[STR_VALS_CID_DRC_COL] = (char*)VAL_STRING(ROW_VALUES(row)+1);
				/* flags column */
				check_val( flags_drc_col, ROW_VALUES(row)+2, DB_INT, 1, 0);
				int_vals[INT_VALS_FLAGS_DRC_COL] = VAL_INT(ROW_VALUES(row)+2);
				/* GWLIST column */
				check_val( gwlist_drc_col, ROW_VALUES(row)+3, DB_STRING, 1, 1);
				str_vals[STR_VALS_GWLIST_DRC_COL] = (char*)VAL_STRING(ROW_VALUES(row)+3);
				/* ATTRS column */
				check_val( attrs_drc_col, ROW_VALUES(row)+4, DB_STRING, 0, 0);
				str_vals[STR_VALS_ATTRS_DRC_COL] = (char*)VAL_STRING(ROW_VALUES(row)+4);
				/* STATE column */
				if (persistent_state) {
					check_val( state_drc_col, ROW_VALUES(row)+5, DB_INT, 1, 0);
					int_vals[INT_VALS_STATE_DRC_COL] = VAL_INT(ROW_VALUES(row)+5);
				} else {
					int_vals[INT_VALS_STATE_DRC_COL] = 0; /* by default enabled */
				}

				/* add the new carrier */
				if ( add_carrier( str_vals[STR_VALS_CID_DRC_COL],
						int_vals[INT_VALS_FLAGS_DRC_COL],
						str_vals[STR_VALS_GWLIST_DRC_COL],
						str_vals[STR_VALS_ATTRS_DRC_COL],
						int_vals[INT_VALS_STATE_DRC_COL], rdata) != 0 ) {
					LM_ERR("failed to add carrier db_id %d -> skipping\n",
						int_vals[INT_VALS_ID_DRC_COL]);
					continue;
				}
			}
			if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
				if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
					LM_ERR( "fetching rows (1)\n");
					goto error;
				}
			} else {
				break;
			}
		} while(RES_ROW_N(res)>0);
	}
	dr_dbf->free_result(db_hdl, res);
	res = 0;


	/* read the routing rules */
	if (dr_dbf->use_table( db_hdl, drr_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drr_table->len, drr_table->s);
		goto error;
	}

	columns[0] = &rule_id_drr_col;
	columns[1] = &group_drr_col;
	columns[2] = &prefix_drr_col;
	columns[3] = &time_drr_col;
	columns[4] = &priority_drr_col;
	columns[5] = &routeid_drr_col;
	columns[6] = &dstlist_drr_col;
	columns[7] = &attrs_drr_col;

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, 0) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		no_rows = estimate_available_rows( 4+32+32+128+32+64+128, 8/*cols*/);
		if (no_rows==0) no_rows = 10;
		if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_WARN("table \"%.*s\" is empty\n", drr_table->len, drr_table->s);
	}

	LM_DBG("initial %d records found in %.*s\n", RES_ROW_N(res),
		drr_table->len, drr_table->s);

	n = 0;
	do {
		for(i=0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;
			/* RULE_ID column */
			check_val( rule_id_drr_col, ROW_VALUES(row), DB_INT, 1, 0);
			int_vals[INT_VALS_RULE_ID_DRR_COL] = VAL_INT (ROW_VALUES(row));
			/* GROUP column */
			check_val( group_drr_col, ROW_VALUES(row)+1, DB_STRING, 1, 1);
			str_vals[STR_VALS_GROUP_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+1);
			/* PREFIX column - it may be null or empty */
			check_val( prefix_drr_col, ROW_VALUES(row)+2, DB_STRING, 0, 0);
			if ((ROW_VALUES(row)+2)->nul || VAL_STRING(ROW_VALUES(row)+2)==0){
				tmp.s = NULL;
				tmp.len = 0;
			} else {
				str_vals[STR_VALS_PREFIX_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+2);
				tmp.s = str_vals[STR_VALS_PREFIX_DRR_COL];
				tmp.len = strlen(str_vals[STR_VALS_PREFIX_DRR_COL]);
			}
			/* TIME column */
			check_val( time_drr_col, ROW_VALUES(row)+3, DB_STRING, 0, 0);
			str_vals[STR_VALS_TIME_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+3);
			/* PRIORITY column */
			check_val( priority_drr_col, ROW_VALUES(row)+4, DB_INT, 1, 0);
			int_vals[INT_VALS_PRIORITY_DRR_COL] = VAL_INT   (ROW_VALUES(row)+4);
			/* ROUTE_ID column */
			check_val( routeid_drr_col, ROW_VALUES(row)+5, DB_STRING, 0, 0);
			str_vals[STR_VALS_ROUTEID_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+5);
			/* DSTLIST column */
			check_val( dstlist_drr_col, ROW_VALUES(row)+6, DB_STRING, 1, 1);
			str_vals[STR_VALS_DSTLIST_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+6);
			/* ATTRS column */
			check_val( attrs_drr_col, ROW_VALUES(row)+7, DB_STRING, 0, 0);
			str_vals[STR_VALS_ATTRS_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+7);
			/* parse the time definition */
			if (str_vals[STR_VALS_TIME_DRR_COL] == NULL || *(str_vals[STR_VALS_TIME_DRR_COL]) == 0)
				time_rec = NULL;
			else if ((time_rec=parse_time_def(str_vals[STR_VALS_TIME_DRR_COL]))==0) {
				LM_ERR("bad time definition <%s> for rule id %d -> skipping\n",
					str_vals[STR_VALS_TIME_DRR_COL], int_vals[INT_VALS_RULE_ID_DRR_COL]);
				continue;
			}
			/* lookup for the script route ID */
			if (str_vals[STR_VALS_ROUTEID_DRR_COL] && str_vals[STR_VALS_ROUTEID_DRR_COL][0]) {
				int_vals[INT_VALS_SCRIPT_ROUTE_ID] =
					get_script_route_ID_by_name( str_vals[STR_VALS_ROUTEID_DRR_COL], rlist, RT_NO);
				if (int_vals[INT_VALS_SCRIPT_ROUTE_ID]==-1) {
					LM_WARN("route <%s> does not exist\n",
						str_vals[STR_VALS_ROUTEID_DRR_COL]);
					int_vals[INT_VALS_SCRIPT_ROUTE_ID] = 0;
				}
			} else {
				int_vals[INT_VALS_SCRIPT_ROUTE_ID] = 0;
			}
			/* build the routing rule */
			if ((ri = build_rt_info( int_vals[INT_VALS_RULE_ID_DRR_COL],
					int_vals[INT_VALS_PRIORITY_DRR_COL], time_rec,
					int_vals[INT_VALS_SCRIPT_ROUTE_ID],
					str_vals[STR_VALS_DSTLIST_DRR_COL],
					str_vals[STR_VALS_ATTRS_DRR_COL], rdata))== 0 ) {
				LM_ERR("failed to add routing info for rule id %d -> "
					"skipping\n", int_vals[INT_VALS_RULE_ID_DRR_COL]);
				tmrec_free( time_rec );
				continue;
			}
			/* add the rule */
			if (add_rule( rdata, str_vals[STR_VALS_GROUP_DRR_COL], &tmp, ri)!=0) {
				LM_ERR("failed to add rule id %d -> skipping\n",
					int_vals[INT_VALS_RULE_ID_DRR_COL]);
				free_rt_info( ri );
				continue;
			}
			n++;
		}
		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
				LM_ERR( "fetching rows (1)\n");
				goto error;
			}
			LM_DBG("additional %d records found in %.*s\n", RES_ROW_N(res),
				drr_table->len, drr_table->s);
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	LM_DBG("%d total records loaded from table %.*s\n", n,
		drr_table->len, drr_table->s);

	return rdata;
error:
	if (res)
		dr_dbf->free_result(db_hdl, res);
	if (rdata)
		free_rt_data( rdata, 1 );
	rdata = NULL;
	return 0;
}
Example #9
0
 void Resource::add_rule( const shared_ptr< Rule >& rule, const int priority )
 {
     rule->set_priority( priority );
     add_rule( rule );
 }
Example #10
0
File: main.c Project: fpereda/lsys
int main(int argc, char *argv[])
{
    struct lsys_opts *opts = get_lsys_opts();

    struct copme_long acts[] = {
        {"depth", 'd', "Generation of the l-system", COPME_HASARG},
        {"axiom", 'a', "Starting point of the l-system", COPME_HASARG},
        {"degree-step", 's', "Delta. Degrees to turn in + and -", COPME_HASARG},
        {"initial-degree", 'i', "Initial degree of the turtle", COPME_HASARG},
        {"delta-depth", 'D', "Delta for each depth. Command '|'", COPME_HASARG},
        {"rule", 'r', "Add a production rule to the l-system", COPME_HASARG},
        {"list-examples", 'l', "List available examples", COPME_NOARG},
        {"example", 'e', "Use settings from an example", COPME_HASARG},
        {0, 0, 0, 0}
    };

    struct copme_long otheracts[] = {
        {"raw", 0, "Don't paint anything. Just print the l-system", COPME_NOARG},
        {"help", 'h', "Display this information message", COPME_NOARG},
        {"version", 'V', "Display version information", COPME_NOARG},
        {0, 0, 0, 0}
    };

    struct copme_group groups[] = {
        {"Actions", "Actions for lsys", acts},
        {"Other actions", "Less-common actions for lsys", otheracts},
        {0, 0, 0}
    };

    struct copme_long *o_depth = copme_option_named(groups, "depth");
    struct copme_long *o_axiom = copme_option_named(groups, "degree-step");
    struct copme_long *o_degree_step = copme_option_named(groups, "degree-step");
    struct copme_long *o_initial_degree = copme_option_named(groups, "initial-degree");
    struct copme_long *o_delta_depth = copme_option_named(groups, "delta-depth");
    struct copme_long *o_rule = copme_option_named(groups, "rule");
    struct copme_long *o_list_examples = copme_option_named(groups, "list-examples");
    struct copme_long *o_example = copme_option_named(groups, "example");
    struct copme_long *o_raw = copme_option_named(groups, "raw");
    struct copme_long *o_help = copme_option_named(groups, "help");
    struct copme_long *o_version = copme_option_named(groups, "version");

    struct copme_state *cst = copme_init(groups, argc, argv);
    while (! copme_finished(cst)) {
        copme_next(cst);

        if (o_rule->arg->specified) {
            o_rule->arg->specified = 0;
            if (add_rule(opts, o_rule->arg->data) > 0)
                goto err;
        }
        if (copme_error(cst))
            goto err;
        if (o_help->specified) {
            copme_usage(cst, usage_pre, 0);
            goto suc;
        }
    }

    if (o_version->specified) {
        printf("%s", version());
        goto suc;
    }

    if (o_list_examples->specified) {
        example_list();
        goto suc;
    }

    if (o_example->arg->specified)
        if (lsys_set_example(o_example->arg->data, opts) > 0) {
            fprintf(stderr, "Example with key '%s' not found.\n",
                    o_example->arg->data);
            goto err;
        }

    if (o_axiom->arg->specified)
        opts->axiom = o_axiom->arg->data;
    if (o_depth->arg->specified)
        opts->depth = atoi(o_depth->arg->data);
    if (o_degree_step->arg->specified)
        opts->degree_step = atof(o_degree_step->arg->data) * M_PI / 180;
    if (o_initial_degree->arg->specified)
        opts->initial_degree = -(atof(o_initial_degree->arg->data) * M_PI / 180);
    if (o_delta_depth->arg->specified) {
        double dd = atof(o_delta_depth->arg->data);
        if (dd > 0 && dd <= 1)
            opts->delta_depth = dd;
        else {
            fprintf(stderr, "delta-depth has to be between 0 and 1.\n");
            goto err;
        }
    }

    if (o_raw->specified) {
        compute_figure(opts->axiom, opts->depth, putchar_wrapper);
        putchar('\n');
        goto suc;
    }

    launch_gui(&argc, &argv);

suc:
    copme_free(cst);
    return EXIT_SUCCESS;
err:
    copme_free(cst);
    return EXIT_FAILURE;
}
Example #11
0
//--------------------------------------------------------------------------------------------------------
// Function called by the main thread's helper thread. Deals with rules that have been added to the dep_q
// by checking if they are ready to be added to the in_q and be processed.
//--------------------------------------------------------------------------------------------------------
void* main_thread_helper(void* arg)
{
	rule_t* rule;
	str_node_t* dep;
	int i, j;
	int addRule, foundDep;

	while(1)
	{
		//check exit condition
		if(adding_Rules == 0 && dep_q->index == 0) break;

		//Wait for signal of items being added to dep_sem
		//if(sem_trywait(&dep_sem)) printf("Sem get blocked!\n");
		sem_wait(&dep_sem);
		if(dep_q->index == 0) continue;//Do nothing if nothing is in dep_q

		for(i = 0; i < dep_q->index; i++) //each rule in dep_q
		{
			addRule = true;
			rule = dep_q->queue[i];
			for(dep = rule->deps; dep != NULL; dep = dep->next)
			{
				foundDep = false;
				for(j = 0; j < out_q->index; j++) //each rule in out_q
				{
					//printf("[%s] vs [%s]\n", dep->str, out_q->queue[j]->target);
					if(strcmp(dep->str, out_q->queue[j]->target) == 0) { foundDep = true; break; }
				} //end out_q
				//printf("(%d)\n", foundDep);
				if(foundDep == false) { addRule = false; break; }
			} //end deps
			//printf("Helper (%s) %d\n", rule->target, addRule);
			if(addRule)
			{
				if(add_rule(IN_QUEUE, rule))
				{
					//remove rule from dep queue
					get_rule(DEP_QUEUE, rule);
					printf("Helper: Rule added to in_q (%s) \n", rule->target);
					
					sem_post(&jobs_sem);
				}
			}
			else //rules dependencies havent been executed
			{
				//do something
				
			}
		} //end dep_q
	}
		/*
		
		
		
		
		
		
		
		//Since there is only one helper thread that should be removing items from dep_q,
		// dont need to worry about using a mutex when looking through items.
		//The case of items being added to dep_q by the main thread while helper thread is
		// processing shouldnt be an issue
		for(i = 0; i < dep_q->index; i++)
		{
			//No need to hold the out_q mutex lock because items cant be taken out of it
			int addRule;
			int foundDep = false;
			rule = dep_q->queue[i];
			printf("Helper (%s)\n", rule->target);
			if(rule->deps == NULL) //something is wrong
			//Compare the rules dependencies with the rules in the out_q
			for(dep = rule->deps; dep != NULL; dep = dep->next)
			{
				addRule = false;
				for(j = 0; j < out_q->index; j++)
				{
					if(dep->str ==  out_q->queue[j]->target) { addRule |= true; break; }
					else { addRule &= false; }
				}
			}

			//rule's deps are in out_q
			if(addRule)
			{
				if(add_rule(IN_QUEUE, rule))
				{	
					//remove rule from dep queue
					get_rule(DEP_QUEUE, rule);
					printf("Helper: Rule added to in_q (%s) \n", rule->target);

					//notify workers of new job
					sem_post(&jobs_sem);
				}
			}
			else //rule's deps arent in out_q
			{
				//No more rules will be added to in_q and
				if(!adding_Rules && in_q->index == 0) { fprintf(stderr, "Rule in dep queue that will never be executed\n"); exit(1); }
			}
		}
	}
	*/
	printf("Helper(%u) exiting\n", (unsigned int)pthread_self());
	return NULL;
}
Example #12
0
query_status_t
deal_with_ts3_packet(struct qserver *server, char *rawpkt, int pktlen)
{
	char *s, *player_name = "unknown";
	int valid_response = 0, mode = 0, all_servers = 0;
	char last_char;
	unsigned short port = 0, down = 0, auth_seen = 0;

	debug(2, "processing...");

	if (0 == pktlen) {
		// Invalid password
		return (REQ_ERROR);
	}

	last_char = rawpkt[pktlen - 1];
	rawpkt[pktlen - 1] = '\0';
	s = rawpkt;
	all_servers = all_ts3_servers(server);

	debug(3, "packet: combined = %d, challenge = %ld, n_servers = %d", server->combined, server->challenge, server->n_servers);
	if (!server->combined) {
		server->retry1 = n_retries;
		if (0 == server->n_requests) {
			server->ping_total = time_delta(&packet_recv_time, &server->packet_time1);
			server->n_requests++;
		}

		if (server->n_servers >= server->challenge) {
			// response fragment recieved
			int pkt_id;
			int pkt_max;

			// We're expecting more to come
			debug(5, "fragment recieved...");
			pkt_id = packet_count(server);
			pkt_max = pkt_id + 1;
			rawpkt[pktlen - 1] = last_char; // restore the last character
			if (!add_packet(server, 0, pkt_id, pkt_max, pktlen, rawpkt, 1)) {
				// fatal error e.g. out of memory
				return (MEM_ERROR);
			}

			// combine_packets will call us recursively
			return (combine_packets(server));
		}
	} else {
		valid_response = valid_ts3_response(server, rawpkt + server->master_pkt_len, pktlen - server->master_pkt_len);

		debug(2, "combined packet: valid_response: %d, challenge: %ld, n_servers: %d, offset: %d", valid_response, server->challenge, server->n_servers, server->master_pkt_len);

		if (0 > valid_response) {
			// Error occured
			return (valid_response);
		}

		server->challenge += valid_response;

		if (valid_response) {
			// Got a valid response, send the next request
			int ret = send_ts3_request_packet(server);
			if (0 != ret) {
				// error sending packet
				debug(4, "Request failed: %d", ret);
				return (ret);
			}
		}

		if (server->n_servers > server->challenge) {
			// recursive call which is still incomplete
			return (INPROGRESS);
		}
	}

	// Correct ping
	// Not quite right but gives a good estimate
	server->ping_total = (server->ping_total * server->n_requests) / 2;

	debug(3, "processing response...");

	s = strtok(rawpkt, "\012\015 |");

	// NOTE: id=XXX and msg=XXX will be processed by the mod following the one they where the response of
	while (NULL != s) {
		debug(4, "LINE: %d, %s\n", mode, s);
		switch (mode) {
		case 0:
			// prompt, use or serverlist response
			if (0 == strcmp("TS3", s)) {
				// nothing to do unless in all servers mode
				if (1 == all_servers) {
					mode++;
				}
			} else if (0 == strncmp("error", s, 5)) {
				// end of use response
				mode++;
			}
			break;

		case 1:
			// serverinfo or serverlist response including condition authentication
			if ((0 == auth_seen) && (0 != strlen(get_param_value(server, "password", ""))) && (0 == strncmp("error", s, 5))) {
				// end of auth response
				auth_seen = 1;
			} else if (0 == strncmp("error", s, 5)) {
				// end of serverinfo response
				mode++;
			} else {
				// Server Rule
				char *key = s;
				char *value = strchr(key, '=');
				if (NULL != value) {
					*value = '\0';
					value++;
					debug(6, "Rule: %s = %s\n", key, value);
					if (0 == strcmp("virtualserver_name", key)) {
						if (1 == all_servers) {
							struct qserver *new_server = add_qserver_byaddr(ntohl(server->ipaddr), port, server->type, NULL);
							if (NULL != new_server) {
								if (down) {
									// Status indicates this server is actually offline
									new_server->server_name = DOWN;
								} else {
									new_server->max_players = server->max_players;
									new_server->num_players = server->num_players;
									new_server->server_name = strdup(decode_ts3_val(value));
									new_server->map_name = strdup("N/A");
									new_server->ping_total = server->ping_total;
									new_server->n_requests = server->n_requests;
								}
								cleanup_qserver(new_server, FORCE);
							}
							down = 0;
						} else {
							server->server_name = strdup(decode_ts3_val(value));
						}
					} else if (0 == strcmp("virtualserver_port", key)) {
						port = atoi(value);
						change_server_port(server, port, 0);
						add_rule(server, key, value, NO_FLAGS);
					} else if (0 == strcmp("virtualserver_maxclients", key)) {
						server->max_players = atoi(value);
					} else if (0 == strcmp("virtualserver_clientsonline", key)) {
						server->num_players = atoi(value);
					} else if (0 == strcmp("virtualserver_queryclientsonline", key)) {
						// clientsonline includes queryclientsonline so remove these from our count
						server->num_players -= atoi(value);
					} else if ((0 == strcmp("virtualserver_status", key)) && (0 != strcmp("online", value))) {
						// Server is actually offline to client so display as down
						down = 1;
						if (1 != all_servers) {
							server->server_name = DOWN;
							//server->saved_data.pkt_index = 0;
							return (DONE_FORCE);
						}
					} else if ((0 == strcmp("id", key)) || (0 == strcmp("msg", key))) {
						// Ignore details from the response code
					} else if (1 != all_servers) {
						add_rule(server, key, value, NO_FLAGS);
					}
				}
			}
			break;

		case 2:
			// clientlist response
			if (0 == strncmp("error", s, 5)) {
				// end of serverinfo response
				mode++;
			} else {
				// Client
				char *key = s;
				char *value = strchr(key, '=');
				if (NULL != value) {
					*value = '\0';
					value++;
					debug(6, "Player: %s = %s\n", key, value);
					if (0 == strcmp("client_nickname", key)) {
						player_name = value;
					} else if (0 == strcmp("clid", key)) {
					} else if ((0 == strcmp("client_type", key)) && (0 == strcmp("0", value))) {
						struct player *player = add_player(server, server->n_player_info);
						if (NULL != player) {
							player->name = strdup(decode_ts3_val(player_name));
						}
					} else if ((0 == strcmp("id", key)) || (0 == strcmp("msg", key))) {
						// Ignore details from the response code
					}
				}
			}
			break;
		}
		s = strtok(NULL, "\012\015 |");
	}

	gettimeofday(&server->packet_time1, NULL);

	server->map_name = strdup("N/A");
	return (DONE_FORCE);
}
Example #13
0
File: gs2.c Project: Bubelbub/qstat
// See the following for protocol details:
// http://dev.kquery.com/index.php?article=42
query_status_t deal_with_gs2_packet( struct qserver *server, char *rawpkt, int pktlen )
{
	char *ptr = rawpkt;
	char *end = rawpkt + pktlen;
	unsigned char type = 0;
	unsigned char no_players = 0;
	unsigned char total_players = 0;
	unsigned char no_teams = 0;
	unsigned char total_teams = 0;
	unsigned char no_headers = 0;
	char **headers = NULL;
	debug( 2, "processing packet..." );

	if ( pktlen < 15 )
	{
		// invalid packet?
		return PKT_ERROR;
	}

	server->n_servers++;
	if ( server->server_name == NULL)
	{
		server->ping_total += time_delta( &packet_recv_time, &server->packet_time1 );
	}
	else
	{
		gettimeofday( &server->packet_time1, NULL);
	}

	// Could check the header here should
	// match the 4 byte id sent
	ptr += 5;
	while ( 0 == type && ptr < end )
	{
		// server info:
		// name value pairs null seperated
		// empty name && value signifies the end of section
		char *var, *val;
		int var_len, val_len;

		var = ptr;
		var_len = strlen( var );

		if ( ptr + var_len + 2 > end )
		{
			if ( 0 != var_len )
			{
				malformed_packet( server, "no rule value" );
			}
			else if ( get_player_info )
			{
				malformed_packet( server, "no player headers" );
			}
			return PKT_ERROR;
		}
		ptr += var_len + 1;

		val = ptr;
		val_len = strlen( val );
		ptr += val_len + 1;
		debug( 2, "var:%s (%d)=%s (%d)\n", var, var_len, val, val_len );

		// Lets see what we've got
		if ( 0 == strcmp( var, "hostname" ) )
		{
			server->server_name = strdup( val );
		}
		else if( 0 == strcmp( var, "game_id" ) )
		{
			server->game = strdup( val );
		}
		else if( 0 == strcmp( var, "gamever" ) )
		{
			// format:
			// v1.0
			server->protocol_version = atoi( val+1 );
			add_rule( server, var, val, NO_FLAGS );
		}
		else if( 0 == strcmp( var, "mapname" ) )
		{
			server->map_name = strdup( val );
		}
		else if( 0 == strcmp( var, "map" ) )
		{
			// For BF2MC compatibility
			server->map_name = strdup( val );
		}
		else if( 0 == strcmp( var, "maxplayers" ) )
		{
			server->max_players = atoi( val );

		}
		else if( 0 == strcmp( var, "numplayers" ) )
		{
			server->num_players = no_players = atoi( val );
		}
		else if( 0 == strcmp( var, "hostport" ) )
		{
			change_server_port( server, atoi( val ), 0 );
		}
		else if ( 0 == var_len )
		{
			// check for end of section
			type = 1;
		}
		else
		{
			add_rule( server, var, val, NO_FLAGS );
		}
	}

	if ( 1 != type )
	{
		// no more info should be player headers here as we
		// requested it
		malformed_packet( server, "no player headers" );
		return PKT_ERROR;
	}

	// player info header
	// format:
	// first byte = player count
	// followed by null seperated header
	no_players = (unsigned char)*ptr;
	debug( 2, "No Players:%d\n", no_players );
	ptr++;

	if ( ptr >= end )
	{
		malformed_packet( server, "no player headers" );
		return PKT_ERROR;
	}

	while ( 1 == type && ptr < end )
	{
		// first we have the headers null seperated
		char **tmpp;
		char *head = ptr;
		int head_len = strlen( head );
		no_headers++;
		tmpp = (char**)realloc( headers, no_headers * sizeof( char* ) );
		if ( NULL == tmpp )
		{
			debug( 0, "Failed to realloc memory for headers\n" );
			if ( NULL != headers )
			{
				free( headers );
			}
			return MEM_ERROR;
		}

		headers = tmpp;
		headers[no_headers-1] = head;

		ptr += head_len + 1;

		// end of headers check
		if ( 0x00 == *ptr )
		{
			type = 2;
			ptr++;
		}
		debug( 2, "player header[%d] = '%s'", no_headers-1, head );
	}

	if ( 2 != type )
	{
		// no more info should be player info here as we
		// requested it
		malformed_packet( server, "no players" );
		return PKT_ERROR;
	}

	while( 2 == type && ptr < end )
	{
		// now each player details
		// add the player
		if ( 0x00 == *ptr )
		{
			// no players
			if ( 0 != no_players )
			{
				malformed_packet( server, "no players" );
				return PKT_ERROR;
			}
		}
		else
		{
			struct player *player = add_player( server, total_players );
			int i;
			for ( i = 0; i < no_headers; i++ )
			{
				char *header = headers[i];
				char *val;
				int val_len;

				if ( ptr >= end )
				{
					malformed_packet( server, "short player detail" );
					return PKT_ERROR;
				}
				val = ptr;
				val_len = strlen( val );
				ptr += val_len + 1;

				// lets see what we got
				if ( 0 == strcmp( header, "player_" ) )
				{
					player->name = strdup( val );
				}
				else if ( 0 == strcmp( header, "score_" ) )
				{
					player->score = atoi( val );
				}
				else if ( 0 == strcmp( header, "deaths_" ) )
				{
					player->deaths = atoi( val );
				}
				else if ( 0 == strcmp( header, "ping_" ) )
				{
					player->ping = atoi( val );
				}
				else if ( 0 == strcmp( header, "kills_" ) )
				{
					player->frags = atoi( val );
				}
				else if ( 0 == strcmp( header, "team_" ) )
				{
					player->team = atoi( val );
				}
				else
				{
					int len = strlen( header );
					if ( '_' == header[len-1] )
					{
						header[len-1] = '\0';
					}
					player_add_info( player, header, val, NO_FLAGS );
				}

				debug( 2, "Player[%d][%s]=%s\n", total_players, headers[i], val );
			}
			total_players++;
		}

		if ( total_players > no_players )
		{
			malformed_packet( server, "to many players %d > %d", total_players, no_players );
			return PKT_ERROR;
		}

		// check for end of player info
		if ( 0x00 == *ptr )
		{
			if ( total_players != no_players )
			{
				malformed_packet( server, "bad number of players %d != %d", total_players, no_players );
				return PKT_ERROR;
			}
			type = 3;
			ptr++;
		}
	}

	if ( 3 != type )
	{
		// no more info should be team info here as we
		// requested it
		malformed_packet( server, "no teams" );
		return PKT_ERROR;
	}

	no_teams = (unsigned char)*ptr;
	ptr++;

	debug( 2, "No teams:%d\n", no_teams );
	no_headers = 0;

	while ( 3 == type && ptr < end )
	{
		// first we have the headers null seperated
		char **tmpp;
		char *head = ptr;
		int head_len = strlen( head );
		no_headers++;
		tmpp = (char**)realloc( headers, no_headers * sizeof( char* ) );
		if ( NULL == tmpp )
		{
			debug( 0, "Failed to realloc memory for headers\n" );
			if ( NULL != headers )
			{
				free( headers );
			}
			return MEM_ERROR;
		}

		headers = tmpp;
		headers[no_headers-1] = head;

		ptr += head_len + 1;

		// end of headers check
		if ( 0x00 == *ptr )
		{
			type = 4;
			ptr++;
		}
	}

	if ( 4 != type )
	{
		// no more info should be team info here as we
		// requested it
		malformed_packet( server, "no teams" );
		return PKT_ERROR;
	}

	while( 4 == type && ptr < end )
	{
		// now each teams details
		int i;
		for ( i = 0; i < no_headers; i++ )
		{
			char *val;
			int val_len;

			if ( ptr >= end )
			{
				malformed_packet( server, "short team detail" );
				return PKT_ERROR;
			}
			val = ptr;
			val_len = strlen( val );
			ptr += val_len + 1;

			// lets see what we got
			if ( 0 == strcmp( headers[i], "team_t" ) )
			{
				// BF being stupid again teams 1 based instead of 0
				players_set_teamname( server, total_teams + 1, val );
			}
			debug( 2, "Team[%d][%s]=%s\n", total_teams, headers[i], val );
		}
		total_teams++;

		if ( total_teams > no_teams )
		{
			malformed_packet( server, "to many teams" );
			return PKT_ERROR;
		}
	}

	return DONE_FORCE;
}
Example #14
0
void process_address_change (
    lispd_iface_elt     *iface,
    lisp_addr_t         new_addr)
{
    lisp_addr_t                 *iface_addr         = NULL;
    lispd_iface_mappings_list   *mapping_list       = NULL;
    int                         aux_afi             = 0;

    // XXX To be modified when full NAT implemented --> When Nat Aware active no IPv6 RLOCs supported
    if (nat_aware == TRUE && new_addr.afi == AF_INET6) {
        return;
    }

    /* Check if the addres is a global address*/
    if (is_link_local_addr(new_addr) == TRUE) {
        lispd_log_msg(LISP_LOG_DEBUG_2,"precess_address_change: the extractet address from the netlink "
                      "messages is a local link address: %s discarded", get_char_from_lisp_addr_t(new_addr));
        return;
    }
    /* If default RLOC afi defined (-a 4 or 6), only accept addresses of the specified afi */
    if (default_rloc_afi != AF_UNSPEC && default_rloc_afi != new_addr.afi) {
        lispd_log_msg(LISP_LOG_DEBUG_2,"precess_address_change: Default RLOC afi defined (-a #): Skipped %s address in iface %s",
                      (new_addr.afi == AF_INET) ? "IPv4" : "IPv6",iface->iface_name);
        return;
    }
    /*
     * Actions to be done due to a change of address: SMR
     */

    switch (new_addr.afi) {
    case AF_INET:
        iface_addr = iface->ipv4_address;
        break;
    case AF_INET6:
        iface_addr = iface->ipv6_address;
        break;
    }

    // Same address that we already have
    if (compare_lisp_addr_t(iface_addr,&new_addr)==0) {
        lispd_log_msg(LISP_LOG_DEBUG_2,"precess_address_change: The detected change of address for interface %s "
                      "doesn't affect",iface->iface_name);
        /* We must rebind the socket just in case the address is from a virtual interface who has changed its interafce number */
        switch (new_addr.afi) {
        case AF_INET:
            bind_socket_src_address(iface->out_socket_v4,&new_addr);
            break;
        case AF_INET6:
            bind_socket_src_address(iface->out_socket_v6,&new_addr);
            break;
        }

        return;
    }

    /*
     * Change source routing rules for this interface and binding
     */

    if (iface_addr->afi != AF_UNSPEC) {
        del_rule(iface_addr->afi,
                 0,
                 iface->iface_index,
                 iface->iface_index,
                 RTN_UNICAST,
                 iface_addr,
                 (iface_addr->afi == AF_INET) ? 32 : 128,
                 NULL,0,0);
    }
    add_rule(new_addr.afi,
             0,
             iface->iface_index,
             iface->iface_index,
             RTN_UNICAST,
             &new_addr,
             (new_addr.afi == AF_INET) ? 32 : 128,
             NULL,0,0);

    switch (new_addr.afi) {
    case AF_INET:
        bind_socket_src_address(iface->out_socket_v4,&new_addr);
        break;
    case AF_INET6:
        bind_socket_src_address(iface->out_socket_v6,&new_addr);
        break;
    }


    aux_afi = iface_addr->afi;
    // Update the new address
    copy_lisp_addr(iface_addr, &new_addr);


    /* The interface was down during initial configuratiopn process and now it is up. Activate address */
    if (aux_afi == AF_UNSPEC) {
        lispd_log_msg(LISP_LOG_DEBUG_1,"process_address_change: Activating the locator address %s"
                      , get_char_from_lisp_addr_t(new_addr));
        activate_interface_address(iface, new_addr);
        if (iface->status == UP) {
            iface_balancing_vectors_calc(iface);

            /*
             * If no default control and data interface, recalculate it
             */

            if ((default_ctrl_iface_v4 == NULL && new_addr.afi == AF_INET) ||
                    (default_ctrl_iface_v6 == NULL && new_addr.afi == AF_INET6)) {
                lispd_log_msg(LISP_LOG_DEBUG_2,"No default control interface. Recalculate new control interface");
                set_default_ctrl_ifaces();
            }

            if ((default_out_iface_v4 == NULL && new_addr.afi == AF_INET) ||
                    (default_out_iface_v6 == NULL && new_addr.afi == AF_INET6)) {
                lispd_log_msg(LISP_LOG_DEBUG_2,"No default output interface. Recalculate new output interface");
                set_default_output_ifaces();
            }
        }
    }

    lispd_log_msg(LISP_LOG_DEBUG_1,"precess_address_change: New address detected for interface %s -> %s",
                  iface->iface_name, get_char_from_lisp_addr_t(new_addr));

    mapping_list = iface->head_mappings_list;
    /* Sort again the locators list of the affected mappings*/
    while (mapping_list != NULL) {
        if (aux_afi != AF_UNSPEC && // When the locator is activated, it is automatically sorted
                ((new_addr.afi == AF_INET && mapping_list->use_ipv4_address == TRUE) ||
                 (new_addr.afi == AF_INET6 && mapping_list->use_ipv6_address == TRUE))) {
            sort_locators_list_elt (mapping_list->mapping, iface_addr);
        }
        mapping_list = mapping_list->next;
    }

    /* Indicate change of address in the interface */

    switch (new_addr.afi) {
    case AF_INET:
        iface->ipv4_changed = TRUE;
        break;
    case AF_INET6:
        iface->ipv6_changed = TRUE;
        break;
    }


    /* If it is compiled in router mode, then recompile default routes changing the indicated src address*/

    if (router_mode == TRUE) {
        switch (new_addr.afi) {
        case AF_INET:
            if (iface == default_out_iface_v4) {
                set_tun_default_route_v4();
            }
            break;
        case AF_INET6:
            if (iface == default_out_iface_v6) {
                del_tun_default_route_v6();
                set_tun_default_route_v6();
            }
            break;
        }
    }

    /* Check if the new address is behind NAT */

    if(nat_aware==TRUE) {
        // TODO : To be modified when implementing NAT per multiple interfaces
        nat_status = UNKNOWN;
        clear_rtr_from_locators (iface);

        if (iface->status == UP) {
            initial_info_request_process();
        } else {
            nat_aware_iface_address_change = TRUE;
        }
    }

    /* Reprograming SMR timer*/
    if (smr_timer == NULL) {
        smr_timer = create_timer (SMR_TIMER);
    }

    start_timer(smr_timer, LISPD_SMR_TIMEOUT,(timer_callback)init_smr, NULL);
}
Example #15
0
int main (int argc, char *argv[])
{
  if (argc != 2)
  {
    fprintf (stderr, "usage: %s rules-file\n", argv[0]);

    return (-1);
  }

  rules_t *rules = malloc (sizeof (rules_t));

  memset (rules, 0, sizeof (rules_t));

  char *file_rules;

  if ((file_rules = argv[1]) != NULL)
  {
    FILE *fp;

    if ((fp = fopen (file_rules, "rb")) != NULL)
    {
      char rule_buf[RP_RULE_BUFSIZ];

      int rule_len;

      while ((rule_len = fgetl (fp, rule_buf)) != -1)
      {
        if (rule_len == 0) continue;

        if (rule_buf[0] == '#') continue;

        int rc = add_rule (rule_buf, rule_len, rules);

        if (rc == 0)
        {
          /* all ok */
        }
        else if (rc == -1)
        {
          fprintf (stderr, "Skipping rule: %s (syntax error)\n", rule_buf);
        }
        else if (rc == -3)
        {
          fprintf (stderr, "Skipping rule: %s (duplicate rule)\n", rule_buf);
        }
        else if (rc == -4)
        {
          fprintf (stderr, "Skipping rule: %s (duplicate result)\n", rule_buf);
        }
      }

      fclose (fp);
    }
    else
    {
      fprintf (stderr, "%s: %s\n", file_rules, strerror (errno));

      free (rules);

      return (-1);
    }
  }

  char word_buf[BLOCK_SIZE];

  int word_len;

  while ((word_len = fgetl (stdin, word_buf)) != -1)
  {
    uint32_t rules_idx;

    for (rules_idx = 0; rules_idx < rules->rules_cnt; rules_idx++)
    {
      char next_buf[BLOCK_SIZE];

      int next_len = apply_rule (rules->rules_buf[rules_idx], rules->rules_len[rules_idx], word_buf, word_len, next_buf);

      if (next_len < 0) continue;

      puts (next_buf);
    }
  }

  return 0;
}
Example #16
0
void process_nl_new_link (struct nlmsghdr *nlh)
{
    struct ifinfomsg                    *ifi            = NULL;
    lispd_iface_elt                     *iface          = NULL;
    int                                 iface_index     = 0;
    uint8_t                             status          = UP;
    char                                iface_name[IF_NAMESIZE];
    uint32_t                            old_iface_index = 0;

    ifi = (struct ifinfomsg *) NLMSG_DATA (nlh);
    iface_index = ifi->ifi_index;


    iface = get_interface_from_index(iface_index);

    if (iface == NULL) {
        /*
         * In some OS when a virtual interface is removed and added again, the index of the interface change.
         * Search lispd_iface_elt by the interface name and update the index.
         */
        if (if_indextoname(iface_index, iface_name) != NULL) {
            iface = get_interface(iface_name);
        }
        if (iface == NULL) {
            lispd_log_msg(LISP_LOG_DEBUG_2, "process_nl_new_link: the netlink message is not for any interface associated with RLOCs  (%s)",
                          iface_name);
            return;
        } else {
            old_iface_index = iface->iface_index;
            iface->iface_index = iface_index;
            lispd_log_msg(LISP_LOG_DEBUG_2,"process_nl_new_link: The new index of the interface %s is: %d. Updating tables",
                          iface_name, iface->iface_index);
            /* Update routing tables and reopen sockets*/
            if (iface->ipv4_address->afi != AF_UNSPEC) {
                del_rule(AF_INET,0,old_iface_index,old_iface_index,RTN_UNICAST,iface->ipv4_address,32,NULL,0,0);
                add_rule(AF_INET,0,iface_index,iface_index,RTN_UNICAST,iface->ipv4_address,32,NULL,0,0);
                close(iface->out_socket_v4);
                iface->out_socket_v4 = open_device_binded_raw_socket(iface->iface_name,AF_INET);
                bind_socket_src_address(iface->out_socket_v4,iface->ipv4_address);
            }
            if (iface->ipv6_address->afi != AF_UNSPEC) {
                del_rule(AF_INET6,0,old_iface_index,old_iface_index,RTN_UNICAST,iface->ipv6_address,128,NULL,0,0);
                add_rule(AF_INET6,0,iface_index,iface_index,RTN_UNICAST,iface->ipv6_address,128,NULL,0,0);
                close(iface->out_socket_v6);
                iface->out_socket_v6 = open_device_binded_raw_socket(iface->iface_name,AF_INET6);
                bind_socket_src_address(iface->out_socket_v6,iface->ipv6_address);
            }
        }
    }

    if ((ifi->ifi_flags & IFF_RUNNING) != 0) {
        lispd_log_msg(LISP_LOG_DEBUG_1, "process_nl_new_link: Interface %s changes its status to UP",iface->iface_name);
        status = UP;
    }
    else {
        lispd_log_msg(LISP_LOG_DEBUG_1, "process_nl_new_link: Interface %s changes its status to DOWN",iface->iface_name);
        status = DOWN;
    }

    process_link_status_change (iface, status);
}
int main(int argc, char *argv[])
{
  ns_rule_handle_h *rh = NULL;
  uint32_t prio = 0,rule_read = 0;
  char *endptr;
  ns_rule_key_size_t key_size = SUPPORTED_TCAM_KEY_SIZE;
  ns_nfm_ret_t ret;
  unsigned int host_id = 15;
  unsigned int device = 0;

  ns_log_init(NS_LOG_COLOR | NS_LOG_CONSOLE);
  ns_log_lvl_set(NS_LOG_LVL_INFO);

  int c;
  while ((c = getopt_long(argc, argv, "l:hi:d:k:rn:", __long_options, NULL)) != -1) {
    switch (c) {
      case 'l':
        ns_log_lvl_set((unsigned int)strtoul(optarg,0,0));
        break;
      case 'i':
        host_id = (unsigned int)strtoul(optarg,0,0);
        if (host_id > 31) {
          fprintf(stderr, "Host_id %d is out of range (0-31)\n", device);
          exit(1);
        }
        break;
      case 'd':
        device = (unsigned int)strtoul(optarg,0,0);
        if (device > 3) {
          fprintf(stderr, "Device %d is out of range (0-3)\n", device);
          exit(1);
        }
        break;
      case 'k':
        key_size = strtoul(optarg, &endptr, 0);
        if (*endptr != '\0') {
          fprintf(stderr, "Invalid keysize %s\n", optarg);
          return 1;
        }
        if (key_size != SUPPORTED_TCAM_KEY_SIZE) {
                                        fprintf(stderr, "Invalid keysize %s, please use " SUPPORTED_TCAM_KEY_SIZE_STR "\n", optarg);
          print_usage(argv[0]);
        }
        break;
      case 'r':
        // Read Rule
        rule_read = 1;
        break;
      case 'n':
        // Rule name to be read or written
        strcpy(rnames, optarg);
        break;
      case 'h':
      default:
        print_usage(argv[0]);
    }
  }

  if (optind != argc)
    print_usage(argv[0]);

  // Init the rules lib
  rh = ns_rules_init(RULESD_Q_NAME, RQNAME, device);
  if (!rh) {
    fprintf(stderr, "ns_rules_init() failed\n");
    return 1;
  }

  if(!rule_read) {
    if (key_size == SUPPORTED_TCAM_KEY_SIZE) {
      /*
       * Reset the configuration.  This is ignored if there was no
       * configuration.  Note that this also flushes the rules from the
       * hardware.
       */
      ret = ns_rules_config_reset(rh);
      if (ret != NS_NFM_SUCCESS) {
        fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
        goto fail;
      }

      // Set the desired lookup key size
      ret = ns_rules_config_set_key_size(rh, key_size);
      if (ret != NS_NFM_SUCCESS) {
        fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
        goto fail;
      }
    }

    // Send config to rulesd
    ret = ns_rules_setup(rh);
    if (ret != NS_NFM_SUCCESS) {
      fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
      goto fail;
    }

    // Add a single rule to send traffic to host.
    // Prepare to add the rule
    //sprintf(rnames[num], "v6sample %d", num);
    ret = add_rule(rh, rnames, prio, SEND_ACTION_VIA_HOST,
        FST_30_MINUTE_LIST_NUM, host_id);
    if (ret != NS_NFM_SUCCESS) {
      fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
      goto fail;
    }

    // Commit
    ret = ns_rule_commit_rulesdb(rh);
    if (ret != NS_NFM_SUCCESS) {
      fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
      goto fail;
    }
  }
  else {

    if(read_rule(rh, rnames)) {
      fprintf(stderr, "failure to read rules @ %s: %d\n", __FILE__, __LINE__);
    }
  }

  // Dump
  ret = ns_rule_dump_rules(rh);
  if (ret != NS_NFM_SUCCESS) {
    fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
    goto fail;
  }

  // Close the rules library.
  ret = ns_rules_close(rh);
  if (ret != NS_NFM_SUCCESS) {
    fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
    goto fail;
  }

  return 0;

fail:
  ns_rules_close(rh);
  return 1;
}
Example #18
0
int
init_acl(const char *path)
{
    // initialize ipset
    ipset_init_library();

    ipset_init(&white_list_ipv4);
    ipset_init(&white_list_ipv6);
    ipset_init(&black_list_ipv4);
    ipset_init(&black_list_ipv6);
    ipset_init(&outbound_block_list_ipv4);
    ipset_init(&outbound_block_list_ipv6);

    cork_dllist_init(&black_list_rules);
    cork_dllist_init(&white_list_rules);
    cork_dllist_init(&outbound_block_list_rules);

    struct ip_set *list_ipv4  = &black_list_ipv4;
    struct ip_set *list_ipv6  = &black_list_ipv6;
    struct cork_dllist *rules = &black_list_rules;

    FILE *f = fopen(path, "r");
    if (f == NULL) {
        LOGE("Invalid acl path.");
        return -1;
    }

    char buf[257];
    while (!feof(f))
        if (fgets(buf, 256, f)) {
            // Discards the whole line if longer than 255 characters
            int long_line = 0;  // 1: Long  2: Error
            while ((strlen(buf) == 255) && (buf[254] != '\n')) {
                long_line = 1;
                LOGE("Discarding long ACL content: %s", buf);
                if (fgets(buf, 256, f) == NULL) {
                    long_line = 2;
                    break;
                }
            }
            if (long_line) {
                if (long_line == 1) {
                    LOGE("Discarding long ACL content: %s", buf);
                }
                continue;
            }

            // Trim the newline
            int len = strlen(buf);
            if (len > 0 && buf[len - 1] == '\n') {
                buf[len - 1] = '\0';
            }

            char *comment = strchr(buf, '#');
            if (comment) {
                *comment = '\0';
            }

            char *line = trimwhitespace(buf);
            if (strlen(line) == 0) {
                continue;
            }

            if (strcmp(line, "[outbound_block_list]") == 0) {
                list_ipv4 = &outbound_block_list_ipv4;
                list_ipv6 = &outbound_block_list_ipv6;
                rules     = &outbound_block_list_rules;
                continue;
            } else if (strcmp(line, "[black_list]") == 0
                       || strcmp(line, "[bypass_list]") == 0) {
                list_ipv4 = &black_list_ipv4;
                list_ipv6 = &black_list_ipv6;
                rules     = &black_list_rules;
                continue;
            } else if (strcmp(line, "[white_list]") == 0
                       || strcmp(line, "[proxy_list]") == 0) {
                list_ipv4 = &white_list_ipv4;
                list_ipv6 = &white_list_ipv6;
                rules     = &white_list_rules;
                continue;
            } else if (strcmp(line, "[reject_all]") == 0
                       || strcmp(line, "[bypass_all]") == 0) {
                acl_mode = WHITE_LIST;
                continue;
            } else if (strcmp(line, "[accept_all]") == 0
                       || strcmp(line, "[proxy_all]") == 0) {
                acl_mode = BLACK_LIST;
                continue;
            }

            char host[257];
            int cidr;
            parse_addr_cidr(line, host, &cidr);

            struct cork_ip addr;
            int err = cork_ip_init(&addr, host);
            if (!err) {
                if (addr.version == 4) {
                    if (cidr >= 0) {
                        ipset_ipv4_add_network(list_ipv4, &(addr.ip.v4), cidr);
                    } else {
                        ipset_ipv4_add(list_ipv4, &(addr.ip.v4));
                    }
                } else if (addr.version == 6) {
                    if (cidr >= 0) {
                        ipset_ipv6_add_network(list_ipv6, &(addr.ip.v6), cidr);
                    } else {
                        ipset_ipv6_add(list_ipv6, &(addr.ip.v6));
                    }
                }
            } else {
                rule_t *rule = new_rule();
                accept_rule_arg(rule, line);
                init_rule(rule);
                add_rule(rules, rule);
            }
        }

    fclose(f);

    return 0;
}
Example #19
0
query_status_t deal_with_cube2_packet( struct qserver *server, char *rawpkt, int pktlen )
{
	// skip unimplemented ack, crc, etc
	int i;
	int numattr;
	int attr[MAX_ATTR];
	char buf[MAX_STRING];
	enum {
		MM_OPEN = 0,
		MM_VETO,
		MM_LOCKED,
		MM_PRIVATE
	};
	struct offset d;
	d.d = (unsigned char *) rawpkt;
	d.pos = 0;
	d.len = pktlen;

	server->ping_total += time_delta( &packet_recv_time, &server->packet_time1 );
	getint( &d ); // we have the ping already
	server->num_players = getint( &d );
	numattr = getint( &d );
	for ( i = 0; i < numattr && i < MAX_ATTR; i++ )
	{
		attr[i] = getint (&d);
	}

	server->protocol_version = attr[0];

	sprintf( buf, "%d %s", attr[0], sb_getversion_s (attr[0]) );
	add_rule( server, "version", buf, NO_FLAGS );

	sprintf( buf, "%d %s", attr[1], sb_getmode_s (attr[1]) );
	add_rule( server, "mode", buf, NO_FLAGS );

	sprintf( buf, "%d", attr[2] );
	add_rule( server, "seconds_left", buf, NO_FLAGS );

	server->max_players = attr[3];

	switch ( attr[5] )
	{
	case MM_OPEN:
		sprintf( buf, "%d open", attr[5] );
		break;
	case MM_VETO:
		sprintf( buf, "%d veto", attr[5] );
		break;
	case MM_LOCKED:
		sprintf( buf, "%d locked", attr[5] );
		break;
	case MM_PRIVATE:
		sprintf( buf, "%d private", attr[5] );
		break;
	default:
		sprintf( buf, "%d unknown", attr[5] );
	}
	add_rule( server, "mm", buf, NO_FLAGS);

	for ( i = 0; i < numattr && i < MAX_ATTR; i++ )
	{
		char buf2[MAX_STRING];
		sprintf( buf, "attr%d", i );
		sprintf( buf2, "%d", attr[i] );
		add_rule( server, buf, buf2, NO_FLAGS );
	}

	getstr( buf, MAX_STRING, &d );
	server->map_name = strdup(buf);
	getstr( buf, MAX_STRING, &d );
	server->server_name = strdup(buf);

	return DONE_FORCE;
}
Example #20
0
File: parse.c Project: NetSys/sts
static struct parse_tf *
parse_tf (const char *name)
{
  FILE *in = fopen (name, "r");
  char *line = NULL;
  int len;
  size_t n;

  if (!in || (len = getline (&line, &n, in)) == -1)
    err (1, "Can't read file \"%s\"", name);

  int tflen;
  char prefix[MAX_PREFIX + 1];

  int res = sscanf (line, "%d$%" QUOTE (MAX_PREFIX) "[^$]$", &tflen, prefix);
  if (res < 1) errx (1, "Can't read len from first line \"%s\".", line);
  tflen /= 2; /* Convert to L */

  struct parse_tf *tf = xcalloc (1, sizeof *tf);
  tf->len = tflen;
  if (res == 2) tf->prefix = xstrdup (prefix);

  /* Skip next line */
  getline (&line, &n, in);
  while ((len = getline (&line, &n, in)) != -1) {
    char *save;
    char *type, *instr, *match, *mask, *rewrite, *outstr, *affected;
    //char *file, *lines, *id;

    type = strtok_r (line, "$", &save);
    instr = strtok_r (NULL, "$", &save);
    match = strtok_r (NULL, "$", &save);
    mask = strtok_r (NULL, "$", &save);
    rewrite = strtok_r (NULL, "$", &save);
    /*inv_match =*/ strtok_r (NULL, "$", &save);
    /*inv_rewrite =*/ strtok_r (NULL, "$", &save);
    outstr = strtok_r (NULL, "$", &save);
    affected = strtok_r (NULL, "$", &save);
    /*influence = */strtok_r (NULL, "$", &save);
    /* TODO: desc
    file = strtok_r (NULL, "$", &save);
    lines = strtok_r (NULL, "$", &save);
    id = strtok_r (NULL, "$", &save);
    if (!id) { id = file; file = lines = NULL; }*/

    struct parse_rule *r = xcalloc (1, sizeof *r);
    r->in = read_array (instr, NULL);
    r->out = read_array (outstr, NULL);
    /*if (file) {
      r->file = xstrdup (file);
      lines[strlen (lines) - 1] = 0;
      r->lines = xstrdup (lines);
    }*/

    if (strcmp (type, "link")) {
      r->match = array_from_str (match);
      if (!strcmp (type, "rw")) {
        r->mask = array_from_str (mask);
        r->rewrite = array_from_str (rewrite);
      }
    }
    r->deps = read_deps (affected);
    add_rule (tf, r);
  }

  free (line);
  fclose (in);
  return tf;
}
Example #21
0
File: debug.c Project: 01org/murphy
int mrp_debug_set_config(const char *cmd)
{
    char    buf[2 * PATH_MAX + 1], *colon, *at, *eq;
    char   *func, *file, *end;
    size_t  len;
    int     del, off, line;

    if (*cmd == '+' || *cmd == '-')
        del = (*cmd++ == '-');
    else
        del = FALSE;

    eq = strchr(cmd, '=');

    if (eq == NULL) {
        strncpy(buf, cmd, sizeof(buf) - 1);
        buf[sizeof(buf) - 1] = '\0';
        off = FALSE;
    }
    else {
        if (!strcmp(eq + 1, "on"))
            off = FALSE;
        else if (!strcmp(eq + 1, "off"))
            off = TRUE;
        else
            return FALSE;

        len = eq - cmd;
        if (len >= sizeof(buf))
            len = sizeof(buf) - 1;

        strncpy(buf, cmd, len);
        buf[len] = '\0';
    }

    colon = strchr(buf, ':');

    if (colon != NULL) {
        if (strchr(buf, '@') != NULL)
            return FALSE;

        *colon = '\0';
        func   = NULL;
        file   = buf;
        line   = strtoul(colon + 1, &end, 10);

        if (end && *end)
            return FALSE;

        mrp_log_info("%s file='%s', line=%d, %s", del ? "del" : "add",
                     file, line, off ? "off" : "on");
    }
    else {
        at = strchr(buf, '@');

        if (at != NULL) {
            *at = '\0';
            func = (at == buf ? NULL : buf);
            file = at + 1;
            line = 0;

            mrp_log_info("%s func='%s', file='%s', %s", del ? "del" : "add",
                         func ? func : "", file, off ? "off" : "on");
        }
        else {
            func = buf;
            file = NULL;
            line = 0;

            mrp_log_info("%s func='%s' %s", del ? "del" : "add",
                         func, off ? "off" : "on");
        }
    }

    if (!del)
        return add_rule(func, file, line, off);
    else
        return del_rule(func, file, line, off);

    return TRUE;
}
Example #22
0
/*
 * Creates the routes to send the traffic to the tun interface to be encapsulated
 */
int configure_routing_to_tun()
{
    lispd_mapping_list  *list        = NULL;
    lispd_mapping_list  *list_elt    = NULL;
    lisp_addr_t         *tun_v4_addr = NULL;
    lisp_addr_t         *tun_v6_addr = NULL;
    lispd_mapping_elt   *mapping     = NULL;
    uint32_t            iface_index  = 0;


    if (tun_bring_up_iface(TUN_IFACE_NAME) != GOOD){
        return (BAD);
    }

    if (router_mode == FALSE)
    {
        /*
         * For mobile node mode, we create two /1 routes covering the full IP addresses space to route all traffic
         * generated by the node to the lispTun0 interface
         *          IPv4: 0.0.0.0/1 and 128.0.0.0/1
         *          IPv6: ::/1      and 8000::/1
         */
        tun_v4_addr = get_main_eid(AF_INET);
        tun_v6_addr = get_main_eid(AF_INET6);

        if (tun_v4_addr != NULL){
            if (tun_add_eid_to_iface(*tun_v4_addr,TUN_IFACE_NAME) != GOOD){
                return (BAD);
            }
            if (set_tun_default_route_v4() != GOOD){
                return (BAD);
            }
        }
        if (tun_v6_addr != NULL){
            if (tun_add_eid_to_iface(*tun_v6_addr,TUN_IFACE_NAME) != GOOD){
                return (BAD);
            }
            if (set_tun_default_route_v6() != GOOD){
                return (BAD);
            }
        }
    }else{
        /*
         * For router mode, add a new routing table with default route to tun interface. Using source routing,
         * We send all traffic generated by EIDs to this table
         */
        list = get_all_mappings(AF_UNSPEC);
        list_elt = list;
        /* Create rules to the new table */
        while (list_elt != NULL){
            mapping = list_elt->mapping;
            if (add_rule(mapping->eid_prefix.afi,
                        0,
                        LISP_TABLE,
                        RULE_TO_LISP_TABLE_PRIORITY,
                        RTN_UNICAST,
                        &(mapping->eid_prefix),
                        mapping->eid_prefix_length,
                        NULL,0,0)!=GOOD){
                free_mapping_list(list, FALSE);
                return (BAD);
            }
            list_elt = list_elt->next;
            if (add_rule(mapping->eid_prefix.afi,
                    0,
                    RT_TABLE_MAIN,
                    RULE_AVOID_LISP_TABLE_PRIORITY,
                    RTN_UNICAST,
                    NULL,0,
                    &(mapping->eid_prefix),
                    mapping->eid_prefix_length,
                    0)!=GOOD){
                free_mapping_list(list, FALSE);
                return (BAD);
            }
        }
        /* Add default route into the new table */
        iface_index = if_nametoindex(TUN_IFACE_NAME);
        tun_v4_addr = get_main_eid(AF_INET);
        tun_v6_addr = get_main_eid(AF_INET6);
        if (tun_v4_addr != NULL){
            add_route(AF_INET,iface_index,NULL,NULL,NULL,0,RULE_TO_LISP_TABLE_PRIORITY,LISP_TABLE);
        }
        if (tun_v6_addr != NULL){
            add_route(AF_INET6,iface_index,NULL,NULL,NULL,0,RULE_TO_LISP_TABLE_PRIORITY,LISP_TABLE);
        }

        free_mapping_list(list, FALSE);
    }
    return (GOOD);
}
Example #23
0
static bool parse_line_v1 (RuleSet* rs, const char* line)
{
	if (0 == strcmp (line, "forward-unmatched")) {
		rs->forward_unmatched = true;
		return true;
	}

	if (0 == strcmp (line, "match-all")) {
		rs->match_all = true;
		return true;
	}

	Rule r;
	clear_rule (&r);

	char *tmp, *fre, *prt;
	int i = 0;
	bool in_match = true;
	tmp = fre = strdup (line);
	for (prt = strtok (tmp, " "); prt; prt = strtok (NULL, " "), ++i) {
		bool rv;
		if (prt[0] == '#') {
			break;
		}
		if (0 == strcmp (prt, "|")) {
			if (i == 0 || !in_match) {
				i = -1;
				break;
			}
			in_match = false;
			r.len = i;
			i = -1; // continue bumps it
			continue;
		}
		if (i >= MAX_MSG) {
			i = -1;
			break;
		}

		if (in_match) {
			switch (i) {
				case 0:
					rv = parse_status (&r, prt);
					break;
				case 1:
					r.match[i] = parse_note (prt); // TODO IFF note-status..
					if (r.match[i] < 128) {
						r.mask[i] = 0x7f;
						rv = true;
						break;
					}
					// no break - fall through
				default:
					rv = parse_match (&r, i, prt);
					break;
			}
		} else {
			switch (i) {
				case 1:
					r.tx_set[i] = parse_note (prt); // TODO IFF note-status..
					if (r.tx_set[i] < 128) {
						r.tx_mask[i] = 0x00;
						rv = true;
						break;
					}
					// no break - fall through
				default:
					rv = parse_replacement (&r, i, prt);
					break;
			}
		}

		if (!rv) {
			i = -1;
			break;
		}
	}

	r.tx_len = i;

	free (fre);
	if (r.tx_len < 1 || r.tx_len > MAX_MSG || r.len < 1 || r.len > MAX_MSG || in_match) {
		return false;
	}

	add_rule (rs, &r);
	return true;
}
int main_seinject(int argc, char **argv) {
	char *policy = NULL, *source = NULL, *target = NULL, *clazz = NULL, *perm = NULL, *perm_token = NULL, *perm_saveptr = NULL, *outfile = NULL, *permissive = NULL;
	policydb_t policydb;
	struct policy_file pf, outpf;
	sidtab_t sidtab;
	int ret_add_rule;
	int load = 0;
	int quiet = 0;
	FILE *fp;
	int i;

	for (i=1; i<argc; i++) {
		if (argv[i][0] == '-') {
			if (argv[i][1] == 's') {
				i++;
				source = argv[i];
				continue;
			}
			if (argv[i][1] == 't') {
				i++;
				target = argv[i];
				continue;
			}
			if (argv[i][1] == 'c') {
				i++;
				clazz = argv[i];
				continue;
			}
			if (argv[i][1] == 'p') {
				i++;
				perm = argv[i];
				continue;
			}
			if (argv[i][1] == 'P') {
				i++;
				policy = argv[i];
				continue;
			}
			if (argv[i][1] == 'o') {
				i++;
				outfile = argv[i];
				continue;
			}
			if (argv[i][1] == 'Z') {
				i++;
				permissive = argv[i];
				continue;
			}
			if (argv[i][1] == 'l') {
				load = 1;
				continue;
			}
			if (argv[i][1] == 'q') {
				quiet = 1;
				continue;
			}
			break;
		}
	}

	if (i < argc || argc == 1 || ((!source || !target || !clazz || !perm) && !permissive)) {
		fprintf(stderr, "%s -s <source type> -t <target type> -c <class> -p <perm>[,<perm2>,<perm3>,...] [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]);
		fprintf(stderr, "%s -Z permissive_type [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]);
		exit(1);
	}

	if (!policy)
		policy = "/sys/fs/selinux/policy";

	sepol_set_policydb(&policydb);
	sepol_set_sidtab(&sidtab);

	if (load_policy(policy, &policydb, &pf)) {
		fprintf(stderr, "Could not load policy\n");
		return 1;
	}

	if (policydb_load_isids(&policydb, &sidtab))
		return 1;

	if (permissive) {
		type_datum_t *type;
		type = hashtab_search(policydb.p_types.table, permissive);
		if (type == NULL) {
			fprintf(stderr, "type %s does not exist\n", permissive);
			return 2;
		}
		if (ebitmap_set_bit(&policydb.permissive_map, type->s.value, 1)) {
			fprintf(stderr, "Could not set bit in permissive map\n");
			return 1;
		}
	} else {
		perm_token = strtok_r(perm, ",", &perm_saveptr);
		while (perm_token) {
			ret_add_rule = add_rule(source, target, clazz, perm_token, &policydb);
			if (ret_add_rule) {
				fprintf(stderr, "Could not add rule for perm: %s\n", perm_token);
				return ret_add_rule;
			}
			perm_token = strtok_r(NULL, ",", &perm_saveptr);
		}
	}

	if (outfile) {
		fp = fopen(outfile, "wb");
		if (!fp) {
			fprintf(stderr, "Could not open outfile\n");
			return 1;
		}

		policy_file_init(&outpf);
		outpf.type = PF_USE_STDIO;
		outpf.fp = fp;

		if (policydb_write(&policydb, &outpf)) {
			fprintf(stderr, "Could not write policy\n");
			return 1;
		}

		fclose(fp);
	}

	if (load) {
		if (load_policy_into_kernel(&policydb)) {
			fprintf(stderr, "Could not load new policy into kernel\n");
			return 1;
		}
	}

	policydb_destroy(&policydb);

	if (quiet == 0)
		fprintf(stdout, "Success\n");
	return 0;
}
Example #25
0
query_status_t deal_with_ottd_packet(struct qserver *server, char *rawpkt, int pktlen)
{
	unsigned char *ptr = (unsigned char*)rawpkt;
	unsigned char *end = (unsigned char*)(rawpkt + pktlen);
	unsigned char type;
	char* str;
	char buf[32];
	unsigned ver;

	server->n_servers++;
	if ( server->server_name == NULL)
	{
		server->ping_total += time_delta( &packet_recv_time, &server->packet_time1);
		server->n_requests++;
	}
	else
	{
		gettimeofday( &server->packet_time1, NULL);
	}

	FAIL_IF(pktlen < 4 || swap_short_from_little(rawpkt) > pktlen, "invalid packet");

	type = ptr[2];
	ver = ptr[3];
	ptr += 4;

	debug(3, "len %hu type %hhu ver %hhu", swap_short_from_little(rawpkt), type, ver);

	FAIL_IF(ver != 4 && ver != 5, "only version 4 and 5 servers are supported");

	if(type == 1) // info packet
	{
		unsigned numgrf = *ptr;
		FAIL_IF(ptr + numgrf * 20 + 1 > end, "invalid newgrf number");
		ptr += numgrf * 20 + 1;

		snprintf(buf, sizeof(buf), "%u", swap_long_from_little(ptr));
		add_rule(server, "date_days", buf, NO_FLAGS);
		ptr += 4;

		snprintf(buf, sizeof(buf), "%u", swap_long_from_little(ptr));
		add_rule(server, "startdate_days", buf, NO_FLAGS);
		ptr += 4;

		FAIL_IF(ptr + 3 > end, "invalid packet");

		snprintf(buf, sizeof(buf), "%hhu", ptr[0]);
		add_rule(server, "maxcompanies", buf, NO_FLAGS);
		snprintf(buf, sizeof(buf), "%hhu", ptr[1]);
		add_rule(server, "numcompanies", buf, NO_FLAGS);
		server->max_spectators = ptr[2];
		ptr += 3;

		GET_STRING;
		server->server_name = strdup(str);

		GET_STRING;
		add_rule(server, "version", str, NO_FLAGS);

		FAIL_IF(ptr + 7 > end, "invalid packet");

		{
			static const char* langs[] = {
				"any",
				"English",
				"German",
				"French"
			};
			unsigned i = *ptr++;
			if(i > 3) i = 0;
			add_rule(server, "language", (char*)langs[i], NO_FLAGS);
		}

		add_rule(server, "password", *ptr++ ? "1" : "0", NO_FLAGS);

		server->max_players = *ptr++;
		server->num_players = *ptr++;
		server->num_spectators = *ptr++;

		GET_STRING;

		server->map_name = strdup(str);

		snprintf(buf, sizeof(buf), "%hu", swap_short_from_little(ptr));
		add_rule(server, "map_width", buf, NO_FLAGS);
		snprintf(buf, sizeof(buf), "%hu", swap_short_from_little(ptr));
		add_rule(server, "map_height", buf, NO_FLAGS);

		{
			static const char* sets[] = {
				"temperate",
				"arctic",
				"desert",
				"toyland"
			};
			unsigned i = *ptr++;
			if(i > 3) i = 0;
			add_rule(server, "map_set", (char*)sets[i], NO_FLAGS);
		}

		add_rule(server, "dedicated", *ptr++ ? "1" : "0", NO_FLAGS);
	}
	else if(type == 3) // player packet
	{
		unsigned i, j;
		INVALID_IF(ptr + 2 > end);

		server->num_players = *ptr++;

		for(i = 0; i < server->num_players; ++i)
		{
			unsigned long long lli;
			struct player* player;
			unsigned char nr;

			nr = *ptr++;

			debug(3, "player number %d", nr);
			player = add_player(server, i);
			FAIL_IF(!player, "can't allocate player");

			GET_STRING;
			player->name = strdup(str);
			debug(3, "name %s", str);
			player->frags = 0;

			INVALID_IF(ptr + 4 + 3*8 + 2 + 1 + 2*MAX_VEHICLE_TYPES + 2*MAX_STATION_TYPES > end);

			snprintf(buf, sizeof(buf), "%u", swap_long_from_little(ptr));
			player_add_info(player, "startdate", buf, 0);
			ptr += 4;

			lli = swap_long_from_little(ptr+4);
			lli <<= 32;
			lli += swap_long_from_little(ptr);
			snprintf(buf, sizeof(buf), "%lld", lli);
			player_add_info(player, "value", buf, 0);
			ptr += 8;

			lli = swap_long_from_little(ptr+4);
			lli <<= 32;
			lli = swap_long_from_little(ptr);
			snprintf(buf, sizeof(buf), "%lld", lli);
			player_add_info(player, "money", buf, 0);
			ptr += 8;

			lli = swap_long_from_little(ptr+4);
			lli <<= 32;
			lli += swap_long_from_little(ptr);
			snprintf(buf, sizeof(buf), "%lld", lli);
			player_add_info(player, "income", buf, 0);
			ptr += 8;

			snprintf(buf, sizeof(buf), "%hu", swap_short_from_little(ptr));
			player_add_info(player, "performance", buf, 0);
			ptr += 2;

			player_add_info(player, "password", *ptr?"1":"0", 0);
			++ptr;

			for (j = 0; j < MAX_VEHICLE_TYPES; ++j)
			{
				snprintf(buf, sizeof(buf), "%hu", swap_short_from_little(ptr));
				player_add_info(player, (char*)vehicle_types[j], buf, 0);
				ptr += 2;
			}
			for (j = 0; j < MAX_STATION_TYPES; ++j)
			{
				snprintf(buf, sizeof(buf), "%hu", swap_short_from_little(ptr));
				player_add_info(player, (char*)station_types[j], buf, 0);
				ptr += 2;
			}
			
			if (ver != 5)
			{
				// connections
				while(ptr + 1 < end && *ptr)
				{
					++ptr;
					GET_STRING; // client name
					debug(3, "%s played by %s", str, player->name);
					GET_STRING; // id
					INVALID_IF(ptr + 4 > end);
					ptr += 4;
				}

				++ptr; // record terminated by zero byte
			}
		}

		// spectators
		while(ptr + 1 < end && *ptr)
		{
			++ptr;
			GET_STRING; // client name
			debug(3, "spectator %s", str);
			GET_STRING; // id
			INVALID_IF(ptr + 4 > end);
			ptr += 4;
		}
		++ptr; // record terminated by zero byte

		server->next_rule = NO_SERVER_RULES; // we're done
		server->next_player_info = server->num_players; // we're done
	}
	else
	{
		malformed_packet( server, "invalid type" );
		return PKT_ERROR;
	}

	server->retry1 = n_retries; // we're done with this packet, reset retry counter

	return DONE_AUTO;
}
int main(int argc, char *argv[])
{
  ns_rule_handle_h *rh = NULL;
  ns_nfm_ret_t ret = NS_NFM_SUCCESS;
  unsigned int host_id = 15;
  unsigned int device = 0;
  unsigned int nrules = 32768;
  unsigned int i;

  ns_log_init(NS_LOG_COLOR | NS_LOG_CONSOLE);
  ns_log_lvl_set(NS_LOG_LVL_INFO);

  int c;
  while ((c = getopt_long(argc, argv, "l:hd:", __long_options, NULL)) != -1) {
    switch (c) {
    case 'l':
      ns_log_lvl_set((unsigned int)strtoul(optarg,0,0));
      break;
    case 'i':
      host_id = (unsigned int)strtoul(optarg,0,0);
      if (host_id > 31) {
        fprintf(stderr, "Host_id %d is out of range (0-31)\n", device);
        exit(1);
      }
      break;
    case 'd':
      device = (unsigned int)strtoul(optarg,0,0);
      if (device > 3) {
        fprintf(stderr, "Device %d is out of range (0-3)\n", device);
        exit(1);
      }
      break;
    case 'h':
    default:
      print_usage(argv[0]);
    }
  }

  if (optind < argc - 1)
    print_usage(argv[0]);

  if (optind < argc) {
    nrules = strtoul(argv[optind], NULL, 0);
    if (nrules > NUM_RULES) {
      fprintf(stderr, "Max rules is %u\n", NUM_RULES);
      return 1;
    }
  }

  // Init the rules lib
  printf("opening connection to rules daemon\n");
  rh = ns_rules_init(RULESD_Q_NAME, RQNAME, device);
  if (!rh) {
    fprintf(stderr, "ns_rules_init() failed\n");
    return 1;
  }

  // Send default config to rulesd
  ret = ns_rules_setup(rh);
  if (ret != NS_NFM_SUCCESS) {
    fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
    goto fail;
  }

  printf("\tflushing rules...\n");
  // Flush all the existing rules.
  ret = ns_rule_flush_hw(rh);
  if (ret != NS_NFM_SUCCESS) {
    fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
    goto fail;
  }

  printf("\tcreating %u rules...\n", nrules);
  for (i = 0; i < nrules; i++) {
    sprintf(rnames[i], "rule %u", i);
    ret = add_rule(rh, rnames[i], SEND_ACTION_PASS,
                   FST_30_SECOND_LIST_NUM);
    if (ret != NS_NFM_SUCCESS) {
      fprintf(stderr, "failure @ %s: %d on rule %u\n", __FILE__, __LINE__, i);
      goto fail;
    }
  }

  // Commit
  printf("\tcommitting new rules...\n");
  ret = ns_rule_commit_rulesdb(rh);
  if (ret != NS_NFM_SUCCESS) {
    fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
    goto fail;
  }

  // Close the rules library.
  printf("done\n");
  ns_rules_close(rh);
  if (ret != NS_NFM_SUCCESS) {
    fprintf(stderr, "failure @ %s: %d\n", __FILE__, __LINE__);
    goto fail;
  }

  return 0;

fail:
  ns_rules_close(rh);
  return 1;
}
Example #27
0
rt_data_t* dr_load_routing_info( db_func_t *dr_dbf, db_con_t* db_hdl,
							str *drd_table, str *drc_table, str* drr_table )
{
	int    int_vals[4];
	char * str_vals[6];
	str tmp;
	db_key_t columns[8];
	db_res_t* res;
	db_row_t* row;
	rt_info_t *ri;
	rt_data_t *rdata;
	tmrec_t   *time_rec;
	int i,n;
	int no_rows = 10;

	res = 0;
	ri = 0;
	rdata = 0;

	/* init new data structure */
	if ( (rdata=build_rt_data())==0 ) {
		LM_ERR("failed to build rdata\n");
		goto error;
	}

	if (db_check_table_version(dr_dbf, db_hdl, drd_table, 5 )!= 0)
		goto error;

	/* read the destinations */
	if (dr_dbf->use_table( db_hdl, drd_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drd_table->len,drd_table->s);
		goto error;
	}

	columns[0] = &id_drd_col;
	columns[1] = &gwid_drd_col;
	columns[2] = &address_drd_col;
	columns[3] = &strip_drd_col;
	columns[4] = &prefix_drd_col;
	columns[5] = &type_drd_col;
	columns[6] = &attrs_drd_col;
	columns[7] = &probe_drd_col;

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, 0 ) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		no_rows = estimate_available_rows( 4+32+15+4+32+4+128+4, 8);
		if (no_rows==0) no_rows = 10;
		if(dr_dbf->fetch_result(db_hdl, &res, no_rows )<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	LM_DBG("%d records found in %.*s\n",
		RES_ROW_N(res), drd_table->len,drd_table->s);

	n = 0;
	do {
		for(i=0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;
			/* DB ID column */
			check_val(ID_DRD_COL, ROW_VALUES(row), DB_INT, 1, 0);
			int_vals[0] = VAL_INT(ROW_VALUES(row));
			/* GW ID column */
			check_val(GWID_DRD_COL, ROW_VALUES(row)+1, DB_STRING, 1, 1);
			str_vals[3] = (char*)VAL_STRING(ROW_VALUES(row)+1);
			/* ADDRESS column */
			check_val(ADDRESS_DRD_COL, ROW_VALUES(row)+2, DB_STRING, 1, 1);
			str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+2);
			/* STRIP column */
			check_val(STRIP_DRD_COL, ROW_VALUES(row)+3, DB_INT, 1, 0);
			int_vals[1] = VAL_INT   (ROW_VALUES(row)+3);
			/* PREFIX column */
			check_val(PREFIX_DRD_COL, ROW_VALUES(row)+4, DB_STRING, 0, 0);
			str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+4);
			/* TYPE column */
			check_val(TYPE_DRD_COL, ROW_VALUES(row)+5, DB_INT, 1, 0);
			int_vals[2] = VAL_INT(ROW_VALUES(row)+5);
			/* ATTRS column */
			check_val(ATTRS_DRD_COL, ROW_VALUES(row)+6, DB_STRING, 0, 0);
			str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+6);
			/*PROBE_MODE column */
			check_val(PROBE_DRD_COL, ROW_VALUES(row)+7, DB_INT, 1, 0);
			int_vals[3] = VAL_INT(ROW_VALUES(row)+7);

			/* add the destinaton definition in */
			if ( add_dst( rdata, str_vals[3], str_vals[0], int_vals[1],
			str_vals[1], int_vals[2], str_vals[2], int_vals[3])<0 ) {
				LM_ERR("failed to add destination id %d -> skipping\n",
					int_vals[0]);
				continue;
			}
			n++;
		}
		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
				LM_ERR( "fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	/* read the carriers, if any */
	if (dr_dbf->use_table( db_hdl, drc_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drc_table->len,drc_table->s);
		goto error;
	}

	columns[0] = &id_drc_col;
	columns[1] = &cid_drc_col;
	columns[2] = &flags_drc_col;
	columns[3] = &gwlist_drc_col;
	columns[4] = &attrs_drc_col;

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 5, 0, 0 ) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		no_rows = estimate_available_rows( 4+4+32+64+64, 5/*cols*/);
		if (no_rows==0) no_rows = 10;
		if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 5, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("table \"%.*s\" empty\n", drc_table->len,drc_table->s );
	} else {
		LM_DBG("%d records found in %.*s\n",
			RES_ROW_N(res), drc_table->len,drc_table->s);
		do {
			for(i=0; i < RES_ROW_N(res); i++) {
				row = RES_ROWS(res) + i;
				/* ID column */
				check_val(ID_DRC_COL, ROW_VALUES(row), DB_INT, 1, 0);
				int_vals[0] = VAL_INT(ROW_VALUES(row));
				/* CARRIER_ID column */
				check_val(CID_DRC_COL, ROW_VALUES(row)+1, DB_STRING, 1, 1);
				str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1);
				/* ID column */
				check_val(ID_DRC_COL, ROW_VALUES(row)+2, DB_INT, 1, 0);
				int_vals[1] = VAL_INT(ROW_VALUES(row)+2);
				/* GWLIST column */
				check_val(GWLIST_DRC_COL, ROW_VALUES(row)+3, DB_STRING, 1, 1);
				str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+3);
				/* ATTRS column */
				check_val(ATTRS_DRC_COL, ROW_VALUES(row)+4, DB_STRING, 0, 0);
				str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+4);

				/* add the new carrier */
				if ( add_carrier( int_vals[0], str_vals[0], int_vals[1],
				str_vals[1], str_vals[2], rdata) != 0 ) {
					LM_ERR("failed to add carrier db_id %d -> skipping\n",
						int_vals[0]);
					continue;
				}
			}
			if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
				if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
					LM_ERR( "fetching rows (1)\n");
					goto error;
				}
			} else {
				break;
			}
		} while(RES_ROW_N(res)>0);
	}
	dr_dbf->free_result(db_hdl, res);
	res = 0;


	/* read the routing rules */
	if (dr_dbf->use_table( db_hdl, drr_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", drr_table->len, drr_table->s);
		goto error;
	}

	columns[0] = &rule_id_drr_col;
	columns[1] = &group_drr_col;
	columns[2] = &prefix_drr_col;
	columns[3] = &time_drr_col;
	columns[4] = &priority_drr_col;
	columns[5] = &routeid_drr_col;
	columns[6] = &dstlist_drr_col;
	columns[7] = &attrs_drd_col;

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, 0) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
		no_rows = estimate_available_rows( 4+32+32+128+32+64+128, 8/*cols*/);
		if (no_rows==0) no_rows = 10;
		if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, &res) < 0) {
			LM_ERR("DB query failed\n");
			goto error;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_WARN("table \"%.*s\" is empty\n", drr_table->len, drr_table->s);
	}

	LM_DBG("%d records found in %.*s\n", RES_ROW_N(res),
		drr_table->len, drr_table->s);

	n = 0;
	do {
		for(i=0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;
			/* RULE_ID column */
			check_val(RULE_ID_DRR_COL, ROW_VALUES(row), DB_INT, 1, 0);
			int_vals[0] = VAL_INT (ROW_VALUES(row));
			/* GROUP column */
			check_val(GROUP_DRR_COL, ROW_VALUES(row)+1, DB_STRING, 1, 1);
			str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1);
			/* PREFIX column - it may be null or empty */
			check_val(PREFIX_DRR_COL, ROW_VALUES(row)+2, DB_STRING, 0, 0);
			if ((ROW_VALUES(row)+2)->nul || VAL_STRING(ROW_VALUES(row)+2)==0){
				tmp.s = NULL;
				tmp.len = 0;
			} else {
				str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+2);
				tmp.s = str_vals[1];
				tmp.len = strlen(str_vals[1]);
			}
			/* TIME column */
			check_val(TIME_DRR_COL, ROW_VALUES(row)+3, DB_STRING, 0, 0);
			str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+3);
			/* PRIORITY column */
			check_val(PRIORITY_DRR_COL, ROW_VALUES(row)+4, DB_INT, 1, 0);
			int_vals[2] = VAL_INT   (ROW_VALUES(row)+4);
			/* ROUTE_ID column */
			check_val(ROUTEID_DRR_COL, ROW_VALUES(row)+5, DB_STRING, 1, 0);
			str_vals[3] = (char*)VAL_STRING(ROW_VALUES(row)+5);
			/* DSTLIST column */
			check_val(DSTLIST_DRR_COL, ROW_VALUES(row)+6, DB_STRING, 1, 1);
			str_vals[4] = (char*)VAL_STRING(ROW_VALUES(row)+6);
			/* ATTRS column */
			check_val(ATTRS_DRD_COL, ROW_VALUES(row)+7, DB_STRING, 0, 0);
			str_vals[5] = (char*)VAL_STRING(ROW_VALUES(row)+7);
			/* parse the time definition */
			if ((time_rec=parse_time_def(str_vals[2]))==0) {
				LM_ERR("bad time definition <%s> for rule id %d -> skipping\n",
					str_vals[2], int_vals[0]);
				continue;
			}
			/* lookup for the script route ID */
			if (str_vals[3][0]) {
				int_vals[3] =  get_script_route_ID_by_name( str_vals[3],
						rlist, RT_NO);
				if (int_vals[3]==-1) {
					LM_WARN("route <%s> does not exist\n",str_vals[3]);
					int_vals[3] = 0;
				}
			} else {
				int_vals[3] = 0;
			}
			/* build the routing rule */
			if ((ri = build_rt_info( int_vals[0], int_vals[2], time_rec,
			int_vals[3], str_vals[4], str_vals[5], rdata))== 0 ) {
				LM_ERR("failed to add routing info for rule id %d -> "
					"skipping\n", int_vals[0]);
				tmrec_free( time_rec );
				continue;
			}
			/* add the rule */
			if (add_rule( rdata, str_vals[0], &tmp, ri)!=0) {
				LM_ERR("failed to add rule id %d -> skipping\n", int_vals[0]);
				free_rt_info( ri );
				continue;
			}
			n++;
		}
		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) {
				LM_ERR( "fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	if (n==0) {
		LM_WARN("no valid routing rules -> discarding all destinations\n");
		free_rt_data( rdata, 0 );
	}

	return rdata;
error:
	if (res)
		dr_dbf->free_result(db_hdl, res);
	if (rdata)
		free_rt_data( rdata, 1 );
	rdata = NULL;
	return 0;
}
Example #28
0
query_status_t
deal_with_crysis_packet(struct qserver *server, char *rawpkt, int pktlen)
{
	char *s, *val, *line;
	query_status_t state = INPROGRESS;

	debug(2, "processing...");

	if (!server->combined) {
		state = valid_crysis_response(server, rawpkt, pktlen);
		server->retry1 = n_retries;
		if (0 == server->n_requests) {
			server->ping_total = time_delta(&packet_recv_time, &server->packet_time1);
			server->n_requests++;
		}

		switch (state) {
		case INPROGRESS:
		{
			// response fragment recieved
			int pkt_id;
			int pkt_max;

			// We're expecting more to come
			debug(5, "fragment recieved...");
			pkt_id = packet_count(server);
			pkt_max = pkt_id++;
			if (!add_packet(server, 0, pkt_id, pkt_max, pktlen, rawpkt, 1)) {
				// fatal error e.g. out of memory
				return (MEM_ERROR);
			}

			// combine_packets will call us recursively
			return (combine_packets(server));
		}

		case DONE_FORCE:
			break;  // single packet response fall through

		default:
			return (state);
		}
	}

	if (DONE_FORCE != state) {
		state = valid_crysis_response(server, rawpkt, pktlen);
		switch (state) {
		case DONE_FORCE:
			break;  // actually process

		default:
			return (state);
		}
	}

	debug(3, "packet: challenge = %ld", server->challenge);
	s = NULL;
	switch (server->challenge) {
	case 1:
		s = crysis_response(server, rawpkt, pktlen);
		if (NULL != s) {
			server->challenge_string = s;
			return (send_crysis_request_packet(server));
		}
		return (REQ_ERROR);

	case 2:
		s = crysis_response(server, rawpkt, pktlen);
		if (NULL == s) {
			return (REQ_ERROR);
		}
		if (0 != strncmp(s, "authorized", 10)) {
			free(s);
			return (REQ_ERROR);
		}
		free(s);
		return (send_crysis_request_packet(server));

	case 3:
		s = crysis_response(server, rawpkt, pktlen);
		if (NULL == s) {
			return (REQ_ERROR);
		}
	}

	// Correct ping
	// Not quite right but gives a good estimate
	server->ping_total = (server->ping_total * server->n_requests) / 2;

	debug(3, "processing response...");

	s = decode_crysis_val(s);
	line = strtok(s, "\012");

	// NOTE: id=XXX and msg=XXX will be processed by the mod following the one they where the response of
	while (NULL != line) {
		debug(4, "LINE: %s\n", line);
		val = strstr(line, ":");
		if (NULL != val) {
			*val = '\0';
			val += 2;
			debug(4, "var: %s, val: %s", line, val);
			if (0 == strcmp("name", line)) {
				server->server_name = strdup(val);
			} else if (0 == strcmp("level", line)) {
				server->map_name = strdup(val);
			} else if (0 == strcmp("players", line)) {
				if (2 == sscanf(val, "%d/%d", &server->num_players, &server->max_players)) {
				}
			} else if (
				(0 == strcmp("version", line)) ||
				(0 == strcmp("gamerules", line)) ||
				(0 == strcmp("time remaining", line))
				) {
				add_rule(server, line, val, NO_FLAGS);
			}
		}

		line = strtok(NULL, "\012");
	}

	gettimeofday(&server->packet_time1, NULL);

	return (DONE_FORCE);
}
Example #29
0
static query_status_t _deal_with_doom3_packet( struct qserver *server, char *rawpkt, int pktlen, unsigned version )
{
	char *ptr = rawpkt;
	char *end = rawpkt + pktlen;
	int type = 0;
	int size = 0;
	int tail_size = 4;
	int viewers = 0;
	int tv = 0;
	unsigned num_players = 0;
	unsigned challenge = 0;
	unsigned protocolver = 0;
	char tmp[32];

	server->n_servers++;
	if ( server->server_name == NULL)
	{
		server->ping_total += time_delta( &packet_recv_time, &server->packet_time1);
	}
	else
	{
		gettimeofday( &server->packet_time1, NULL);
	}

	// Check if correct reply
	if ( pktlen < sizeof(doom3_inforesponse) +4 +4 +1 ||
		memcmp( doom3_inforesponse, ptr, sizeof(doom3_inforesponse)) != 0 )
	{
		malformed_packet(server, "too short or invalid response");
		return PKT_ERROR;
	}
	ptr += sizeof(doom3_inforesponse);

	if ( 5 == version )
	{
		// TaskID
		ptr += 4;
		// osmask + ranked
		tail_size++;
	}

	challenge = swap_long_from_little(ptr);
	ptr += 4;

	protocolver = swap_long_from_little(ptr);
	ptr += 4;

	snprintf(tmp, sizeof(tmp), "%u.%u", protocolver >> 16, protocolver & 0xFFFF);
	debug(2, "challenge: 0x%08X, protocol: %s (0x%X)", challenge, tmp, protocolver);

	server->protocol_version = protocolver;
	add_rule( server, "protocol", tmp, NO_FLAGS );


	if ( 5 == version )
	{
		// Size Long
		size = swap_long_from_little(ptr);
		debug( 2, "Size = %d", size );
		ptr += 4;
	}

// Commented out until we have a better way to specify the expected version
// This is due to prey demo requiring version 4 yet prey retail version 3
/*
	if( protocolver >> 16 != version )
	{
		malformed_packet(server, "protocol version %u, expected %u", protocolver >> 16, version );
		return PKT_ERROR;
	}
*/

	while ( ptr < end )
	{
		// server info:
		// name value pairs null seperated
		// empty name && value signifies the end of section
		char *key, *val;
		unsigned keylen, vallen;

		key = ptr;
		ptr = memchr(ptr, '\0', end-ptr);
		if ( !ptr )
		{
			malformed_packet( server, "no rule key" );
			return PKT_ERROR;
		}
		keylen = ptr - key;

		val = ++ptr;
		ptr = memchr(ptr, '\0', end-ptr);
		if ( !ptr )
		{
			malformed_packet( server, "no rule value" );
			return PKT_ERROR;
		}
		vallen = ptr - val;
		++ptr;

		if( keylen == 0 && vallen == 0 )
		{
			type = 1;
			break; // end
		}

		debug( 2, "key:%s=%s:", key, val);

		// Lets see what we've got
		if ( 0 == strcasecmp( key, "si_name" ) )
		{
			server->server_name = strdup( val );
		}
		else if( 0 == strcasecmp( key, "fs_game" ) )
		{
			server->game = strdup( val );
		}
#if 0
		else if( 0 == strcasecmp( key, "si_version" ) )
		{
			// format:
x
			// DOOM 1.0.1262.win-x86 Jul  8 2004 16:46:37
			server->protocol_version = atoi( val+1 );
		}
#endif
		else if( 0 == strcasecmp( key, "si_map" ) )
		{
			if ( 5 == version || 6 == version )
			{
				// ET:QW reports maps/<mapname>.entities
				// so we strip that here if it exists
				char *tmpp = strstr( val, ".entities" );
				if ( NULL != tmpp )
				{
					*tmpp = '\0';
				}

				if ( 0 == strncmp( val, "maps/", 5 ) )
				{
					val += 5;
				}
			}
			server->map_name = strdup( val );
		}
		else if ( 0 == strcasecmp( key, "si_maxplayers" ) )
		{
			server->max_players = atoi( val );
		}
		else if (  0 == strcasecmp( key, "ri_maxViewers" ) )
		{
			char max[20];
			sprintf( max, "%d", server->max_players );
			add_rule( server, "si_maxplayers", max, NO_FLAGS );
			server->max_players = atoi( val );
		}
		else if (  0 == strcasecmp( key, "ri_numViewers" ) )
		{
			viewers = atoi( val );
			tv = 1;
		}

		add_rule( server, key, val, NO_FLAGS );
	}

	if ( type != 1 )
	{
		// no more info should be player headers here as we
		// requested it
		malformed_packet( server, "player info missing" );
		return PKT_ERROR;
	}

	// now each player details
	while( ptr < end - tail_size )
	{
		struct player *player;
		char *val;
		unsigned char player_id = *ptr++;
		short ping = 0;
		unsigned rate = 0;

		if( ( 6 == version && MAX_WOLF_ASYNC_CLIENTS == player_id ) || MAX_DOOM3_ASYNC_CLIENTS == player_id )
		{
			break;
		}
		debug( 2, "ID = %d\n", player_id );

		// Note: id's are not steady
		if ( ptr + 7 > end ) // 2 ping + 4 rate + empty player name ('\0')
		{
			// run off the end and shouldnt have
			malformed_packet( server, "player info too short" );
			return PKT_ERROR;
		}
/*
		if ( 6 == version )
		{
			// Playerid is broken in wolf its always 0
			player_id = num_players;
		}
*/

		player = add_player( server, player_id );
		if( ! player )
		{
			malformed_packet( server, "duplicate player id" );
			return PKT_ERROR;
		}

		// doesnt support score so set a sensible default
		player->score = 0;
		player->frags = 0;

		// Ping
		ping = swap_short_from_little(ptr);
		player->ping = ping;
		ptr += 2;

		if ( 5 != version || 0xa0013 >= protocolver ) // No Rate in ETQW since v1.4 ( protocol v10.19 )
		{
			// Rate
			rate = swap_long_from_little(ptr);
			{
				char buf[16];
				snprintf(buf, sizeof(buf), "%u", rate);
				player_add_info(player, "rate", buf, NO_FLAGS);
			}
			ptr += 4;
		}

		if ( 5 == version && ( ( 0xd0009 == protocolver || 0xd000a == protocolver ) && 0 != num_players ) ) // v13.9 or v13.10
		{
			// Fix the packet offset due to the single bit used for bot
			// which realigns at the byte boundary for the player name
			ptr++;
		}

		// Name
		val = ptr;
		ptr = memchr(ptr, '\0', end-ptr);
		if ( !ptr )
		{
			malformed_packet( server, "player name not null terminated" );
			return PKT_ERROR;
		}
		player->name = strdup( val );
		ptr++;

		switch( version )
		{
		case 2: // Quake 4
			val = ptr;
			ptr = memchr(ptr, '\0', end-ptr);
			if ( !ptr )
			{
				malformed_packet( server, "player clan not null terminated" );
				return PKT_ERROR;
			}
			player->tribe_tag = strdup( val );
			ptr++;
			debug( 2, "Player[%d] = %s, ping %hu, rate %u, id %hhu, clan %s",
					num_players, player->name, ping, rate, player_id, player->tribe_tag);
			break;

		case 5: // ETQW
		case 6: // Wolfenstien
			if ( 0xa0011 <= protocolver ) // clan tag since 10.17
			{
				// clantag position
				ptr++;

				// clantag
				val = ptr;
				ptr = memchr(ptr, '\0', end-ptr);
				if ( !ptr )
				{
					malformed_packet( server, "player clan not null terminated" );
					return PKT_ERROR;
				}
				player->tribe_tag = strdup( val );
				ptr++;
			}

			// Bot flag
			if ( 0xd0009 == protocolver || 0xd000a == protocolver ) // v13.9 or v13.10
			{
				// Bot flag is a single bit so need to realign everything from here on in :(
				int i;
				unsigned char *tp = (unsigned char*)ptr;
				player->type_flag = (*tp)<<7;

				// alignment is reset at the end
				for( i = 0; i < 8 && tp < (unsigned char*)end; i++ )
				{
					*tp = (*tp)>>1 | *(tp+1)<<7;
					tp++;
				}
			}
			else
			{
				player->type_flag = *ptr++;
			}

			if ( 0xa0011 <= protocolver ) // clan tag since 10.17
			{
				debug( 2, "Player[%d] = %s, ping %hu, rate %u, id %hhu, bot %hu, clan %s",
					num_players, player->name, ping, rate, player_id, player->type_flag, player->tribe_tag);
			}
			else
			{
				debug( 2, "Player[%d] = %s, ping %hu, rate %u, id %hhu, bot %hu",
					num_players, player->name, ping, rate, player_id, player->type_flag );
			}
			break;

		default:
			debug( 2, "Player[%d] = %s, ping %hu, rate %u, id %hhu", num_players, player->name, ping, rate, player_id );
		}