コード例 #1
0
ファイル: format_pcap.c プロジェクト: superpig0501/libtrace
static int pcap_start_input(libtrace_t *libtrace) {
    char errbuf[PCAP_ERRBUF_SIZE];


    /* Check if the file is already open */
    if (INPUT.pcap)
        return 0; /* success */

    /* Open the trace file for reading */
    if ((INPUT.pcap =
                pcap_open_offline(libtrace->uridata,
                                  errbuf)) == NULL) {
        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
                      errbuf);
        return -1;
    }

    /* If a filter has been configured, compile and apply it */
    if (DATA(libtrace)->filter) {
        if (DATA(libtrace)->filter->flag == 0) {
            pcap_compile(INPUT.pcap,
                         &DATA(libtrace)->filter->filter,
                         DATA(libtrace)->filter->filterstring,
                         1, 0);
            DATA(libtrace)->filter->flag = 1;
        }
        if (pcap_setfilter(INPUT.pcap,&DATA(libtrace)->filter->filter)
                == -1) {
            trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
                          pcap_geterr(INPUT.pcap));
            return -1;
        }
    }
    return 0;
}
コード例 #2
0
ファイル: format_dag24.c プロジェクト: EaseTheWorld/libtrace
/* Initialises a DAG input trace */
static int dag_init_input(libtrace_t *libtrace) {
	struct stat buf;
        char *dag_dev_name = NULL;
	char *scan = NULL;

	/* Since DAG 2.5 has been changed to support a slightly different URI
	 * format, it's probably a good idea to deal with URIs specified in
	 * such a fashion even if we just end up ignoring the stream number */
	if ((scan = strchr(libtrace->uridata,',')) == NULL) {
		dag_dev_name = strdup(libtrace->uridata);
	} else {
		dag_dev_name = (char *)strndup(libtrace->uridata,
				(size_t)(scan - libtrace->uridata));
	}


	/* Make sure a DAG device with the right name exists */	
        if (stat(dag_dev_name, &buf) == -1) {
                trace_set_err(libtrace,errno,"stat(%s)",dag_dev_name);
		free(dag_dev_name);
                return -1;
        }
	
	dag_init_format_data(libtrace);
	if (S_ISCHR(buf.st_mode)) {
                /* DEVICE */
                if((FORMAT_DATA->fd = dag_open(dag_dev_name)) < 0) {
                        trace_set_err(libtrace,errno,"Cannot open DAG %s",
                                        dag_dev_name);
			free(dag_dev_name);
                        return -1;
                }

		/* Memory-map ourselves a pointer to the DAG memory hole */
                if((FORMAT_DATA->buf = (void *)dag_mmap(FORMAT_DATA->fd)) == MAP_FAILED) {
                        trace_set_err(libtrace,errno,"Cannot mmap DAG %s",
                                        dag_dev_name);
			free(dag_dev_name);
                        return -1;
                }
        } else {
                trace_set_err(libtrace,errno,"Not a valid dag device: %s",
                                dag_dev_name);
		free(dag_dev_name);
                return -1;
        }

	free(dag_dev_name);

        return 0;
}
コード例 #3
0
ファイル: format_dag24.c プロジェクト: EaseTheWorld/libtrace
/* Extracts DUCK information from the DAG card and produces a DUCK packet */
static int dag_get_duckinfo(libtrace_t *libtrace,
                                libtrace_packet_t *packet) {
        dag_inf lt_dag_inf;

	/* Allocate memory for the DUCK data */
        if (packet->buf_control == TRACE_CTRL_EXTERNAL ||
                        !packet->buffer) {
                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
                packet->buf_control = TRACE_CTRL_PACKET;
                if (!packet->buffer) {
                        trace_set_err(libtrace, errno,
                                        "Cannot allocate packet buffer");
                        return -1;
                }
        }

	/* DUCK doesn't actually have a format header, as such */
        packet->header = 0;
        packet->payload = packet->buffer;

	/* Check that the DAG card supports DUCK */
        if ((ioctl(FORMAT_DATA->fd, DAG_IOINF, &lt_dag_inf) < 0)) {
                trace_set_err(libtrace, errno,
                                "Error using DAG_IOINF");
                return -1;
        }
        if (!IsDUCK(&lt_dag_inf)) {
                printf("WARNING: %s does not have modern clock support - No DUCK information will be gathered\n", libtrace->uridata);
                return 0;
        }

	/* Get the DUCK information from the card */
        if ((ioctl(FORMAT_DATA->fd, DAG_IOGETDUCK, (duck_inf *)packet->payload)
                                < 0)) {
                trace_set_err(libtrace, errno, "Error using DAG_IOGETDUCK");
                return -1;
        }

	/* Set the type */
        packet->type = TRACE_RT_DUCK_2_4;

	/* Set the packet's trace to point at a DUCK trace, so that the
	 * DUCK format functions will be called on the packet rather than the
	 * DAG ones */
        if (!DUCK.dummy_duck)
                DUCK.dummy_duck = trace_create_dead("duck:dummy");
        packet->trace = DUCK.dummy_duck;
        return sizeof(duck_inf);
}
コード例 #4
0
ファイル: format_pcap.c プロジェクト: superpig0501/libtrace
static int pcapint_write_packet(libtrace_out_t *libtrace,
                                libtrace_packet_t *packet)
{
    int err;

    if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)
        return 0;

    if (!OUTPUT.trace.pcap) {
        OUTPUT.trace.pcap = (pcap_t *)pcap_open_live(
                                libtrace->uridata,65536,0,0,NULL);
    }
