From: Oumer Teyeb <oumer@kom.auc.dk>
To: netfilter@lists.netfilter.org
Subject: Re: libipq and threads, problems, very annoying problem
Date: Tue, 14 Oct 2003 18:04:25 +0200 [thread overview]
Message-ID: <3F8C1E89.3040008@kom.auc.dk> (raw)
In-Reply-To: 3F8C1B1F.3090501@kom.auc.dk
I am sorry, but I forgot to mention that I am aware that libipq is not
thread safe (I read it in one of the message boards, don't remember
where). Can this problem be attributed to that ? And if so is there a
way around it? I am kind of stuck with my project unless I do this
properly, so help is really really appreciated.
Thanks again
Oumer Teyeb wrote:
> Hi,
>
> Here is a sample code where I try to delay every packet by some time
> (in the code I posted here it is fixed to 100 msec.). Inorder to do
> so, I start a pthread for every packet that is received by libipq . I
> have iptables rules that queues tcp packets that are coming and going
> to some other machine. I then ftp to that machine. The program works,
> the problem is with the dumping. I have two files, one is supposed to
> capture the files when they reach the queue (new_file_2) and the other
> just before the set verdict is called (new_file_3). The new_file_2
> works properly. The problem is with new_file_3. I couldn't get how,
> but somehow, at some location, some erroneous entries are put into the
> file, the end effect being tcpdump not able to recognize the file at
> some point. To check, I commented out the only line which makes the
> two files differ, i.e the one that changes the time stamp of the
> packet header (as indicated by *********), and the two files are not
> the same. First I thought maybe one thread was writing to the file,
> and then another thread becomes active and writes also. So I
> introduced a mutex_variable that will avoid such
> problem. But it doesn't help at all. Could you please tell me what I
> am doing wrong? I have to save the files myself as tcpdump get the
> packets before the firewall for incoming packets
> Thanks in advance,
> Oumer
>
> #include <sys/time.h>
> #include <linux/netfilter.h>
> #include <netinet/in.h>
> #include <libipq.h>
> #include <pthread.h>
> #include <unistd.h>
> #include <signal.h>
> #include <string.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include "errors.h"
> #include <mcheck.h>
>
> #define BUFSIZE 2048
>
> struct ipq_handle *h;
> ipq_packet_msg_t *m;
>
> FILE* new_file_2;
> FILE* new_file_3;
>
> pthread_mutex_t mutex_write;
>
> /* char src_mac[6] = {0,0,0xb4,0x4b,0x2c, 0xe1}; */
> /* char dst_mac[6] = {0,0xb,0x46, 0x10, 0x57, 0x80}; */
> /* char ether_type[2] = {8,0}; */
>
> char src_dst_ether [14] = {0,0,0xb4,0x4b,0x2c, 0xe1,0,0xb,0x46, 0x10,
> 0x57, 0x80,8,0};
>
> //stolen from pcap
> struct PCAP_file_header {
> unsigned int magic;
> short major;
> short minor;
> int thiszone; /* gmt to local correction */
> unsigned int sigfigs; /* accuracy of timestamps */
> unsigned int snaplen; /* max length saved portion of each pkt */
> unsigned int linktype; /* data link type (LINKTYPE_*) */
> };
>
> struct PCAP_packet_header {
> struct timeval ts; /* time stamp */
> int caplen; /* length of portion present */
> int len; /* length this packet (off wire) */
> };
>
> typedef struct {
> int sleep_time;
> ipq_packet_msg_t *packet;
> // unsigned char *data;
> struct PCAP_packet_header pkt_header;
> int thread_id;
> } params;
>
> static void die(struct ipq_handle *h)
> {
> ipq_perror("ipq_error::");
> ipq_destroy_handle(h);
> exit(1);
> }
>
> void *delay_packet (void *param_packet)
> {
> int status;
> params *myparams= (params*) param_packet;
> status = pthread_detach (pthread_self ());
> if (status != 0)
> err_abort (status, "Detach thread");
>
> usleep(100000);
> pthread_mutex_lock (&mutex_write);
> // gettimeofday(&(myparams->pkt_header.ts), NULL);
> ************************
> fwrite(&(myparams->pkt_header), sizeof(struct PCAP_packet_header),1,
> new_file_3);
> fwrite(src_dst_ether,1, 14, new_file_3);
> fwrite((unsigned int*)(myparams->packet+1), 1,
> myparams->packet->data_len, new_file_3);
> //free(myparams->packet);
> pthread_mutex_unlock (&mutex_write);
> status = ipq_set_verdict(h, myparams->packet->packet_id,NF_ACCEPT,
> 0, NULL);
> if (status < 0)
> die(h);
> free(myparams);
> return NULL;
> }
>
> void signal_handler(int sig)
> {
> if (h)
> ipq_destroy_handle(h);
> fclose(new_file_2);
> fclose(new_file_3);
> exit(0);
> }
>
> int main(int argc, char **argv)
> {
> mtrace();
> int status;
> unsigned char buf[BUFSIZE];
> int thread_id=0;
> new_file_2= fopen("dump_tcp_data.txt", "w+b");
> new_file_3 = fopen("dump_tcp_data_after.txt", "w+b");
> pthread_mutex_init(&mutex_write, NULL);
> struct PCAP_file_header *file_header = (struct
> PCAP_file_header*)(malloc(sizeof(struct PCAP_file_header)));
> file_header->magic=0xa1b2c3d4;
> file_header->major=2;
> file_header->minor=4;
> file_header->thiszone=0;
> file_header->sigfigs=0;
> file_header->snaplen=65535;
> file_header->linktype=1;
> fwrite(file_header, sizeof(struct PCAP_file_header),1, new_file_2);
> fwrite(file_header, sizeof(struct PCAP_file_header),1, new_file_3);
> free(file_header);
> pthread_t thread;
> h = ipq_create_handle(0, PF_INET);
> sigset(SIGINT, signal_handler);
> if (!h)
> die(h);
> status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
> if (status < 0)
> die(h);
> printf("PACKET_ID\t\tDATA_LENGTH\tSTATUS\n");
> printf("=========\t\t============\t=======\n");
> while (1) {
> status = ipq_read(h, buf, BUFSIZE, 0);
> if (status < 0)
> die(h);
> switch (ipq_message_type(buf)) {
> case NLMSG_ERROR:
> {
> fprintf(stderr, "Error! %s\n", ipq_errstr());
> break;
> }
> case IPQM_PACKET: {
> params *packet_param = (params*)malloc (sizeof (params));;
> if (!packet_param)
> {
> printf("memory allocatin problem\n");
> die(h);
> }
> struct PCAP_packet_header *pkt_header=
> (struct PCAP_packet_header*)(malloc(sizeof(struct
> PCAP_packet_header)));
> ipq_packet_msg_t *m = ipq_get_packet(buf);
> gettimeofday(&(pkt_header->ts), NULL);
> pkt_header->caplen=m->data_len+14;
> pkt_header->len=m->data_len+14;
> unsigned char *data = (unsigned
> char*)(m+1); printf("%lud\t\t%u\t\t", m->packet_id,
> m->data_len);
> packet_param-> packet = m;
> packet_param->pkt_header = *(pkt_header);
> if (m->data_len > 0)
> {
> fwrite(pkt_header, sizeof(struct PCAP_packet_header),1,
> new_file_2);
> fwrite(src_dst_ether,1,14,new_file_2);
> /* packet_param->data =(unsigned char*) malloc (sizeof(unsigned
> char*) * m->data_len);
>
> for (x=0; x < m->data_len; x++)
> {
> packet_param->data[x] = *(data+x);
> }
> */
> fwrite(data, 1, m->data_len, new_file_2);
>
> status = pthread_create ( &thread, NULL, delay_packet,
> packet_param);
> if (status != 0)
> err_abort (status, "Create a new thread");
> break;
> }
> }
>
> default:{
> fprintf(stderr, "Unknown message type!\n");
> break;
> }
> }
> }
> ipq_destroy_handle(h);
> return 0;
> }
>
>
>
>
next prev parent reply other threads:[~2003-10-14 16:04 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-10-14 15:49 libipq and threads, problems, very annoying problem Oumer Teyeb
2003-10-14 16:04 ` Oumer Teyeb [this message]
2003-10-14 16:47 ` Scott MacKay
2003-10-14 18:03 ` oumer
2003-10-14 21:21 ` oumer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3F8C1E89.3040008@kom.auc.dk \
--to=oumer@kom.auc.dk \
--cc=netfilter@lists.netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox