+void snoop_send_packet(char *packet, uint16_t size, in_addr_t destination, uint16_t port)
+{
+ struct sockaddr_in snoop_addr = {0};
+ if (!destination || !port || snoopfd <= 0 || size <= 0 || !packet)
+ return;
+
+ snoop_addr.sin_family = AF_INET;
+ snoop_addr.sin_addr.s_addr = destination;
+ snoop_addr.sin_port = ntohs(port);
+
+ LOG(5, 0, 0, "Snooping %d byte packet to %s:%d\n", size,
+ fmtaddr(snoop_addr.sin_addr.s_addr, 0),
+ htons(snoop_addr.sin_port));
+
+ if (sendto(snoopfd, packet, size, MSG_DONTWAIT | MSG_NOSIGNAL, (void *) &snoop_addr, sizeof(snoop_addr)) < 0)
+ LOG(0, 0, 0, "Error sending intercept packet: %s\n", strerror(errno));
+
+ STAT(packets_snooped);
+}
+
+static int dump_session(FILE **f, sessiont *s)
+{
+ if (!s->opened || !s->ip || !(s->cin || s->cout) || !*s->user || s->walled_garden)
+ return 1;
+
+ if (!*f)
+ {
+ char filename[1024];
+ char timestr[64];
+ time_t now = time(NULL);
+
+ strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", localtime(&now));
+ snprintf(filename, sizeof(filename), "%s/%s", config->accounting_dir, timestr);
+
+ if (!(*f = fopen(filename, "w")))
+ {
+ LOG(0, 0, 0, "Can't write accounting info to %s: %s\n", filename, strerror(errno));
+ return 0;
+ }
+
+ LOG(3, 0, 0, "Dumping accounting information to %s\n", filename);
+ fprintf(*f, "# dslwatch.pl dump file V1.01\n"
+ "# host: %s\n"
+ "# time: %ld\n"
+ "# uptime: %ld\n"
+ "# format: username ip qos uptxoctets downrxoctets\n",
+ hostname,
+ now,
+ now - basetime);
+ }
+
+ LOG(4, 0, 0, "Dumping accounting information for %s\n", s->user);
+ fprintf(*f, "%s %s %d %u %u\n",
+ s->user, // username
+ fmtaddr(htonl(s->ip), 0), // ip
+ (s->throttle_in || s->throttle_out) ? 2 : 1, // qos
+ (uint32_t) s->cin, // uptxoctets
+ (uint32_t) s->cout); // downrxoctets