diff --git a/monitor/nlmon.c b/monitor/nlmon.c
index 4ecbc5f0..d5f8634e 100644
--- a/monitor/nlmon.c
+++ b/monitor/nlmon.c
@@ -43,6 +43,7 @@
 #include <linux/genetlink.h>
 #include <linux/rtnetlink.h>
 #include <linux/filter.h>
+#include <linux/limits.h>
 #include <ell/ell.h>
 
 #ifndef ARPHRD_NETLINK
@@ -94,6 +95,8 @@
 #define BSS_CAPABILITY_APSD		(1<<11)
 #define BSS_CAPABILITY_DSSS_OFDM	(1<<13)
 
+#define BYTES_PER_MB			1000000
+
 struct nlmon *cur_nlmon;
 
 enum msg_type {
@@ -115,6 +118,11 @@ struct nlmon {
 	bool noies;
 	bool read;
 	enum time_format time_format;
+
+	char *file_prefix;
+	unsigned int file_idx;
+	unsigned int max_files;
+	unsigned int max_size;
 };
 
 struct nlmon_req {
@@ -7388,6 +7396,64 @@ static bool nlmon_req_match(const void *a, const void *b)
 	return (req->seq == match->seq && req->pid == match->pid);
 }
 
+/*
+ * Ensures that PCAP names are zero padded when needed. This makes the files
+ * sort correctly.
+ */
+static void next_pcap_name(char *buf, size_t size, const char *prefix,
+				unsigned int idx, unsigned int max)
+{
+	unsigned int ndigits = 1;
+
+	while (max > 9) {
+		max /= 10;
+		ndigits++;
+	}
+
+	snprintf(buf, size, "%s%.*u", prefix, ndigits, idx);
+}
+
+static bool check_pcap(struct nlmon *nlmon, size_t next_size)
+{
+	char path[PATH_MAX];
+
+	if (!nlmon->pcap)
+		return false;
+
+	if (!nlmon->max_size)
+		return true;
+
+	if (pcap_get_size(nlmon->pcap) + next_size <= nlmon->max_size)
+		return true;
+
+	pcap_close(nlmon->pcap);
+
+	/* Exausted the single PCAP file */
+	if (nlmon->max_files < 2) {
+		printf("Reached maximum size of PCAP, exiting\n");
+		nlmon->pcap = NULL;
+		l_main_quit();
+		return false;
+	}
+
+	next_pcap_name(path, sizeof(path), nlmon->file_prefix,
+			++nlmon->file_idx, nlmon->max_files);
+
+	nlmon->pcap = pcap_create(path);
+
+	if (nlmon->max_files > nlmon->file_idx)
+		return true;
+
+	/* Remove oldest PCAP file */
+	next_pcap_name(path, sizeof(path), nlmon->file_prefix,
+		nlmon->file_idx - nlmon->max_files, nlmon->max_files);
+
+	if (remove(path) < 0)
+		printf("Failed to remove old PCAP file %s\n", path);
+
+	return true;
+}
+
 static void store_packet(struct nlmon *nlmon, const struct timeval *tv,
 					uint16_t pkt_type,
 					uint16_t arphrd_type,
@@ -7396,7 +7462,7 @@ static void store_packet(struct nlmon *nlmon, const struct timeval *tv,
 {
 	uint8_t sll_hdr[16], *buf = sll_hdr;
 
-	if (!nlmon->pcap)
+	if (!check_pcap(nlmon, sizeof(sll_hdr) + size))
 		return;
 
 	memset(sll_hdr, 0, sizeof(sll_hdr));
@@ -7522,6 +7588,9 @@ struct nlmon *nlmon_create(uint16_t id, const struct nlmon_config *config)
 	nlmon->noies = config->noies;
 	nlmon->read = config->read_only;
 	nlmon->time_format = config->time_format;
+	nlmon->max_files = config->pcap_file_count;
+	/* Command line expects MB, but use bytes internally */
+	nlmon->max_size = config->pcap_file_size * BYTES_PER_MB;
 
 	return nlmon;
 }
@@ -8549,13 +8618,20 @@ struct nlmon *nlmon_open(uint16_t id, const char *pathname,
 	struct nlmon *nlmon;
 	struct l_io *pae_io;
 	struct pcap *pcap;
+	char path[PATH_MAX];
 
 	pae_io = open_pae();
 	if (!pae_io)
 		return NULL;
 
 	if (pathname) {
-		pcap = pcap_create(pathname);
+		if (config->pcap_file_count > 1)
+			next_pcap_name(path, sizeof(path), pathname,
+					0, config->pcap_file_count);
+		else
+			snprintf(path, sizeof(path), "%s", pathname);
+
+		pcap = pcap_create(path);
 		if (!pcap) {
 			l_io_destroy(pae_io);
 			return NULL;
@@ -8568,6 +8644,7 @@ struct nlmon *nlmon_open(uint16_t id, const char *pathname,
 
 	nlmon->pae_io = pae_io;
 	nlmon->pcap = pcap;
+	nlmon->file_prefix = l_strdup(pathname);
 
 	l_io_set_read_handler(nlmon->pae_io, pae_receive, nlmon, NULL);
 
@@ -8590,5 +8667,7 @@ void nlmon_close(struct nlmon *nlmon)
 	if (nlmon->pcap)
 		pcap_close(nlmon->pcap);
 
+	l_free(nlmon->file_prefix);
+
 	l_free(nlmon);
 }
diff --git a/monitor/nlmon.h b/monitor/nlmon.h
index bbc5d250..fa027021 100644
--- a/monitor/nlmon.h
+++ b/monitor/nlmon.h
@@ -37,6 +37,10 @@ struct nlmon_config {
 	bool noies;
 	bool read_only;
 	enum time_format time_format;
+
+	/* File size in MB */
+	uint32_t pcap_file_size;
+	uint32_t pcap_file_count;
 };
 
 struct nlmon *nlmon_open(uint16_t id, const char *pathname,
