void net_game_thread(net_client_descr_t *clients) { Field *net_field = malloc(sizeof(Field)); char* field_buffer = malloc(512); game_init(net_field); for(int i = 0; i < MAX_CONNECTIONS; i++) { // sending packet 2 (game start) Packet *p = (Packet*) packet_create(2, 1, "1"); queue_push(clients[i].send, p); clients[i].field = net_field; } while(net_server_status != SHUTDOWN) { game_update(net_field); int game_over = 1; for(int i = 0; i < MAX_CONNECTIONS; i++) { if (!net_field->players[i].is_dead) game_over = 0; } if (game_over) { Packet* p = (Packet *) packet_create(8, 1, "1"); for(int i = 0; i < MAX_CONNECTIONS; i++) queue_push(clients[i].send, p); net_server_status = SHUTDOWN; break; } packer_pack_field(field_buffer, net_field); Packet* p = (Packet*) packet_create(3, strlen(field_buffer), field_buffer); for(int i = 0; i < MAX_CONNECTIONS; i++) queue_push(clients[i].send, p); usleep(30000); } }
extern int irc_send_ping(t_connection * conn) { t_packet * p; char data[MAX_IRC_MESSAGE_LEN]; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!(p = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return -1; } if((conn_get_wol(conn) == 1)) return 0; conn_set_ircping(conn,get_ticks()); if (conn_get_state(conn)==conn_state_bot_username) sprintf(data,"PING :%u\r\n",conn_get_ircping(conn)); /* Undernet doesn't reveal the servername yet ... neither do we */ else if ((6+strlen(server_get_hostname())+2+1)<=MAX_IRC_MESSAGE_LEN) sprintf(data,"PING :%s\r\n",server_get_hostname()); else eventlog(eventlog_level_error,__FUNCTION__,"maximum message length exceeded"); eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data); packet_set_size(p,0); packet_append_data(p,data,strlen(data)); conn_push_outqueue(conn,p); packet_del_ref(p); return 0; }
extern int send_d2cs_gameinforeq(t_connection * c) { t_packet * packet; t_game * game; t_realm * realm; if (!(c)) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn"); return -1; } if (!(game = conn_get_game(c))) { eventlog(eventlog_level_error,__FUNCTION__,"conn had NULL game"); return -1; } if (!(realm = conn_get_realm(c))) { eventlog(eventlog_level_error,__FUNCTION__,"conn had NULL realm"); return -1; } if ((packet=packet_create(packet_class_d2cs_bnetd))) { packet_set_size(packet,sizeof(t_bnetd_d2cs_gameinforeq)); packet_set_type(packet,BNETD_D2CS_GAMEINFOREQ); bn_int_set(&packet->u.bnetd_d2cs_gameinforeq.h.seqno,0); packet_append_string(packet,game_get_name(game)); conn_push_outqueue(realm_get_conn(realm),packet); packet_del_ref(packet); } return 0; }
/** * \brief Cyberspace data transmission. * * This function sends data between the cyberspace server and * clients. * * @param fd communication socket to use * @param tag tag for data * @param data data to transmit * @param len length of data to transmit * @return the result of the packet_send() function */ int cyberspace_transmit(int fd, int tag, unsigned char * data, int len) { unsigned char packet[MAX_PACKET_SIZE] = {0}; packet_create(tag, data, len, packet); return packet_send(fd, packet); }
void rx_source_adv(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct source_adv_p *source = (struct source_adv_p *) (packet->data + nodedata->overhead); struct sensor_adv_p *sensor; packet_t *packet0; destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; /* check adv sequence */ if (source->s_seq <= nodedata->s_seq[source->source]) { /* old request */ packet_dealloc(packet); return; } nodedata->s_seq[source->source] = source->s_seq; /* reply */ packet0 = packet_create(c, nodedata->overhead + sizeof(struct sensor_adv_p), -1); sensor = (struct sensor_adv_p *) (packet0->data + nodedata->overhead); if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet); packet_dealloc(packet0); return; } sensor->type = SENSOR_ADV_TYPE; sensor->sensor = c->node; sensor->source = source->source; sensor->s_seq = source->s_seq; TX(&c0, packet0); packet_dealloc(packet); return; }
probe_t * probe_create() { probe_t * probe; // We calloc probe to set *_time and caller members to 0 if (!(probe = calloc(1, sizeof(probe_t)))) goto ERR_PROBE; if (!(probe->packet = packet_create())) { fprintf(stderr, "Cannot create packet\n"); goto ERR_PACKET; } if (!(probe->layers = dynarray_create())) goto ERR_LAYERS; // if (!(probe->bitfield = bitfield_create(0))) goto ERR_BITFIELD; probe_set_left_to_send(probe, 1); return probe; /* ERR_BITFIELD: probe_layers_free(probe); */ ERR_LAYERS: packet_free(probe->packet); ERR_PACKET: free(probe); ERR_PROBE: return NULL; }
/* * Open a TCP channel with the remote endpoint */ DWORD network_open_tcp_channel(Remote *remote, LPCSTR remoteHost, USHORT remotePort, PacketRequestCompletion *complete) { Packet *request = packet_create(PACKET_TLV_TYPE_REQUEST, "network_open_tcp_channel"); DWORD res = ERROR_SUCCESS; do { // Verify that the packet was allocated if (!request) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the host/port combination packet_add_tlv_string(request, TLV_TYPE_NETWORK_GENERAL_REMOTE_HOST, remoteHost); packet_add_tlv_uint(request, TLV_TYPE_NETWORK_GENERAL_REMOTE_PORT, remotePort); // Transmit the request res = packet_transmit(remote, request, complete); } while (0); return res; }
extern int send_bits_gamelist_del(t_connection * c, t_game const * game) { t_packet * p; if (!game) { eventlog(eventlog_level_error,"send_bits_gamelist_del","got NULL game"); return -1; } p = packet_create(packet_class_bits); if (!p) { eventlog(eventlog_level_error,"send_bits_gamelist_del","could not create packet"); return -1; } packet_set_size(p,sizeof(t_bits_gamelist_del)); packet_set_type(p,BITS_GAMELIST_DEL); /***/ bn_int_set(&p->u.bits_gamelist_del.id,game_get_id(game)); /***/ if (c) { /* send the packet on the connection */ bits_packet_generic(p,BITS_ADDR_PEER); send_bits_packet_on(p,c); } else { /* broadcast the packet */ bits_packet_generic(p,BITS_ADDR_BCAST); handle_bits_packet(bits_loopback_connection,p); /* also remove the game from this server */ send_bits_packet(p); } packet_del_ref(p); return 0; }
extern int irc_send_pong(t_connection * conn, char const * params) { t_packet * p; char data[MAX_IRC_MESSAGE_LEN]; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if ((1+strlen(server_get_hostname())+1+4+1+strlen(server_get_hostname())+((params)?(2+strlen(params)):(0))+2+1) > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"max message length exceeded"); return -1; } if (!(p = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return -1; } if (params) sprintf(data,":%s PONG %s :%s\r\n",server_get_hostname(),server_get_hostname(),params); else sprintf(data,":%s PONG %s\r\n",server_get_hostname(),server_get_hostname()); eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data); packet_set_size(p,0); packet_append_data(p,data,strlen(data)); conn_push_outqueue(conn,p); packet_del_ref(p); return 0; }
static int on_d2cs_authreply(t_connection * c, t_packet const * packet) { t_packet * rpacket; unsigned int version; unsigned int try_version; unsigned int reply; char const * realmname; t_realm * realm; if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_authreply)) { eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size"); return -1; } if (!(realmname=packet_get_str_const(packet,sizeof(t_d2cs_bnetd_authreply),REALM_NAME_LEN))) { eventlog(eventlog_level_error,__FUNCTION__,"got bad realmname"); return -1; } if (!(realm=realmlist_find_realm(realmname))) { realm=realmlist_find_realm_by_ip(conn_get_addr(c)); /* should not fail - checked in handle_init_packet() handle_init.c */ eventlog(eventlog_level_warn,__FUNCTION__, "warn: realm name mismatch %s %s", realm_get_name(realm), realmname); if (!(prefs_allow_d2cs_setname())) { /* fail if allow_d2cs_setname = false */ eventlog(eventlog_level_error,__FUNCTION__, "d2cs not allowed to set realm name"); return -1; } if (realm_get_active(realm)) { /* fail if realm already active */ eventlog(eventlog_level_error,__FUNCTION__, "cannot set realm name to %s (realm already active)",realmname); return -1; } realm_set_name(realm,realmname); } version=prefs_get_d2cs_version(); try_version=bn_int_get(packet->u.d2cs_bnetd_authreply.version); if (version && version != try_version) { eventlog(eventlog_level_error,__FUNCTION__,"d2cs version mismatch 0x%X - 0x%X", try_version,version); reply=BNETD_D2CS_AUTHREPLY_BAD_VERSION; } else { reply=BNETD_D2CS_AUTHREPLY_SUCCEED; } if (reply==BNETD_D2CS_AUTHREPLY_SUCCEED) { eventlog(eventlog_level_info,__FUNCTION__,"d2cs %s authed", addr_num_to_ip_str(conn_get_addr(c))); conn_set_state(c,conn_state_loggedin); realm_active(realm,c); } else { eventlog(eventlog_level_error,__FUNCTION__,"failed to auth d2cs %s", addr_num_to_ip_str(conn_get_addr(c))); } if ((rpacket=packet_create(packet_class_d2cs_bnetd))) { packet_set_size(rpacket,sizeof(t_bnetd_d2cs_authreply)); packet_set_type(rpacket,BNETD_D2CS_AUTHREPLY); bn_int_set(&rpacket->u.bnetd_d2cs_authreply.h.seqno,1); bn_int_set(&rpacket->u.bnetd_d2cs_authreply.reply,reply); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } return 0; }
/** * Programma per generare codice C (array) di pacchetti di vari protocolli, * anche concatenati */ int main(int argc, char *argv[]) { if(argc < 3) { printf("use:\n\t%s ... eth ip tcp data", argv[0]); return 0; } int i; packet_t *p = packet_create(argv[argc-1], strlen(argv[argc-1])); for(i = (argc - 2); i > 0; i--) { if(add_proto(p, argv[i])) printf("%s added\n", argv[i]); else { printf("unknow protocol %s\n", argv[i]); return 0; } } printf("%d\n\n", p->size); char *c_data = (char *) malloc(p->size * 6 + 30); strcpy(c_data, "char test_packet[] = {\t"); for(i = 0; i < p->size; i++) { char t_data[8]; sprintf(t_data, "0x%.2X", p->data[i]); strcat(c_data, t_data); if(i < p->size -1) { if(((i % 7) == 0) && i > 3) strcat(c_data, ",\n\t\t\t\t\t\t"); else strcat(c_data, ", "); } } strcat(c_data, " };\n"); char t_data[8]; sprintf(t_data, "%d", p->size); strcat(c_data, "packet_t *pack = packet_create(test_packet, "); strcat(c_data, t_data); strcat(c_data, ");\n\n"); printf("\n%s\n", c_data); return 0; }
/* * Write to the remote end of the channel */ DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, PUCHAR buffer, ULONG length, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; DWORD res = ERROR_SUCCESS; LPCSTR method = "core_channel_write"; Packet *request; Tlv methodTlv; do { // Allocate a request packet if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the supplied TLVs packet_add_tlvs(request, addend, addendLength); // If no method TLV as added, add the default one. if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); // Add the channel identifier and the length to write packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel)); // if the channel data is ment to be compressed, compress it! if( channel_is_flag( channel, CHANNEL_FLAG_COMPRESS ) ) packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA|TLV_META_TYPE_COMPRESSED, buffer, length); else packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA, buffer, length); packet_add_tlv_uint(request, TLV_TYPE_LENGTH, channel_get_id(channel)); // Initialize the packet completion routine if (completionRoutine) { // Duplicate the completion routine dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } // Transmit the packet with the supplied completion routine, if any. res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
packet_t *packet_new(enum packet_id type, ...) { packet_constructor_t pc = packet_create(type); /* build the fields */ va_list ap; va_start(ap, type); unsigned nfields = packet_format[type].nfields; for (unsigned field = 0; field < nfields; field++) { switch (packet_format[type].ftype[field]) { case FIELD_BYTE: packet_add_jbyte(&pc, va_arg(ap, int)); break; case FIELD_UBYTE: packet_add_jubyte(&pc, va_arg(ap, int)); break; case FIELD_SHORT: packet_add_jshort(&pc, va_arg(ap, int)); break; case FIELD_INT: packet_add_jint(&pc, va_arg(ap, long)); break; case FIELD_LONG: packet_add_jlong(&pc, va_arg(ap, long long)); break; case FIELD_FLOAT: packet_add_jfloat(&pc, va_arg(ap, double)); break; case FIELD_DOUBLE: packet_add_jdouble(&pc, va_arg(ap, double)); break; case FIELD_STRING: packet_add_string(&pc, va_arg(ap, unsigned char *)); break; default: dief("unhandled field type %d (packet 0x%02x, field %u)", packet_format[type].ftype[field], type, field); } } va_end(ap); return packet_construct(&pc); }
static int on_d2cs_authreply(t_connection * c, t_packet const * packet) { t_packet * rpacket; unsigned int version; unsigned int try_version; unsigned int reply; char const * realmname; t_realm * realm; if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_authreply)) { eventlog(eventlog_level_error,"on_d2cs_authreply","got bad packet size"); return -1; } if (!(realmname=packet_get_str_const(packet,sizeof(t_d2cs_bnetd_authreply),REALM_NAME_LEN))) { eventlog(eventlog_level_error,"on_d2cs_authreply","got bad realmname"); return -1; } if (!(realm=realmlist_find_realm_by_ip(conn_get_addr(c)))) { eventlog(eventlog_level_error,"handle_init_packet", "realm not found"); return -1; } if (realm_get_name(realm) && strcasecmp(realmname,realm_get_name(realm))) { eventlog(eventlog_level_error,"handle_init_packet", "warn: realm name mismatch %s %s", realm_get_name(realm),realmname); } version=prefs_get_d2cs_version(); try_version=bn_int_get(packet->u.d2cs_bnetd_authreply.version); if (version && version != try_version) { eventlog(eventlog_level_error,"on_d2cs_authreply","d2cs version mismatch 0x%X - 0x%X", try_version,version); reply=BNETD_D2CS_AUTHREPLY_BAD_VERSION; } else { reply=BNETD_D2CS_AUTHREPLY_SUCCEED; } if (reply==BNETD_D2CS_AUTHREPLY_SUCCEED) { eventlog(eventlog_level_error,"on_d2cs_authreply","d2cs %s authed", addr_num_to_ip_str(conn_get_addr(c))); conn_set_state(c,conn_state_loggedin); if (prefs_allow_d2cs_setname()) realm_set_name(realm,realmname); realm_active(realm,c); } else { eventlog(eventlog_level_error,"on_d2cs_authreply","failed to auth d2cs %s", addr_num_to_ip_str(conn_get_addr(c))); } if ((rpacket=packet_create(packet_class_d2cs_bnetd))) { packet_set_size(rpacket,sizeof(t_bnetd_d2cs_authreply)); packet_set_type(rpacket,BNETD_D2CS_AUTHREPLY); bn_int_set(&rpacket->u.bnetd_d2cs_authreply.reply,reply); queue_push_packet(conn_get_out_queue(c),rpacket); packet_del_ref(rpacket); } return 0; }
/* * Interact with a given channel such that data on the remote end is * forwarded in real time rather than being polled. */ DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, BOOL enable, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; LPCSTR method = "core_channel_interact"; DWORD res = ERROR_SUCCESS; Packet *request; Tlv methodTlv; do { if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the supplied TLVs packet_add_tlvs(request, addend, addendLength); // If no method TLV as added, add the default one. if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); // Add the channel identifier packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel)); // Add the enable/disable boolean packet_add_tlv_bool(request, TLV_TYPE_BOOL, enable); // Initialize the packet completion routine if (completionRoutine) { // Duplicate the completion routine dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } // Transmit the packet with the supplied completion routine, if any. res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
static int on_client_gameinforeq(t_connection * c, t_packet * packet) { t_game_charinfo * info; t_packet * rpacket; char const * gamename; t_game * game; unsigned int seqno, n; if (!(gamename=packet_get_str_const(packet,sizeof(t_client_d2cs_gameinforeq),MAX_GAMENAME_LEN))) { eventlog(eventlog_level_error,__FUNCTION__,"got bad game name"); return -1; } if (!(game=d2cs_gamelist_find_game(gamename))) { eventlog(eventlog_level_error,__FUNCTION__,"game %s not found",gamename); return 0; } seqno=bn_short_get(packet->u.client_d2cs_gameinforeq.seqno); if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_gameinforeply)); packet_set_type(rpacket,D2CS_CLIENT_GAMEINFOREPLY); bn_short_set(&rpacket->u.d2cs_client_gameinforeply.seqno,seqno); bn_int_set(&rpacket->u.d2cs_client_gameinforeply.gameflag,game_get_gameflag(game)); bn_int_set(&rpacket->u.d2cs_client_gameinforeply.etime,std::time(NULL)-d2cs_game_get_create_time(game)); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.charlevel,game_get_charlevel(game)); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.leveldiff,game_get_leveldiff(game)); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.maxchar,game_get_maxchar(game)); packet_append_string(rpacket, game_get_desc(game) ? game_get_desc(game) : NULL); n=0; BEGIN_LIST_TRAVERSE_DATA_CONST(game_get_charlist(game),info,t_game_charinfo) { if (!info->charname) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL charname in game %s char list",gamename); continue; } packet_append_string(rpacket,info->charname); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.chclass[n],info->chclass); /* GUI is limited to a max level of 255 */ if (info->level < 255) { bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.level[n],info->level); } else { bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.level[n], 255); } n++; } END_LIST_TRAVERSE_DATA_CONST() bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.currchar,n); if (n!=game_get_currchar(game)) { eventlog(eventlog_level_error,__FUNCTION__,"game %s character list corrupted",gamename); } conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); }
extern int irc_send_cmd2(t_connection * conn, char const * prefix, char const * command, char const * postfix, char const * comment) { t_packet * p; char data[MAX_IRC_MESSAGE_LEN+1]; int len; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!prefix) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL prefix"); return -1; } if (!command) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL command"); return -1; } if (!postfix) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL postfix"); return -1; } if (!(p = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return -1; } if (comment) { len = 1+strlen(prefix)+1+strlen(command)+1+strlen(postfix)+2+strlen(comment)+1+2; if (len > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len); return -1; } else sprintf(data,":%s %s %s :%s\r\n",prefix,command,postfix,comment); } else { len = 1+strlen(prefix)+1+strlen(command)+1+strlen(postfix)+1+2; if (len > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len); return -1; } else sprintf(data,":%s %s %s\r\n",prefix,command,postfix); } packet_set_size(p,0); packet_append_data(p,data,len); // eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data); conn_push_outqueue(conn,p); packet_del_ref(p); return 0; }
END_TEST START_TEST(test_packet_decode_with_null_data_pointer) { Packet *packet = packet_create( ); int err = packet_decode(packet, NULL, sizeof pkt10); fail_unless((err != 0), "packet_decode returned OK expected ERROR"); packet_destroy(packet); }
int transmit(size_t *sent) { void *packet = NULL; size_t bytes = 0; if (packet_create(&packet, &bytes)) return -1; if (!packet) return 0; return network_packet(packet, bytes, sent); }
END_TEST START_TEST(test_packet_decode_with_zero_size) { Packet *packet = packet_create( ); int err = packet_decode(packet, pkt10, 0); fail_unless((err != 0), "packet_decode returned OK expected ERROR"); packet_destroy(packet); }
extern int udptest_send(t_connection const * c) { t_packet * upacket; struct sockaddr_in caddr; unsigned int tries,successes; memset(&caddr,0,sizeof(caddr)); caddr.sin_family = PSOCK_AF_INET; caddr.sin_port = htons(conn_get_game_port(c)); caddr.sin_addr.s_addr = htonl(conn_get_game_addr(c)); for (tries=successes=0; successes!=2 && tries<5; tries++) { if (!(upacket = packet_create(packet_class_udp))) { eventlog(eventlog_level_error,"udptest_send","[%d] could not allocate memory for packet",conn_get_socket(c)); continue; } packet_set_size(upacket,sizeof(t_server_udptest)); packet_set_type(upacket,SERVER_UDPTEST); bn_int_tag_set(&upacket->u.server_udptest.bnettag,BNETTAG); if (hexstrm) { fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] ", conn_get_game_socket(c), packet_get_class_str(upacket),(unsigned int)packet_get_class(upacket), packet_get_type_str(upacket,packet_dir_from_server),packet_get_type(upacket)); fprintf(hexstrm,"from=%s ", addr_num_to_addr_str(conn_get_game_addr(c),conn_get_game_port(c))); fprintf(hexstrm,"to=%s ", addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port))); fprintf(hexstrm,"length=%u\n", packet_get_size(upacket)); hexdump(hexstrm,packet_get_raw_data(upacket,0),packet_get_size(upacket)); } if (psock_sendto(conn_get_game_socket(c), packet_get_raw_data_const(upacket,0),packet_get_size(upacket), 0,(struct sockaddr *)&caddr,(psock_t_socklen)sizeof(caddr))!=(int)packet_get_size(upacket)) eventlog(eventlog_level_error,"udptest_send","[%d] failed to send UDPTEST to %s (attempt %u) (psock_sendto: %s)",conn_get_socket(c),addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),conn_get_game_port(c)),tries+1,strerror(psock_errno())); else successes++; packet_del_ref(upacket); } if (successes!=2) return -1; return 0; }
extern int irc_send_cmd(t_connection * conn, char const * command, char const * params) { t_packet * p; char data[MAX_IRC_MESSAGE_LEN+1]; int len; char const * ircname = server_get_hostname(); char const * nick; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!command) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL command"); return -1; } if (!(p = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return -1; } nick = conn_get_loggeduser(conn); if (!nick) nick = ""; /* snprintf isn't portable -> check message length first */ if (params) { len = 1+strlen(ircname)+1+strlen(command)+1+strlen(nick)+1+strlen(params)+2; if (len > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len); return -1; } else sprintf(data,":%s %s %s %s\r\n",ircname,command,nick,params); } else { len = 1+strlen(ircname)+1+strlen(command)+1+strlen(nick)+1+2; if (len > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len); return -1; } else sprintf(data,":%s %s %s\r\n",ircname,command,nick); } packet_set_size(p,0); packet_append_data(p,data,len); // eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data); conn_push_outqueue(conn,p); packet_del_ref(p); return 0; }
extern t_packet * packet_duplicate(t_packet const * src) { t_packet * p; if (!(p = packet_create(packet_get_class(src)))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return NULL; } packet_append_data(p,src->u.data,packet_get_size(src)); packet_set_flags(p,packet_get_flags(src)); return p; }
static int on_bnetd_accountloginreply(t_connection * c, t_packet * packet) { unsigned int seqno; t_sq * sq; t_packet * opacket, * rpacket; t_connection * client; int result, reply; char const * account; t_elem * elem; if (!packet || !c) return -1; seqno=bn_int_get(packet->u.d2cs_bnetd.h.seqno); if (!(sq=sqlist_find_sq(seqno))) { eventlog(eventlog_level_error,__FUNCTION__,"seqno %d not found",seqno); return -1; } if (!(client=d2cs_connlist_find_connection_by_sessionnum(sq_get_clientid(sq)))) { eventlog(eventlog_level_error,__FUNCTION__,"client %d not found",sq_get_clientid(sq)); sq_destroy(sq,&elem); return -1; } if (!(opacket=sq_get_packet(sq))) { eventlog(eventlog_level_error,__FUNCTION__,"previous packet missing (seqno: %d)",seqno); sq_destroy(sq,&elem); return -1; } result=bn_int_get(packet->u.bnetd_d2cs_accountloginreply.reply); if (result==BNETD_D2CS_CHARLOGINREPLY_SUCCEED) { reply=D2CS_CLIENT_LOGINREPLY_SUCCEED; account=packet_get_str_const(opacket,sizeof(t_client_d2cs_loginreq),MAX_CHARNAME_LEN); d2cs_conn_set_account(client,account); d2cs_conn_set_state(client,conn_state_authed); eventlog(eventlog_level_info,__FUNCTION__,"account %s authed",account); } else { eventlog(eventlog_level_warn,__FUNCTION__,"client %d login request was rejected by bnetd",sq_get_clientid(sq)); reply=D2CS_CLIENT_LOGINREPLY_BADPASS; } if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_loginreply)); packet_set_type(rpacket,D2CS_CLIENT_LOGINREPLY); bn_int_set(&rpacket->u.d2cs_client_loginreply.reply,reply); conn_push_outqueue(client,rpacket); packet_del_ref(rpacket); } sq_destroy(sq,&elem); return 0; }
extern int handle_d2cs_init(t_connection * c) { t_packet * packet; if ((packet=packet_create(packet_class_d2cs_bnetd))) { packet_set_size(packet,sizeof(t_bnetd_d2cs_authreq)); packet_set_type(packet,BNETD_D2CS_AUTHREQ); bn_int_set(&packet->u.bnetd_d2cs_authreq.sessionnum,conn_get_sessionnum(c)); queue_push_packet(conn_get_out_queue(c),packet); packet_del_ref(packet); } eventlog(eventlog_level_info,"handle_d2cs_init","sent init packet to d2cs (sessionnum=%d)", conn_get_sessionnum(c)); return 0; }
DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, PUCHAR buffer, ULONG length, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; DWORD res = ERROR_SUCCESS; LPCSTR method = "core_channel_write"; Packet *request; Tlv methodTlv; do { if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } packet_add_tlvs(request, addend, addendLength); if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel)); if( channel_is_flag( channel, CHANNEL_FLAG_COMPRESS ) ) packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA|TLV_META_TYPE_COMPRESSED, buffer, length); else packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA, buffer, length); packet_add_tlv_uint(request, TLV_TYPE_LENGTH, channel_get_id(channel)); if (completionRoutine) { dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
/* * Create a response packet from a request, referencing the requestors * message identifier. */ Packet *packet_create_response(Packet *request) { Packet *response = NULL; Tlv method, requestId; BOOL success = FALSE; PacketTlvType responseType; if (packet_get_type(request) == PACKET_TLV_TYPE_PLAIN_REQUEST) responseType = PACKET_TLV_TYPE_PLAIN_RESPONSE; else responseType = PACKET_TLV_TYPE_RESPONSE; do { // Get the request TLV's method if (packet_get_tlv_string(request, TLV_TYPE_METHOD, &method) != ERROR_SUCCESS) break; // Try to allocate a response packet if (!(response = packet_create(responseType, (PCHAR)method.buffer))) break; // Get the request TLV's request identifier if (packet_get_tlv_string(request, TLV_TYPE_REQUEST_ID, &requestId) != ERROR_SUCCESS) break; // Add the request identifier to the packet packet_add_tlv_string(response, TLV_TYPE_REQUEST_ID, (PCHAR)requestId.buffer); success = TRUE; } while (0); // Cleanup on failure if (!success) { if (response) packet_destroy(response); response = NULL; } return response; }
DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, BOOL enable, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; LPCSTR method = "core_channel_interact"; DWORD res = ERROR_SUCCESS; Packet *request; Tlv methodTlv; do { if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } packet_add_tlvs(request, addend, addendLength); if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel)); packet_add_tlv_bool(request, TLV_TYPE_BOOL, enable); if (completionRoutine) { dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
/* * Tries to open a channel with the remote endpoint, optionally calling the * supplied completion routine upon response. */ DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; DWORD res = ERROR_SUCCESS; PCHAR method = "core_channel_open"; Packet *request; Tlv methodTlv; do { // Allocate the request if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the supplied TLVs packet_add_tlvs(request, addend, addendLength); // If no method TLV as added, add the default one. if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); // Initialize the packet completion routine if (completionRoutine) { // Duplicate the completion routine dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } // Transmit the packet with the supplied completion routine, if any. res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
/* Periodic exchange of hello packets */ int hello_callback(call_t *c, void *args) { struct entitydata *entitydata = get_entity_private_data(c); struct nodedata *nodedata = get_node_private_data(c); entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node, c->entity}; destination_t destination = {BROADCAST_ADDR, {-1, -1, -1}}; packet_t *packet = packet_create(c, nodedata->overhead + sizeof(struct xy_hello_p), -1); struct xy_hello_p *hello = (struct xy_hello_p *) (packet->data + nodedata->overhead); position_t *pos = get_node_position(c->node); /* set mac header */ if (SET_HEADER(&c0, packet, &destination) == -1) { packet_dealloc(packet); return -1; } /* set header */ hello->type = XY_HELLO_TYPE; hello->src = c->node; hello->position.x = pos->x; hello->position.y = pos->y; hello->position.z = pos->z; TX(&c0, packet); entitydata->TX_hello++; /* check neighbors timeout */ if (nodedata->h_timeout > 0) { das_selective_delete(nodedata->neighbors, neighbor_timeout, (void *) c); } /* schedules hello */ if (nodedata->h_nbr > 0) { nodedata->h_nbr --; } if (nodedata->h_nbr == -1 || nodedata->h_nbr > 0) { scheduler_add_callback(get_time() + nodedata->h_period, c, hello_callback, NULL); } return 0; }