#ifdef HAVE_PCAP_INJECT
    err=pcap_inject(OUTPUT.trace.pcap,
                    packet->payload,
                    trace_get_capture_length(packet));
    if (err!=(int)trace_get_capture_length(packet))
        err=-1;
#else
#ifdef HAVE_PCAP_SENDPACKET
    err=pcap_sendpacket(OUTPUT.trace.pcap,
                        packet->payload,
                        trace_get_capture_length(packet));
#else
    trace_set_err(packet->trace,TRACE_ERR_UNSUPPORTED,"writing is not supported on this platform");
    return -1;
#endif
#endif
    return err;
}
コード例 #5
0
ファイル: format_pcapfile.c プロジェクト: wanduow/libtrace
static int pcapfile_init_input(libtrace_t *libtrace) {
	libtrace->format_data = malloc(sizeof(struct pcapfile_format_data_t));
	if (!libtrace->format_data) {
		trace_set_err(libtrace, TRACE_ERR_INIT_FAILED, "Unable to allocate memory for "
			"format data inside pcapfile_init_input()");
		return -1;
	}

	IN_OPTIONS.real_time = 0;
	DATA(libtrace)->started = false;
	return 0;
}
コード例 #6
0
ファイル: format_pcapfile.c プロジェクト: wanduow/libtrace
static int pcapfile_start_input(libtrace_t *libtrace) 
{
	int err;

	if (!libtrace->io) {
		libtrace->io=trace_open_file(libtrace);
		DATA(libtrace)->started=false;
	}

	if (!DATA(libtrace)->started) {

		if (!libtrace->io) {
			trace_set_err(libtrace, TRACE_ERR_BAD_IO, "Trace cannot start IO in pcapfile_start_input()");
			return -1;
		}

		err=wandio_read(libtrace->io,
				&DATA(libtrace)->header,
				sizeof(DATA(libtrace)->header));

		DATA(libtrace)->started = true;
		if (!(sizeof(DATA(libtrace)->header) > 0)) {
			trace_set_err(libtrace, TRACE_ERR_INIT_FAILED, "Trace is missing header in pcapfile_start_input()");
			return -1;
		}

		if (err<1) {
			trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
				"Error while reading pcap file header\n");
			return -1;
		}

                if (err != (int)sizeof(DATA(libtrace)->header)) {
                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
                                "Incomplete pcap file header");
                        return -1;
                }
        	
		if (!header_is_magic(&(DATA(libtrace)->header))) {
			trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,
					"Not a pcap tracefile (magic=%08x)\n",swapl(libtrace,DATA(libtrace)->header.magic_number));
			return -1; /* Not a pcap file */
		}

		if (swaps(libtrace,DATA(libtrace)->header.version_major)!=2
			&& swaps(libtrace,DATA(libtrace)->header.version_minor)!=4) {
			trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,
					"Unknown pcap tracefile version %d.%d\n",
					swaps(libtrace,
						DATA(libtrace)->header.version_major),
					swaps(libtrace,
						DATA(libtrace)->header.version_minor));
			return -1;
		}

	}

	return 0;
}
コード例 #7
0
ファイル: format_dag24.c プロジェクト: EaseTheWorld/libtrace
/* Starts a DAG input trace */
static int dag_start_input(libtrace_t *libtrace) {	
	if(dag_start(FORMAT_DATA->fd) < 0) {
                trace_set_err(libtrace,errno,"Cannot start DAG %s",
                                libtrace->uridata);
                return -1;
        }

	/* Flush the memory hole */
	while(dag_available(libtrace) != 0)
		FORMAT_DATA->diff = 0;
	FORMAT_DATA->drops = 0;
	return 0;
}
コード例 #8
0
ファイル: format_pcap.c プロジェクト: superpig0501/libtrace
static uint64_t pcap_get_dropped_packets(libtrace_t *trace)
{
    struct pcap_stat stats;
    if (pcap_stats(DATA(trace)->input.pcap,&stats)==-1) {
        char *errmsg = pcap_geterr(DATA(trace)->input.pcap);
        trace_set_err(trace,TRACE_ERR_UNSUPPORTED,
                      "Failed to retreive stats: %s\n",
                      errmsg ? errmsg : "Unknown pcap error");
        return ~0;
    }

    return stats.ps_drop;
}
コード例 #9
0
ファイル: format_rt.c プロジェクト: superpig0501/libtrace
/* Sends an RT ACK to the server to acknowledge receipt of packets */
static int rt_send_ack(libtrace_t *libtrace, 
		uint32_t seqno)  {
	
	static char *ack_buffer = 0;
	char *buf_ptr;
	int numbytes = 0;
	size_t to_write = 0;
	rt_header_t *hdr;
	rt_ack_t *ack_hdr;
	
	if (!ack_buffer) {
		ack_buffer = (char*)malloc(sizeof(rt_header_t) 
							+ sizeof(rt_ack_t));
	}
	
	hdr = (rt_header_t *) ack_buffer;
	ack_hdr = (rt_ack_t *) (ack_buffer + sizeof(rt_header_t));
	
	hdr->type = TRACE_RT_ACK;
	hdr->length = sizeof(rt_ack_t);

	ack_hdr->sequence = seqno;
	
	to_write = hdr->length + sizeof(rt_header_t);
	buf_ptr = ack_buffer;

	/* Keep trying until we write the entire ACK */
	while (to_write > 0) {
		numbytes = send(RT_INFO->input_fd, buf_ptr, to_write, 0); 
		if (numbytes == -1) {
			if (errno == EINTR || errno == EAGAIN) {
				continue;
			}
			else {
				printf("Error sending ack\n");
				perror("send");
				trace_set_err(libtrace, TRACE_ERR_RT_FAILURE, 
						"Error sending ack");
				return -1;
			}
		}
		to_write = to_write - numbytes;
		buf_ptr = buf_ptr + to_write;
		
	}

	return 1;
}
コード例 #10
0
ファイル: format_bpf.c プロジェクト: EaseTheWorld/libtrace
/* Starts a BPF input trace */
static int bpf_start_input(libtrace_t *libtrace)
{
	int bpfid=0;
	struct bpf_version bv;
	struct ifreq ifr;
	unsigned int v;

	/* Find and open a bpf device */
	do {
		char buffer[64];
		snprintf(buffer,sizeof(buffer),"/dev/bpf%d", bpfid);
		bpfid++;
		
		FORMATIN(libtrace)->fd = open(buffer, O_RDONLY);
	} while(FORMATIN(libtrace)->fd == -1 && errno == EBUSY);

	if (FORMATIN(libtrace)->fd == -1) {
		trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,
				"No free bpf devices");
		return -1;
	}

	/* Check the BPF Version is ok */
	if (ioctl(FORMATIN(libtrace)->fd, BIOCVERSION, &bv) == -1) {
		trace_set_err(libtrace,errno,
				"Failed to read the bpf version");
		close(FORMATIN(libtrace)->fd);
		return -1;
	}

	if (bv.bv_major != BPF_MAJOR_VERSION) {
		trace_set_err(libtrace,errno, 
			"Unknown kernel BPF version (%d.%d, libtrace requires at least %d.%d)",
			bv.bv_major,
			bv.bv_minor,
			BPF_MAJOR_VERSION,
			BPF_MINOR_VERSION);
		close(FORMATIN(libtrace)->fd);
		return -1;
	}

	if (bv.bv_minor < BPF_MINOR_VERSION) {
		trace_set_err(libtrace,errno, "Kernel version too old (%d.%d, libtrace requires at least %d.%d)",
			bv.bv_major,
			bv.bv_minor,
			BPF_MAJOR_VERSION,
			BPF_MINOR_VERSION);
		close(FORMATIN(libtrace)->fd);
		return -1;
	}

	/* We assume the default kernel buffer size is sufficient. */
	if (ioctl(FORMATIN(libtrace)->fd, BIOCGBLEN,
			&FORMATIN(libtrace)->buffersize)==-1) {
		trace_set_err(libtrace,errno,"Failed to find buffer length");
		close(FORMATIN(libtrace)->fd);
		return -1;
	}

	FORMATIN(libtrace)->buffer = NULL;
	FORMATIN(libtrace)->bufptr = NULL;
	FORMATIN(libtrace)->remaining = 0;

	/* Attach to the device */
	strncpy(ifr.ifr_name, libtrace->uridata, sizeof(ifr.ifr_name));
	if (ioctl(FORMATIN(libtrace)->fd, BIOCSETIF, &ifr) == -1) {
		trace_set_err(libtrace,errno,"Failed to attach");
		close(FORMATIN(libtrace)->fd);
		return -1;
	}

	/* Set the link type */
	if (ioctl(FORMATIN(libtrace)->fd, BIOCGDLT,
			 &FORMATIN(libtrace)->linktype) == -1) {
		trace_set_err(libtrace,errno,"Failed to retrieve link type");
		close(FORMATIN(libtrace)->fd);
		return -1;
	}
	
	/* TODO: If BIOCGDLTLIST exists then we should perhaps do something
	 *       with it.  We don't have the same concept of multiple DLT's
         *       as pcap does.  We grab the rawest possible thing and then
	 *	 decode packets by understanding the protocols.  So perhaps
	 *	 we should setup a rating of DLT's that we'll prefer in order.
	 *       For example we should try and get 802.11 frames rather than
	 *       802.3 frames.  The general rule should be "whatever actually
	 *       went over the air", although of course if we don't support
	 *       what went over the air we should fall back to something we
	 *       /do/ support.
	 */
	
	/* Using timeouts seems sucky.  We'll always use immediate mode.  We
         * pray the kernel is smart enough that if a another packet arrives
         * while we're processing this one that it will buffer them into it's
	 * kernel buffer so we can receive packets later. (It'll need to do this
	 * to deal with us spending time processing the last 'n' packets anyway)
	 */
	
	v=1;
	if (ioctl(FORMATIN(libtrace)->fd, BIOCIMMEDIATE, &v) == -1) {
		trace_set_err(libtrace,errno,"Failed to set immediate mode");
		close(FORMATIN(libtrace)->fd);
		return -1;
	}

	/* Set promiscous mode, if the user has asked us to do so */
	if (FORMATIN(libtrace)->promisc) {
		if (ioctl(FORMATIN(libtrace)->fd, BIOCPROMISC, NULL) == -1) {
			trace_set_err(libtrace,errno,
				"Failed to set promisc mode");
			close(FORMATIN(libtrace)->fd);
			return -1;

		}
	}

	FORMATIN(libtrace)->stats_valid = 0;

	/* TODO: we should always set a bpf filter for snapping */

	/* We're done! */
	return 0;
}
コード例 #11
0
ファイル: format_rt.c プロジェクト: superpig0501/libtrace
/* Sets the trace format for the packet to match the format it was originally
 * captured in, rather than the RT format */
