I need to save UDP packets to a file and would like to use the pcap format to reuse the various tools available (wireshark, tcpdump, ...).
There are some information in this thread but I can't find how to write the global file header 'struct pcap_file_header'.
pcap_t* pd = pcap_open_dead(DLT_RAW, 65535);
pcap_dumper_t* pdumper = pcap_dump_open(pd, filename);
struct pcap_file_header file_hdr;
file_hdr.magic_number = 0xa1b2c3d4;
file_hdr.version_major = 2;
file_hdr.version_minor = 4;
file_hdr.thiszone = 0;
file_hdr.sigfigs = 0;
file_hdr.snaplen = 65535;
file_hdr.linktype = 1;
// How do I write file_hdr to m_pdumper?
while( (len = recvmsg(sd, &msg_hdr, 0)) > 0 )
pcap_dump((u_char*)m_pdumper, &m_pcap_pkthdr, (const u_char*)&data);
How should I write the global file header?
If there is no specific pcap function available, how can I retrieve the file descriptor to insert the header using write()?
You shouldn't need to write that header, pcap_open_dead should do it for you. You only need to fill out and write that header yourself if you want to write the file directly instead of using pcap_dump and friends. There's an example here of a trivial program write out a pcap file with those functions.
original answer, concerning writing the file directly:
I can't remember exactly how this works, but I wrote a patch to redir a while ago that would write out pcap files, you may be able to use it as an example.
You can find it attached to this debian bug. (bug link fixed.)
Some of it is for faking the ethernet and IP headers, and may not be applicable as you're using pcap_dump_open and pcap_dump where as the patch linked above writes out the pcap file without using any libraries, but I'll leave this here anyway in case it helps.
If you are interested in UDP and TCP only, you should use DLT_EN10MB instead of DLT_RAW ( cf pcap_open_dead to simulate full UDP packets capture ).
It is much better when editing in WireShak.
Related
I would like to get a list of the wireless networks available. Ideally this would be via some C call, but I don't mind if I have to kludge it with a system call. Even better if the required C call or program doesn't require some exotic 3rd party package.
The internet seems to suggest I use sudo iwlist <interface> scan which does seem to do the trick from the command line, but I'd rather not require root permissions. I only want to see the basics, not change anything.
It's pretty easy to do a scan in the command line. The man pages are your friend here (check out iwconfig and iwlist). But using the C interface is a little more difficult so I'll focus on that.
First of all, as other people have mentioned, definitely download out the wireless tools source code. All the documentation for the programming interface is in the .c files. As far as I can tell, there is no web documentation for the api. However, the source code is pretty easy to read through. You pretty much only need iwlib.h and iwlib.c for this question.
While you can use iw_set_ext and iw_get_ext, the libiw implements a basic scanning function iw_scan, from which you can extract most of the information that you need.
Here is a simple program to get the ESSID for all available wireless networks. Compile with -liw and run with sudo.
#include <stdio.h>
#include <time.h>
#include <iwlib.h>
int main(void) {
wireless_scan_head head;
wireless_scan *result;
iwrange range;
int sock;
/* Open socket to kernel */
sock = iw_sockets_open();
/* Get some metadata to use for scanning */
if (iw_get_range_info(sock, "wlan0", &range) < 0) {
printf("Error during iw_get_range_info. Aborting.\n");
exit(2);
}
/* Perform the scan */
if (iw_scan(sock, "wlan0", range.we_version_compiled, &head) < 0) {
printf("Error during iw_scan. Aborting.\n");
exit(2);
}
/* Traverse the results */
result = head.result;
while (NULL != result) {
printf("%s\n", result->b.essid);
result = result->next;
}
exit(0);
}
DISCLAIMER: This is just a demonstration program. It's possible for some results to not have an essid. In addition, this assumes your wireless interface is "wlan0". You get the idea.
Read the iwlib source code!
The Wireless Tools package -- of which iwlist is a part -- also contains a Wireless Tools Helper Library. You need to include iwlib.h and link with libiw.a (i.e. add -liw). Then look up the documentation for the iw_set_ext function. The SIOCSIWSCAN parameter will be of most use. For an example of how to use this interface, take a look at the KWifiManager source in the KDE library (see: Interface_wireless_wirelessextensions::get_available_networks method). Alternatively, you can also download the Wireless Tools source code and take a look at how the iwlib iw_set_ext function is also used for scanning in iwlist.c.
As for privileges, I imagine the process will need to run as root to perform the scan. I'd love to know if this could be done otherwise as well.
Since you are using Ubuntu 8.04 the libiw-dev package should be of use.
You can use nmcli which does not require root permissions or name of WIFI interface.
nmcli -t -f ssid dev wifi
I want to write my own tag on the device file (scsi file sdb, sdc...) on Linux.
I use linux C open(), read(), write() functions on /dev/sdb file, write my key in this file. But when usb disk device Unplug from computer and plug again, in /dev/sdb's key, sometimes it's gone, or is unstable.
I don't know why.
char readBuf[512] = { 0 };
char key[12] = "h%27dcd*()jd";
int fd = open("/dev/sdb",O_RDWR);
lseek(fd,1024,SEEK_SET);
read(fd,readBuf,512);
for(int i=0; i<sizeof key; ++i)
{
readBuf[i] = ~key[i];
}
lseek(fd,1024,SEEK_SET);
write(fd,readBuf,512);
//In order to mark the Usb disk bear fruit...
for setting a fixed mount point:
you can assign a static mount point (like /dev/sdb) for USB devices using udev rules and a symlink. you can identify the device in the udev rule by i.e. vendor id and product id,...
ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="my_device"
https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name
for writing bit-wise to specific memory location on the stick:
to write data bytewise to arbitrary blocks on a block device use tools like dd ( https://en.wikipedia.org/wiki/Dd_(Unix) ). file io tools like read(), write() can not be used for writing bytewise WITHOUT using a file...
I have 2 programs written in C, one program writes to the pcap file and the second program reads from it at the same time.For writing ,I am using the following code
while(j < 100000)
{
pcount = pcap_dispatch(p,2000,&pcap_dump,(u_char *)pd);
j = j+pcount;
printf("Got %d packets , total packets %d\n",pcount,j);
}
And for decoding the packets, I am using the following code
while( (returnValue=pcap_next_ex(pcap,&header,&data)) >= 0)
{
printf("Packet # %d ",++packetCount);
printf("return value %d\n",returnValue);
}
When i run the program separately i.e when I stop writing to the pcap file, It decodes the packets perfectly. But when I run both the programs at the same time, the decoder does not decode all the packets. If i get 100 packets, the decoder will show only 50-60 decoded packets.
Any help will be appreciated.
In my opinion, reader's file is not getting updated as soon as the writer writes in the pcap file. This might be due to the reason that reader's file pointer is not refreshed i.e its reading the non updated version of file.
Hope it will help you.
This is what pipes are for. I suggest something like
pcap_writer -w - | tee permanent-file.pcap | pcap_reader -r -
where pcap_writer and pcap_reader are your programs. This way you create something that can be combined in a different manner, if wanted.
When i try to download a set of files using stream sockets over an HTTP protocol, it only gets data from the first file i try to download.
Assume a loop like the following...
char* file = (char*) malloc(enough_space);
char page[] = {"www.foobar.com"};
for(int n=0 ; n<10 ; n++)
{
sprintf(file, "file%i.html", n);
fopen(file, "wb");
sprintf(request, "GET %s HTTP/1.1\nHost: %s\n\n", file, page);
write( socket, request, strlen(request) );
read_file(output_file);
fclose(output_file);
}
Where a connection has been established first.
This code would give me file1.html, including its header from the server.. But only the first file, and this puzzles me.. What will i have to do in order to get them all?
Thanks up front.
HTTP was designed so that just a single file can be downloaded over a TCP connection. To download multiple files over one TCP connection, you could use HTTP Pipelining. You can read more here: HTTP pipelining request text example
Or you could just use one of the many libraries that will handle this, and many other caveats of HTTP for you: libcurl, libsoup...
I am working with libpcap to check http info. libpcap can not reassemble tcp segment.
there are many corner cases to deal manually. I also read wireshark source code. It's too big.
Does have any open source code can reassemble tcp and disect http data in c?
Have hacked code of driftnet, tcpflow, pcap etc. earlier.
tcpflow can re-assemble dumps from ie tcpdump. A "typical" chain of work could be:
$ tcpdump -nnieth0 -w dump.raw
# dump dum dump
$ mkdir tmp && cd tmp
tmp/$ tcpflow -r ../dump.raw
# This joins the transfers into separate files
# Now one can investigate each transfere from those separate files
# Next join them to one:
tmp/$ cat * > ../dump.flow
tmp/$ cd ..
# Extract some data
$ foremost -i dump.flow
Believe you can find some useful lines in the source-code for these.
Else:
A HTTP parsing library: HTTP Parser
Easiest way to do this is download wireshark software open pcap file or live capture it. after that right click any packet and go to "follow tcp stream"...you will see your http data in opened window.
If you want to build a program from scratch.-
A pcap file structure for tcp transaction is something like this:
[pcap_file_header]
for each packet
[pcap_packet] --this contains packet len info
[ip_header]----usually of size 20 or more
[tcp_header]--usually of size 20 or more
[packet] ---len stored in pcap packet header
Now to read the info, first get your pcap file in stream pointer.
Read packet file header(google for various type of struct)
start a loop
for each packet
read pcap_phdr from file or stream
add offset of ip_hdr length and tcp hdr length
for example pointer=pointer+20(for ip)+20(for tcp)
the pointer should be pointing to your data
so just give read pcap_phdr.caplen amount of byte and print it character by character.
The smallest TCP/IP stack I know of, which is open source is uIP but it is a bit odd, as it is designed for extremely small systems (microcontrollers)
Another small Open Source TCP/IP stack, which is a bit more traditional is lwIP