Browse Source

abstractize recording format and fix ipv6 header

closes #293 #290

Change-Id: I85db7068067da803898c64491dca90cfc737c677
changes/53/9753/1
Richard Fuchs 9 years ago
parent
commit
eefb085528
3 changed files with 37 additions and 25 deletions
  1. +34
    -25
      daemon/recording.c
  2. +2
    -0
      daemon/socket.c
  3. +1
    -0
      daemon/socket.h

+ 34
- 25
daemon/recording.c View File

@ -21,6 +21,14 @@
struct pcap_format {
int linktype;
int headerlen;
void (*header)(unsigned char *, struct packet_stream *);
};
static int check_main_spool_dir(const char *spoolpath);
static char *recording_setup_file(struct recording *recording);
static char *meta_setup_file(struct recording *recording);
@ -47,6 +55,8 @@ static void setup_stream_proc(struct packet_stream *);
static void setup_media_proc(struct call_media *);
static void kernel_info_proc(struct packet_stream *, struct rtpengine_target_info *);
static void pcap_eth_header(unsigned char *, struct packet_stream *);
static const struct recording_method methods[] = {
@ -77,12 +87,22 @@ static const struct recording_method methods[] = {
},
};
static const struct pcap_format pcap_format_raw = {
.linktype = DLT_RAW,
.headerlen = 0,
};
static const struct pcap_format pcap_format_eth = {
.linktype = DLT_EN10MB,
.headerlen = 14,
.header = pcap_eth_header,
};
// Global file reference to the spool directory.
static char *spooldir = NULL;
const struct recording_method *selected_recording_method;
int rec_format;
static const struct pcap_format *pcap_format;
@ -109,9 +129,9 @@ void recording_fs_init(const char *spoolpath, const char *method_str, const char
found:
if(!strcmp("raw", format_str))
rec_format = 0;
pcap_format = &pcap_format_raw;
else if(!strcmp("eth", format_str))
rec_format = 1;
pcap_format = &pcap_format_eth;
else {
ilog(LOG_ERR, "Invalid value for recording format \"%s\".", format_str);
exit(-1);
@ -408,10 +428,7 @@ static char *recording_setup_file(struct recording *recording) {
recording_path = file_path_str(recording->meta_prefix, "/pcaps/", ".pcap");
recording->pcap.recording_path = recording_path;
if(rec_format == 1)
recording->pcap.recording_pd = pcap_open_dead(DLT_EN10MB, 65535);
else
recording->pcap.recording_pd = pcap_open_dead(DLT_RAW, 65535);
recording->pcap.recording_pd = pcap_open_dead(pcap_format->linktype, 65535);
recording->pcap.recording_pdumper = pcap_dump_open(recording->pcap.recording_pd, recording_path);
if (recording->pcap.recording_pdumper == NULL) {
pcap_close(recording->pcap.recording_pd);
@ -454,6 +471,12 @@ static unsigned int fake_ip_header(unsigned char *out, struct packet_stream *str
return hdr_len + inp->len;
}
static void pcap_eth_header(unsigned char *pkt, struct packet_stream *stream) {
memset(pkt, 0, 14);
uint16_t *hdr16 = (void *) pkt;
hdr16[6] = htons(stream->selected_sfd->socket.local.address.family->ethertype);
}
/**
* Write out a PCAP packet with payload string.
* A fair amount extraneous of packet data is spoofed.
@ -462,24 +485,10 @@ static void stream_pcap_dump(pcap_dumper_t *pdumper, struct packet_stream *strea
if (!pdumper)
return;
int ether_len = 0;
if(rec_format == 1)
ether_len = 14;
unsigned char pkt[s->len + MAX_PACKET_HEADER_LEN + ether_len];
unsigned int pkt_len = fake_ip_header(pkt + ether_len, stream, s);
if(rec_format == 1) {
pkt_len += 14;
memset(pkt, 0, 14);
switch(stream->selected_sfd->socket.local.address.family->af) {
case AF_INET:
pkt[12] = 0x08;
break;
case AF_INET6:
pkt[12] = 0x86;
break;
}
}
unsigned char pkt[s->len + MAX_PACKET_HEADER_LEN + pcap_format->headerlen];
unsigned int pkt_len = fake_ip_header(pkt + pcap_format->headerlen, stream, s) + pcap_format->headerlen;
if (pcap_format->header)
pcap_format->header(pkt, stream);
// Set up PCAP packet header
struct pcap_pkthdr header;


+ 2
- 0
daemon/socket.c View File

@ -58,6 +58,7 @@ static socktype_t __socket_types[] = {
static struct socket_family __socket_families[__SF_LAST] = {
[SF_IP4] = {
.af = AF_INET,
.ethertype = 0x0800,
.sockaddr_size = sizeof(struct sockaddr_in),
.name = "IPv4",
.rfc_name = "IP4",
@ -86,6 +87,7 @@ static struct socket_family __socket_families[__SF_LAST] = {
},
[SF_IP6] = {
.af = AF_INET6,
.ethertype = 0x86dd,
.sockaddr_size = sizeof(struct sockaddr_in6),
.name = "IPv6",
.rfc_name = "IP6",


+ 1
- 0
daemon/socket.h View File

@ -48,6 +48,7 @@ struct socket_type {
struct socket_family {
int idx;
int af;
unsigned int ethertype;
size_t sockaddr_size;
const char *name; /* "IPv4" */
const char *rfc_name; /* "IP4" */


Loading…
Cancel
Save