capturing user data using pcap in c - libpcap

I wanted to send my own data size of 1024 bytes through a particular interface . Suppose we have two hosts , one is sending and another is receiving.
Receiving host is using pcap mechanism to receive the data from other host.As per my knowledge Pcap receives echo packets from interface.
Here i want my own data to be received. How can i achieve that ??? Im a beginner ,so please help me out how to deal with pcap.
Actually I want to receive all data into a host ,save it and later forward it to my actual destination.
Is it possible using pcap???
client:
import socket
import select
import sys
import time
import json
import os
import pickle
from time import sleep
c=1
while(c):
if os.path.exists('/home/mininet/save.txt'):
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
count=5
while (count):
f1=open("/home/mininet/save.txt","r")
d=f1.read()
f1.close()
if d.strip():
d=int(d)
f=open("/home/mininet/test1.txt", "rb")
l = f.read(1024)
s.sendto(l,("10.0.0.1",9999))
count=count-1
time.sleep(d)
c=0
s.close()
This is the client part and in server the corresponding program to receive these data..
First both client and server was connected with each other . Then that link is broken and placed a host in between them to monitor the traffic.
Each data should reach to that newly created host then that host redirect that data to the server. I wanted to achieve this using pcap.

Here is an example:
/*
* Use pcap_open_live() to open a packet capture device.
* Use pcap_dump() to output the packet capture data in
* binary format to a file for processing later.
*/
#include <unistd.h>
#include <stdio.h>
#include <pcap.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define IFSZ 16
#define FLTRSZ 120
#define MAXHOSTSZ 256
#define PCAP_SAVEFILE "./pcap_savefile"
extern char *inet_ntoa();
int
usage(char *progname)
{
printf("Usage: %s <interface> [<savefile name>]\n", basename(progname));
exit(11);
}
int
main(int argc, char **argv)
{
pcap_t *p; /* packet capture descriptor */
struct pcap_stat ps; /* packet statistics */
pcap_dumper_t *pd; /* pointer to the dump file */
char ifname[IFSZ]; /* interface name (such as "en0") */
char filename[80]; /* name of savefile for dumping packet data */
char errbuf[PCAP_ERRBUF_SIZE]; /* buffer to hold error text */
char lhost[MAXHOSTSZ]; /* local host name */
char fltstr[FLTRSZ]; /* bpf filter string */
char prestr[80]; /* prefix string for errors from pcap_perror */
struct bpf_program prog; /* compiled bpf filter program */
int optimize = 1; /* passed to pcap_compile to do optimization */
int snaplen = 80; /* amount of data per packet */
int promisc = 0; /* do not change mode; if in promiscuous */
/* mode, stay in it, otherwise, do not */
int to_ms = 1000; /* timeout, in milliseconds */
int count = 20; /* number of packets to capture */
u_int32 net = 0; /* network IP address */
u_int32 mask = 0; /* network address mask */
char netstr[INET_ADDRSTRLEN]; /* dotted decimal form of address */
char maskstr[INET_ADDRSTRLEN]; /* dotted decimal form of net mask */
int linktype = 0; /* data link type */
int pcount = 0; /* number of packets actually read */
/*
* For this program, the interface name must be passed to it on the
* command line. The savefile name may be optionally passed in
* as well. If no savefile name is passed in, "./pcap_savefile" is
* used. If there are no arguments, the program has been invoked
* incorrectly.
*/
if (argc < 2)
usage(argv[0]);
if (strlen(argv[1]) > IFSZ) {
fprintf(stderr, "Invalid interface name.\n");
exit(1);
}
strcpy(ifname, argv[1]);
/*
* If there is a second argument (the name of the savefile), save it in
* filename. Otherwise, use the default name.
*/
if (argc >= 3)
strcpy(filename,argv[2]);
else
strcpy(filename, PCAP_SAVEFILE);
/*
* Open the network device for packet capture. This must be called
* before any packets can be captured on the network device.
*/
if (!(p = pcap_open_live(ifname, snaplen, promisc, to_ms, errbuf))) {
fprintf(stderr, "Error opening interface %s: %s\n",
ifname, errbuf);
exit(2);
}
/*
* Look up the network address and subnet mask for the network device
* returned by pcap_lookupdev(). The network mask will be used later
* in the call to pcap_compile().
*/
if (pcap_lookupnet(ifname, &net, &mask, errbuf) < 0) {
fprintf(stderr, "Error looking up network: %s\n", errbuf);
exit(3);
}
/*
* Create the filter and store it in the string called 'fltstr.'
* Here, you want only incoming packets (destined for this host),
* which use port 69 (tftp), and originate from a host on the
* local network.
*/
/* First, get the hostname of the local system */
if (gethostname(lhost,sizeof(lhost)) < 0) {
fprintf(stderr, "Error getting hostname.\n");
exit(4);
}
/*
* Second, get the dotted decimal representation of the network address
* and netmask. These will be used as part of the filter string.
*/
inet_ntop(AF_INET, (char*) &net, netstr, sizeof netstr);
inet_ntop(AF_INET, (char*) &mask, maskstr, sizeof maskstr);
/* Next, put the filter expression into the fltstr string. */
sprintf(fltstr,"dst host %s and src net %s mask %s and udp port 69",
lhost, netstr, maskstr);
/*
* Compile the filter. The filter will be converted from a text
* string to a bpf program that can be used by the Berkely Packet
* Filtering mechanism. The fourth argument, optimize, is set to 1 so
* the resulting bpf program, prog, is compiled for better performance.
*/
if (pcap_compile(p,&prog,fltstr,optimize,mask) < 0) {
/*
* Print out appropriate text, followed by the error message
* generated by the packet capture library.
*/
fprintf(stderr, "Error compiling bpf filter on %s: %s\n",
ifname, pcap_geterr(p));
exit(5);
}
/*
* Load the compiled filter program into the packet capture device.
* This causes the capture of the packets defined by the filter
* program, prog, to begin.
*/
if (pcap_setfilter(p, &prog) < 0) {
/* Copy appropriate error text to prefix string, prestr */
sprintf(prestr, "Error installing bpf filter on interface %s",
ifname);
/*
* Print error to screen. The format will be the prefix string,
* created above, followed by the error message that the packet
* capture library generates.
*/
pcap_perror(p,prestr);
exit(6);
}
/*
* Open dump device for writing packet capture data. In this sample,
* the data will be written to a savefile. The name of the file is
* passed in as the filename string.
*/
if ((pd = pcap_dump_open(p,filename)) == NULL) {
/*
* Print out error message if pcap_dump_open failed. This will
* be the below message followed by the pcap library error text,
* obtained by pcap_geterr().
*/
fprintf(stderr,
"Error opening savefile \"%s\" for writing: %s\n",
filename, pcap_geterr(p));
exit(7);
}
/*
* Call pcap_dispatch() to read and process a maximum of count (20)
* packets. For each captured packet (a packet that matches the filter
* specified to pcap_compile()), pcap_dump() will be called to write
* the packet capture data (in binary format) to the savefile specified
* to pcap_dump_open(). Note that packet in this case may not be a
* complete packet. The amount of data captured per packet is
* determined by the snaplen variable which is passed to
* pcap_open_live().
*/
if ((pcount = pcap_dispatch(p, count, &pcap_dump, (char *)pd)) < 0) {
/*
* Print out appropriate text, followed by the error message
* generated by the packet capture library.
*/
sprintf(prestr,"Error reading packets from interface %s",
ifname);
pcap_perror(p,prestr);
exit(8);
}
printf("Packets received and successfully passed through filter: %d.\n",
pcount);
/*
* Get and print the link layer type for the packet capture device,
* which is the network device selected for packet capture.
*/
if (!(linktype = pcap_datalink(p))) {
fprintf(stderr,
"Error getting link layer type for interface %s",
ifname);
exit(9);
}
printf("The link layer type for packet capture device %s is: %d.\n",
ifname, linktype);
/*
* Get the packet capture statistics associated with this packet
* capture device. The values represent packet statistics from the time
* pcap_open_live() was called up until this call.
*/
if (pcap_stats(p, &ps) != 0) {
fprintf(stderr, "Error getting Packet Capture stats: %s\n",
pcap_geterr(p));
exit(10);
}
/* Print the statistics out */
printf("Packet Capture Statistics:\n");
printf("%d packets received by filter\n", ps.ps_recv);
printf("%d packets dropped by kernel\n", ps.ps_drop);
/*
* Close the savefile opened in pcap_dump_open().
*/
pcap_dump_close(pd);
/*
* Close the packet capture device and free the memory used by the
* packet capture descriptor.
*/
pcap_close(p);
}

