⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fromipsumdump.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 2 页
字号:
    if (_binary) {	Vector<const unsigned char *> args;	int nbytes;	for (const IPSummaryDump::FieldReader * const *fp = _fields.begin(); fp != _fields.end(); ++fp) {	    if (!(*fp)->inb)		goto bad_field;	    switch ((*fp)->type) {	      case IPSummaryDump::B_0:		nbytes = 0;		goto got_nbytes;	      case IPSummaryDump::B_1:		nbytes = 1;		goto got_nbytes;	      case IPSummaryDump::B_2:		nbytes = 2;		goto got_nbytes;	      case IPSummaryDump::B_4:	      case IPSummaryDump::B_4NET:		nbytes = 4;		goto got_nbytes;	      case IPSummaryDump::B_6PTR:		nbytes = 6;		goto got_nbytes;	      case IPSummaryDump::B_8:		nbytes = 8;		goto got_nbytes;	      case IPSummaryDump::B_16:		nbytes = 16;		goto got_nbytes;	      got_nbytes:		if (data + nbytes <= end) {		    args.push_back((const unsigned char *) data);		    data += nbytes;		} else		    goto bad_field;		break;	      case IPSummaryDump::B_SPECIAL:		args.push_back((const unsigned char *) data);		data = (const char *) (*fp)->inb(d, (const uint8_t *) data, (const uint8_t *) end, *fp);		break;	      bad_field:	      default:		args.push_back(0);		data = end;		break;	    }	}	for (int *fip = _field_order.begin();	     fip != _field_order.end() && d.p;	     ++fip) {	    const IPSummaryDump::FieldReader *f = _fields[*fip];	    if (!args[*fip] || !f->inject)		continue;	    d.clear_values();	    if (f->inb(d, args[*fip], (const uint8_t *) end, f)) {		f->inject(d, f);		nfields++;	    }	}    } else {	Vector<String> args;	while (args.size() < _fields.size()) {	    const char *original_data = data;	    while (data < end)		if (isspace((unsigned char) *data))		    break;		else if (*data == '\"')		    data = cp_skip_double_quote(data, end);		else		    ++data;	    args.push_back(line.substring(original_data, data));	    while (data < end && isspace((unsigned char) *data))		++data;	}	for (int *fip = _field_order.begin();	     fip != _field_order.end() && d.p;	     ++fip) {	    const IPSummaryDump::FieldReader *f = _fields[*fip];	    if (!args[*fip] || args[*fip].equals("-", 1) || !f->inject)		continue;	    d.clear_values();	    if (f->ina(d, args[*fip], f)) {		f->inject(d, f);		nfields++;	    }	}    }    if (!nfields) {	// bad format	if (!_format_complaint) {	    // don't complain if the line was all blank	    if (binary || !cp_is_space(line)) {		if (_fields.size() == 0)		    _ff.error(errh, "no '!data' provided");		else		    _ff.error(errh, "packet parse error");		_format_complaint = true;	    }	}	if (d.p)	    d.p->kill();	d.p = 0;    }    // set source and destination ports even if no transport info on packet    if (d.p && d.default_ip_flowid)	(void) d.make_ip(0);	// may fail    // set up transport header if necessary    if (d.p && d.is_ip && d.p->ip_header())	(void) d.make_transp();    if (d.p && d.is_ip && d.p->ip_header()) {	// set IP length	uint32_t ip_len;	if (!d.p->ip_header()->ip_len) {	    ip_len = d.want_len;	    if (ip_len >= (uint32_t) d.p->network_header_offset())		ip_len -= d.p->network_header_offset();	    if (ip_len > 0xFFFF)		ip_len = 0xFFFF;	    else if (ip_len == 0)		ip_len = d.p->network_length();	    d.p->ip_header()->ip_len = htons(ip_len);	} else	    ip_len = ntohs(d.p->ip_header()->ip_len);	// set UDP length	if (d.p->ip_header()->ip_p == IP_PROTO_UDP	    && IP_FIRSTFRAG(d.p->ip_header())	    && !d.p->udp_header()->uh_ulen) {	    int len = ip_len - d.p->network_header_length();	    d.p->udp_header()->uh_ulen = htons(len);	}	// set destination IP address annotation	d.p->set_dst_ip_anno(d.p->ip_header()->ip_dst);	// set checksum	if (_checksum) {	    uint32_t xlen = 0;	    if (ip_len > (uint32_t) d.p->network_length())		xlen = ip_len - d.p->network_length();	    if (!xlen || (d.p = d.p->put(xlen))) {		if (xlen && _zero)		    memset(d.p->end_data() - xlen, 0, xlen);		SET_EXTRA_LENGTH_ANNO(d.p, EXTRA_LENGTH_ANNO(d.p) - xlen);		set_checksums(d.p, d.p->ip_header());	    }	}    }    // set extra length annotation (post-other length adjustments)    if (d.p && d.want_len > d.p->length())	SET_EXTRA_LENGTH_ANNO(d.p, d.want_len - d.p->length());    return d.p;}inline Packet *set_packet_lengths(Packet *p, uint32_t extra_length){    uint32_t length = p->length() + extra_length;    if (htons(length) != p->ip_header()->ip_len) {	if (WritablePacket *q = p->uniqueify()) {	    click_ip *ip = q->ip_header();	    ip->ip_len = htons(length);	    if (ip->ip_p == IP_PROTO_UDP)		q->udp_header()->uh_ulen = htons(length - (ip->ip_hl << 2));	    return q;	} else	    return 0;    } else	return p;}Packet *FromIPSummaryDump::handle_multipacket(Packet *p){    assert(!_work_packet || _work_packet == p);    if (!p || !EXTRA_PACKETS_ANNO(p)) {	_work_packet = 0;	return p;    }    uint32_t count = 1 + EXTRA_PACKETS_ANNO(p);    // set up _multipacket variables on new packets (_work_packet == 0)    if (!_work_packet) {	assert(count > 1);	// set length of all but the last packet	_multipacket_length = (p->length() + EXTRA_LENGTH_ANNO(p)) / count;	// beware if there isn't enough EXTRA_LENGTH to cover all the packets	if (_multipacket_length < p->length()) {	    _multipacket_length = p->length();	    SET_EXTRA_LENGTH_ANNO(p, _multipacket_length * (count - 1));	}	// set timestamps	_multipacket_end_timestamp = p->timestamp_anno();	if (FIRST_TIMESTAMP_ANNO(p)) {	    _multipacket_timestamp_delta = (p->timestamp_anno() - FIRST_TIMESTAMP_ANNO(p)) / (count - 1);	    p->timestamp_anno() = FIRST_TIMESTAMP_ANNO(p);	} else	    _multipacket_timestamp_delta = Timestamp();	// prepare IP lengths for _multipacket_extra_length	_work_packet = set_packet_lengths(p, _multipacket_length - p->length());	if (!_work_packet)	    return 0;    }    // prepare packet to return    if ((p = p->clone())) {	SET_EXTRA_PACKETS_ANNO(p, 0);	SET_EXTRA_LENGTH_ANNO(p, _multipacket_length - p->length());    }    // reduce weight of _work_packet    SET_EXTRA_PACKETS_ANNO(_work_packet, count - 2);    SET_EXTRA_LENGTH_ANNO(_work_packet, EXTRA_LENGTH_ANNO(_work_packet) - _multipacket_length);    if (count == 2) {	_work_packet->timestamp_anno() = _multipacket_end_timestamp;	_work_packet = set_packet_lengths(_work_packet, EXTRA_LENGTH_ANNO(_work_packet));    } else	_work_packet->timestamp_anno() += _multipacket_timestamp_delta;    return p;}voidFromIPSummaryDump::run_timer(Timer *){    if (_active) {	if (output_is_pull(0))	    _notifier.wake();	else	    _task.reschedule();    }}boolFromIPSummaryDump::check_timing(Packet *p){    assert(!_work_packet || _work_packet == p);    if (!_have_timing) {	_timing_offset = Timestamp::now() - p->timestamp_anno();	_have_timing = true;    }    Timestamp now = Timestamp::now();    Timestamp t = p->timestamp_anno() + _timing_offset;    if (now < t) {	t -= Timer::adjustment();	if (now < t) {	    _timer.schedule_at(t);	    if (output_is_pull(0))		_notifier.sleep();	} else {	    if (output_is_push(0))		_task.fast_reschedule();	}	_work_packet = p;	return false;    }    _work_packet = 0;    return true;}boolFromIPSummaryDump::run_task(Task *){    if (!_active)	return false;    Packet *p;    while (1) {	p = (_work_packet ? _work_packet : read_packet(0));	if (!p && !_ff.initialized()) {	    if (_stop)		router()->please_stop_driver();	    return false;	} else if (!p)	    break;	if (p && _timing && !check_timing(p))	    return false;	if (_multipacket)	    p = handle_multipacket(p);	// check sampling probability	if (_sampling_prob >= (1 << SAMPLING_SHIFT)	    || (click_random() & ((1 << SAMPLING_SHIFT) - 1)) < _sampling_prob)	    break;	if (p)	    p->kill();    }    if (p)	output(0).push(p);    _task.fast_reschedule();    return true;}Packet *FromIPSummaryDump::pull(int){    if (!_active)	return 0;    Packet *p;    while (1) {	p = (_work_packet ? _work_packet : read_packet(0));	if (!p && !_ff.initialized()) {	    if (_stop)		router()->please_stop_driver();	    _notifier.sleep();	    return 0;	}	if (p && _timing && !check_timing(p))	    return 0;	if (_multipacket)	    p = handle_multipacket(p);	// check sampling probability	if (_sampling_prob >= (1 << SAMPLING_SHIFT)	    || (click_random() & ((1 << SAMPLING_SHIFT) - 1)) < _sampling_prob)	    break;	if (p)	    p->kill();    }    _notifier.wake();    return p;}enum { H_SAMPLING_PROB, H_ACTIVE, H_ENCAP, H_STOP };StringFromIPSummaryDump::read_handler(Element *e, void *thunk){    FromIPSummaryDump *fd = static_cast<FromIPSummaryDump *>(e);    switch ((intptr_t)thunk) {      case H_SAMPLING_PROB:	return cp_unparse_real2(fd->_sampling_prob, SAMPLING_SHIFT);      case H_ACTIVE:	return cp_unparse_bool(fd->_active);      case H_ENCAP:	return "IP";      default:	return "<error>";    }}intFromIPSummaryDump::write_handler(const String &s_in, Element *e, void *thunk, ErrorHandler *errh){    FromIPSummaryDump *fd = static_cast<FromIPSummaryDump *>(e);    String s = cp_uncomment(s_in);    switch ((intptr_t)thunk) {      case H_ACTIVE: {	  bool active;	  if (cp_bool(s, &active)) {	      fd->_active = active;	      if (fd->output_is_push(0) && active && !fd->_task.scheduled())		  fd->_task.reschedule();	      else if (!fd->output_is_push(0))		  fd->_notifier.set_active(active, true);	      return 0;	  } else	      return errh->error("'active' should be Boolean");      }      case H_STOP:	fd->_active = false;	fd->router()->please_stop_driver();	return 0;      default:	return -EINVAL;    }}voidFromIPSummaryDump::add_handlers(){    add_read_handler("sampling_prob", read_handler, H_SAMPLING_PROB);    add_read_handler("active", read_handler, H_ACTIVE, Handler::CHECKBOX);    add_write_handler("active", write_handler, H_ACTIVE);    add_read_handler("encap", read_handler, H_ENCAP);    add_write_handler("stop", write_handler, H_STOP, Handler::BUTTON);    _ff.add_handlers(this);    if (output_is_push(0))	add_task_handlers(&_task);}ELEMENT_REQUIRES(userlevel FromFile IPSummaryDumpInfo)EXPORT_ELEMENT(FromIPSummaryDump)CLICK_ENDDECLS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -