LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Libipq and C question (for loop) (http://www.linuxquestions.org/questions/programming-9/libipq-and-c-question-for-loop-4175414486/)

MiniComa 07-02-2012 01:39 PM

Libipq and C question (for loop)
 
Hello,

I am trying to get IDs of the first ten packets which payload is more than 1300 but instead of this I can see all ids in the output. What I am doing wrong? Thank you for help.

Code:

/*
 *  TT.c
 *
 *  compile: gcc -Wall TT.c -o TT -lipq
 */

#include <netinet/in.h>
#include <libipq.h>
#include <linux/netfilter.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>

#define BUFSIZE 65536



static void die(struct ipq_handle *h) {
   
    ipq_perror("passer");
    ipq_destroy_handle(h);
   
}


void start_packet_engine() {
 
            int status;
    unsigned char buf[BUFSIZE];
    struct ipq_handle *h;

   
    printf("\nWaiting for packets\n");
       

    h = ipq_create_handle(0, PF_INET);
   
    if (!h)
        die(h);
   
   
    status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
   
    if (status < 0)
        die(h);
   
   
    do {
        status = ipq_read(h, buf, BUFSIZE, 0);
        if (status < 0)
            die(h);
       
       
        switch (ipq_message_type(buf)) {
           
            case NLMSG_ERROR: {
                fprintf(stderr, "Received error message %d\n",
                ipq_get_msgerr(buf));
                break;
            }
          case IPQM_PACKET:
 {
  ipq_packet_msg_t *m = ipq_get_packet(buf);
 
   
  /* Cast the IP Header from the raw packet */
  struct iphdr *iph = ((struct iphdr *)m->payload);
 
  /* Cast the TCP Header from the raw packet */
  struct tcphdr *tcp = (struct tcphdr *)(m->payload + (iph->ihl << 2));   
 
 
 
  /* calculate the length of the payload */
  int unsigned payload_length = (unsigned int) ntohs(iph->tot_len) -
((iph->ihl << 2) + (tcp->doff << 2));

 
if (payload_length > 1300) {

int j;
int jmax = 10;
for (j=0; j < jmax; j++) {
printf("id: %u\n",(unsigned int) m->packet_id);
}
}

  status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL); 
  break;
    }
    }

             
     
    }
    while (1);
   
    printf("Engine Stopped...\n");
   
    ipq_destroy_handle(h);
   
}

int main() {
    start_packet_engine();
    return 0;
}


padeen 07-03-2012 01:55 AM

It's hard to tell because the formatting is messed up, but it looks to me like you are not doing anything with j.

A quick look suggests this code would print out the id (of every packet > 1300) 10 times. Is it not doing that?

pan64 07-03-2012 05:56 AM

also: if (!h) die (h); looks strange for me, I think it does not work.

MiniComa 07-03-2012 02:56 PM

I took main body of this example from libipq man page: http://linux.die.net/man/3/libipq and it works fine for me. Padeen, I think you could be right. How can I reconstruct this loop that it would give me wanted effect? I take packets from buffer with this function "ipq_packet_msg_t *m = ipq_get_packet(buf);" and put them back with "status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);".

padeen 07-03-2012 08:50 PM

Think about the scope of j and jmax.

When you enter the
Quote:

if (payload_length > 1300)
block, you are creating new variables j and jmax. Those variables are lost when you leave the block. This means each new time that you process a packet of length > 1300, you are starting afresh with new j and jmax.

http://en.wikipedia.org/wiki/Scope_%...hin_a_function

You may want to move j and jmax somewhere outside the block so they remain in scope the entire time that you are looking at packets. Hint: you probably don't want a for... construction. Instead, an if... break or exit() may work better.

MiniComa 07-05-2012 01:39 PM

Thank you padeen. You have helped me alot. One more question. Let say that I want to get id of every N th packet.

Code:

int j;
int jmax = X;
 
if (payload_length > 1300) {


if (j < jmax) {
printf("id: %u\n",(unsigned int) m->packet_id);
j = j +N;
}
}

Is this code correct to get the result?

padeen 07-05-2012 08:56 PM

No, that looks like it would print out jmax/N times. Try going through the loop in your head.

For every Nth count, you could try modulo arithmetic, e.g.

Code:

for (packet_size > 1300 && j % N == 0) {
    ...
}
j++


MiniComa 07-07-2012 07:53 AM

Thank you padeen. All problems solved for now.


All times are GMT -5. The time now is 07:26 AM.