sys/queue.h - Linux

This is a discussion on sys/queue.h - Linux ; I am looking for some documentation on using #include Has anybody ever used it? I would like to integrate a linked list using it. I am writing a packet sniffer and am using a packetCache structure to hold captured packets ...

+ Reply to Thread
Results 1 to 9 of 9

Thread: sys/queue.h

  1. sys/queue.h

    I am looking for some documentation on using #include
    Has anybody ever used it? I would like to integrate a linked list
    using it.

    I am writing a packet sniffer and am using a packetCache structure to
    hold captured packets for exporting purposes and data collection.

    well here is the code


    /*
    * Copyright (c) 2007 HydraResearch. All rights reserved.
    *
    * This program is free software: you can redistribute it and/or
    modify
    * it under the terms of the GNU General Public License as
    published by
    * the Free Software Foundation, either version 3 of the License,
    or
    * (at your option) any later version.
    *
    * This program is distributed in the hope that it will be
    useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU General Public License for more details.
    *
    * You should have received a copy of the GNU General Public
    License
    * along with this program. If not, see <http://www.gnu.org/
    licenses
    *
    * Author: Matt Westerburg
    */

    #include "config.h"
    #include "sll.h"
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include /*includes the ethernet.h*/
    #include

    #define VERSION "0.1"

    /*implement booleans*/
    #define TRUE 1
    #define FALSE 0
    typedef int bool;

    /*
    * function prototypes
    */
    void print_help();
    void signal_capture_cntrlc(int sig);

    /*node*/
    struct packetCache
    {
    struct packetCache *next;
    ssize_t len;
    unsigned char data[0];
    };

    /*status variables*/
    unsigned long long total_captured_packets = 0;
    Sll *head = NULL;
    Sll *new = NULL;

    /*configuration options*/
    char *interface = NULL;
    bool promiscuous_mode = FALSE;
    bool cache_packets = FALSE;
    bool debug = FALSE;
    bool display = FALSE;
    int wait_time = 0;
    int max_packets = -1;

    /*pcap_loop callback routine*/
    void capture_callback(u_char *buffer, const struct pcap_pkthdr*
    packet_header, u_char* data)
    {
    total_captured_packets++;
    if (display == TRUE)
    {
    fprintf(stdout, "Received packet %d\n");
    }
    if (cache_packets == TRUE)
    {
    struct packetCache *pc;
    if ((pc = (struct packetCache *) malloc (sizeof
    (struct packetCache) + packet_header->len)) == NULL)
    {
    fprintf(stderr, "Memory Allocation Error!\n");
    fprintf(stderr, "Turning off caching\n");
    cache_packets = FALSE;
    }
    else
    {
    if (debug == TRUE)
    {
    fprintf(stderr, "Packet Cached\n");
    }
    pc->len = packet_header->len;
    memcpy (pc->data, data, packet_header->len);
    pc->next = NULL;
    pcache_last = pc;
    }
    }
    }

    int main(int argc, char **argv)
    {
    /*setup the signals*/
    (void) signal(SIGINT, signal_capture_cntrlc);
    int i;
    char errbuf[PCAP_ERRBUF_SIZE]; /*error buffer for pcap
    operations*/
    pcap_t* descr;
    const u_char *packet;
    struct pcap_pkthdr hdr;
    struct ether_header *eptr;
    u_char *ptr;

    /*command line options parsing*/
    int option;
    while ((option = getopt(argc, argv, "idwm:ch")) != -1)
    {
    switch (option)
    {

    case 'i':
    interface = optarg;
    break;
    case 'h':
    print_help();
    return 0;
    case 'd':
    debug = TRUE;
    break;
    case 'p':
    promiscuous_mode = TRUE;
    break;
    case 'w':
    wait_time = (int)optarg;
    break;
    case 'c':
    cache_packets = TRUE;
    break;
    case 'D':
    display = TRUE;
    break;
    case 'm':
    max_packets = (int)optarg;
    break;
    case '?':
    if (isprint(optopt))
    {
    fprintf(stderr, "Unknown
    option '-%c'.\n", optopt);
    }
    else
    {
    fprintf(stderr, "Unknown
    option character '\\x%x'.\n", optopt);
    }
    print_help();
    return 1;
    default:
    print_help();
    abort();
    }
    }

    /*display option values*/
    if (debug == TRUE)
    {
    fprintf(stdout, "Interface: %s\n", interface);
    fprintf(stdout, "Promiscuous_mode: %d\n",
    promiscuous_mode);
    fprintf(stdout, "Debug: %d\n", debug);
    fprintf(stdout, "Display: %d\n", display);
    fprintf(stdout, "Wait_time: %d\n", wait_time);
    fprintf(stdout, "Max_packets: %d\n", max_packets);
    fprintf(stdout, "Cache_packets: %d\n", cache_packets);
    }

    /*latch onto an interface*/
    if (interface == NULL)
    {
    /*set interface if one was not given by the user*/
    interface = pcap_lookupdev(errbuf);
    }
    descr = pcap_open_live(interface, BUFSIZ, promiscuous_mode,
    wait_time, errbuf);
    if (descr == NULL)
    {
    fprintf(stderr, "Couldn't open device %s: %s\n",
    interface, errbuf);
    return 2;
    }
    if (debug == TRUE)
    {
    fprintf(stderr, "Opened device: %s\n", interface);
    }


    /*packet capture loop*/
    int status = pcap_loop(descr, max_packets, (pcap_handler)
    capture_callback, NULL);
    switch (status)
    {
    case -1:
    fprintf(stderr, "Error: %s\n", errbuf);
    break;
    case -2:
    if (debug == TRUE)
    {
    fprintf(stderr, "Exiting Loop status:
    %d\n", status);
    }
    break;
    case '0':
    if (debug == TRUE)
    {
    fprintf(stderr, "Capture loop exited
    successfully\n");
    }
    default:
    if (debug == TRUE)
    {
    fprintf(stderr, "Unknown exit code: %d
    \n", status);
    }
    }

    return 0;
    }

    void print_help()
    {

    fprintf(stderr, "/*********************/\n");
    fprintf(stderr, "Packman v%s\n", VERSION);
    fprintf(stderr, "command line switches\n");
    fprintf(stderr, "-i interface (example ./pk -i eth0)\n");
    fprintf(stderr, "-p (enables promiscuous mode)\n");
    fprintf(stderr, "-d (enables debugging)\n");
    fprintf(stderr, "-w wait_time ms (wait time in ms between
    packet captures) (example -w 10)\n");
    fprintf(stderr, "-h help\n");
    fprintf(stderr, "-m max_packets (maximum number of packets to
    capture) (example -m 1000)\n");
    fprintf(stderr, "-D turns display mode on\n");
    fprintf(stderr, "-c turns on caching\n");
    }

    void signal_capture_cntrlc(int sig)
    {
    fprintf(stderr, "Caught a INT signal\n");
    fprintf(stderr, "Shutting Down\n");
    exit(0);
    }


    I am getting back into C so I would like some serious criticism.


  2. Re: sys/queue.h

    On Jul 15, 8:14 pm, westymatt wrote:
    > I am looking for some documentation on using #include
    > Has anybody ever used it? I would like to integrate a linked list
    > using it.


    The best documentation is in /usr/include/sys/queue.h
    A few remarks on the code below...

    > I am writing a packet sniffer and am using a packetCache structure to
    > hold captured packets for exporting purposes and data collection.
    >
    > well here is the code
    >
    >


    > #define TRUE 1
    > #define FALSE 0
    > typedef int bool;


    You can get these from stdbool.h.

    > {
    > struct packetCache *pc;
    > if ((pc = (struct packetCache *) malloc (sizeof
    > (struct packetCache) + packet_header->len)) == NULL)


    Many people will argue that the assignemt is better written:
    pc = malloc( sizeof *pc + packet_header->len)
    (no cast and take the size of the object rather than a type.)
    I have a slight preference that there be no cast, since
    failure to include a prototype will cause a compiler
    warning, and I strongly encourage sizeof object instead
    of sizeof(type), since it can be verified by local inspection
    of the code (ie, I don't have to look for the declaration
    of pc to confirm that it is a struct packetCache *.
    And, the line stays correct when pc's type is changed
    to be a struct newpacketCache *)


    > /*command line options parsing*/
    > int option;
    > while ((option = getopt(argc, argv, "idwm:ch")) != -1)
    > {


    IMO, this should not be in main, but moved to a seperate
    function.

    > print_help();
    > return 1;


    return EXIT_FAILURE is more portable, but this
    is okay on linux.

    > default:
    > print_help();
    > abort();


    Hmmm. I'm not sure I want a program to
    dump core due to erroneous command line
    args.

    >
    > void signal_capture_cntrlc(int sig)
    > {
    > fprintf(stderr, "Caught a INT signal\n");
    > fprintf(stderr, "Shutting Down\n");
    > exit(0);}


    You really should not call fprintf
    from within the signal handler, as it is not
    re-entrant. Especially since you registered with
    signal() instead of sigaction, you may receive
    a SIGINT during one of the calls to fprintf and
    your program will lock up.




  3. Re: sys/queue.h

    The structure

    struct packetCache
    {
    struct packetCache *next;
    ssize_t len;
    unsigned char data[0];
    };

    The unsigned char data[0] is this essentially making a single char?


  4. Re: sys/queue.h

    In article <1184558755.459343.104170@o61g2000hsh.googlegroups. com>,
    westymatt wrote:

    >The unsigned char data[0] is this essentially making a single char?


    No




  5. Re: sys/queue.h

    Out of curiousity what does it create? Unregulated array growth


  6. Re: sys/queue.h

    In article <1184600375.603213.254750@g4g2000hsf.googlegroups.c om>,
    westymatt wrote:

    >Out of curiousity what does it create? Unregulated array growth


    It creates a way to access data beyond what's defined in the struct.


  7. Re: sys/queue.h

    On Mon, 16 Jul 2007 20:29:00 -0000 ellis@no.spam wrote:

    | In article <1184600375.603213.254750@g4g2000hsf.googlegroups.c om>,
    | westymatt wrote:
    |
    |>Out of curiousity what does it create? Unregulated array growth
    |
    | It creates a way to access data beyond what's defined in the struct.

    Variable length structs, assuming the length information is in, or can be
    derived from, what is in the fixed part of the struct, and the [0] member
    is the last member.

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-07-16-1608@ipal.net |
    |------------------------------------/-------------------------------------|

  8. Re: sys/queue.h

    I am sorry I follow what your saying, I just don't understand how it
    does.


  9. Re: sys/queue.h

    In article <1184625899.920399.62260@o61g2000hsh.googlegroups.c om>,
    westymatt wrote:

    >I am sorry I follow what your saying, I just don't understand how it
    >does.


    Then you need to go to comp.lang.c and ask. This is a linux kernel
    issue. (Or you can read the code in the kernel and see how the
    struct is being used.)

    --
    http://www.spinics.net/lists/kernel/