void mpeg4_p2_video_packetizer_c::flush_frames(bool end_of_file) { if (m_ref_frames.empty()) return; if (m_ref_frames.size() == 1) { video_frame_t &frame = m_ref_frames.front(); // The first frame in the file. Only apply the timecode, nothing else. if (-1 == frame.timecode) { get_next_timecode_and_duration(frame.timecode, frame.duration); add_packet(new packet_t(new memory_c(frame.data, frame.size, true), frame.timecode, frame.duration)); } return; } video_frame_t &bref_frame = m_ref_frames.front(); video_frame_t &fref_frame = m_ref_frames.back(); for (auto &frame : m_b_frames) get_next_timecode_and_duration(frame.timecode, frame.duration); get_next_timecode_and_duration(fref_frame.timecode, fref_frame.duration); add_packet(new packet_t(new memory_c(fref_frame.data, fref_frame.size, true), fref_frame.timecode, fref_frame.duration, FRAME_TYPE_P == fref_frame.type ? bref_frame.timecode : VFT_IFRAME)); for (auto &frame : m_b_frames) add_packet(new packet_t(new memory_c(frame.data, frame.size, true), frame.timecode, frame.duration, bref_frame.timecode, fref_frame.timecode)); m_ref_frames.pop_front(); m_b_frames.clear(); if (end_of_file) m_ref_frames.clear(); }
/* * Some browsers use a hybrid SSLv2 "client hello" */ int process_sslv23_client_hello(SSL *ssl) { uint8_t *buf = ssl->bm_data; int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1]; int ret = SSL_OK; /* we have already read 3 extra bytes so far */ // int read_len = SOCKET_READ(ssl->client_fd, buf, bytes_needed-3); int read_len = pbuf_copy_partial(ssl->ssl_pbuf, buf, bytes_needed - 3, 0); int cs_len = buf[1]; int id_len = buf[3]; int ch_len = buf[5]; int i, j, offset = 8; /* start at first cipher */ int random_offset = 0; DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len); add_packet(ssl, buf, read_len); /* connection has gone, so die */ if (bytes_needed < 0) { return SSL_ERROR_CONN_LOST; } /* now work out what cipher suite we are going to use */ for (j = 0; j < NUM_PROTOCOLS; j++) { for (i = 0; i < cs_len; i += 3) { if (ssl_prot_prefs[j] == buf[offset + i]) { ssl->cipher = ssl_prot_prefs[j]; goto server_hello; } } } /* ouch! protocol is not supported */ ret = SSL_ERROR_NO_CIPHER; goto error; server_hello: /* get the session id */ offset += cs_len - 2; /* we've gone 2 bytes past the end */ #ifndef CONFIG_SSL_SKELETON_MODE ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions, ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL); #endif /* get the client random data */ offset += id_len; /* random can be anywhere between 16 and 32 bytes long - so it is padded * with 0's to the left */ if (ch_len == 0x10) { random_offset += 0x10; } memcpy(&ssl->dc->client_random[random_offset], &buf[offset], ch_len); ret = send_server_hello_sequence(ssl); error: return ret; }
static void rtmp_stream_data(void *data, struct encoder_packet *packet) { struct rtmp_stream *stream = data; struct encoder_packet new_packet; bool added_packet = false; if (disconnected(stream)) return; if (packet->type == OBS_ENCODER_VIDEO) obs_parse_avc_packet(&new_packet, packet); else obs_duplicate_encoder_packet(&new_packet, packet); pthread_mutex_lock(&stream->packets_mutex); if (!disconnected(stream)) { added_packet = (packet->type == OBS_ENCODER_VIDEO) ? add_video_packet(stream, &new_packet) : add_packet(stream, &new_packet); } pthread_mutex_unlock(&stream->packets_mutex); if (added_packet) os_sem_post(stream->send_sem); else obs_free_encoder_packet(&new_packet); }
bool simply_msg_animate_element_done(SimplyMsg *self, uint32_t id) { size_t length; ElementAnimateDonePacket *packet = malloc0(length = sizeof(*packet)); if (!packet) { return false; } packet->id = id; return add_packet(self, (Packet*) packet, CommandElementAnimateDone, length); }
static bool send_click(SimplyMsg *self, Command type, ButtonId button) { size_t length; ClickPacket *packet = malloc0(length = sizeof(*packet)); if (!packet) { return false; } packet->button = button; return add_packet(self, (Packet*) packet, type, length); }
/* * Convert the file's data into a number of packets */ void packetize(char* data, int file_length, int payload_size) { int current_byte; // Index of "data" int bytes_read; // Bytes read from "data" char* pckt_data; // Bytes meant for a packet first_seqno = 0; // Move bytes from data buffer into pckt_data and create packets current_byte = 0; bytes_read = 0; pckt_data = (char*)malloc(sizeof(pckt_data)*payload_size); //printf("Reading file...\n"); while(current_byte < file_length) { pckt_data[bytes_read] = data[current_byte]; if(bytes_read == payload_size) { //printf("Current byte: %d, Bytes read: %d\n",current_byte, bytes_read); struct packet* pckt = create_packet(pckt_data, bytes_read, DAT, current_byte - bytes_read + 1); add_packet(pckt, data_packets); free(pckt_data); pckt_data = (char*)malloc(sizeof(pckt_data)*payload_size); bytes_read = 0; } //printf("bytes_read: %d\n",bytes_read); //printf("current_byte: %d\n",current_byte); bytes_read++; current_byte++; } // End of file, packet size is less than MAX_PAYLOAD_SIZE // =>Shave off empty memory struct packet* pckt = create_packet(pckt_data, bytes_read, DAT, current_byte); add_packet(pckt, data_packets); //printf("sender: end of file\n"); // Debug: print list of data packets int i = 0; while(data_packets[i] != 0) { //if(i){printf("data packet %d seqno: %d, ackno: %d\n",i,data_packets[i]->header.seqno, data_packets[i]->header.ackno);} //if(i){printf("Data_packets[%d]:\n",i);print_contents(data_packets[i]);} i++; } }
bool simply_msg_accel_tap(SimplyMsg *self, AccelAxisType axis, int32_t direction) { size_t length; AccelTapPacket *packet = malloc0(length = sizeof(*packet)); if (!packet) { return false; } packet->axis = axis; packet->direction = direction; return add_packet(self, (Packet*) packet, CommandAccelTap, length); }
static bool send_menu_item(SimplyMsg *self, Command type, uint16_t section, uint16_t item) { size_t length; MenuItemEventPacket *packet = malloc0(length = sizeof(*packet)); if (!packet) { return false; } packet->section = section; packet->item = item; return add_packet(self, (Packet*) packet, type, length); }
int AsyncTaskThread::do_retry_all_request(request_retry_all* req) { int limit_size = (int) (MAX_QUEUE_SIZE * safety_ratio); // safe int async_queue_size = async_queue.size(); int retry_packet_count = limit_size - async_queue_size; int pushed_packet_count = 0; if (retry_packet_count <= 0) { log_debug("async_queue size: %d", async_queue_size); } else { std::vector<base_packet*> packet_vector; int left_packet_count = 0; left_packet_count = request_storage->read_request(packet_vector, retry_packet_count); log_debug("left %d packet(s), vector size :%d", left_packet_count, packet_vector.size()); //push packet to the async_task_queue. for (int i = 0; i < packet_vector.size(); ++i) { base_packet *req = packet_vector[i]; if (req != NULL) { //if failed to push the packet to the task queue, //the packet `req was pushed into local storage `request_storage by add_packet(function). if(!add_packet(req)) { log_error("failed to push the packet, packet pcode: %d", req->getPCode()); } pushed_packet_count++; } else { log_error("[FATAL ERROR] packet is null ,read from the request storage."); } } } log_debug("push %d packet(s) to asyn task queue. current count of packets: %d", pushed_packet_count,request_storage->get_packet_count()); if (request_storage->get_packet_count() > 0) { request_retry_all *retry_all = new request_retry_all(); if (retry_all != NULL) { if(!add_packet(retry_all)) { log_error("failed to add retry all to the async queue."); delete retry_all; } } } return request_storage->get_packet_count(); }
bool send_window(SimplyMsg *self, Command type, uint32_t id) { if (!s_broadcast_window) { return false; } size_t length; WindowEventPacket *packet = malloc0(length = sizeof(*packet)); if (!packet) { return false; } packet->id = id; return add_packet(self, (Packet*) packet, type, length); }
static bool add_video_packet(struct rtmp_stream *stream, struct encoder_packet *packet) { check_to_drop_frames(stream); /* if currently dropping frames, drop packets until it reaches the * desired priority */ if (packet->priority < stream->min_priority) return false; else stream->min_priority = 0; return add_packet(stream, packet); }
/* Main sender function. Taken from the state diagram on slide 6, chapter 5 */ void sender(int window, int timeout) { int base = 1; int nextseqnum = 1; bool allsent = false; PQueue sendQ; pqueue_init(&sendQ, window); while ( !(allsent && pqueue_empty(&sendQ)) ) { int acknum = -1; /* Send new data */ if (!allsent && nextseqnum < base + window) { Packet* packet = add_packet(&sendQ, nextseqnum); if (packet == NULL) { allsent = true; } else { send_packet(packet); if (base == nextseqnum) start_timer(timeout); nextseqnum++; } } /* Attempt to receive an ACK. */ acknum = get_ack(0); if (acknum > 0) { base = acknum + 1; if (base == nextseqnum) stop_timer(); else start_timer(timeout); } /* Clean up the queue */ while (!pqueue_empty(&sendQ) && pqueue_head(&sendQ)->seqn < base) { pqueue_pop(&sendQ); } /* Handle timeouts */ if (cnt_active && cnt_time >= cnt_timeout) { start_timer(cnt_timeout); pqueue_map(&sendQ, &send_packet); } pqueue_debug_print(&sendQ); } pqueue_destroy(&sendQ); }
bool rfs_uc_tcp_gro::rx_dispatch_packet(mem_buf_desc_t* p_rx_pkt_mem_buf_desc_info, void* pv_fd_ready_array /* = NULL */) { struct iphdr* p_ip_h = p_rx_pkt_mem_buf_desc_info->path.rx.p_ip_h; struct tcphdr* p_tcp_h = p_rx_pkt_mem_buf_desc_info->path.rx.p_tcp_h; if (!m_b_active) { if (!m_b_reserved && m_p_gro_mgr->is_stream_max()) { goto out; } } if (!tcp_ip_check(p_rx_pkt_mem_buf_desc_info, p_ip_h, p_tcp_h)) { if (m_b_active) { flush_gro_desc(pv_fd_ready_array); } goto out; } if (!m_b_active) { if (!m_b_reserved) { m_b_reserved = m_p_gro_mgr->reserve_stream(this); } init_gro_desc(p_rx_pkt_mem_buf_desc_info, p_ip_h, p_tcp_h); m_b_active = true; } else { if (ntohl(p_tcp_h->seq) != m_gro_desc.next_seq) { flush_gro_desc(pv_fd_ready_array); goto out; } if (!timestamp_check(p_tcp_h)) { flush_gro_desc(pv_fd_ready_array); goto out; } add_packet(p_rx_pkt_mem_buf_desc_info, p_ip_h, p_tcp_h); } if (m_gro_desc.buf_count >= m_n_buf_max || m_gro_desc.ip_tot_len >= m_n_byte_max) { flush_gro_desc(pv_fd_ready_array); } return true; out: return rfs_uc::rx_dispatch_packet(p_rx_pkt_mem_buf_desc_info, pv_fd_ready_array); }
/* * Process the handshake record. */ int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len) { int ret = SSL_OK; ssl->hs_status = SSL_NOT_OK; /* not connected */ /* To get here the state must be valid */ switch (handshake_type) { case HS_CLIENT_HELLO: if ((ret = process_client_hello(ssl)) == SSL_OK) ret = send_server_hello_sequence(ssl); break; #ifdef CONFIG_SSL_CERT_VERIFICATION case HS_CERTIFICATE:/* the client sends its cert */ ret = process_certificate(ssl, &ssl->x509_ctx); if (ret == SSL_OK) /* verify the cert */ { int cert_res; int pathLenConstraint = 0; cert_res = x509_verify(ssl->ssl_ctx->ca_cert_ctx, ssl->x509_ctx, &pathLenConstraint); ret = (cert_res == 0) ? SSL_OK : SSL_X509_ERROR(cert_res); } break; case HS_CERT_VERIFY: ret = process_cert_verify(ssl); add_packet(ssl, buf, hs_len); /* needs to be done after */ break; #endif case HS_CLIENT_KEY_XCHG: ret = process_client_key_xchg(ssl); break; case HS_FINISHED: ret = process_finished(ssl, buf, hs_len); disposable_free(ssl); /* free up some memory */ break; } return ret; }
int mpeg4_p10_video_packetizer_c::process(packet_cptr packet) { if (VFT_PFRAMEAUTOMATIC == packet->bref) { packet->fref = -1; packet->bref = m_ref_timecode; } m_ref_timecode = packet->timecode; if (m_nalu_size_len_dst && (m_nalu_size_len_dst != m_nalu_size_len_src)) change_nalu_size_len(packet); remove_filler_nalus(*packet->data); add_packet(packet); return FILE_STATUS_MOREDATA; }
static bool add_video_packet(struct rtmp_stream *stream, struct encoder_packet *packet) { check_to_drop_frames(stream, false); check_to_drop_frames(stream, true); /* if currently dropping frames, drop packets until it reaches the * desired priority */ if (packet->drop_priority < stream->min_priority) { stream->dropped_frames++; return false; } else { stream->min_priority = 0; } stream->last_dts_usec = packet->dts_usec; return add_packet(stream, packet); }
static GstBuffer * gst_rtp_qcelp_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp) { GstRtpQCELPDepay *depay; GstBuffer *outbuf; GstClockTime timestamp; guint payload_len, offset, index; guint8 *payload; guint LLL, NNN; depay = GST_RTP_QCELP_DEPAY (depayload); payload_len = gst_rtp_buffer_get_payload_len (rtp); if (payload_len < 2) goto too_small; timestamp = GST_BUFFER_PTS (rtp->buffer); payload = gst_rtp_buffer_get_payload (rtp); /* 0 1 2 3 4 5 6 7 * +-+-+-+-+-+-+-+-+ * |RR | LLL | NNN | * +-+-+-+-+-+-+-+-+ */ /* RR = payload[0] >> 6; */ LLL = (payload[0] & 0x38) >> 3; NNN = (payload[0] & 0x07); payload_len--; payload++; GST_DEBUG_OBJECT (depay, "LLL %u, NNN %u", LLL, NNN); if (LLL > 5) goto invalid_lll; if (NNN > LLL) goto invalid_nnn; if (LLL != 0) { /* we are interleaved */ if (!depay->interleaved) { guint size; GST_DEBUG_OBJECT (depay, "starting interleaving group"); /* bundling is not allowed to change in one interleave group */ depay->bundling = count_packets (depay, payload, payload_len); GST_DEBUG_OBJECT (depay, "got bundling of %u", depay->bundling); /* we have one bundle where NNN goes from 0 to L, we don't store the index * 0 frames, so L+1 packets. Each packet has 'bundling - 1' packets */ size = (depay->bundling - 1) * (LLL + 1); /* create the array to hold the packets */ if (depay->packets == NULL) depay->packets = g_ptr_array_sized_new (size); GST_DEBUG_OBJECT (depay, "created packet array of size %u", size); g_ptr_array_set_size (depay->packets, size); /* we were previously not interleaved, figure out how much space we * need to deinterleave */ depay->interleaved = TRUE; } } else { /* we are not interleaved */ if (depay->interleaved) { GST_DEBUG_OBJECT (depay, "stopping interleaving"); /* flush packets if we were previously interleaved */ flush_packets (depay); } depay->bundling = 0; } index = 0; offset = 1; while (payload_len > 0) { gint frame_len; gboolean do_erasure; frame_len = get_frame_len (depay, payload[0]); GST_DEBUG_OBJECT (depay, "got frame len %d", frame_len); if (frame_len == 0) goto invalid_frame; if (frame_len < 0) { /* need to add an erasure frame but we can recover */ frame_len = -frame_len; do_erasure = TRUE; } else { do_erasure = FALSE; } if (frame_len > payload_len) goto invalid_frame; if (do_erasure) { /* create erasure frame */ outbuf = create_erasure_buffer (depay); } else { /* each frame goes into its buffer */ outbuf = gst_rtp_buffer_get_payload_subbuffer (rtp, offset, frame_len); } GST_BUFFER_PTS (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = FRAME_DURATION; gst_rtp_drop_meta (GST_ELEMENT_CAST (depayload), outbuf, g_quark_from_static_string (GST_META_TAG_AUDIO_STR)); if (!depay->interleaved || index == 0) { /* not interleaved or first frame in packet, just push */ gst_rtp_base_depayload_push (depayload, outbuf); if (timestamp != -1) timestamp += FRAME_DURATION; } else { /* put in interleave buffer */ add_packet (depay, LLL, NNN, index, outbuf); if (timestamp != -1) timestamp += (FRAME_DURATION * (LLL + 1)); } payload_len -= frame_len; payload += frame_len; offset += frame_len; index++; /* discard excess packets */ if (depay->bundling > 0 && depay->bundling <= index) break; } while (index < depay->bundling) { GST_DEBUG_OBJECT (depay, "filling with erasure buffer"); /* fill remainder with erasure packets */ outbuf = create_erasure_buffer (depay); add_packet (depay, LLL, NNN, index, outbuf); index++; } if (depay->interleaved && LLL == NNN) { GST_DEBUG_OBJECT (depay, "interleave group ended, flushing"); /* we have the complete interleave group, flush */ flush_packets (depay); } return NULL; /* ERRORS */ too_small: { GST_ELEMENT_WARNING (depay, STREAM, DECODE, (NULL), ("QCELP RTP payload too small (%d)", payload_len)); return NULL; } invalid_lll: { GST_ELEMENT_WARNING (depay, STREAM, DECODE, (NULL), ("QCELP RTP invalid LLL received (%d)", LLL)); return NULL; } invalid_nnn: { GST_ELEMENT_WARNING (depay, STREAM, DECODE, (NULL), ("QCELP RTP invalid NNN received (%d)", NNN)); return NULL; } invalid_frame: { GST_ELEMENT_WARNING (depay, STREAM, DECODE, (NULL), ("QCELP RTP invalid frame received")); return NULL; } }
static GstBuffer * gst_rtp_qdm2_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) { GstRtpQDM2Depay *rtpqdm2depay; GstBuffer *outbuf; guint16 seq; rtpqdm2depay = GST_RTP_QDM2_DEPAY (depayload); { gint payload_len; guint8 *payload; guint avail; guint pos = 0; payload_len = gst_rtp_buffer_get_payload_len (buf); if (payload_len < 3) goto bad_packet; payload = gst_rtp_buffer_get_payload (buf); seq = gst_rtp_buffer_get_seq (buf); if (G_UNLIKELY (seq != rtpqdm2depay->nextseq)) { GST_DEBUG ("GAP in sequence number, Resetting data !"); /* Flush previous data */ flush_data (rtpqdm2depay); /* And store new timestamp */ rtpqdm2depay->ptimestamp = rtpqdm2depay->timestamp; rtpqdm2depay->timestamp = GST_BUFFER_TIMESTAMP (buf); /* And that previous data will be pushed at the bottom */ } rtpqdm2depay->nextseq = seq + 1; GST_DEBUG ("Payload size %d 0x%x sequence:%d", payload_len, payload_len, seq); GST_MEMDUMP ("Incoming payload", payload, payload_len); while (pos < payload_len) { switch (payload[pos]) { case 0x80:{ GST_DEBUG ("Unrecognized 0x80 marker, skipping 12 bytes"); pos += 12; } break; case 0xff: /* HEADERS */ GST_DEBUG ("Headers"); /* Store the incoming timestamp */ rtpqdm2depay->ptimestamp = rtpqdm2depay->timestamp; rtpqdm2depay->timestamp = GST_BUFFER_TIMESTAMP (buf); /* flush the internal data if needed */ flush_data (rtpqdm2depay); if (G_UNLIKELY (!rtpqdm2depay->configured)) { guint8 *ourdata; GstBuffer *codecdata; GstCaps *caps; /* First bytes are unknown */ GST_MEMDUMP ("Header", payload + pos, 32); ourdata = payload + pos + 10; pos += 10; rtpqdm2depay->channs = GST_READ_UINT32_BE (payload + pos + 4); rtpqdm2depay->samplerate = GST_READ_UINT32_BE (payload + pos + 8); rtpqdm2depay->bitrate = GST_READ_UINT32_BE (payload + pos + 12); rtpqdm2depay->blocksize = GST_READ_UINT32_BE (payload + pos + 16); rtpqdm2depay->framesize = GST_READ_UINT32_BE (payload + pos + 20); rtpqdm2depay->packetsize = GST_READ_UINT32_BE (payload + pos + 24); /* 16 bit empty block (0x02 0x00) */ pos += 30; GST_DEBUG ("channs:%d, samplerate:%d, bitrate:%d, blocksize:%d, framesize:%d, packetsize:%d", rtpqdm2depay->channs, rtpqdm2depay->samplerate, rtpqdm2depay->bitrate, rtpqdm2depay->blocksize, rtpqdm2depay->framesize, rtpqdm2depay->packetsize); /* Caps */ codecdata = gst_buffer_new_and_alloc (48); memcpy (GST_BUFFER_DATA (codecdata), headheader, 20); memcpy (GST_BUFFER_DATA (codecdata) + 20, ourdata, 28); caps = gst_caps_new_simple ("audio/x-qdm2", "samplesize", G_TYPE_INT, 16, "rate", G_TYPE_INT, rtpqdm2depay->samplerate, "channels", G_TYPE_INT, rtpqdm2depay->channs, "codec_data", GST_TYPE_BUFFER, codecdata, NULL); gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), caps); gst_caps_unref (caps); rtpqdm2depay->configured = TRUE; } else { GST_DEBUG ("Already configured, skipping headers"); pos += 40; } break; default:{ /* Shuffled packet contents */ guint packetid = payload[pos++]; guint packettype = payload[pos++]; guint packlen = payload[pos++]; guint hsize = 2; GST_DEBUG ("Packet id:%d, type:0x%x, len:%d", packetid, packettype, packlen); /* Packets bigger than 0xff bytes have a type with the high bit set */ if (G_UNLIKELY (packettype & 0x80)) { packettype &= 0x7f; packlen <<= 8; packlen |= payload[pos++]; hsize = 3; GST_DEBUG ("Packet id:%d, type:0x%x, len:%d", packetid, packettype, packlen); } if (packettype > 0x7f) { GST_ERROR ("HOUSTON WE HAVE A PROBLEM !!!!"); } add_packet (rtpqdm2depay, packetid, packlen + hsize, payload + pos - hsize); pos += packlen; } } } GST_DEBUG ("final pos %d", pos); avail = gst_adapter_available (rtpqdm2depay->adapter); if (G_UNLIKELY (avail)) { GST_DEBUG ("Pushing out %d bytes of collected data", avail); outbuf = gst_adapter_take_buffer (rtpqdm2depay->adapter, avail); GST_BUFFER_TIMESTAMP (outbuf) = rtpqdm2depay->ptimestamp; GST_DEBUG ("Outgoing buffer timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (rtpqdm2depay->ptimestamp)); return outbuf; } } return NULL; /* ERRORS */ bad_packet: { GST_ELEMENT_WARNING (rtpqdm2depay, STREAM, DECODE, (NULL), ("Packet was too short")); return NULL; } }
query_status_t deal_with_tm_packet( struct qserver *server, char *rawpkt, int pktlen ) { char *s; char *pkt = rawpkt; char *key = NULL, *value = NULL, *tmpp = NULL; char fullname[256]; struct player *player = NULL; int pkt_max = server->saved_data.pkt_max; unsigned total_len, expected_len; int method_response = 1; debug( 2, "processing..." ); s = rawpkt; // We may get the setup handle and the protocol version in one packet we may not // So we continue to parse if we see the handle if ( 4 <= pktlen && 0 == memcmp( pkt, "\x0b\x00\x00\x00", 4 ) ) { // setup handle identifier // greater 2^31 = XML-RPC, less = callback server->challenge = 0x80000001; if ( 4 == pktlen ) { return 0; } pktlen -= 4; pkt += 4; } if ( 11 <= pktlen && 1 == sscanf( pkt, "GBXRemote %d", &server->protocol_version ) ) { // Got protocol version send request send_tm_request_packet( server ); return 0; } if ( 8 <= pktlen && 0 == memcmp( pkt+4, &server->challenge, 4 ) ) { // first 4 bytes = the length // Note: We use pkt_id to store the length of the expected packet // this could cause loss but very unlikely unsigned long len; memcpy( &len, rawpkt, 4 ); // second 4 bytes = handle identifier we sent in the request if ( 8 == pktlen ) { // split packet // we have at least one more packet coming if ( ! add_packet( server, len, 0, 2, pktlen, rawpkt, 1 ) ) { // fatal error e.g. out of memory return -1; } return 0; } else { // ensure the length is stored server->saved_data.pkt_id = (int)len; s += 8; } } total_len = combined_length( server, server->saved_data.pkt_id ); expected_len = server->saved_data.pkt_id; debug( 2, "total: %d, expected: %d\n", total_len, expected_len ); if ( total_len < expected_len + 8 ) { // we dont have a complete response add the packet int last, new_max; if ( total_len + pktlen >= expected_len + 8 ) { last = 1; new_max = pkt_max; } else { last = 0; new_max = pkt_max + 1; } if ( ! add_packet( server, server->saved_data.pkt_id, pkt_max - 1, new_max, pktlen, rawpkt, 1 ) ) { // fatal error e.g. out of memory return -1; } if ( last ) { // we are the last packet run combine to call us back return combine_packets( server ); } return 0; } 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); } // Terminate the packet data pkt = (char*)malloc( pktlen + 1 ); if ( NULL == pkt ) { debug( 0, "Failed to malloc memory for packet terminator\n" ); return MEM_ERROR; } memcpy( pkt, rawpkt, pktlen ); pkt[pktlen] = '\0'; //fprintf( stderr, "S=%s\n", s ); s = strtok( pkt + 8, "\015\012" ); while ( NULL != s ) { //fprintf( stderr, "S=%s\n", s ); if ( 0 == strncmp( s, "<member><name>", 14 ) ) { key = s + 14; tmpp = strstr( key, "</name>" ); if ( NULL != tmpp ) { *tmpp = '\0'; } s = strtok( NULL, "\015\012" ); value = NULL; continue; } else if ( NULL != key && 0 == strncmp( s, "<value>", 7 ) ) { // value s += 7; if ( 0 == strncmp( s, "<string>", 8 ) ) { // String value = s+8; tmpp = strstr( s, "</string>" ); } else if ( 0 == strncmp( s, "<i4>", 4 ) ) { // Int value = s+4; tmpp = strstr( s, "</i4>" ); } else if ( 0 == strncmp( s, "<boolean>", 9 ) ) { // Boolean value = s+9; tmpp = strstr( s, "</boolean>" ); } else if ( 0 == strncmp( s, "<double>", 8 ) ) { // Double value = s+8; tmpp = strstr( s, "</double>" ); } // also have struct and array but not interested in those if ( NULL != tmpp ) { *tmpp = '\0'; } if ( NULL != value ) { debug( 4, "%s = %s\n", key, value ); } } else if ( 0 == strncmp( s, "</struct>", 9 ) && 3 > method_response ) { // end of method response method_response++; } if ( NULL != value && NULL != key ) { switch( method_response ) { case 1: // GetServerOptions response if ( 0 == strcmp( "Name", key ) ) { server->server_name = strdup( value ); } else if ( 0 == strcmp( "CurrentMaxPlayers", key ) ) { server->max_players = atoi( value ); } else { sprintf( fullname, "server.%s", key ); add_rule( server, fullname, value, NO_FLAGS); } break; case 2: // GetCurrentChallengeInfo response if ( 0 == strcmp( "Name", key ) ) { server->map_name = strdup( value ); } else { sprintf( fullname, "challenge.%s", key ); add_rule( server, fullname, value, NO_FLAGS); } break; case 3: // GetPlayerList response // Player info if ( 0 == strcmp( "Login", key ) ) { player = add_player( server, server->n_player_info ); server->num_players++; } else if ( NULL != player ) { if ( 0 == strcmp( "NickName", key ) ) { player->name = strdup( value ); } else if ( 0 == strcmp( "PlayerId", key ) ) { //player->number = atoi( value ); } else if ( 0 == strcmp( "TeamId", key ) ) { player->team = atoi( value ); } else if ( 0 == strcmp( "IsSpectator", key ) ) { player->flags = player->flags & 1; } else if ( 0 == strcmp( "IsInOfficialMode", key ) ) { player->flags = player->flags & 2; } else if ( 0 == strcmp( "LadderRanking", key ) ) { player->score = atoi( value ); } } break; } value = NULL; } s = strtok( NULL, "\015\012" ); } free( pkt ); if ( 0 == strncmp( rawpkt + pktlen - 19, "</methodResponse>", 17 ) ) { // last packet seen return DONE_FORCE; } return INPROGRESS; }
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); }
query_status_t deal_with_dirtybomb_packet(struct qserver *server, char *rawpkt, int pktlen) { unsigned char *s, *l, pkt_id, pkt_max; debug(2, "processing..."); if (8 > pktlen) { // not valid response malformed_packet(server, "packet too small"); return PKT_ERROR; } if (rawpkt[4] != 0x01) { // not a known response malformed_packet(server, "unknown packet type 0x%02hhx", rawpkt[4]); return PKT_ERROR; } // Response ID - long // Response Type - byte // Current Packet Number - byte pkt_id = rawpkt[5]; // Last Packet Number - byte pkt_max = rawpkt[6]; // Payload Blob - msgpack map s = (unsigned char*)rawpkt + 7; if (!server->combined) { int pkt_cnt = packet_count(server); server->retry1 = n_retries; if (0 == server->n_requests) { server->ping_total = time_delta( &packet_recv_time, &server->packet_time1 ); server->n_requests++; } if (pkt_cnt < pkt_max) { // We're expecting more to come debug( 5, "fragment recieved..." ); 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); } } // Correct ping // Not quite right but gives a good estimate server->ping_total = (server->ping_total * server->n_requests) / 2; debug(3, "processing response..."); gettimeofday(&server->packet_time1, NULL); l = (unsigned char *)rawpkt + pktlen - 1; if (!unpack_msgpack(server, s, l)) { return PKT_ERROR; } return DONE_FORCE; }
int main(int argc, char **argv) { if(argc < 2) { errno = EINVAL; perror("Un fichier pcap doit être passé en argument"); exit(1); } char errbuf[PCAP_ERRBUF_SIZE]; pkthdr h; Flux *flu; // Ouverture du fichier pcap_t *file = pcap_open_offline(argv[1], errbuf); const u_char *packet = pcap_next(file, &h); // Taille des en-têtes u_int size_ip, size_tcp; // Structures des différents en-têtes const sniff_eth *ethernet; /* The ethernet header */ const sniff_ip *ip; /* The IP header */ const sniff_tcp *tcp; /* The TCP header */ // Lecture des packets while(packet != NULL) { ethernet = (sniff_eth*)(packet); // Si on a l'entête IP qui suit if(ethernet->type == IP_T) { ip = (sniff_ip*)(packet + SIZE_ETHERNET); size_ip = IP_HL(ip)*4; // Si c'est un protocole TCP if(ip->prot == TCP) { tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); size_tcp = TH_OFF(tcp)*4; // On récupère les IPs u_char *ip_src = calloc(IP_LEN, sizeof(u_char)); memcpy(ip_src, ip->src, sizeof(ip->src)); u_char *ip_dst = calloc(IP_LEN, sizeof(u_char)); memcpy(ip_dst, ip->dst, sizeof(ip->dst)); // On récupère les ports int port_src = htons(tcp->s_port); int port_dst = htons(tcp->d_port); // On change la taille du packet par la taille des données h.len = htons(ip->tot_len) - size_ip - size_tcp; // on récupère le flux, ou on en creer un s'il n'existe pas flu = add_flux(ip_src, ip_dst, port_src, port_dst); // Si on a un flux alors on lui ajoute ce packet if(flu != NULL) add_packet(flu, &h); } } // On lit le packet suivant packet = pcap_next(file, &h); } // On ecrit les fichiers de flux write_flux(); // On nettoie la mémoire clean(); printf("Pour créer le graph représentant l'évolution du débit en fonction du temps sur un flux,\n"); printf("Choisissez le flux qui correspond à votre téléchargement, notez son numéro et taper dans la console:\n$ ./plot numero_flux\n"); return 0; }
query_status_t deal_with_ts3_packet(struct qserver *server, char *rawpkt, int pktlen) { char *s, *player_name = "unknown"; int valid_response = 0, mode = 0, all_servers = 0; char last_char; unsigned short port = 0, down = 0, auth_seen = 0; debug(2, "processing..."); if (0 == pktlen) { // Invalid password return (REQ_ERROR); } last_char = rawpkt[pktlen - 1]; rawpkt[pktlen - 1] = '\0'; s = rawpkt; all_servers = all_ts3_servers(server); debug(3, "packet: combined = %d, challenge = %ld, n_servers = %d", server->combined, server->challenge, server->n_servers); if (!server->combined) { server->retry1 = n_retries; if (0 == server->n_requests) { server->ping_total = time_delta(&packet_recv_time, &server->packet_time1); server->n_requests++; } if (server->n_servers >= server->challenge) { // response fragment recieved int pkt_id; int pkt_max; // We're expecting more to come debug(5, "fragment recieved..."); pkt_id = packet_count(server); pkt_max = pkt_id + 1; rawpkt[pktlen - 1] = last_char; // restore the last character if (!add_packet(server, 0, pkt_id, pkt_max, pktlen, rawpkt, 1)) { // fatal error e.g. out of memory return (MEM_ERROR); } // combine_packets will call us recursively return (combine_packets(server)); } } else { valid_response = valid_ts3_response(server, rawpkt + server->master_pkt_len, pktlen - server->master_pkt_len); debug(2, "combined packet: valid_response: %d, challenge: %ld, n_servers: %d, offset: %d", valid_response, server->challenge, server->n_servers, server->master_pkt_len); if (0 > valid_response) { // Error occured return (valid_response); } server->challenge += valid_response; if (valid_response) { // Got a valid response, send the next request int ret = send_ts3_request_packet(server); if (0 != ret) { // error sending packet debug(4, "Request failed: %d", ret); return (ret); } } if (server->n_servers > server->challenge) { // recursive call which is still incomplete return (INPROGRESS); } } // Correct ping // Not quite right but gives a good estimate server->ping_total = (server->ping_total * server->n_requests) / 2; debug(3, "processing response..."); s = strtok(rawpkt, "\012\015 |"); // NOTE: id=XXX and msg=XXX will be processed by the mod following the one they where the response of while (NULL != s) { debug(4, "LINE: %d, %s\n", mode, s); switch (mode) { case 0: // prompt, use or serverlist response if (0 == strcmp("TS3", s)) { // nothing to do unless in all servers mode if (1 == all_servers) { mode++; } } else if (0 == strncmp("error", s, 5)) { // end of use response mode++; } break; case 1: // serverinfo or serverlist response including condition authentication if ((0 == auth_seen) && (0 != strlen(get_param_value(server, "password", ""))) && (0 == strncmp("error", s, 5))) { // end of auth response auth_seen = 1; } else if (0 == strncmp("error", s, 5)) { // end of serverinfo response mode++; } else { // Server Rule char *key = s; char *value = strchr(key, '='); if (NULL != value) { *value = '\0'; value++; debug(6, "Rule: %s = %s\n", key, value); if (0 == strcmp("virtualserver_name", key)) { if (1 == all_servers) { struct qserver *new_server = add_qserver_byaddr(ntohl(server->ipaddr), port, server->type, NULL); if (NULL != new_server) { if (down) { // Status indicates this server is actually offline new_server->server_name = DOWN; } else { new_server->max_players = server->max_players; new_server->num_players = server->num_players; new_server->server_name = strdup(decode_ts3_val(value)); new_server->map_name = strdup("N/A"); new_server->ping_total = server->ping_total; new_server->n_requests = server->n_requests; } cleanup_qserver(new_server, FORCE); } down = 0; } else { server->server_name = strdup(decode_ts3_val(value)); } } else if (0 == strcmp("virtualserver_port", key)) { port = atoi(value); change_server_port(server, port, 0); add_rule(server, key, value, NO_FLAGS); } else if (0 == strcmp("virtualserver_maxclients", key)) { server->max_players = atoi(value); } else if (0 == strcmp("virtualserver_clientsonline", key)) { server->num_players = atoi(value); } else if (0 == strcmp("virtualserver_queryclientsonline", key)) { // clientsonline includes queryclientsonline so remove these from our count server->num_players -= atoi(value); } else if ((0 == strcmp("virtualserver_status", key)) && (0 != strcmp("online", value))) { // Server is actually offline to client so display as down down = 1; if (1 != all_servers) { server->server_name = DOWN; //server->saved_data.pkt_index = 0; return (DONE_FORCE); } } else if ((0 == strcmp("id", key)) || (0 == strcmp("msg", key))) { // Ignore details from the response code } else if (1 != all_servers) { add_rule(server, key, value, NO_FLAGS); } } } break; case 2: // clientlist response if (0 == strncmp("error", s, 5)) { // end of serverinfo response mode++; } else { // Client char *key = s; char *value = strchr(key, '='); if (NULL != value) { *value = '\0'; value++; debug(6, "Player: %s = %s\n", key, value); if (0 == strcmp("client_nickname", key)) { player_name = value; } else if (0 == strcmp("clid", key)) { } else if ((0 == strcmp("client_type", key)) && (0 == strcmp("0", value))) { struct player *player = add_player(server, server->n_player_info); if (NULL != player) { player->name = strdup(decode_ts3_val(player_name)); } } else if ((0 == strcmp("id", key)) || (0 == strcmp("msg", key))) { // Ignore details from the response code } } } break; } s = strtok(NULL, "\012\015 |"); } gettimeofday(&server->packet_time1, NULL); server->map_name = strdup("N/A"); return (DONE_FORCE); }
int rudp_sendto(rudp_socket_t rsocket, void* data, int len, struct sockaddr_in* to) { if (len>RUDP_MAXPKTSIZE) { perror("rudp_sendto: packet too long"); return -1; } //Create an internal socket structure struct rudp_socket_int* sockint = (struct rudp_socket_int*)malloc(sizeof(struct rudp_socket_int)); memcpy(sockint,rsocket,sizeof(struct rudp_socket_int)); //Look up state of (socket,remote peer) pair int cstate = getsstate(sockint->socket_id,to); switch(cstate) { case INITIAL: { //Add a peer to the socket if (addpeer(sid,to)==-1) return -1; int pnum = getpeernum(sid,to); //Create a queue for this socket/peer pair and add the packet to this queue init_queue(sid,pnum); add_packet(data,len,sid,pnum); //Send a SYN packet send_syn(sockint->socket_desc,sid,pnum,to); break; } case SENT_SYN: { int pnum = getpeernum(sid,to); //Get the data and add it to the queue add_packet(data,len,sid,pnum); break; } case SENDING: { int pnum = getpeernum(sid,to); //Get the data and add it to the queue add_packet(data,len,sid,pnum); send_data(sockint->socket_desc,sid,pnum,to); break; } case SENT_FIN: { int pnum = getpeernum(sid,to); //Get the data and add it to the queue add_packet(data,len,sid,pnum); setsstate(sid,to,SENDING); break; } case CLOSED: { return -1; } } return 0; }