static int rt_set_format(libtrace_t *libtrace, libtrace_packet_t *packet) 
{

	/* We need to assign the packet to a "dead" trace */

	/* Try to minimize the number of corrupt packets that slip through
	 * while making it easy to identify new pcap DLTs */
	if (packet->type > TRACE_RT_DATA_DLT && 
			packet->type < TRACE_RT_DATA_DLT_END) {
		if (!RT_INFO->dummy_pcap) {
			RT_INFO->dummy_pcap = trace_create_dead("pcap:-");
		}
		packet->trace = RT_INFO->dummy_pcap;
		return 0;	
	}

	if (packet->type > TRACE_RT_DATA_BPF &&
			packet->type < TRACE_RT_DATA_BPF_END) {

		if (!RT_INFO->dummy_bpf) {
			RT_INFO->dummy_bpf = trace_create_dead("bpf:-");
			/* This may fail on a non-BSD machine */
			if (trace_is_err(RT_INFO->dummy_bpf)) {
				trace_perror(RT_INFO->dummy_bpf, "Creating dead bpf trace");
				return -1;
			}
		}
		packet->trace = RT_INFO->dummy_bpf;
		return 0;
	}

	switch (packet->type) {
		case TRACE_RT_DUCK_2_4:
		case TRACE_RT_DUCK_2_5:
			if (!RT_INFO->dummy_duck) {
				RT_INFO->dummy_duck = trace_create_dead("duck:dummy");
			}
			packet->trace = RT_INFO->dummy_duck;
			break;
		case TRACE_RT_DATA_ERF:
			if (!RT_INFO->dummy_erf) {
				RT_INFO->dummy_erf = trace_create_dead("erf:-");
			}
			packet->trace = RT_INFO->dummy_erf;
			break;
		case TRACE_RT_DATA_LINUX_NATIVE:
			if (!RT_INFO->dummy_linux) {
				RT_INFO->dummy_linux = trace_create_dead("int:");
				/* This may fail on a non-Linux machine */
				if (trace_is_err(RT_INFO->dummy_linux)) {
					trace_perror(RT_INFO->dummy_linux, "Creating dead int trace");
					return -1;
				}
			}
			packet->trace = RT_INFO->dummy_linux;
			break;
		case TRACE_RT_DATA_LINUX_RING:
			if (!RT_INFO->dummy_ring) {
				RT_INFO->dummy_ring = trace_create_dead("ring:");
				/* This may fail on a non-Linux machine */
				if (trace_is_err(RT_INFO->dummy_ring)) {
					trace_perror(RT_INFO->dummy_ring, "Creating dead int trace");
					return -1;
				}
			}
			packet->trace = RT_INFO->dummy_ring;
			break;
		case TRACE_RT_STATUS:
		case TRACE_RT_METADATA:
			/* Just use the RT trace! */
			packet->trace = libtrace;
			break;
		case TRACE_RT_DATA_LEGACY_ETH:
		case TRACE_RT_DATA_LEGACY_ATM:
		case TRACE_RT_DATA_LEGACY_POS:
			printf("Sending legacy over RT is currently not supported\n");
			trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Legacy packet cannot be sent over rt");
			return -1;
		default:
			printf("Unrecognised format: %u\n", packet->type);
			trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Unrecognised packet format");
			return -1;
	}
	return 0; /* success */
}		
コード例 #12
0
ファイル: format_rt.c プロジェクト: superpig0501/libtrace
/* Receives data from an RT server */
static int rt_read(libtrace_t *libtrace, void **buffer, size_t len, int block) 
{
        int numbytes;
	
	assert(len <= RT_BUF_SIZE);
	
	if (!RT_INFO->pkt_buffer) {
		RT_INFO->pkt_buffer = (char*)malloc((size_t)RT_BUF_SIZE);
		RT_INFO->buf_current = RT_INFO->pkt_buffer;
		RT_INFO->buf_filled = 0;
	}

#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT 0
#endif

	if (block)
		block=0;
	else
		block=MSG_DONTWAIT;

	/* If we don't have enough buffer space for the amount we want to
	 * read, move the current buffer contents to the front of the buffer
	 * to make room */
	if (len > RT_INFO->buf_filled) {
		memcpy(RT_INFO->pkt_buffer, RT_INFO->buf_current, 
				RT_INFO->buf_filled);
		RT_INFO->buf_current = RT_INFO->pkt_buffer;
#ifndef MSG_NOSIGNAL
#  define MSG_NOSIGNAL 0
#endif
		/* Loop as long as we don't have all the data that we were
		 * asked for */
		while (len > RT_INFO->buf_filled) {
                	if ((numbytes = recv(RT_INFO->input_fd,
                                                RT_INFO->buf_current + 
						RT_INFO->buf_filled,
                                                RT_BUF_SIZE-RT_INFO->buf_filled,
                                                MSG_NOSIGNAL|block)) <= 0) {
				if (numbytes == 0) {
					trace_set_err(libtrace, TRACE_ERR_RT_FAILURE, 
							"No data received");
					return -1;
				}
				
                	        if (errno == EINTR) {
                	                /* ignore EINTR in case
                	                 * a caller is using signals
					 */
                	                continue;
                	        }
				if (errno == EAGAIN) {
					/* We asked for non-blocking mode, so
					 * we need to return now */
					trace_set_err(libtrace,
							EAGAIN,
							"EAGAIN");
					return -1;
				}
				
                        	perror("recv");
				trace_set_err(libtrace, errno,
						"Failed to read data into rt recv buffer");
                        	return -1;
                	}
			RT_INFO->buf_filled+=numbytes;
		}

        }
	*buffer = RT_INFO->buf_current;
	RT_INFO->buf_current += len;
	RT_INFO->buf_filled -= len;
        return len;
}
コード例 #13
0
ファイル: format_rt.c プロジェクト: superpig0501/libtrace
/* Connects to an RT server 
 *
 * Returns -1 if an error occurs
 */
