How to use pcap structures with the good includes - c

Since yesterday i'm learning how to use pcap to parse a pcap file.
And since yesterday i'm getting an error :
Here is my simple code, trying to write the fd in pcap_t structure:
#include <pcap/pcap.h>
#include <sys/types.h>
#include <pcap-bpf.h>
#include <stdio.h>
int main() {
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *result;
if ((result = pcap_open_offline("test.pcap", errbuf)) == NULL) {
printf("%s\n", errbuf);
return -1;
}
printf("fd=%d\n", result->fd);
return 0;
}
and here is my error:
gcc -Wextra -Wall -Werror -I./includes -c -o main.o main.c
main.c: In function ‘main’:
main.c:14:27: error: dereferencing pointer to incomplete type
printf("fd=%d\n", result->fd);
^
make: *** [main.o] Error 1
I saw this post: Pcap Incomplete Type
Where the guy is having almost the same problem as I have, but still, I can't find a solution, I included what pcap_open_offline needs, I also included pcap-bpf.h because I saw that pcap_t is using bpf_program.
The first answer is saying "The error is because the compiler cannot see the definition of the structure" but in my case the structure is pcap_t and is typedef in pcap.h, which i included.
I just don't get how to include correclty with pcap.
Also, I'm on Ubuntu, and i cannot find all my .h file about pcap. When I look on google, I only find .h from apple and windows, so I assume that i'm using the same as the apple one, but i'm not sure about that !
I'm reading this documentation to see structures fields :
http://www.opensource.apple.com/source/libpcap/libpcap-18/libpcap/pcap.h
http://www.opensource.apple.com/source/libpcap/libpcap-9/libpcap/pcap-int.h
But again, the apple.com is scaring me, i'm not sure that I should rely on that. For instance, pcap-int.h doesn't seem to exist in my system.
Thank you !

For instance, pcap-int.h doesn't seem to exist in my system.
It's not supposed to. It's part of the pcap source code, but it's internal to libpcap, and the data structures it defines are subject to change from cap release to release, so you can't use them in a pcap program.
You rarely if ever need to the file descriptor associated with a pcap_t, but, in those rare cases where you do, you get it with the pcap_fileno() function:
printf("fd=%d\n", pcap_fileno(result));
However, when you open a capture file, using pcap_open_offline(), rather than opening a device for a live capture, there is no file descriptor associated with it, there's just a "standard I/O" FILE *. As the man page for pcap_fileno() says:
If p refers to a ``savefile'' that was opened using functions such as
pcap_open_offline() or pcap_fopen_offline(), a ``dead'' pcap_t opened
using pcap_open_dead(), or a pcap_t that was created with pcap_create()
but that has not yet been activated with pcap_activate(), it returns
-1.
so it should print "fd=-1" in your program.
The first answer is saying "The error is because the compiler cannot see the definition of the structure" but in my case the structure is pcap_t and is typedef in pcap.h, which i included.
It's typedefed as a structure in pcap.h, but that structure isn't fully defined in pcap.h. C allows a pointer to a structure that's not fully defined; this allows a library to provide a "handle" for a data structure that only the library itself can look at or modify. That's the case with the pcap_t structure; code outside libpcap should not look at it or modify it, it should make calls to libpcap routines to do that.
Also, I'm on Ubuntu, and i cannot find all my .h file about cap.
You probably need to install the "libpcap-dev" package. The "libpcap" package just installs enough libraries to allow programs already compiled with libpcap to run; the "libpcap-dev" package installs the header files to allow programs to be compiled with libpcap.
When I look on google, I only find .h from apple and windows
It doesn't find the GitHub repository for libpcap? That's surprising.
so I assume that i'm using the same as the apple one
Apple's libpcap is based on the one from the Tcpdump Group, which is the one on GitHub. The one in Ubuntu is also based on the one from the Tcpdump Group, as is WinPcap, which is the version for Windows.

Related

Compiling a Linux program under Mac OS X

