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

📄 fprobe.c

📁 模仿cisco路由器
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (cmpmtime(&flow->ctime, &flown->ctime) < 0)			flown->ctime = flow->ctime;		flown->tcp_flags |= flow->tcp_flags;		flown->size += flow->size;		flown->pkts += flow->pkts;		if (flow->flags & FLOW_FRAG) {			/* Fragmented flow require some additional work */			if (flow->flags & FLOW_TL) {				/*				?FIXME?				Several packets with FLOW_TL (attack)				*/				flown->sp = flow->sp;				flown->dp = flow->dp;			}			if (flow->flags & FLOW_LASTFRAG) {				/*				?FIXME?				Several packets with FLOW_LASTFRAG (attack)				*/				flown->sizeP = flow->sizeP;			}			flown->flags |= flow->flags;			flown->sizeF += flow->sizeF;			if ((flown->flags & FLOW_LASTFRAG)				&& (flown->sizeF >= flown->sizeP)) {				/* All fragments received - flow reassembled */				*flowpp = flown->next;				pthread_mutex_unlock(&flows_mutex[h]);#if ((DEBUG) & DEBUG_I)				flows_total--;				flows_fragmented--;#endif				flown->id = 0;				flown->flags &= ~FLOW_FRAG;#if ((DEBUG) & (DEBUG_U | DEBUG_S))				strcat(logbuf," R");#endif				ret = put_into(flown, MOVE_INTO#if ((DEBUG) & (DEBUG_U | DEBUG_S))						, logbuf#endif					);			}		}		if (flag == MOVE_INTO) mem_free(flow);	}	pthread_mutex_unlock(&flows_mutex[h]);	return ret;}void *fill(int fields, uint16_t *format, struct Flow *flow, void *p){	int i;	for (i = 0; i < fields; i++) {#if ((DEBUG) & DEBUG_F)		my_log(LOG_DEBUG, "F: field %04d at %x", format[i], (unsigned) p);#endif		switch (format[i]) {			case NETFLOW_IPV4_SRC_ADDR:				((struct in_addr *) p)->s_addr = flow->sip.s_addr;				p += NETFLOW_IPV4_SRC_ADDR_SIZE;				break;			case NETFLOW_IPV4_DST_ADDR:				((struct in_addr *) p)->s_addr = flow->dip.s_addr;				p += NETFLOW_IPV4_DST_ADDR_SIZE;				break;			case NETFLOW_INPUT_SNMP:				*((uint16_t *) p) = snmp_input_index;				p += NETFLOW_INPUT_SNMP_SIZE;				break;			case NETFLOW_OUTPUT_SNMP:				*((uint16_t *) p) = snmp_output_index;				p += NETFLOW_OUTPUT_SNMP_SIZE;				break;			case NETFLOW_PKTS_32:				*((uint32_t *) p) = htonl(flow->pkts);				p += NETFLOW_PKTS_32_SIZE;				break;			case NETFLOW_BYTES_32:				*((uint32_t *) p) = htonl(flow->size);				p += NETFLOW_BYTES_32_SIZE;				break;			case NETFLOW_FIRST_SWITCHED:				*((uint32_t *) p) = htonl(getuptime(&flow->ctime));				p += NETFLOW_FIRST_SWITCHED_SIZE;				break;			case NETFLOW_LAST_SWITCHED:				*((uint32_t *) p) = htonl(getuptime(&flow->mtime));				p += NETFLOW_LAST_SWITCHED_SIZE;				break;			case NETFLOW_L4_SRC_PORT:				*((uint16_t *) p) = flow->sp;				p += NETFLOW_L4_SRC_PORT_SIZE;				break;			case NETFLOW_L4_DST_PORT:				*((uint16_t *) p) = flow->dp;				p += NETFLOW_L4_DST_PORT_SIZE;				break;			case NETFLOW_PROT:				*((uint8_t *) p) = flow->proto;				p += NETFLOW_PROT_SIZE;				break;			case NETFLOW_SRC_TOS:				*((uint8_t *) p) = flow->tos;				p += NETFLOW_SRC_TOS_SIZE;				break;			case NETFLOW_TCP_FLAGS:				*((uint8_t *) p) = flow->tcp_flags;				p += NETFLOW_TCP_FLAGS_SIZE;				break;			case NETFLOW_VERSION:				*((uint16_t *) p) = htons(netflow->Version);				p += NETFLOW_VERSION_SIZE;				break;			case NETFLOW_COUNT:				*((uint16_t *) p) = htons(emit_count);				p += NETFLOW_COUNT_SIZE;				break;			case NETFLOW_UPTIME:				*((uint32_t *) p) = htonl(getuptime(&emit_time));				p += NETFLOW_UPTIME_SIZE;				break;			case NETFLOW_UNIX_SECS:				*((uint32_t *) p) = htonl(emit_time.sec);				p += NETFLOW_UNIX_SECS_SIZE;				break;			case NETFLOW_UNIX_NSECS:				*((uint32_t *) p) = htonl(emit_time.usec * 1000);				p += NETFLOW_UNIX_NSECS_SIZE;				break;			case NETFLOW_FLOW_SEQUENCE:				*((uint32_t *) p) = htonl(emit_sequence);				p += NETFLOW_FLOW_SEQUENCE_SIZE;				break;			case NETFLOW_PAD8:			/* Unsupported (uint8_t) */			case NETFLOW_ENGINE_TYPE:			case NETFLOW_ENGINE_ID:			case NETFLOW_FLAGS7_1:			case NETFLOW_SRC_MASK:			case NETFLOW_DST_MASK:				*((uint8_t *) p) = 0;				p += NETFLOW_PAD8_SIZE;				break;			case NETFLOW_PAD16:			/* Unsupported (uint16_t) */			case NETFLOW_SRC_AS:			case NETFLOW_DST_AS:			case NETFLOW_FLAGS7_2:				*((uint16_t *) p) = 0;				p += NETFLOW_PAD16_SIZE;				break;			case NETFLOW_PAD32:			/* Unsupported (uint32_t) */			case NETFLOW_IPV4_NEXT_HOP:			case NETFLOW_ROUTER_SC:				*((uint32_t *) p) = 0;				p += NETFLOW_PAD32_SIZE;				break;			default:				my_log(LOG_CRIT, "fill(): Unknown format at %x[%d]: %d",					format, i, format[i]);				exit(1);		}	}#if ((DEBUG) & DEBUG_F)	my_log(LOG_DEBUG, "F: return %x", (unsigned) p);#endif	return p;}void *emit_thread(){	struct Flow *flow;	void *p;	struct timeval now;	struct timespec timeout;	unsigned sent = 0, size, ret;#if ((DEBUG) & DEBUG_E)	void *pp;	int cnt, seq = 0;	char sip[16], dip[16];#endif	p = (void *) &emit_packet + netflow->HeaderSize;	timeout.tv_nsec = 0;	for (;;) {		pthread_mutex_lock(&emit_mutex);		while (!flows_emit) {			gettimeofday(&now, 0);			timeout.tv_sec = now.tv_sec + emit_timeout;			/* Do not wait until emit_packet will filled - it may be too long */			if (pthread_cond_timedwait(&emit_cond, &emit_mutex, &timeout) && emit_count) {				pthread_mutex_unlock(&emit_mutex);				goto sendit;			}		}		flow = flows_emit;		flows_emit = flows_emit->next;#if ((DEBUG) & DEBUG_I)		emit_queue--;#endif				pthread_mutex_unlock(&emit_mutex);#ifdef UPTIME_TRICK		if (!emit_count) {			gettime(&start_time);			start_time.sec -= start_time_offset;		}#endif#if ((DEBUG) & DEBUG_E)		sprintf(sip, "%s", inet_ntoa(flow->sip));		sprintf(dip, "%s", inet_ntoa(flow->dip));		my_log(LOG_DEBUG,"E: %d(%d) %d/%d %s>%s P:%x TCP:%x %d>%d",			flow->ctime.sec, flow->mtime.sec - flow->ctime.sec,			flow->size, flow->pkts, sip, dip, flow->proto, flow->tcp_flags,			ntohs(flow->sp), ntohs(flow->dp));#endif				p = fill(netflow->FlowFields, netflow->FlowFormat, flow, p);		mem_free(flow);		emit_count++;		if (emit_count == netflow->MaxFlows) {		sendit:			gettime(&emit_time);			p = fill(netflow->HeaderFields, netflow->HeaderFormat, 0, &emit_packet);#if ((DEBUG) & DEBUG_E)			pp = (void *) &emit_packet;			my_log(LOG_DEBUG, "E: Hdr ver:%d cnt:%d uptime:%d secs:%d nsecs:%d",				ntohs(*(uint16_t*)(pp + 0)),				ntohs(*(uint16_t*)(pp + 2)),				ntohl(*(uint32_t*)(pp + 4)),				ntohl(*(uint32_t*)(pp + 8)),				ntohl(*(uint32_t*)(pp + 12))			);			cnt= ntohs(*(uint16_t *)(pp + 2));			pp = (void *) &emit_packet + netflow->HeaderSize;			for (; cnt--;) {				sprintf(sip, "%s", inet_ntoa(*(struct in_addr*)(pp + 0)));				sprintf(dip, "%s", inet_ntoa(*(struct in_addr*)(pp + 4)));				my_log(LOG_DEBUG, "E: #%d %d-%d %d/%d %s>%s P:%x TCP:%x %d>%d",					seq++,					ntohl(*(uint32_t*)(pp + 24)),					ntohl(*(uint32_t*)(pp + 28)),					ntohl(*(uint32_t*)(pp + 20)),					ntohl(*(uint32_t*)(pp + 16)),					sip,					dip,					*(uint8_t *)(pp + 38),					*(uint8_t *)(pp + 37),					ntohs(*(uint16_t*)(pp + 32)),					ntohs(*(uint16_t*)(pp + 34))				);				pp += netflow->FlowSize;			}#endif			size = netflow->HeaderSize + emit_count * netflow->FlowSize;			ret = sendto(sock, emit_packet, size, 0,					(struct sockaddr *) &server, sizeof(server));			if ( ret < size) {#if ((DEBUG) & DEBUG_E) || defined MESSAGES				my_log(LOG_ERR, "sendto() == %d: %s", ret, strerror(errno));#endif			}#if ((DEBUG) & DEBUG_E)			else {				my_log(LOG_DEBUG, "E: Emitted %d flow(s)", emit_count);			}#endif			emit_sequence += emit_count;			emit_count = 0;#if ((DEBUG) & DEBUG_I)			emit_pkts++;#endif			/* Rate limit */			if (emit_rate_bytes) {				sent += size;				size = sent / emit_rate_bytes;				if (size) {					sent %= emit_rate_bytes;					timeout.tv_sec = 0;					timeout.tv_nsec = emit_rate_delay * size;					while (nanosleep(&timeout, &timeout) == -1 && errno == EINTR);				}			}		}	}}	void *unpending_thread(){	struct timeval now;	struct timespec timeout;#if ((DEBUG) & (DEBUG_S | DEBUG_U))	char logbuf[256];#endif	timeout.tv_nsec = 0;	pthread_mutex_lock(&unpending_mutex);	for (;;) {		while (!(pending_tail->flags & FLOW_PENDING)) {			gettimeofday(&now, 0);			timeout.tv_sec = now.tv_sec + unpending_timeout;			pthread_cond_timedwait(&unpending_cond, &unpending_mutex, &timeout);		}#if ((DEBUG) & (DEBUG_S | DEBUG_U))		*logbuf = 0;#endif		if (put_into(pending_tail, COPY_INTO#if ((DEBUG) & (DEBUG_S | DEBUG_U))				, logbuf#endif			) < 0) {#if ((DEBUG) & DEBUG_I)			pkts_lost_unpending++;#endif						}#if ((DEBUG) & DEBUG_U)		my_log(LOG_DEBUG, "%s%s", "U:", logbuf);#endif		pending_tail->flags = 0;		pending_tail = pending_tail->next;#if ((DEBUG) & DEBUG_I)		pkts_pending_done++;#endif	}}void *scan_thread(){#if ((DEBUG) & (DEBUG_S | DEBUG_U))	char logbuf[256];#endif	int i;	struct Flow *flow, **flowpp;	struct Time now;	struct timespec timeout;	timeout.tv_nsec = 0;	pthread_mutex_lock(&scan_mutex);	for (;;) {		gettime(&now);		timeout.tv_sec = now.sec + scan_interval;		pthread_cond_timedwait(&scan_cond, &scan_mutex, &timeout);		gettime(&now);#if ((DEBUG) & DEBUG_S)		my_log(LOG_DEBUG, "S: %d", now.sec);#endif		for (i = 0; i < 1 << HASH_BITS ; i++) {			pthread_mutex_lock(&flows_mutex[i]);			flow = flows[i];			flowpp = &flows[i];			while (flow) {				if (flow->flags & FLOW_FRAG) {					/* Process fragmented flow */					if ((now.sec - flow->mtime.sec) > frag_lifetime) {						/* Fragmented flow expired - put it into special chain */#if ((DEBUG) & DEBUG_I)						flows_fragmented--;						flows_total--;#endif						*flowpp = flow->next;						flow->id = 0;						flow->flags &= ~FLOW_FRAG;						flow->next = scan_frag_dreg;						scan_frag_dreg = flow;						flow = *flowpp;						continue;					}				} else {					/* Flow is not frgamented */					if ((now.sec - flow->mtime.sec) > inactive_lifetime						|| (flow->mtime.sec - flow->ctime.sec) > active_lifetime) {						/* Flow expired */#if ((DEBUG) & DEBUG_S)						my_log(LOG_DEBUG, "S: E %x", flow);#endif#if ((DEBUG) & DEBUG_I)						flows_total--;#endif						*flowpp = flow->next;						pthread_mutex_lock(&emit_mutex);						flow->next = flows_emit;						flows_emit = flow;#if ((DEBUG) & DEBUG_I)						emit_queue++;#endif										pthread_mutex_unlock(&emit_mutex);						flow = *flowpp;						continue;					}				}				flowpp = &flow->next;				flow = flow->next;			} /* chain loop */			pthread_mutex_unlock(&flows_mutex[i]);		} /* hash loop */		if (flows_emit) pthread_cond_signal(&emit_cond);		while (scan_frag_dreg) {			flow = scan_frag_dreg;			scan_frag_dreg = flow->next;#if ((DEBUG) & (DEBUG_S | DEBUG_U))			*logbuf = 0;#endif			put_into(flow, MOVE_INTO#if ((DEBUG) & (DEBUG_S | DEBUG_U))				, logbuf#endif			);#if ((DEBUG) & DEBUG_S)			my_log(LOG_DEBUG, "%s%s", "S: FE", logbuf);#endif		}	}}void pcap_callback(u_char *useless,	const struct pcap_pkthdr* pkthdr, const u_char *packet){	struct ip *nl;	void *tl;	struct Flow *flow;	int off_frag, psize;#if ((DEBUG) & DEBUG_C)	char buf[64];	char logbuf[256];#endif	if (killed) return; /* SIGTERM received - stop capturing */#if ((DEBUG) & DEBUG_C)	sprintf(logbuf, "C: %d/%d", pkthdr->caplen, pkthdr->len);#endif	/* Offset (from begin of captured packet) to network layer header */	nl = (void *) packet + off_nl;	psize = pkthdr->caplen - off_nl;	/* Sanity check */	if (psize < (signed) sizeof(struct ip) || nl->ip_v != 4) {#if ((DEBUG) & DEBUG_C)		strcat(logbuf, " U");		my_log(LOG_DEBUG, "%s", logbuf);#endif#if ((DEBUG) & DEBUG_I)		pkts_ignored++;#endif		return;	}	if (pending_head->flags) {#if ((DEBUG) & DEBUG_C) || defined MESSAGES		my_log(LOG_ERR,# if ((DEBUG) & DEBUG_C)			"%s %s %s", logbuf,# else			"%s %s",# endif			"pending queue full:", "packet lost");#endif#if ((DEBUG) & DEBUG_I)		pkts_lost_capture++;#endif		goto done;	}

⌨️ 快捷键说明

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