Related

Is there a way to accelerate the resize image performance of GraphicsMagick on mips CPU?

I'm using a netgear WNDR4300 to run GraphicsMaigick to resize JPEG images.
This is the cpuinfo,
cat /proc/cpuinfo
system type : Atheros AR9344 rev 2
machine : NETGEAR WNDR4300
processor : 0
cpu model : MIPS 74Kc V4.12
BogoMIPS : 278.93
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
isa : mips1 mips2 mips32r1 mips32r2
ASEs implemented : mips16 dsp dsp2
shadow register sets : 1
kscratch registers : 0
package : 0
core : 0
VCED exceptions : not available
VCEI exceptions : not available
It's very slow, and took over 4 minuntes for every photo.
root#OpenWrt:/mnt/sda1/media/# ll
drwxrwxrwx 2 root root 131072 Jun 10 14:07 ./
drwxrwxrwx 7 root root 131072 Jun 8 10:18 ../
-rwxrwxrwx 1 root root 4130026 Feb 10 2018 IMG_20180210_115807.jpg*
root#OpenWrt:/mnt/sda1/media/kidds# time gm mogrify -output-directory > /mnt/sda1/web -resize 64x64 -quality 75 IMG_20170628_100052.jpg
real 4m 19.72s
user 3m 21.86s
sys 0m 9.29s
UPDATE:
root#OpenWrt:~# gm identify -version
GraphicsMagick 1.3.31 2018-11-17 Q8 http://www.GraphicsMagick.org/
Copyright (C) 2002-2018 GraphicsMagick Group.
Additional copyrights and licenses apply to this software.
See http://www.GraphicsMagick.org/www/Copyright.html for details.
Feature Support:
Native Thread Safe yes
Large Files (> 32 bit) yes
Large Memory (> 32 bit) no
BZIP no
DPS no
FlashPix no
FreeType yes
Ghostscript (Library) no
JBIG no
JPEG-2000 no
JPEG yes
Little CMS no
Loadable Modules yes
OpenMP no
PNG yes
TIFF yes
TRIO no
UMEM no
WebP no
WMF no
X11 no
XML no
ZLIB yes
Host type: mips-openwrt-linux-gnu
Configured using the command:
./configure '--target=mips-openwrt-linux' '--host=mips-openwrt-linux' '--build=x86_64-pc-linux-gnu' '--program-prefix=' '--program-suffix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--libexecdir=/usr/lib' '--sysconfdir=/etc' '--datadir=/usr/share' '--localstatedir=/var' '--mandir=/usr/man' '--infodir=/usr/info' '--disable-nls' '--enable-shared' '--disable-static' '--enable-dependency-tracking' '--with-modules' '--with-threads' '--without-magick-plus-plus' '--without-perl' '--without-bzlib' '--without-dps' '--without-fpx' '--without-jbig' '--without-webp' '--with-jpeg' '--without-jp2' '--without-lcms2' '--without-lzma' '--with-png' '--with-tiff' '--without-trio' '--with-ttf' '--without-umem' '--without-wmf' '--without-xml' '--with-zlib' '--without-zstd' '--without-x' 'build_alias=x86_64-pc-linux-gnu' 'host_alias=mips-openwrt-linux' 'target_alias=mips-openwrt-linux' 'CC=mips-openwrt-linux-musl-gcc' 'CFLAGS=-Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-save
Final Build Parameters:
CC = mips-openwrt-linux-musl-gcc
CFLAGS = -Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -mips16 -minterlink-mips16 -iremap/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/build_dir/target-mips_24kc_musl/GraphicsMagick-1.3.31:GraphicsMagick-1.3.31 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -flto -Wall
CPPFLAGS = -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/usr/include -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/include -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/usr/include -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/include/fortify -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/include -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/usr/include/freetype2
CXX = mips-openwrt-linux-musl-g++
CXXFLAGS = -Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -mips16 -minterlink-mips16 -iremap/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/build_dir/target-mips_24kc_musl/GraphicsMagick-1.3.31:GraphicsMagick-1.3.31 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -flto
LDFLAGS = -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/usr/lib -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/lib -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/usr/lib -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/lib -znow -zrelro -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/usr/lib
LIBS = -lfreetype -lz -lltdl -lm -lpthread
UPDATE2: sample mode
root#OpenWrt:/mnt/sda1/media/kidds# time gm mogrify -output-directory /mnt/sda1/web -sample 64x64 -quality 75 IMG_20170628_100052.jpg
real 0m 20.76s
user 0m 8.70s
sys 0m 3.29s
Is there any way to improve the performance? I just want resize some photoes, if there is some library provided by MIPS, I can write a tool to call it using C language.
I grabbed the file example.c from the v9c source on the IJG website and quickly hacked it about as below to only write every 8th row and every 8th column from your 4640x3480 input file. It creates the following 580x435 image which GraphicsMagick can then presumably manage to resize down to 64x64 in reasonable time since the file is 64x smaller.
You would use:
gm convert result.ppm -resize 64x64 thumb.jpg
It only uses 1.1MB of RAM because it only reads 1 line at a time - I tested using:
/usr/bin/time -l ./example photo.jpg
You could experiment with the decimation factor, I used 8, but you could try 4, or 10 and see the tradeoff between time and quality. Just change the 8 on the second-to-last line of the file.
The code looks like this - I have added "HACK" in the comments so you can see where I was busy making ugly dirty code:
#include <stdio.h>
#include <stdlib.h>
#include "jpeglib.h"
#include <setjmp.h>
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr) cinfo->err;
/* Always display the message. */
/* We could postpone this until after returning, if we chose. */
(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
GLOBAL(int)
read_JPEG_file (char * filename,int factor)
{
/* This struct contains the JPEG decompression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
*/
struct jpeg_decompress_struct cinfo;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
/* More stuff */
FILE * infile; /* source file */
FILE * outfile; /* result file */ // HACK
JSAMPARRAY buffer; /* Output row buffer */
int row_stride; /* physical row width in output buffer */
/* In this example we want to open the input file before doing anything else,
* so that the setjmp() error recovery below can assume the file is open.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to read binary files.
*/
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return 0;
}
/* Step 1: allocate and initialize JPEG decompression object */
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 0;
}
/* Now we can initialize the JPEG decompression object. */
jpeg_create_decompress(&cinfo);
/* Step 2: specify data source (eg, a file) */
jpeg_stdio_src(&cinfo, infile);
/* Step 3: read file parameters with jpeg_read_header() */
(void) jpeg_read_header(&cinfo, TRUE);
/* We can ignore the return value from jpeg_read_header since
* (a) suspension is not possible with the stdio data source, and
* (b) we passed TRUE to reject a tables-only JPEG file as an error.
* See libjpeg.txt for more info.
*/
/* Step 4: set parameters for decompression */
/* In this example, we don't need to change any of the defaults set by
* jpeg_read_header(), so we do nothing here.
*/
/* Step 5: Start decompressor */
(void) jpeg_start_decompress(&cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/
/* We may need to do some setup of our own at this point before reading
* the data. After jpeg_start_decompress() we have the correct scaled
* output image dimensions available, as well as the output colormap
* if we asked for color quantization.
* In this example, we need to make an output work buffer of the right size.
*/
/* JSAMPLEs per row in output buffer */
row_stride = cinfo.output_width * cinfo.output_components;
/* Make a one-row-high sample array that will go away when done with image */
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
/* Step 6: while (scan lines remain to be read) */
/* jpeg_read_scanlines(...); */
// Write a simple PPM file called "result.ppm" that can be thumbnailed with GraphicsMagick
// gm convert result.ppm -resize 64x64 thumbnail.jpg
if ((outfile = fopen("result.ppm", "wb")) == NULL) { // HACK
fprintf(stderr, "can't open result.ppm\n"); // HACK
return 0; // HACK
}
int outwidth = cinfo.output_width/factor; // HACK
int outheight = cinfo.output_height/factor; // HACK
fprintf(outfile,"P6\n%d %d\n255\n",outwidth,outheight); // HACK
unsigned char * outbuf; // HACK
outbuf = (unsigned char*)malloc(outwidth*3); // HACK
int line=0; // HACK
while (cinfo.output_scanline < cinfo.output_height) {
/* jpeg_read_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could ask for
* more than one scanline at a time if that's more convenient.
*/
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
// Do every Nth row // HACK
if(line%factor==0){ // HACK
int pixel,op;
op=0;
for(pixel=0;pixel<row_stride/3;pixel+=factor){
outbuf[op++] = buffer[0][(pixel*3) +0];
outbuf[op++] = buffer[0][(pixel*3) +1];
outbuf[op++] = buffer[0][(pixel*3) +2];
}
fwrite(outbuf,1,op,outfile); // HACK
} // HACK
line++; // HACK
}
/* Step 7: Finish decompression */
(void) jpeg_finish_decompress(&cinfo);
/* Step 8: Release JPEG decompression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 1;
}
int main(int argc, char*argv[]){
// Read "test.jpg" and only output every 8th row and every 8th column for a 64x size reduction
read_JPEG_file ("test.jpg",8); // HACK
}
I compiled it with:
clang -std=c11 $(pkg-config --cflags --libs libjpeg) example.c -o example

How to set a range for DHCP IP address leasing in WiFi softAP()?

I am trying to make a mesh network using ESP32 module. The WiFi.h softAPConfig() can be used to set the starting address for leasing, but it progress upwards without reusing the already leased addresses which are no more in use. So I want to limit the leasing range between two addresses.
I found this piece of code from dhcpserver.h
/* Defined in esp_misc.h */
typedef struct {
bool enable;
ip4_addr_t start_ip;
ip4_addr_t end_ip;
} dhcps_lease_t;
This is the code I compiled and uploaded into the ESP32 module
#include "WiFi.h"
char *ssid = "AirMesh";
IPAddress local_IP(192,168,1,0);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.print("Setting soft-AP configuration ... ");
Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");
Serial.print("Setting soft-AP ... ");
Serial.println(WiFi.softAP("ESPsoftAP_01") ? "Ready" : "Failed!");
Serial.print("Soft-AP IP address = ");
Serial.println(WiFi.softAPIP());
WiFi.softAP(ssid);
}
void loop() {}
The first device when connected gives an IP 192.168.1.1, the second device an IP 192.168.1.2, when I disconnect the first device and reconnected it and it gives an IP 192.168.1.3 (every connection use different physical addresses)
This progression keeps going
EDIT:
After digging it up, I think I found the code responsible for ranging IP leasing, but couldn't figure out what it means.
lease.start_ip.addr = static_cast<uint32_t>(local_ip) + (1 << 24);
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (11 << 24);
After trial and error methord, I managed to find the answer
Change the code in WiFiAP.cpp file (i have forked and requested a pull replacing 11 with 10 since the maximum number of connections possible for ESP32 is 10)
lease.start_ip.addr = static_cast<uint32_t>(local_ip) + (1 << 24);
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (n << 24);
Where n is number of IP addresses that must be allocated to external devices.
For ex:-
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (20 << 24);
means if the starting IP is 192.168.1.0 the DHCP will assign address starting from 192.168.1.1 to 192.168.1.20, while 192.168.1.0 (starting IP will be the address of the ESP32 module)
Doesn't the access point use the first ip of 192.168.1.1 not 1.0?
So 2-11 is 10 connections.

