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

📄 fromtcpdump.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
📖 第 1 页 / 共 2 页
字号:
    else if (s + 9 <= end && memcmp(s + 1, "[bad udp", 8) == 0 && (s2 = find(s + 9, end, ']')) + 1 < end && s2[1] == ' ')	s = s2 + 2;    // then check for 'udp LENGTH'    if (s + 4 < end && s[0] == 'u' && s[1] == 'd' && s[2] == 'p' && s[3] == ' ' && isdigit(s[4])) {	uint32_t dl;	s = cp_unsigned(s + 4, end, 0, &dl);	*data_len = dl;    }    return s;}Packet *FromTcpdump::read_packet(ErrorHandler *errh){    WritablePacket *q = Packet::make(0, (const unsigned char *)0, sizeof(click_ip) + sizeof(click_tcp), 20);    if (!q) {	_ff.error(errh, "out of memory!");	_dead = true;	return 0;    }    if (_zero)	memset(q->data(), 0, q->length());    q->set_ip_header((click_ip *)q->data(), sizeof(click_ip));    click_ip *iph = q->ip_header();    iph->ip_v = 4;    iph->ip_hl = sizeof(click_ip) >> 2;    iph->ip_off = 0;    iph->ip_tos = 0;    iph->ip_ttl = 2;    click_udp *udph = q->udp_header();        String line;    StringAccum payload;    String ip_opt;    String tcp_opt;        while (1) {	if (_ff.read_line(line, errh) <= 0) {	    q->kill();	    _dead = true;	    return 0;	}	const char *s = line.data();	const char *end = line.end();	if (s >= end || s[0] == '#')	    continue;	else if (!isdigit(s[0]))	    break;	// first, read timestamp	const char *s2 = find(s, end, ' ');	if (!cp_time(line.substring(s, s2), &q->timestamp_anno()))	    break;	s = s2 + 1;	// then, guess protocol	iph->ip_p = 0;	const char *colon = find(s, end, ':');	for (colon++; colon < end && *colon == ' '; colon++)	    /* nada */;	if (colon < end) {	    if (*colon == 'i')		iph->ip_p = IP_PROTO_ICMP;	    else if (*colon == 'u' || (*colon == '[' && colon + 1 < end && colon[1] == 'u'))		iph->ip_p = IP_PROTO_UDP;	    else if (*colon == '.' || (*colon >= 'A' && *colon <= 'Z'))		iph->ip_p = IP_PROTO_TCP;	}		// then, read source IP address and port	s2 = find(s, end, ' ');	if (s2 == s || s2 + 2 >= end || s2[1] != '>' || s2[2] != ' ')	    break;	if (iph->ip_p == IP_PROTO_TCP || iph->ip_p == IP_PROTO_UDP) {	    const char *sm = s2 - 1;	    while (sm > s && *sm != '.' && *sm != ':')		sm--;	    if (!cp_ip_address(line.substring(s, sm), (IPAddress *) &iph->ip_src)		|| !cp_tcpudp_port(line.substring(sm + 1, s2), iph->ip_p, &udph->uh_sport))		break;	    else		udph->uh_sport = htons(udph->uh_sport);	} else if (!cp_ip_address(line.substring(s, s2), (IPAddress *) &iph->ip_src))	    break;	s = s2 + 3;	// then, read destination IP address and port	s2 = find(s, end, ':');	if (iph->ip_p == IP_PROTO_TCP || iph->ip_p == IP_PROTO_UDP) {	    const char *sm = s2 - 1;	    while (sm > s && *sm != '.' && *sm != ':')		sm--;	    if (!cp_ip_address(line.substring(s, sm), (IPAddress *) &iph->ip_dst)		|| !cp_tcpudp_port(line.substring(sm + 1, s2), iph->ip_p, &udph->uh_dport))		break;	    else		udph->uh_dport = htons(udph->uh_dport);	} else if (!cp_ip_address(line.substring(s, s2), (IPAddress *) &iph->ip_dst))	    break;	// then, read protocol data	int data_len = -1;	if (iph->ip_p == IP_PROTO_TCP && IP_FIRSTFRAG(iph)) {	    s = read_tcp_line(q, colon, end, &data_len);	    iph = q->ip_header();	} else if (iph->ip_p == IP_PROTO_UDP && IP_FIRSTFRAG(iph)) {	    s = read_udp_line(q, colon, end, &data_len);	    q->take(sizeof(click_tcp) - sizeof(click_udp));	} else {	    q->take(sizeof(click_tcp));	    s = colon;	}	// parse IP stuff at the end of the line	// TTL and ID	s2 = end - 1;	while (s2 > s) {	    while (s2 > s && isspace(*s2))		s2--;	    if (s2 <= s || (*s2 != ')' && *s2 != ']'))		break;	    char opener = (*s2 == ')' ? '(' : '[');	    const char *open = s2 - 1;	    while (open >= s && *open != opener)		open--;	    const char *close = s2;	    s2 = open - 1;	    uint32_t u;	    	    if (open >= s && open < close) {		const char *item = open + 1;		while (item < close) {		    if (close - item >= 7 && memcmp(item, "tos 0x", 6) == 0) {			item = cp_unsigned(item + 6, close, 16, &u);			iph->ip_tos = u;		    } else if (close - item >= 6 && memcmp(item, "ECT(", 4) == 0 && (item[4] == '0' || item[4] == '1') && item[5] == ')') {			iph->ip_tos = (iph->ip_tos & ~IP_ECNMASK) | (item[4] == '0' ? IP_ECN_ECT1 : IP_ECN_ECT2);			item += 6;		    } else if (close - item >= 2 && item[0] == 'C' && item[1] == 'E') {			iph->ip_tos = (iph->ip_tos & ~IP_ECNMASK) | IP_ECN_CE;			item += 2;		    } else if (close - item >= 2 && item[0] == 'D' && item[1] == 'F') {			iph->ip_off |= htons(IP_DF);			item += 2;		    } else if (close - item >= 10 && memcmp(item, "frag ", 5) == 0 && isdigit(item[5])) {			item = cp_unsigned(item + 5, close, 0, &u);			iph->ip_id = htons(u);			if (item > close - 2 || *item != ':' || !isdigit(item[1]))			    break;			item = cp_unsigned(item + 1, close, 0, &u);			data_len = u;			if (item > close - 2 || *item != '@' || !isdigit(item[1]))			    break;			item = cp_unsigned(item + 1, close, 0, &u);			iph->ip_off = (iph->ip_off & htons(~IP_OFFMASK)) | htons(u);			if (item < close && *item == '+')			    iph->ip_off |= htons(IP_MF), item++;		    } else if (close - item >= 5 && memcmp(item, "ttl ", 4) == 0 && isdigit(item[4])) {			item = cp_unsigned(item + 4, close, 0, &u);			iph->ip_ttl = u;		    } else if (close - item >= 4 && memcmp(item, "id ", 3) == 0 && isdigit(item[3])) {			item = cp_unsigned(item + 3, close, 0, &u);			iph->ip_id = htons(u);		    } else if (close - item >= 5 && memcmp(item, "len ", 4) == 0 && isdigit(item[4])) {			item = cp_unsigned(item + 4, close, 0, &u);			if (data_len < 0 || u == q->length() + data_len)			    data_len = u - q->length();			else if (iph->ip_p == IP_PROTO_TCP) {			    // the discrepancy must be due to TCP options			    int delta = u - (q->length() + data_len);			    q->change_headroom_and_length(q->headroom(), u - data_len);			    q->tcp_header()->th_off = (q->transport_length() >> 2);			    if (delta > 0)				q->end_data()[-delta] = TCPOPT_EOL;			}		    } else			break;		    while (item < close && (*item == ',' || isspace(*item)))			item++;		}	    }	}		// set IP length	if (data_len < 0)	    data_len = 0;	iph->ip_len = ntohs(q->length() + data_len);	SET_EXTRA_LENGTH_ANNO(q, data_len);	// set UDP length (after IP length is available)	if (iph->ip_p == IP_PROTO_UDP && IP_FIRSTFRAG(iph))	    q->udp_header()->uh_ulen = htons(ntohs(iph->ip_len) - (iph->ip_hl << 2));		// set checksum	if (_checksum)	    set_checksums(q, iph);		return q;    }    // bad format if we get here    if (!_format_complaint) {	// don't complain if the line was all blank	const char *s = line.begin();	while (s < line.end() && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))	    s++;	if (s != line.end()) {	    _ff.error(errh, "packet parse error");	    _format_complaint = true;	}    }    if (q)	q->kill();    return 0;}boolFromTcpdump::run_task(){    if (!_active)	return false;    Packet *p;    while (1) {	p = read_packet(0);	if (_dead) {	    if (_stop)		router()->please_stop_driver();	    return false;	}	// check sampling probability	if (_sampling_prob >= (1 << SAMPLING_SHIFT)	    || (uint32_t)(random() & ((1 << SAMPLING_SHIFT) - 1)) < _sampling_prob)	    break;	if (p)	    p->kill();    }    if (p)	output(0).push(p);    _task.fast_reschedule();    return true;}Packet *FromTcpdump::pull(int){    if (!_active)	return 0;    Packet *p;    while (1) {	p = read_packet(0);	if (_dead) {	    if (_stop)		router()->please_stop_driver();	    _notifier.set_listeners(false);	    return 0;	}	// check sampling probability	if (_sampling_prob >= (1 << SAMPLING_SHIFT)	    || (uint32_t)(random() & ((1 << SAMPLING_SHIFT) - 1)) < _sampling_prob)	    break;	if (p)	    p->kill();    }    _notifier.set_listeners(true);    return p;}enum { H_SAMPLING_PROB, H_ACTIVE, H_ENCAP, H_STOP };StringFromTcpdump::read_handler(Element *e, void *thunk){    FromTcpdump *fd = static_cast<FromTcpdump *>(e);    switch ((intptr_t)thunk) {      case H_SAMPLING_PROB:	return cp_unparse_real2(fd->_sampling_prob, SAMPLING_SHIFT) + "\n";      case H_ACTIVE:	return cp_unparse_bool(fd->_active) + "\n";      case H_ENCAP:	return "IP\n";      default:	return "<error>\n";    }}intFromTcpdump::write_handler(const String &s_in, Element *e, void *thunk, ErrorHandler *errh){    FromTcpdump *fd = static_cast<FromTcpdump *>(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_listeners(active);	      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;    }}voidFromTcpdump::add_handlers(){    add_read_handler("sampling_prob", read_handler, (void *)H_SAMPLING_PROB);    add_read_handler("active", read_handler, (void *)H_ACTIVE);    add_write_handler("active", write_handler, (void *)H_ACTIVE);    add_read_handler("encap", read_handler, (void *)H_ENCAP);    add_write_handler("stop", write_handler, (void *)H_STOP);    _ff.add_handlers(this);    if (output_is_push(0))	add_task_handlers(&_task);}ELEMENT_REQUIRES(userlevel FromFile IPSummaryDump)EXPORT_ELEMENT(FromTcpdump)#include <click/bighashmap.cc>CLICK_ENDDECLS

⌨️ 快捷键说明

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