static PyObject* binding_invoke(PyObject* self, PyObject* args) { dprintf("[PYTHON] a function was invoked on: %s", self->ob_type->tp_name); const char* packetBytes = NULL; BOOL isLocal = FALSE; Py_ssize_t packetLength = 0; PyArg_ParseTuple(args, "is#", &isLocal, &packetBytes, &packetLength); dprintf("[PYTHON] packet %p is %u bytes and is %s", packetBytes, packetLength, isLocal ? "local" : "not local"); Packet packet = { 0 }; packet.header = *(PacketHeader*)packetBytes; packet.payload = (PUCHAR)(packetBytes + sizeof(PacketHeader)); packet.payloadLength = (ULONG)packetLength - sizeof(PacketHeader); // If the functionality doesn't require interaction with MSF, then // make the packet as local so that the packet receives the request // and so that the packet doesn't get sent to Meterpreter packet.local = isLocal; command_handle(gRemote, &packet); // really not sure how to deal with the non-local responses at this point. if (packet.partner == NULL) { // "None" return Py_BuildValue(""); } PyObject* result = PyString_FromStringAndSize(packet.partner->payload, packet.partner->payloadLength); packet_destroy(packet.partner); return result; }
int add_new_rpc_request(packet_t *incomePacket) { portBASE_TYPE xStatus; int retries; xStatus = 0; if(requestQueue != NULL && incomePacket) { retries = SYSTEM_MSG_QUEUE_ADD_RETRIES; while((xStatus != pdPASS) && (retries-- >= 0)) { xStatus = xQueueSendToBack( requestQueue, &incomePacket, (portTickType) QUEUE_SEND_WAIT_TIMEOUT ); if(xStatus != pdPASS) { vTaskDelay(SYSTEM_TASK_DELAY); } } if((xStatus != pdPASS) && (retries < 0)) { strbuffer_t *error = strbuffer_new(); strbuffer_append(error, "Unable to add message to requestQueue after "); strbuffer_append(error, int_to_string(SYSTEM_MSG_QUEUE_ADD_RETRIES)); strbuffer_append(error, " retries"); logger(LEVEL_ERR, error->value); strbuffer_destroy(&error); packet_destroy(&incomePacket); } } else { return FALSE; } return (xStatus == pdPASS); }
/* Execute a group entry of type INDIRECT. */ static void execute_indirect(struct group_entry *entry, struct packet *pkt) { if (entry->desc->buckets_num > 0) { struct ofl_bucket *bucket = entry->desc->buckets[0]; struct packet *p = packet_clone(pkt); if (VLOG_IS_DBG_ENABLED(LOG_MODULE)) { char *b = ofl_structs_bucket_to_string(bucket, entry->dp->exp); VLOG_DBG_RL(LOG_MODULE, &rl, "Writing bucket: %s.", b); free(b); } action_set_write_actions(p->action_set, bucket->actions_num, bucket->actions); entry->stats->byte_count += p->buffer->size; entry->stats->packet_count++; entry->stats->counters[0]->byte_count += p->buffer->size; entry->stats->counters[0]->packet_count++; action_set_execute(p->action_set, p); packet_destroy(p); } else { VLOG_DBG_RL(LOG_MODULE, &rl, "No bucket in group."); } }
/* Executes a group entry of type ALL. */ static void execute_all(struct group_entry *entry, struct packet *pkt) { size_t i; /* TODO Zoltan: Currently packets are always cloned. However it should * be possible to see if cloning is necessary, or not, based on bucket actions. */ for (i=0; i<entry->desc->buckets_num; i++) { struct ofl_bucket *bucket = entry->desc->buckets[i]; struct packet *p = packet_clone(pkt); if (VLOG_IS_DBG_ENABLED(LOG_MODULE)) { char *b = ofl_structs_bucket_to_string(bucket, entry->dp->exp); VLOG_DBG_RL(LOG_MODULE, &rl, "Writing bucket: %s.", b); free(b); } action_set_write_actions(p->action_set, bucket->actions_num, bucket->actions); entry->stats->byte_count += p->buffer->size; entry->stats->packet_count++; entry->stats->counters[i]->byte_count += p->buffer->size; entry->stats->counters[i]->packet_count++; /* Cookie field is set 0xffffffffffffffff because we cannot associate to any particular flow */ action_set_execute(p->action_set, p, 0xffffffffffffffff); packet_destroy(p); } }
/* Execute a group entry of type FAILFAST. */ static void execute_ff(struct group_entry *entry, struct packet *pkt) { size_t b = select_from_ff_group(entry); if (b != -1) { struct ofl_bucket *bucket = entry->desc->buckets[b]; struct packet *p = packet_clone(pkt); if (VLOG_IS_DBG_ENABLED(LOG_MODULE)) { char *b = ofl_structs_bucket_to_string(bucket, entry->dp->exp); VLOG_DBG_RL(LOG_MODULE, &rl, "Writing bucket: %s.", b); free(b); } action_set_write_actions(p->action_set, bucket->actions_num, bucket->actions); entry->stats->byte_count += p->buffer->size; entry->stats->packet_count++; entry->stats->counters[b]->byte_count += p->buffer->size; entry->stats->counters[b]->packet_count++; /* Cookie field is set 0xffffffffffffffff because we cannot associate to any particular flow */ action_set_execute(p->action_set, p, 0xffffffffffffffff); packet_destroy(p); } else { VLOG_DBG_RL(LOG_MODULE, &rl, "No bucket in group."); } }
// Write a packet to the output buffer. int Port_tcp::send() { // Check that this port is usable. if (config_.down) throw("port down"); int bytes = 0; // Get the next packet. Context* cxt = nullptr; while ((cxt = tx_queue_.dequeue())) { // Send the packet. int l_bytes = write(io_fd_, cxt->packet_->buf_.data_, cxt->packet_->size_); if (bytes < 0) continue; // TODO: What do we do if we send 0 bytes? if (bytes == 0) continue; // Destroy the packet data. packet_destroy(cxt->packet_); // Destroy the packet context. delete cxt; bytes += l_bytes; } // Return number of bytes sent. return bytes; }
int main(int argc, char **argv) { if(!check_permissions()) { exit(EXIT_FAILURE); } if((argc != 3) && (argc != 4)) { printf("usage: %s iface ttl\n", argv[0]); exit(EXIT_FAILURE); } char *iface = argv[1]; int ttl = atoi(argv[2]); int ipversion;// ipversion = 4 to IPv4; ipversion = 6 to IPv6; if(argc == 4){ ipversion = atoi(argv[3]); } else{ ipversion = 4; } log_init(LOG_EXTRA, "log.txt", 1, 1024*1024*16); struct packet *pkt; struct sender4 *s; if (ipversion == 4){ s = sender4_create(iface); pkt = sender4_send_icmp(s, 2, ttl, 1, 1, 1, 1, 1000); sender4_destroy(s); } else if (ipversion == 6){ struct sender6 *s6 = sender6_create(iface); struct libnet_in6_addr ipv6_dst; struct sockaddr_in6 sa; inet_pton(AF_INET6, "2800:3f0:4004:803::1012", &(sa.sin6_addr)); memcpy(&ipv6_dst, &sa.sin6_addr, sizeof(struct libnet_in6_addr)); pkt = sender6_send_icmp(s6, ipv6_dst, ttl, 1, 1, 1, 1, 1, 1000); sender6_destroy(s6); } char *str = packet_tostr(pkt); logd(LOG_DEBUG, "%s\n", str); free(str); packet_destroy(pkt); sleep(2); if (ipversion == 4){ pkt = sender4_send_icmp_fixrev(s, 2, ttl, 1, 1, 1, 1, 1000); } /*else if (ipversion == 6){ struct libnet_in6_addr dst_ipv6; dst_ipv6 = nameToAddr6WithSender(s, "::2"); pkt = sender_send_icmp6_fixrev(s, dst_ipv6, ttl, 1, 1, 1, 1, 1000); } str = packet_tostr(pkt); logd(LOG_DEBUG, "%s\n", str); free(str); packet_destroy(pkt);*/ log_destroy(); exit(EXIT_SUCCESS); }
static void colo_flush_packets(void *opaque, void *user_data) { CompareState *s = user_data; Connection *conn = opaque; Packet *pkt = NULL; while (!g_queue_is_empty(&conn->primary_list)) { pkt = g_queue_pop_head(&conn->primary_list); compare_chr_send(s, pkt->data, pkt->size, pkt->vnet_hdr_len); packet_destroy(pkt, NULL); } while (!g_queue_is_empty(&conn->secondary_list)) { pkt = g_queue_pop_head(&conn->secondary_list); packet_destroy(pkt, NULL); } }
/* * Called from the compare thread on the primary * for compare packet with secondary list of the * specified connection when a new packet was * queued to it. */ static void colo_compare_connection(void *opaque, void *user_data) { CompareState *s = user_data; Connection *conn = opaque; Packet *pkt = NULL; GList *result = NULL; int ret; while (!g_queue_is_empty(&conn->primary_list) && !g_queue_is_empty(&conn->secondary_list)) { pkt = g_queue_pop_head(&conn->primary_list); switch (conn->ip_proto) { case IPPROTO_TCP: result = g_queue_find_custom(&conn->secondary_list, pkt, (GCompareFunc)colo_packet_compare_tcp); break; case IPPROTO_UDP: result = g_queue_find_custom(&conn->secondary_list, pkt, (GCompareFunc)colo_packet_compare_udp); break; case IPPROTO_ICMP: result = g_queue_find_custom(&conn->secondary_list, pkt, (GCompareFunc)colo_packet_compare_icmp); break; default: result = g_queue_find_custom(&conn->secondary_list, pkt, (GCompareFunc)colo_packet_compare_other); break; } if (result) { ret = compare_chr_send(s, pkt->data, pkt->size, pkt->vnet_hdr_len); if (ret < 0) { error_report("colo_send_primary_packet failed"); } trace_colo_compare_main("packet same and release packet"); g_queue_remove(&conn->secondary_list, result->data); packet_destroy(pkt, NULL); } else { /* * If one packet arrive late, the secondary_list or * primary_list will be empty, so we can't compare it * until next comparison. */ trace_colo_compare_main("packet different"); g_queue_push_head(&conn->primary_list, pkt); /* TODO: colo_notify_checkpoint();*/ break; } } }
int cmd_capture(int argc, char **argv) { parse_opts(argc, argv, capture_options, capture_usage); argv += optind; if (help_opt || !*argv || argv[1]) parse_usage_and_die(capture_usage, capture_options); char *dev = argv[0]; int fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (fd < 0) die_errno("Unable to obtain monitoring socket"); if (dev_bind_ifname(fd, dev) < 0) perror("Unable to bind device on the socket"); FILE *fp = NULL; if (ofilename) { fp = fopen(ofilename, "wb"); if (!fp) die_errno("fopen"); } struct pkt_hdr pkt; packet_init(&pkt); int captured = 0; for (;;) { if (packet_get(fd, &pkt, NULL, NULL) == -1) die_errno("fail to get packet"); if (!pkt.pkt_len) continue; printf("."); fflush(stdout); if (fp) fwrite(&pkt, sizeof(pkt), 1, fp); if (++captured == cap_nr_pkt) break; } printf("\n"); packet_destroy(&pkt); close(fd); if (fp) fclose(fp); return 0; }
/*! * @brief Add a group packet to the parent packet. * @param packet Pointer to the container packet that the group is to be added to. * @param type The type of group packet being added. * @param groupPacket the packet containing the group data (created by `packet_create_group`). * @returns Indication of success or failure. * @remarks The function calls `packet_destroy` on the `groupPacket` if adding the packet succeeds. */ DWORD packet_add_group(Packet* packet, TlvType type, Packet* groupPacket) { DWORD result = packet_add_tlv_raw(packet, type, groupPacket->payload, groupPacket->payloadLength); if (result == ERROR_SUCCESS) { packet_destroy(groupPacket); return ERROR_SUCCESS; } return result; }
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); }
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); }
void action_set_execute(struct action_set *set, struct packet *pkt, uint64_t cookie) { struct action_set_entry *entry, *next; LIST_FOR_EACH_SAFE(entry, next, struct action_set_entry, node, &set->actions) { dp_execute_action(pkt, entry->action); list_remove(&entry->node); free(entry); } /* Clear the action set in any case. Group processing depend on * a clean action-set. Jean II */ action_set_clear_actions(pkt->action_set); /* According to the spec. if there was a group action, the output * port action should be ignored */ if (pkt->out_group != OFPG_ANY) { uint32_t group_id = pkt->out_group; pkt->out_group = OFPG_ANY; /* Transfer packet to the group. It will be destroyed. Jean II */ group_table_execute(pkt->dp->groups, pkt, group_id); return; } else if (pkt->out_port != OFPP_ANY) { uint32_t port_id = pkt->out_port; uint32_t queue_id = pkt->out_queue; uint16_t max_len = pkt->out_port_max_len; pkt->out_port = OFPP_ANY; pkt->out_port_max_len = 0; pkt->out_queue = 0; dp_actions_output_port(pkt, port_id, queue_id, max_len, cookie); packet_destroy(pkt); return; } /* No output or group action. Just drop the packet. Jean II */ packet_destroy(pkt); }
extern void packet_del_ref(t_packet * packet) { if (!packet) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet"); return; } if (packet->ref<2) /* if would go to zero */ packet_destroy(packet); else packet->ref--; }
size_t packet_get_ping_size() { static size_t size = 0; /* If the size isn't known yet, calculate it. */ if(size == 0) { packet_t *p = packet_create_ping(0, ""); uint8_t *data = packet_to_bytes(p, &size, (options_t)0); safe_free(data); packet_destroy(p); } return size; }
/* * 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; }
/* * Return 0 on success, if return -1 means the pkt * is unsupported(arp and ipv6) and will be sent later */ static int packet_enqueue(CompareState *s, int mode, Connection **con) { ConnectionKey key; Packet *pkt = NULL; Connection *conn; if (mode == PRIMARY_IN) { pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len, s->pri_rs.vnet_hdr_len); } else { pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len, s->sec_rs.vnet_hdr_len); } if (parse_packet_early(pkt)) { packet_destroy(pkt, NULL); pkt = NULL; return -1; } fill_connection_key(pkt, &key); conn = connection_get(s->connection_track_table, &key, &s->conn_list); if (!conn->processing) { g_queue_push_tail(&s->conn_list, conn); conn->processing = true; } if (mode == PRIMARY_IN) { if (!colo_insert_packet(&conn->primary_list, pkt)) { error_report("colo compare primary queue size too big," "drop packet"); } } else { if (!colo_insert_packet(&conn->secondary_list, pkt)) { error_report("colo compare secondary queue size too big," "drop packet"); } } *con = conn; return 0; }
int main(int argc, const char *argv[]) { packet_t *packet; uint8_t *bytes; size_t length; /* Create a SYN */ packet = packet_create_syn(0x1234, 0x0000, 0x0000); packet_print(packet); /* Convert it to bytes and free the original */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); safe_free(bytes); /* Create a MSG */ packet = packet_create_msg(0x1234, 0x0000, 0x0001, (uint8_t*)"AAAAA", 5); packet_print(packet); /* Convert it to bytes and free the orignal */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); safe_free(bytes); /* Create a FIN */ packet = packet_create_fin(0x1234); packet_print(packet); /* Convert it to bytes and free the orignal */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); safe_free(bytes); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); print_memory(); return 0; }
/* * Create a packet of a given type (request/response) and method. */ Packet *packet_create(PacketTlvType type, LPCSTR method) { Packet *packet = NULL; BOOL success = FALSE; do { if (!(packet = (Packet *)malloc(sizeof(Packet)))) break; memset(packet, 0, sizeof(packet)); // Initialize the header length and message type packet->header.length = htonl(sizeof(TlvHeader)); packet->header.type = htonl((DWORD)type); // Initialize the payload to be blank packet->payload = NULL; packet->payloadLength = 0; // Add the method TLV if provided if (method) { if (packet_add_tlv_string(packet, TLV_TYPE_METHOD, method) != ERROR_SUCCESS) break; } success = TRUE; } while (0); // Clean up the packet on failure if ((!success) && (packet)) { packet_destroy(packet); packet = NULL; } return packet; }
size_t packet_get_msg_size(options_t options) { static size_t size = 0; /* If the size isn't known yet, calculate it. */ if(size == 0) { packet_t *p; if(options & OPT_CHUNKED_DOWNLOAD) p = packet_create_msg_chunked(0, 0); else p = packet_create_msg_normal(0, 0, 0, (uint8_t *)"", 0); safe_free(packet_to_bytes(p, &size, options)); packet_destroy(p); } return size; }
extern int bits_va_lock_account(const char *name) { t_account * ac; t_packet * p; t_query * q; if (!name) { eventlog(eventlog_level_error,"bits_va_lock_account","got NULL name"); return -1; } if ((ac = accountlist_find_account(name))) { if (account_get_bits_state(ac)!=account_state_unknown) { eventlog(eventlog_level_warn,"bits_va_lock_account","tried to lock an account which is already locked"); return 0; } } else { /* create a dummy account */ ac = create_vaccount(name,0); if (!ac) { eventlog(eventlog_level_error,"bits_va_lock_account","could not create dummy vaccount"); return -1; } } p = packet_create(packet_class_bits); packet_set_size(p, sizeof(t_bits_va_lock)); packet_set_type(p, BITS_VA_LOCK); bits_packet_generic(p, BITS_ADDR_PEER); q = query_create(bits_query_type_bits_va_lock); if (!q) { eventlog(eventlog_level_error,"bits_va_lock_account","bits_query_push failed."); packet_destroy(p); return -1; } /*bits_query_set_processed(q,-1);*/ bn_int_set(&p->u.bits_va_lock.qid,q->qid); packet_append_string(p,name); query_attach_account(q,"account",ac); send_bits_packet_up(p); packet_del_ref(p); account_set_bits_state(ac,account_state_pending); /* request sent */ accountlist_add_account(ac); return 0; }
END_TEST /* XXX * This test isn't really supposed to be here but its the best way to * validate that the decode went through the entire packet */ START_TEST(test_packet_proto_count) { Packet *packet = packet_create( ); int err = packet_decode(packet, pkt10, sizeof pkt10); fail_unless((err == 0), "packet_decode returned ERROR"); err = packet_proto_count(packet); fail_unless((err == 5), "packet_proto_count(packet) returned %d, expected 5", err); unsigned i; Protocol *proto = packet_proto_first(packet, &i); fail_unless((packet_proto_proto(proto) == PROTO_ETH), "layer %d not ETH"); proto = packet_proto_next(packet, &i); fail_unless((packet_proto_proto(proto) == PROTO_PPPOE), "layer %d not PPPOE"); proto = packet_proto_next(packet, &i); fail_unless((packet_proto_proto(proto) == PROTO_PPP), "layer %d not PPP"); proto = packet_proto_next(packet, &i); fail_unless((packet_proto_proto(proto) == PROTO_IP4), "layer %d not IP4"); proto = packet_proto_next(packet, &i); fail_unless((packet_proto_proto(proto) == PROTO_TCP), "layer %d not TCP"); packet_destroy(packet); }
void * accept_eep_client(void *data) { packet_t *pkt; // Begin accepting connections while (eep_cfg.server_sock > 0) { if ((pkt = capture_eep_receive())) { // Avoid parsing from multiples sources. // Avoid parsing while screen in being redrawn capture_lock(); if (capture_packet_parse(pkt) != 0) { packet_destroy(pkt); } capture_unlock(); } } // Leave the thread gracefully pthread_exit(NULL); return 0; }
/* * Transmit a single string to the remote connection with instructions to * print it to the screen or whatever medium has been established. */ DWORD send_core_console_write(Remote *remote, LPCSTR fmt, ...) { Packet *request = NULL; CHAR buf[8192]; va_list ap; DWORD res; do { va_start(ap, fmt); _vsnprintf(buf, sizeof(buf) - 1, fmt, ap); va_end(ap); // Create a message with the 'core_print' method if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, "core_console_write"))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the string to print if ((res = packet_add_tlv_string(request, TLV_TYPE_STRING, buf)) != NO_ERROR) break; res = packet_transmit(remote, request, NULL); } while (0); // Cleanup on failure if (res != ERROR_SUCCESS) { if (request) packet_destroy(request); } return res; }
void parse_packet(u_char *info, const struct pcap_pkthdr *header, const u_char *packet) { // Capture info capture_info_t *capinfo = (capture_info_t *) info; // UDP header data struct udphdr *udp; // UDP header size uint16_t udp_off; // TCP header data struct tcphdr *tcp; // TCP header size uint16_t tcp_off; // Packet data u_char data[MAX_CAPTURE_LEN]; // Packet payload data u_char *payload = NULL; // Whole packet size uint32_t size_capture = header->caplen; // Packet payload size uint32_t size_payload = size_capture - capinfo->link_hl; // Captured packet info packet_t *pkt; // Ignore packets while capture is paused if (capture_paused()) return; // Check if we have reached capture limit if (capture_cfg.limit && sip_calls_count() >= capture_cfg.limit) return; // Check maximum capture length if (header->caplen > MAX_CAPTURE_LEN) return; // Copy packet payload memcpy(data, packet, header->caplen); // Check if we have a complete IP packet if (!(pkt = capture_packet_reasm_ip(capinfo, header, data, &size_payload, &size_capture))) return; // Only interested in UDP packets if (pkt->proto == IPPROTO_UDP) { // Get UDP header udp = (struct udphdr *)((u_char *)(data) + (size_capture - size_payload)); udp_off = sizeof(struct udphdr); // Set packet ports pkt->src.port = htons(udp->uh_sport); pkt->dst.port = htons(udp->uh_dport); // Remove UDP Header from payload size_payload -= udp_off; if ((int32_t)size_payload < 0) size_payload = 0; // Remove TCP Header from payload payload = (u_char *) (udp) + udp_off; // Complete packet with Transport information packet_set_type(pkt, PACKET_SIP_UDP); packet_set_payload(pkt, payload, size_payload); } else if (pkt->proto == IPPROTO_TCP) { // Get TCP header tcp = (struct tcphdr *)((u_char *)(data) + (size_capture - size_payload)); tcp_off = (tcp->th_off * 4); // Set packet ports pkt->src.port = htons(tcp->th_sport); pkt->dst.port = htons(tcp->th_dport); // Get actual payload size size_payload -= tcp_off; if ((int32_t)size_payload < 0) size_payload = 0; // Get payload start payload = (u_char *)(tcp) + tcp_off; // Complete packet with Transport information packet_set_type(pkt, PACKET_SIP_TCP); packet_set_payload(pkt, payload, size_payload); // Create a structure for this captured packet if (!(pkt = capture_packet_reasm_tcp(pkt, tcp, payload, size_payload))) return; #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) // Check if packet is TLS if (capture_cfg.keyfile) { tls_process_segment(pkt, tcp); } #endif // Check if packet is WS or WSS capture_ws_check_packet(pkt); } else { // Not handled protocol packet_destroy(pkt); return; } // Avoid parsing from multiples sources. // Avoid parsing while screen in being redrawn capture_lock(); // Check if we can handle this packet if (capture_packet_parse(pkt) == 0) { #ifdef USE_EEP // Send this packet through eep capture_eep_send(pkt); #endif // Store this packets in output file dump_packet(capture_cfg.pd, pkt); // If storage is disabled, delete frames payload if (capture_cfg.storage == 0) { packet_free_frames(pkt); } // Allow Interface refresh and user input actions capture_unlock(); return; } // Not an interesting packet ... packet_destroy(pkt); // Allow Interface refresh and user input actions capture_unlock(); }
void pipeline_process_packet(struct pipeline *pl, struct packet *pkt) { struct flow_table *table, *next_table; if (VLOG_IS_DBG_ENABLED(LOG_MODULE)) { char *pkt_str = packet_to_string(pkt); VLOG_DBG_RL(LOG_MODULE, &rl, "processing packet: %s", pkt_str); free(pkt_str); } if (!packet_handle_std_is_ttl_valid(pkt->handle_std)) { if ((pl->dp->config.flags & OFPC_INVALID_TTL_TO_CONTROLLER) != 0) { VLOG_DBG_RL(LOG_MODULE, &rl, "Packet has invalid TTL, sending to controller."); send_packet_to_controller(pl, pkt, 0/*table_id*/, OFPR_INVALID_TTL); } else { VLOG_DBG_RL(LOG_MODULE, &rl, "Packet has invalid TTL, dropping."); } packet_destroy(pkt); return; } next_table = pl->tables[0]; while (next_table != NULL) { struct flow_entry *entry; VLOG_DBG_RL(LOG_MODULE, &rl, "trying table %u.", next_table->stats->table_id); pkt->table_id = next_table->stats->table_id; table = next_table; next_table = NULL; entry = flow_table_lookup(table, pkt); if (entry != NULL) { if (VLOG_IS_DBG_ENABLED(LOG_MODULE)) { char *m = ofl_structs_flow_stats_to_string(entry->stats, pkt->dp->exp); VLOG_DBG_RL(LOG_MODULE, &rl, "found matching entry: %s.", m); free(m); } execute_entry(pl, entry, &next_table, &pkt); /* Packet could be destroyed by a meter instruction */ if (!pkt) return; if (next_table == NULL) { /* Cookie field is set 0xffffffffffffffff because we cannot associate it to any particular flow */ action_set_execute(pkt->action_set, pkt, 0xffffffffffffffff); packet_destroy(pkt); return; } } else { /* OpenFlow 1.3 default behavior on a table miss */ VLOG_DBG_RL(LOG_MODULE, &rl, "No matching entry found. Dropping packet."); packet_destroy(pkt); return; } } VLOG_WARN_RL(LOG_MODULE, &rl, "Reached outside of pipeline processing cycle."); }
/*! * @brief Create a response packet from a request. * @details Create a response packet from a request, referencing the requestors * message identifier. * @param request The request \c Packet to build a response for. * @return Pointer to a new \c Packet. */ 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); // If the packet that is being handled is considered local, then we // associate the response with the request so that it can be handled // locally (and vice versa) if (request->local) { request->partner = response; response->partner = request; } success = TRUE; } while (0); // Cleanup on failure if (!success) { if (response) { packet_destroy(response); } response = NULL; } return response; }
void teardown( ) { packet_destroy(packet); }
packet_t * capture_packet_reasm_tcp(packet_t *packet, struct tcphdr *tcp, u_char *payload, int size_payload) { vector_iter_t it = vector_iterator(capture_cfg.tcp_reasm); packet_t *pkt; u_char *new_payload; //! Assembled if ((int32_t) size_payload <= 0) return packet; while ((pkt = vector_iterator_next(&it))) { if (addressport_equals(pkt->src, packet->src) && addressport_equals(pkt->dst, packet->dst)) { break; } } // If we already have this packet stored if (pkt) { frame_t *frame; // Append this frames to the original packet vector_iter_t frames = vector_iterator(packet->frames); while ((frame = vector_iterator_next(&frames))) packet_add_frame(pkt, frame->header, frame->data); // Destroy current packet as its frames belong to the stored packet packet_destroy(packet); } else { // First time this packet has been seen pkt = packet; // Add To the possible reassembly list vector_append(capture_cfg.tcp_reasm, packet); } // Store firt tcp sequence if (pkt->tcp_seq == 0) { pkt->tcp_seq = ntohl(tcp->th_seq); } // If the first frame of this packet if (vector_count(pkt->frames) == 1) { // Set initial payload packet_set_payload(pkt, payload, size_payload); } else { // Check payload length. Dont handle too big payload packets if (pkt->payload_len + size_payload > MAX_CAPTURE_LEN) { packet_destroy(pkt); vector_remove(capture_cfg.tcp_reasm, pkt); return NULL; } new_payload = sng_malloc(pkt->payload_len + size_payload); if (pkt->tcp_seq < ntohl(tcp->th_seq)) { // Append payload to the existing pkt->tcp_seq = ntohl(tcp->th_seq); memcpy(new_payload, pkt->payload, pkt->payload_len); memcpy(new_payload + pkt->payload_len, payload, size_payload); } else { // Prepend payload to the existing memcpy(new_payload, payload, size_payload); memcpy(new_payload + size_payload, pkt->payload, pkt->payload_len); } packet_set_payload(pkt, new_payload, pkt->payload_len + size_payload); sng_free(new_payload); } // This packet is ready to be parsed int valid = sip_validate_packet(pkt); if (valid == VALIDATE_COMPLETE_SIP) { // Full SIP packet! vector_remove(capture_cfg.tcp_reasm, pkt); return pkt; } else if (valid == VALIDATE_NOT_SIP) { vector_remove(capture_cfg.tcp_reasm, pkt); return pkt; } // An incomplete SIP Packet return NULL; }