Error in writing/Reading to I2C EEPROM + STM32F0 Discovery

I am struggling to Write or read to AT24C256 I2C EEPROM. I am using STM32F0 discovery board to read/write to EEPROM.
I am using HAL library and CUBEMX for basic structure. I have written small code to test the read and write function. On debugging the the values of Test is always '2' whereas it should be '1' if it's successful in writing into memory. Here it is :-
#define ADDR_24LCxx_Write 0x50
#define ADDR_24LCxx_Read 0x50
#define BufferSize 5
uint8_t WriteBuffer[BufferSize],ReadBuffer[BufferSize],Test;
uint16_t i;
I2C_HandleTypeDef hi2c1;
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
for(i=0; i<5; i++)
{
WriteBuffer[i]=i;
}
if(HAL_I2C_Mem_Write(&hi2c1, ADDR_24LCxx_Write, 0, I2C_MEMADD_SIZE_8BIT,WriteBuffer,BufferSize, 0x10) == HAL_OK)
{
Test = 1;
}
else
{
Test = 2;
}
HAL_I2C_Mem_Read(&hi2c1, ADDR_24LCxx_Read, 0, I2C_MEMADD_SIZE_8BIT,ReadBuffer,BufferSize, 0x10);
if(memcmp(WriteBuffer,ReadBuffer,BufferSize) == 0 ) /* check date */
{
Test = 3;
}
else
{
Test = 4;
}
}
You should step in the function HAL_I2C_Mem_Write to understand why it does not return HAL_OK. More particularly, you should check what it exactly returns, it would help you.
Looking at your code, I am confident that the issue is with I2C address. In the AT24C256 datasheet, they say that the I2C address is:
1 0 1 0 0 A1 A2 R/W
Assuming that you connected the pins A1 and A2 to GND, the I2C address is:
1 0 1 0 0 0 0 R/W
In hex, the I2C address is 0xA0. So, change your adress definition as follows:
#define ADDR_24LCxx 0xA0
And in the HAL functions:
HAL_I2C_Mem_Write(&hi2c1, ADDR_24LCxx, 0, I2C_MEMADD_SIZE_8BIT,WriteBuffer,BufferSize, 100)
HAL_I2C_Mem_Read(&hi2c1, ADDR_24LCxx, 0, I2C_MEMADD_SIZE_8BIT,ReadBuffer,BufferSize, 100)
Please note that I have also increased the timeout to 100ms. For testing, you don't really want to have timeout issues....