I am trying to use make under Mac OS X (El Capitan) to compile a program which I know to work under Linux. The program makes use of USB libraries. I had to modify the config.mk file for these libraries to be found, but now I end up with errors in the compilation (undeclared identifiers).
Link to source: https://github.com/pali/0xFFFF
It requires usb.h, which seems to be part of usblib-compat. I installed the latter by brew install usblib-compat. But still usb.h couldn't be seen, although I knew where it was: specifically, symbolic link to usb.h and to the library may be found under /usr/local/include and under /usr/local/lib, respectively.
After many trials, I progressed somehow. Namely, the file config.mk is clearly read during the make'ing process, although I have to admit that it is not clear to me how this is done; anyway, I noticed two lines commented:
CPPFLAGS += -I/usr/local/include
LDFLAGS += -L/usr/local/lib -Wl,-R/usr/local/lib
(for the sake of precision, in the original config.mk the local dir was replaced by a pkg dir. I replaced it in these lines.)
I uncommented them and now something happens: the usb.h is found. I think the first of these variable definitions tells the compiler where to look tor header files, and the second tells the linker where to look for libraries - but again it is not completely clear to me.
In any case, I have still problems. Namely, the make'ing process outputs two warnings and an error, and then stops:
usb-device.c:90:57: warning: unused parameter 'udev' [-Wunused-parameter]
static void usb_reattach_kernel_driver(usb_dev_handle * udev, int interface) {
^
usb-device.c:90:67: warning: unused parameter 'interface' [-Wunused-parameter]
static void usb_reattach_kernel_driver(usb_dev_handle * udev, int interface) {
usb-device.c:324:13: error: use of undeclared identifier 'RTLD_DEFAULT' if ( dlsym(RTLD_DEFAULT, "libusb_init") )
Seems this program is difficult to port from Linux to Mac, although I think it should be portable. If anyone has any idea about what to do (apart from running a Linux distribution...), it would be much appreciated.
EDIT
dlfcn.h has the following:
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#define RTLD_NOLOAD 0x10
#define RTLD_NODELETE 0x80
#define RTLD_FIRST 0x100 /* Mac OS X 10.5 and later */
/*
* Special handle arguments for dlsym().
*/
#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
#define RTLD_SELF ((void *) -3) /* Search this and subsequent objects (Mac OS X 10.5 and later) */
#endif /* not POSIX */
Ok, finally I have been successful. I think it be worth publishing my solution - maybe others could find it useful.
So, the first point is: if I run make in the program's main folder, usb.h is not found. Then, we have to install the corresponding library.
There are two possibilities for this to be done. The first and more obvious would be to install, through home brew, libusb-1.0 and libusb-compat (the latter provides a compatibility interface for programs that use libusb-0.1, which is the first version of libusb, and is not compatible with libusb-1.0. usb.h is included in libusb-compat):
brew install libusb
brew install libusb-compat
However, this leads to other problems, as reported in the other answer. I had worked around them, but eventually found out that my program got angry when using libusb-compat (if I understand correctly, interfacing the usb port through two layers of libraries is too slow for a flasher).
So, the other possibility: installing the actual libusb-0.1. This is not available through home brew. It is however available through ports, with the name of libusb-legacy. So, I had to install ports, install the X-code command line utilities (which required first going to Apples' website to accept their legal things...) and run
sudo port install libusb-legacy
Ok, now calling make would not do the trick since the compiler is not able to find the library yet. For that, I had to edit the config.mk file which is included in the main directory of the program, uncommenting the last two lines, and editing them somewhat in order to point to the directory where libusb-legacy is stored:
CPPFLAGS += -I/opt/local/include/libusb-legacy -D_DARWIN_C_SOURCE
LDFLAGS += -L/opt/local/lib/libusb-legacy
(the -D_DARWIN_C_SOURCE defines the environmental variable required for other variables to be defined by the libraries. In the Makefile in the src directory, in fact, _POSIX_C_SOURCE is defined.)
Do you think all this did the job? No. In fact at this point I ended up with another error: the linker not being able to find some library called -lusb. I don't know why this syntax, but after some thought I realised that -lusb is somewhat a short for libusb. And the libusb I am using is actually called libusb-legacy... So I went into the Makefile in the src directory, where -lusb is introduced, and changed -lusb to -lusb-compat. Tah-dah! Compiled. A few warnings about non-used variables and a comparison between two different types of integers, but nothing more. And the program runs - after a few trials, I have been able to reflash my bricked phone, which now is alive again! Very happy!!! :)
Looking at the dlfcn.h source code, it seems that the identifier is defined only if _POSIX_C_SOURCE is not defined, or _DARWIN_C_SOURCE is defined. Thus I'd just add #define _DARWIN_C_SOURCE;
Or you could add the corresponding -D switch in the config.mk:
CPPFLAGS += -I/usr/local/include -D_DARWIN_C_SOURCE

Minix 3 stdio.h doesn't recognize FILE *f

I'm developing something on Minix 3 and, when it comes to deal with io files, I got a problem.
In the code:
#include <stdio.h> /* If I don't call any stdio funcs compiler doesnt's complain*/
int main() {
FILE * fp; /* I get the following: " * not expected " */
return 0;
}
Already tried everything that comes to my mind, can't figure it out..
/EDIT/
From what I can tell, when I include something, if I call functions not related to structs, it's OK. Is it the structs ?
I will assume you have checked whether the Minix file is present, that it really defines the type FILE and that your include path provides the correct -Ioption to the compiler to find that file.
Depending on your environment it could happen that an environment variable INCLUDE exists and is recognized by your compiler to provide additional include paths, recognized even before the include options from the command line. In such a case it might happen to include a stdio.hfrom a different compiler. Visual Studio is known to provide such an environment variable by default, and that has bitten me once before.
EDIT: Running the preprocessor in isolation may help to find out what is really happening in any case. Verify that FILEis defined in the preprocessed version of your file.

Typedefs included, but not functions

I'm writing some code that uses a C library provided by MATLAB (to extract data from *.mat files). In my IDE (Code::Blocks), I've included the folder containing the necessary "mat.h", which is on a network drive. My code recognises types defined in mat.h when I do this, but whenever I call functions from the file I get an "undefined reference" error. This is the same case for the example code MathWorks provides. What sort of problem usually causes this?
#include "mat.h"
int main (void) {
MATFile *pmat; // Compiles only when compiler is told to search in mat.h directory
pmat = matOpen("example_filename", "r"); // Never compiles
return 0;
}
Thanks!
Cameron
"undefined reference" is normally a linker error. It's not a problem of a header file. You need to tell the linker to link MATLAB's library (or a dedicated object) to your program.
No idea how this is done in Code::Blocks though. In the Code:Blocks documentation it is described here.
Have you checked the contents of mat.h? Does it declare matOpen()? Also, does the error occur when compiling or linking? If it's during the link phase, you probably need to reference the library that contains the implementation of matOpen() (a .lib in Windows, or .a in Unix). The .h file only declares the function.

Compiling icmp related codes under cygwin (missing "icmp" struct)

I'm using cygwin to compile a network tool(iffinder).
After ./configure and make i have a problem that i guess is related to struct icmp. Where is the icmp struct in header files. I searched for it in cygwin header files, but i didn't find anything.
How can i compile source codes which need icmp, in cygwin?
If it helps, you can find the source code of iffinder here
Note: I have ip_icmp.h in my cygwin's header files.
Compile error:
iffinder.c:1059: warning: "struct icmp" declared inside parameter list
iffinder.c:1059: warning: its scope is only this definition or
declaration, which is probably not what you want iffinder.c: In
function `handle_icmp_error': iffinder.c:1069: error: dereferencing
pointer to incomplete type
...
In cygwin, the icmp.h is empty. I suggest you copy a icmp.h from a open source project, and compile it with your project. Maybe, you have many errors and you have to correct them, but you just need an icmp struct and it will solve your problem.
iffinder.c line 54 does #include <netinet/ip_icmp.h> - is this header file present on your system?

#ifdef KERNEL2x & file_operations(..,..,..,..) , ssize_t function,printk()

Hi I have several questions. I will be glad if someone will answer :)
I'm trying to compile linux driver for an lcd 16X2 module.
I'm trying to use in my code the struct file_operations();
1. I notice by other codes that they add #ifdef KERNEL21 to compile. I tryed to this and I got much less errors. why it's work this way. im using kernel 2.6.18-128.4.1.el5.. soo do I need to change to #ifdef KERNEL26? I get more errors if I try to do soo.
2.some of the file_operation arguments are function the rtuen ssize_t. what is this mean? in other code eample there is also "#ifdef KERNEL21" but still I get an error:
"lcd_module.c:74: error: expected identifier or ג(ג before ג{ג token"
3.last qustion, I worked with a Makfile example and I get .o file and not .ko that im use to work with. how do I run the module with the .o file?
thank on advance :)
ssize_t is basically a signed size_t and is widely used in the kernel because values less than zero are used to return errors in places where an unsigned size is expected. For example, the read file operation is expected to return the number of bytes read, but in case of insufficient memory you can return -ENOMEM and errno will be set appropriately in the user-space program.
With the 2.6 kernel you are supposed to use the Makefile from the kernel-headers package rather than a hand-crafted one, and it produces a .ko file rather than an .o. Further reading here: http://www.cyberciti.biz/tips/build-linux-kernel-module-against-installed-kernel-source-tree.html

Resources