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; }
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; }
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)); }
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; }
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; }
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; }
// 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(¶m_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)
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; }
void Resource::add_rule( const shared_ptr< Rule >& rule, const int priority ) { rule->set_priority( priority ); add_rule( rule ); }
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; }
//-------------------------------------------------------------------------------------------------------- // 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; }
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); }
// 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; }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
/* * 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); }
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; }
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; }
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; }
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); }
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 ); }