assiging makes pointer integer witout cast

hello all i have write a c program which connects to a mysql server and executes a sql query from a text file which has only one query.
#include <mysql.h>
#include <stdio.h>
main() {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "127.0.0.1";
char *user = "root";
char *password = "PASSWORD"; /* set me first */
char *database = "har";
conn = mysql_init(NULL);
char ch, file_name[25];
char *ch1;
FILE *fp;
printf("Enter the name of file you wish to see ");
gets(file_name);
fp = fopen(file_name,"r"); // read mode
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(0);
}
while( ( ch = fgetc(fp) ) != EOF )
printf("%c",ch);
ch1=ch;
/* Connect to database */
if (!mysql_real_connect(conn, server,
NULL , NULL, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(0);
}
printf("%c",ch);
/* send SQL query */
if (mysql_query(conn, ch1)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(0);
}
res = mysql_use_result(conn);
/* output table name */
printf("MySQL Tables in mysql database:\n");
while ((row = mysql_fetch_row(res)) != NULL)
printf("%s \n", row[0]);
/* close connection */
mysql_free_result(res);
mysql_close(conn);
fclose(fp);
}
i am unable to understand where i have gone wrong....
thanks in advance...
This is the line causing problem:
ch1=ch;
ch1 is a pointer to a character, whereas ch is a character.
Do you intend to store the bytes read from fp in a char array pointed by ch1? What you are doing is, every time in the while loop you are reading a character using fgetc storing it in ch and printing it.
Then, when while loop gets over, you are assigning a char to a char pointer. I am not sure what you are trying to do with this. But this definitely causes the problem.
You're going wrong in a lot of ways:
You don't declare the return type or arguments for main.
You're using gets. Never ever use gets, don't even think about. Use fgets instead.
fgetc returns an int, not a char so your ch should be an int. You won't be able to recognize EOF until you fix this.
You're declaring char ch and char *ch1 but assigning ch to ch1. That's where the error in your title is coming from.
Your code appears to be trying feed your SQL to MySQL one byte at a time and that's not going to do anything useful. I think you're meaning to use fgets to read the SQL file one line a time so that you can feed each line to MySQL as a single SQL statement.
You should spend some time reading about your compiler's warning switches

