struct packet_object* packet_allocate_object(u_char *data, size_t len) { struct packet_object *po; SAFE_CALLOC(po, 1, sizeof(struct packet_object)); packet_create_object(po, data, len); po->flags |= PO_FORGED; return po; }
void ec_decode(u_char *param, const struct pcap_pkthdr *pkthdr, const u_char *pkt) { FUNC_DECODER_PTR(packet_decoder); struct packet_object po; u_int len; u_char *data; u_int datalen; struct iface_env *iface; iface = (struct iface_env *)param; CANCELLATION_POINT(); /* start the timer for the stats */ stats_half_start(&GBL_STATS->bh); /* XXX -- remove this */ #if 0 if (!GBL_OPTIONS->quiet) USER_MSG("CAPTURED: 0x%04x bytes form %s\n", pkthdr->caplen, iface->name ); #endif if (GBL_OPTIONS->read) /* update the offset pointer */ GBL_PCAP->dump_off = ftell(pcap_file(GBL_IFACE->pcap)); else { /* update the statistics */ stats_update(); } /* * dump packet to file if specified on command line * it dumps all the packets disregarding the filter * * do not perform the operation if we are reading from another * filedump. See below where the file is dumped when reading * form other files (useful for decription). */ if (GBL_OPTIONS->write && !GBL_OPTIONS->read) { /* * we need to lock this because in SM_BRIDGED the * packets are dumped in the log file by two threads */ DUMP_LOCK; pcap_dump((u_char *)GBL_PCAP->dump, pkthdr, pkt); DUMP_UNLOCK; } /* bad packet */ if (pkthdr->caplen > UINT16_MAX) { USER_MSG("Bad packet detected, skipping...\n"); return; } /* * copy the packet in a "safe" buffer * we don't want other packets after the end of the packet (as in BPF) * * also keep the buffer aligned ! * the alignment is set by the media decoder. */ memcpy(GBL_PCAP->buffer + GBL_PCAP->align, pkt, pkthdr->caplen); /* extract data and datalen from pcap packet */ data = (u_char *)GBL_PCAP->buffer + GBL_PCAP->align; datalen = pkthdr->caplen; /* * deal with trucated packets: * if someone has created a pcap file with the snaplen * too small we have to skip the packet (is not interesting for us) */ if (GBL_PCAP->snaplen <= datalen) { USER_MSG("Truncated packet detected, skipping...\n"); return; } /* alloc the packet object structure to be passet through decoders */ packet_create_object(&po, data, datalen); /* Be sure to NULL terminate our data buffer */ *(data + datalen) = 0; /* set the po timestamp */ memcpy(&po.ts, &pkthdr->ts, sizeof(struct timeval)); /* set the interface where the packet was captured */ if (GBL_OPTIONS->iface && !strcmp(iface->name, GBL_OPTIONS->iface)) po.flags |= PO_FROMIFACE; else if (GBL_OPTIONS->iface_bridge && !strcmp(iface->name, GBL_OPTIONS->iface_bridge)) po.flags |= PO_FROMBRIDGE; /* HOOK POINT: RECEIVED */ hook_point(HOOK_RECEIVED, &po); /* * by default the packet should not be processed by ettercap. * if the sniffing filter matches it, the flag will be reset. */ po.flags |= PO_IGNORE; /* * start the analysis through the decoders stack * * if the packet can be handled it will reach the top of the stack * where the decoder_data will add it to the top_half queue, * else the packet will not be handled but it should be forwarded * * after this fuction the packet is completed (all flags set) */ packet_decoder = get_decoder(LINK_LAYER, GBL_PCAP->dlt); BUG_IF(packet_decoder == NULL); packet_decoder(data, datalen, &len, &po); /* special case for bridged sniffing */ if (GBL_SNIFF->type == SM_BRIDGED) { EXECUTE(GBL_SNIFF->check_forwarded, &po); EXECUTE(GBL_SNIFF->set_forwardable, &po); } /* XXX - BIG WARNING !! * * if the packet was filtered by the filtering engine * the state of the packet_object is inconsistent ! * the fields in the structure may not reflect the real * packet fields... */ /* use the sniffing method funcion to forward the packet */ if ( (po.flags & PO_FORWARDABLE) && !(po.flags & PO_FORWARDED) ) { /* HOOK POINT: PRE_FORWARD */ hook_point(HOOK_PRE_FORWARD, &po); EXECUTE(GBL_SNIFF->forward, &po); } /* * dump packets to a file from another file. * this is useful when decrypting packets or applying filters * on pcapfile and we want to save the result in a file */ if (GBL_OPTIONS->write && GBL_OPTIONS->read) { DUMP_LOCK; /* reuse the original pcap header, but with the modified packet */ pcap_dump((u_char *)GBL_PCAP->dump, pkthdr, po.packet); DUMP_UNLOCK; } /* * if it is the last packet set the flag * and send the packet to the top half. * we have to do this because the last packet * might be dropped by the filter. */ if (GBL_OPTIONS->read && GBL_PCAP->dump_size == GBL_PCAP->dump_off) { po.flags |= PO_EOF; top_half_queue_add(&po); } /* free the structure */ packet_destroy_object(&po); /* calculate the stats */ stats_half_end(&GBL_STATS->bh, pkthdr->caplen); CANCELLATION_POINT(); return; }