Cleanup pcap_utils

This commit is contained in:
emanuele-f 2021-07-01 18:58:37 +02:00
parent 51dc0dde7e
commit da141fa8df
4 changed files with 53 additions and 79 deletions

View File

@ -88,12 +88,14 @@ import java.util.List;
import java.util.Locale;
public class Utils {
public static final byte[] PCAP_HEADER = Utils.hexStringToByteArray("d4c3b2a1020004000000000000000000ffff000065000000");
public static final int UID_UNKNOWN = -1;
public static final int UID_NO_FILTER = -2;
private static Boolean rootAvailable = null;
private static Locale primaryLocale = null;
// magic: 0xa1b2c3d4, v2.4, snaplen: 65535, LINKTYPE_RAW
public static final byte[] PCAP_HEADER = Utils.hexStringToByteArray("d4c3b2a1020004000000000000000000ffff000065000000");
public static String formatBytes(long bytes) {
long divisor;
String suffix;

View File

@ -17,76 +17,46 @@
* Copyright 2020-21 - Emanuele Faranda
*/
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <sys/socket.h>
#include <android/log.h>
#include <errno.h>
#include "common/utils.h"
#include "pcap_utils.h"
/* ******************************************************* */
#define LINKTYPE_RAW 101
#define PCAP_TAG "PCAP_DUMP"
#define SNAPLEN 65535
#define LINKTYPE_RAW 101
/* ******************************************************* */
static size_t frame_id = 1;
static uint8_t pcap_buffer[sizeof(struct pcaprec_hdr_s) + SNAPLEN];
/* ******************************************************* */
static void write_pcap(int fd, const struct sockaddr *srv, int srv_size, const void *ptr, int len) {
if(sendto(fd, ptr, len, 0, srv, srv_size) < 0)
__android_log_print(ANDROID_LOG_ERROR, PCAP_TAG, "sendto(%u) error[%d]: %s", len, errno, strerror(errno));
void pcap_build_hdr(struct pcap_hdr_s *pcap_hdr) {
pcap_hdr->magic_number = 0xa1b2c3d4;
pcap_hdr->version_major = 2;
pcap_hdr->version_minor = 4;
pcap_hdr->thiszone = 0;
pcap_hdr->sigfigs = 0;
pcap_hdr->snaplen = SNAPLEN;
pcap_hdr->network = LINKTYPE_RAW;
}
/* ******************************************************* */
static size_t init_pcap_rec_hdr(struct pcaprec_hdr_s *pcap_rec, int length) {
size_t incl_len;
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts))
__android_log_print(ANDROID_LOG_ERROR, PCAP_TAG, "clock_gettime error[%d]: %s", errno, strerror(errno));
incl_len = (length < SNAPLEN ? length : SNAPLEN);
pcap_rec->ts_sec = (guint32_t) ts.tv_sec;
pcap_rec->ts_usec = (guint32_t) (ts.tv_nsec / 1000);
pcap_rec->incl_len = (guint32_t) incl_len;
pcap_rec->orig_len = (guint32_t) length;
return(incl_len);
/* Returns the size of a PCAP record */
int pcap_rec_size(int pkt_len) {
return((pkt_len < SNAPLEN ? pkt_len : SNAPLEN) + (int)sizeof(struct pcaprec_hdr_s));
}
/* ******************************************************* */
void write_pcap_hdr(int fd, const struct sockaddr *srv, int srv_size) {
struct pcap_hdr_s pcap_hdr;
pcap_hdr.magic_number = 0xa1b2c3d4;
pcap_hdr.version_major = 2;
pcap_hdr.version_minor = 4;
pcap_hdr.thiszone = 0;
pcap_hdr.sigfigs = 0;
pcap_hdr.snaplen = SNAPLEN;
pcap_hdr.network = LINKTYPE_RAW;
write_pcap(fd, srv, srv_size, &pcap_hdr, sizeof(struct pcap_hdr_s));
}
/* ******************************************************* */
size_t dump_pcap_rec(u_char *buffer, const u_char *pkt, int pkt_len) {
/* Dumps a packet into the provided buffer. The buffer must have at least pcap_rec_size()
* bytes available */
void pcap_dump_rec(u_char *buffer, const u_char *pkt, int pkt_len) {
struct pcaprec_hdr_s *pcap_rec = (pcaprec_hdr_s*) buffer;
struct timespec ts = {0};
size_t incl_len = init_pcap_rec_hdr(pcap_rec, pkt_len);
size_t tot_len = sizeof(struct pcaprec_hdr_s) + incl_len;
if(clock_gettime(CLOCK_REALTIME, &ts))
log_d("clock_gettime failed[%d]: %s", errno, strerror(errno));
// NOTE: use incl_size as the packet may be cut due to the SNAPLEN
// Assumption: there is enough available space in buffer
memcpy(buffer + sizeof(struct pcaprec_hdr_s), pkt, incl_len);
pcap_rec->ts_sec = ts.tv_sec;
pcap_rec->ts_usec = (ts.tv_nsec / 1000);
pcap_rec->incl_len = (pkt_len < SNAPLEN ? pkt_len : SNAPLEN);
pcap_rec->orig_len = pkt_len;
return(tot_len);
memcpy(buffer + sizeof(struct pcaprec_hdr_s), pkt, pcap_rec->incl_len);
}

View File

@ -20,28 +20,28 @@
#ifndef __MY_PCAP_H__
#define __MY_PCAP_H__
typedef uint16_t guint16_t;
typedef uint32_t guint32_t;
typedef int32_t gint32_t;
#include <stdlib.h>
#include <stdint.h>
typedef struct pcap_hdr_s {
guint32_t magic_number;
guint16_t version_major;
guint16_t version_minor;
gint32_t thiszone;
guint32_t sigfigs;
guint32_t snaplen;
guint32_t network;
uint32_t magic_number;
uint16_t version_major;
uint16_t version_minor;
int32_t thiszone;
uint32_t sigfigs;
uint32_t snaplen;
uint32_t network;
} __packed pcap_hdr_s;
typedef struct pcaprec_hdr_s {
guint32_t ts_sec;
guint32_t ts_usec;
guint32_t incl_len;
guint32_t orig_len;
uint32_t ts_sec;
uint32_t ts_usec;
uint32_t incl_len;
uint32_t orig_len;
} __packed pcaprec_hdr_s;
void write_pcap_hdr(int fd, const struct sockaddr *srv, int srv_size);
size_t dump_pcap_rec(u_char *buffer, const u_char *pkt, int pkt_len);
void pcap_build_hdr(struct pcap_hdr_s *pcap_hdr);
int pcap_rec_size(int pkt_len);
void pcap_dump_rec(u_char *buffer, const u_char *pkt, int pkt_len);
#endif // __MY_PCAP_H__

View File

@ -941,20 +941,22 @@ void account_packet(vpnproxy_data_t *proxy, const zdtun_pkt_t *pkt, uint8_t from
notify_connection(&proxy->conns_updates, conn_tuple, data);
if (proxy->pcap_dump.buffer) {
int tot_size = pkt->len + (int) sizeof(pcaprec_hdr_s);
int rec_size = pcap_rec_size(pkt->len);
if ((JAVA_PCAP_BUFFER_SIZE - proxy->pcap_dump.buffer_idx) <= tot_size) {
// Flush the buffer
if ((JAVA_PCAP_BUFFER_SIZE - proxy->pcap_dump.buffer_idx) <= rec_size) {
// Flush the buffer
javaPcapDump(proxy);
}
if ((JAVA_PCAP_BUFFER_SIZE - proxy->pcap_dump.buffer_idx) <= tot_size)
if ((JAVA_PCAP_BUFFER_SIZE - proxy->pcap_dump.buffer_idx) <= rec_size)
log_e("Invalid buffer size [size=%d, idx=%d, tot_size=%d]",
JAVA_PCAP_BUFFER_SIZE, proxy->pcap_dump.buffer_idx, tot_size);
else
proxy->pcap_dump.buffer_idx += dump_pcap_rec(
(u_char *) proxy->pcap_dump.buffer + proxy->pcap_dump.buffer_idx,
JAVA_PCAP_BUFFER_SIZE, proxy->pcap_dump.buffer_idx, rec_size);
else {
pcap_dump_rec((u_char *) proxy->pcap_dump.buffer + proxy->pcap_dump.buffer_idx,
(u_char *) pkt->buf, pkt->len);
proxy->pcap_dump.buffer_idx += rec_size;
}
}
}