/* Read selected tags for a file into tags structure (or create it if NULL). * If some tags are already present, don't read them. * If present_tags is NULL, allocate new tags. */ struct file_tags *read_file_tags (const char *file, struct file_tags *present_tags, const int tags_sel) { struct file_tags *tags; struct decoder *df; int needed_tags; assert (file != NULL); if (present_tags) { tags = present_tags; needed_tags = ~tags->filled & tags_sel; } else { tags = tags_new (); needed_tags = tags_sel; } if (file_type(file) == F_URL) return tags; df = get_decoder (file); if (!df) { logit ("Can't find decoder functions for %s", file); return tags; } if (needed_tags) { /* This makes sure that we don't cause a memory leak */ assert (!((needed_tags & TAGS_COMMENTS) && (tags->title || tags->artist || tags->album))); df->info (file, tags, needed_tags); tags->filled |= tags_sel; } else debug ("No need to read any tags"); return tags; }
void capture_init(void) { pcap_t *pd; pcap_t *pb = NULL; /* for the bridge */ pcap_dumper_t *pdump; bpf_u_int32 net, mask; struct bpf_program bpf; char pcap_errbuf[PCAP_ERRBUF_SIZE]; /* * if the user didn't specified the interface, * we have to found one... */ if (!GBL_OPTIONS->read && GBL_OPTIONS->iface == NULL) { char *ifa = pcap_lookupdev(pcap_errbuf); ON_ERROR(ifa, NULL, "No suitable interface found..."); GBL_OPTIONS->iface = iface_name(ifa); } if (GBL_OPTIONS->iface) DEBUG_MSG("capture_init %s", GBL_OPTIONS->iface); else DEBUG_MSG("capture_init (no interface)"); if (GBL_SNIFF->type == SM_BRIDGED) { if (!strcmp(GBL_OPTIONS->iface, GBL_OPTIONS->iface_bridge)) FATAL_ERROR("Bridging iface must be different from %s", GBL_OPTIONS->iface); USER_MSG("Bridging %s and %s...\n\n", GBL_OPTIONS->iface, GBL_OPTIONS->iface_bridge); } else if (GBL_OPTIONS->read) { USER_MSG("Reading from %s... ", GBL_OPTIONS->pcapfile_in); } else USER_MSG("Listening on %s... ", GBL_OPTIONS->iface); /* set the snaplen to maximum */ GBL_PCAP->snaplen = UINT16_MAX; /* open the interface from GBL_OPTIONS (user specified) */ if (GBL_OPTIONS->read) pd = pcap_open_offline(GBL_OPTIONS->pcapfile_in, pcap_errbuf); else pd = pcap_open_live(GBL_OPTIONS->iface, GBL_PCAP->snaplen, GBL_PCAP->promisc, PCAP_TIMEOUT, pcap_errbuf); ON_ERROR(pd, NULL, "pcap_open: %s", pcap_errbuf); /* * update to the reap assigned snapshot. * this may be different reading from files */ DEBUG_MSG("requested snapshot: %d assigned: %d", GBL_PCAP->snaplen, pcap_snapshot(pd)); GBL_PCAP->snaplen = pcap_snapshot(pd); /* get the file size */ if (GBL_OPTIONS->read) { struct stat st; fstat(fileno(pcap_file(pd)), &st); GBL_PCAP->dump_size = st.st_size; } /* set the pcap filters */ if (GBL_PCAP->filter != NULL && strcmp(GBL_PCAP->filter, "")) { DEBUG_MSG("pcap_filter: %s", GBL_PCAP->filter); if (pcap_lookupnet(GBL_OPTIONS->iface, &net, &mask, pcap_errbuf) == -1) ERROR_MSG("%s", pcap_errbuf); if (pcap_compile(pd, &bpf, GBL_PCAP->filter, 1, mask) < 0) ERROR_MSG("%s", pcap_errbuf); if (pcap_setfilter(pd, &bpf) == -1) ERROR_MSG("pcap_setfilter"); pcap_freecode(&bpf); } /* if in bridged sniffing, we have to open even the other iface */ if (GBL_SNIFF->type == SM_BRIDGED) { pb = pcap_open_live(GBL_OPTIONS->iface_bridge, GBL_PCAP->snaplen, GBL_PCAP->promisc, PCAP_TIMEOUT, pcap_errbuf); ON_ERROR(pb, NULL, "%s", pcap_errbuf); /* set the pcap filters */ if (GBL_PCAP->filter != NULL) { if (pcap_lookupnet(GBL_OPTIONS->iface_bridge, &net, &mask, pcap_errbuf) == -1) ERROR_MSG("%s", pcap_errbuf); if (pcap_compile(pb, &bpf, GBL_PCAP->filter, 1, mask) < 0) ERROR_MSG("%s", pcap_errbuf); if (pcap_setfilter(pb, &bpf) == -1) ERROR_MSG("pcap_setfilter"); pcap_freecode(&bpf); } } /* open the dump file */ if (GBL_OPTIONS->write) { DEBUG_MSG("pcapfile_out: %s", GBL_OPTIONS->pcapfile_out); pdump = pcap_dump_open(pd, GBL_OPTIONS->pcapfile_out); ON_ERROR(pdump, NULL, "%s", pcap_geterr(pd)); GBL_PCAP->dump = pdump; } /* set the right dlt type for the iface */ GBL_PCAP->dlt = pcap_datalink(pd); DEBUG_MSG("capture_init: %s [%d]", pcap_datalink_val_to_description(GBL_PCAP->dlt), GBL_PCAP->dlt); USER_MSG("(%s)\n\n", pcap_datalink_val_to_description(GBL_PCAP->dlt)); /* check that the bridge type is the same as the main iface */ if (GBL_SNIFF->type == SM_BRIDGED && pcap_datalink(pb) != GBL_PCAP->dlt) FATAL_ERROR("You can NOT bridge two different type of interfaces !"); /* check if we support this media */ if (get_decoder(LINK_LAYER, GBL_PCAP->dlt) == NULL) { if (GBL_OPTIONS->read) FATAL_ERROR("Dump file not supported (%s)", pcap_datalink_val_to_description(GBL_PCAP->dlt)); else FATAL_ERROR("Inteface \"%s\" not supported (%s)", GBL_OPTIONS->iface, pcap_datalink_val_to_description(GBL_PCAP->dlt)); } /* set the alignment for the buffer */ set_alignment(GBL_PCAP->dlt); /* allocate the buffer for the packets (UINT16_MAX) */ SAFE_CALLOC(GBL_PCAP->buffer, UINT16_MAX + GBL_PCAP->align, sizeof(char)); /* set the global descriptor for both the iface and the bridge */ GBL_PCAP->pcap = pd; if (GBL_SNIFF->type == SM_BRIDGED) GBL_PCAP->pcap_bridge = pb; /* on exit clean up the structures */ atexit(capture_close); }
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; }
static void *precache_thread (void *data) { struct precache *precache = (struct precache *)data; int decoded; struct sound_params new_sound_params; struct decoder_error err; precache->buf_fill = 0; precache->sound_params.channels = 0; /* mark that sound_params were not yet filled. */ precache->decoded_time = 0.0; precache->f = get_decoder (precache->file); assert (precache->f != NULL); precache->decoder_data = precache->f->open(precache->file); precache->f->get_error(precache->decoder_data, &err); if (err.type != ERROR_OK) { logit ("Failed to open the file for precache: %s", err.err); decoder_error_clear (&err); precache->f->close (precache->decoder_data); return NULL; } audio_plist_set_time (precache->file, precache->f->get_duration(precache->decoder_data)); /* Stop at PCM_BUF_SIZE, because when we decode too much, there is no * place where we can put the data that doesn't fit into the buffer. */ while (precache->buf_fill < PCM_BUF_SIZE) { decoded = precache->f->decode (precache->decoder_data, precache->buf + precache->buf_fill, PCM_BUF_SIZE, &new_sound_params); if (!decoded) { /* EOF so fast? We can't pass this information * in precache, so give up. */ logit ("EOF when precaching."); precache->f->close (precache->decoder_data); return NULL; } precache->f->get_error (precache->decoder_data, &err); if (err.type == ERROR_FATAL) { logit ("Error reading file for precache: %s", err.err); decoder_error_clear (&err); precache->f->close (precache->decoder_data); return NULL; } if (!precache->sound_params.channels) precache->sound_params = new_sound_params; else if (!sound_params_eq(precache->sound_params, new_sound_params)) { /* There is no way to store sound with two different * parameters in the buffer, give up with * precaching. (this should never happen). */ logit ("Sound parameters have changed when precaching."); decoder_error_clear (&err); precache->f->close (precache->decoder_data); return NULL; } bitrate_list_add (&precache->bitrate_list, precache->decoded_time, precache->f->get_bitrate( precache->decoder_data)); precache->buf_fill += decoded; precache->decoded_time += decoded / (float)(sfmt_Bps( new_sound_params.fmt) * new_sound_params.rate * new_sound_params.channels); if (err.type != ERROR_OK) { decoder_error_clear (&err); break; /* Don't lose the error message */ } } precache->ok = 1; logit ("Successfully precached file (%d bytes)", precache->buf_fill); return NULL; }
static gboolean setup_recoder_pipeline (GstSmartEncoder * smart_encoder) { GstPad *tmppad; GstCaps *caps; /* Fast path */ if (G_UNLIKELY (smart_encoder->encoder)) return TRUE; GST_DEBUG ("Creating internal decoder and encoder"); /* Create decoder/encoder */ caps = gst_pad_get_current_caps (smart_encoder->sinkpad); smart_encoder->decoder = get_decoder (caps); if (G_UNLIKELY (smart_encoder->decoder == NULL)) goto no_decoder; gst_caps_unref (caps); gst_element_set_bus (smart_encoder->decoder, GST_ELEMENT_BUS (smart_encoder)); caps = gst_pad_get_current_caps (smart_encoder->sinkpad); smart_encoder->encoder = get_encoder (caps); if (G_UNLIKELY (smart_encoder->encoder == NULL)) goto no_encoder; gst_caps_unref (caps); gst_element_set_bus (smart_encoder->encoder, GST_ELEMENT_BUS (smart_encoder)); GST_DEBUG ("Creating internal pads"); /* Create internal pads */ /* Source pad which we'll use to feed data to decoders */ smart_encoder->internal_srcpad = gst_pad_new ("internal_src", GST_PAD_SRC); g_object_set_qdata ((GObject *) smart_encoder->internal_srcpad, INTERNAL_ELEMENT, smart_encoder); gst_pad_set_active (smart_encoder->internal_srcpad, TRUE); /* Sink pad which will get the buffers from the encoder. * Note: We don't need an event function since we'll be discarding all * of them. */ smart_encoder->internal_sinkpad = gst_pad_new ("internal_sink", GST_PAD_SINK); g_object_set_qdata ((GObject *) smart_encoder->internal_sinkpad, INTERNAL_ELEMENT, smart_encoder); gst_pad_set_chain_function (smart_encoder->internal_sinkpad, internal_chain); gst_pad_set_active (smart_encoder->internal_sinkpad, TRUE); GST_DEBUG ("Linking pads to elements"); /* Link everything */ tmppad = gst_element_get_static_pad (smart_encoder->encoder, "src"); if (GST_PAD_LINK_FAILED (gst_pad_link (tmppad, smart_encoder->internal_sinkpad))) goto sinkpad_link_fail; gst_object_unref (tmppad); if (!gst_element_link (smart_encoder->decoder, smart_encoder->encoder)) goto encoder_decoder_link_fail; tmppad = gst_element_get_static_pad (smart_encoder->decoder, "sink"); if (GST_PAD_LINK_FAILED (gst_pad_link (smart_encoder->internal_srcpad, tmppad))) goto srcpad_link_fail; gst_object_unref (tmppad); GST_DEBUG ("Done creating internal elements/pads"); return TRUE; no_decoder: { GST_WARNING ("Couldn't find a decoder for %" GST_PTR_FORMAT, caps); gst_caps_unref (caps); return FALSE; } no_encoder: { GST_WARNING ("Couldn't find an encoder for %" GST_PTR_FORMAT, caps); gst_caps_unref (caps); return FALSE; } srcpad_link_fail: { gst_object_unref (tmppad); GST_WARNING ("Couldn't link internal srcpad to decoder"); return FALSE; } sinkpad_link_fail: { gst_object_unref (tmppad); GST_WARNING ("Couldn't link encoder to internal sinkpad"); return FALSE; } encoder_decoder_link_fail: { GST_WARNING ("Couldn't link decoder to encoder"); return FALSE; } }