How to use libpcap to sniff on multiple devices?

I am trying to create a sniffer that can sniff on multiple devices. In my code the program will receive a list of devices that a user wants to sniff on. I take the list of device and store it into an array that I use to loop through and pass along to a function that creates the pcap_t handle like the function below:
void *startPcapProcess(char * dev){
char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */
pcap_t *handle; /* packet capture handle */
/* filter expression [3] */
char filter_exp[] = "(dst port 53) and (udp[0xa] & 0x78 = 0x28)";
struct bpf_program fp; /* compiled filter program (expression) */
bpf_u_int32 mask; /* subnet mask */
bpf_u_int32 net; /* ip */
printf("%s","startPacketProcess called\n");
printf("Device sent to startPacketProcess: %s\n", dev);
/* get network number and mask associated with capture device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Couldn't get netmask for device %s: %s\n",
dev, errbuf);
net = 0;
mask = 0;
}
/* open capture device */
handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
exit(EXIT_FAILURE);
}
/* make sure we're capturing on an Ethernet device [2] */
if (pcap_datalink(handle) != DLT_EN10MB) {
fprintf(stderr, "%s is not an Ethernet\n", dev);
exit(EXIT_FAILURE);
}
/* compile the filter expression */
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n",
filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
/* apply the compiled filter */
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n",
filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
pcap_freecode(&fp);
/* now we can set our callback function */
pcap_loop(handle, -1, process_packet, NULL);
printf("%s","End startPacketProcess call\n");
}
However, when I make a call to this function within my for loop it is only able to capture on one device since it seems to get stuck in the pcap_loop callback function. As a result of this I tried to do multi threading and the for loop that I use to pass in all the devices to open and capture to goes through the loop, but the pcap_loop callback function does not seem to execute. The following code shows my use of multi threading:
for (i = 0; i < numDevice; i++){
printf("Device returned by getDevices call: %s\n", deviceList[i]);
printf("%s","Entering for loop\n");
pthread_create(&tid, thAttr, startPacketProcess,(void*)deviceList[i]);
}
Does anyone know what I am doing wrong and can you provide me with suggestions on how to resolve this issue?
Thanks,
Linh
process_packet might be the problem. Try getting the packet in the thread context.
struct pcap_pkthdr *pkt_header;
u_char *pkt_data;
while ((retval = pcap_next_ex(mpPcap, &pkt_header, (const u_char **) &pkt_data)) >= 0) {
//Do Whatever
}
Have you tried using pcap_findalldevs() or pcap_findalldevs_ex()