static int rt_connect(libtrace_t *libtrace) {
        struct hostent *he;
        struct sockaddr_in remote;
	rt_header_t connect_msg;
	rt_deny_conn_t deny_hdr;	
	rt_hello_t hello_opts;
	uint8_t reason;
	
	if ((he=gethostbyname(RT_INFO->hostname)) == NULL) {
                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
				"Failed to convert hostname %s to address",
				RT_INFO->hostname);
		return -1;
        }
        if ((RT_INFO->input_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
				"Could not create socket");
		return -1;
        }

	memset(&remote,0, sizeof(remote));
        remote.sin_family = AF_INET;
        remote.sin_port = htons(RT_INFO->port);
        remote.sin_addr = *((struct in_addr *)he->h_addr);

        if (connect(RT_INFO->input_fd, (struct sockaddr *)&remote,
                                (socklen_t)sizeof(struct sockaddr)) == -1) {
                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
				"Could not connect to host %s on port %d",
				RT_INFO->hostname, RT_INFO->port);
		return -1;
        }

	/* We are connected, now receive message from server */
	
	if (recv(RT_INFO->input_fd, (void*)&connect_msg, sizeof(rt_header_t), 0) != sizeof(rt_header_t) ) {
		trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
				"Could not receive connection message from %s",
				RT_INFO->hostname);
		return -1;
	}
	
	switch (connect_msg.type) {
		case TRACE_RT_DENY_CONN:
			/* Connection was denied */
			
			if (recv(RT_INFO->input_fd, (void*)&deny_hdr, 
						sizeof(rt_deny_conn_t),
						0) != sizeof(rt_deny_conn_t)) {
				reason = 0;
			}	
			reason = deny_hdr.reason;
			trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
				"Connection attempt is denied: %s",
				rt_deny_reason(reason));	
			return -1;
		case TRACE_RT_HELLO:
			/* Hello message - read the options sent to us by the
			 * server */
			if (recv(RT_INFO->input_fd, (void*)&hello_opts, 
						sizeof(rt_hello_t), 0)
					!= sizeof(rt_hello_t)) {
				trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
					"Failed to receive TRACE_RT_HELLO options");
				return -1;
			}
			RT_INFO->reliable = hello_opts.reliable;
			
			return 0;
		default:
			trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
					"Unknown message type received: %d",
					connect_msg.type);
			return -1;
	}
	trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
			"Somehow you managed to reach this unreachable code");
        return -1;
}
コード例 #14
0
ファイル: format_pcap.c プロジェクト: superpig0501/libtrace
static libtrace_direction_t pcap_get_direction(const libtrace_packet_t *packet) {
    libtrace_direction_t direction  = -1;
    switch(pcap_get_link_type(packet)) {
    /* Only packets encapsulated in Linux SLL or PFLOG have any
     * direction information */

    case TRACE_TYPE_LINUX_SLL:
    {
        libtrace_sll_header_t *sll;
        sll = trace_get_packet_buffer(packet, NULL, NULL);
        /* TODO: should check remaining>=sizeof(*sll) */
        if (!sll) {
            trace_set_err(packet->trace,
                          TRACE_ERR_BAD_PACKET,
                          "Bad or missing packet");
            return -1;
        }
        /* 0 == LINUX_SLL_HOST */
        /* the Waikato Capture point defines "packets
         * originating locally" (ie, outbound), with a
         * direction of 0, and "packets destined locally"
         * (ie, inbound), with a direction of 1.
         * This is kind-of-opposite to LINUX_SLL.
         * We return consistent values here, however
         *
         * Note that in recent versions of pcap, you can
         * use "inbound" and "outbound" on ppp in linux
         */
        if (sll->pkttype == TRACE_SLL_OUTGOING) {
            direction = TRACE_DIR_OUTGOING;
        } else {
            direction = TRACE_DIR_INCOMING;
        }
        break;

    }
    case TRACE_TYPE_PFLOG:
    {
        libtrace_pflog_header_t *pflog;
        pflog = trace_get_packet_buffer(packet, NULL, NULL);
        /* TODO: should check remaining >= sizeof(*pflog) */
        if (!pflog) {
            trace_set_err(packet->trace,
                          TRACE_ERR_BAD_PACKET,
                          "Bad or missing packet");
            return -1;
        }
        /* enum    { PF_IN=0, PF_OUT=1 }; */
        if (ntohs(pflog->dir==0)) {

            direction = TRACE_DIR_INCOMING;
        }
        else {
            direction = TRACE_DIR_OUTGOING;
        }
        break;
    }
    default:
        break;
    }
    return direction;
}
コード例 #15
0
ファイル: format_pcap.c プロジェクト: superpig0501/libtrace
static int pcap_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
    int ret = 0;
    int linktype;
    uint32_t flags = 0;

    assert(libtrace->format_data);
    linktype = pcap_datalink(DATA(libtrace)->input.pcap);
    packet->type = pcap_linktype_to_rt(linktype);

    /* If we're using the replacement pcap_next_ex() we need to
     * make sure we have a buffer to *shudder* memcpy into
     */
    if (!packet->buffer) {
        packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
        if (!packet->buffer) {
            trace_set_err(libtrace, errno,
                          "Cannot allocate memory");
            return -1;
        }
        packet->header = packet->buffer;
        packet->payload = (char *)packet->buffer+sizeof(struct pcap_pkthdr);

    }

    flags |= TRACE_PREP_OWN_BUFFER;

    for(;;) {

        struct pcap_pkthdr *pcap_hdr = NULL;
        u_char *pcap_payload = NULL;

        ret = pcap_next_ex(INPUT.pcap, &pcap_hdr,
                           (const u_char **)&pcap_payload);

        packet->header = pcap_hdr;
        packet->payload = pcap_payload;

        switch(ret) {
        case 1:
            break; /* no error */
        case 0:
            if (libtrace_halt)
                return 0;
            continue; /* timeout expired */
        case -1:
            trace_set_err(libtrace,TRACE_ERR_BAD_PACKET,
                          "%s",pcap_geterr(INPUT.pcap));
            return -1; /* Error */
        case -2:
            return 0; /* EOF */
        }

        /*
         * pcap is nasty in that the header and payload aren't
         * necessarily located sequentially in memory, but most
         * sensible uses of pcap_prepare_packet will involve a
         * buffer where header and payload are sequential.
         *
         * Basically, don't call pcap_prepare_packet here!
         *
        if (pcap_prepare_packet(libtrace, packet, packet->buffer,
        		packet->type, flags)) {
        	return -1;
        }
        */
        return ((struct pcap_pkthdr*)packet->header)->len
               +sizeof(struct pcap_pkthdr);
    }
}
コード例 #16
0
ファイル: format_pcap.c プロジェクト: superpig0501/libtrace
static int pcapint_start_input(libtrace_t *libtrace) {
    char errbuf[PCAP_ERRBUF_SIZE];

#ifdef HAVE_PCAP_CREATE
    int ret = 0;

    if ((INPUT.pcap = pcap_create(libtrace->uridata, errbuf)) == NULL) {
        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
        return -1; /* failure */
    }
    if ((pcap_set_snaplen(INPUT.pcap, DATA(libtrace)->snaplen) ==
            PCAP_ERROR_ACTIVATED)) {
        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
        return -1; /* failure */
    }

    if ((pcap_set_promisc(INPUT.pcap, DATA(libtrace)->promisc) ==
            PCAP_ERROR_ACTIVATED)) {
        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
        return -1; /* failure */
    }

    if ((pcap_set_timeout(INPUT.pcap, 1) == PCAP_ERROR_ACTIVATED)) {
        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
        return -1; /* failure */
    }

    if ((ret = pcap_activate(INPUT.pcap)) != 0) {
        if (ret == PCAP_WARNING_PROMISC_NOTSUP) {
            trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,"Promiscuous mode unsupported");
            return -1;
        }
        if (ret == PCAP_WARNING) {
            pcap_perror(INPUT.pcap, "Pcap Warning:");
        } else {
            trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
                          pcap_geterr(INPUT.pcap));
            return -1;
        }
    }

#else

    /* Open the live device */
    if ((INPUT.pcap =
                pcap_open_live(libtrace->uridata,
                               DATA(libtrace)->snaplen,
                               DATA(libtrace)->promisc,
                               1,
                               errbuf)) == NULL) {
        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
        return -1; /* failure */
    }
#endif
    /* Set a filter if one is defined */
    if (DATA(libtrace)->filter) {
        if (DATA(libtrace)->filter->flag == 0) {
            pcap_compile(INPUT.pcap,
                         &DATA(libtrace)->filter->filter,
                         DATA(libtrace)->filter->filterstring,
                         1, 0);
            DATA(libtrace)->filter->flag = 1;
        }
        if (pcap_setfilter(INPUT.pcap,&DATA(libtrace)->filter->filter)
                == -1) {
            trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
                          pcap_geterr(INPUT.pcap));
            return -1; /* failure */
        }
    }
#ifdef HAVE_PCAP_SETNONBLOCK
    pcap_setnonblock(INPUT.pcap,0,errbuf);
#endif
    return 0; /* success */
}