I am trying to build a network scanner.
I know the procedure so I want to ping all available hosts in the network and then get the ARP table so I can map the MAC address for each IP.
I Googled for ARP table but I didn't find any guide how to implement this feature.
I also found these similar questions on Stack overflow:
Link1
Link2
The answer are unclear on how to implement the ARP feature.
Is there any official guide for this one? Is Apple approving the ARP table feature?
UPDATE AFTER 10.2
Check the library here
I finally got it working so I will post the procedure in detail to save some time for other guys:
Go to Applications and right click on Xcode -> Show package contents and browse to: Developer ▸ Platforms ▸ MacOSX.platform ▸ Developer ▸ SDKs ▸ MacOSX10.10.sdk ▸ usr ▸ include. From "net" folder copy the route.h and if_types.h and from the "netinet" folder copy the if_ether.h into your Xcode project.
Then import the following .m and .h files:
MacFinder.h
#import <Foundation/Foundation.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include "if_types.h"
#if TARGET_IPHONE_SIMULATOR
#include <net/route.h>
#else
#include "route.h"
#endif
#include "if_ether.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#interface MacFinder : NSObject{
int nflag;
}
-(NSString*) ip2mac: (char*)ip;
#end
MacFinder.m
#import "MacFinder.h"
#implementation MacFinder
-(NSString*) ip2mac: (char*)ip
{
int found_entry = 0;
NSString *mAddr = nil;
u_long addr = inet_addr(ip);
int mib[6];
size_t needed;
char *host, *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
extern int h_errno;
struct hostent *hp;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if ((buf = malloc(needed)) == NULL)
err(1, "malloc");
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
err(1, "actual retrieval of routing table");
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
if (addr) {
if (addr != sin->sin_addr.s_addr)
continue;
found_entry = 1;
}
if (nflag == 0)
hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
sizeof sin->sin_addr, AF_INET);
else
hp = 0;
if (hp)
host = hp->h_name;
else {
host = "?";
if (h_errno == TRY_AGAIN)
nflag = 1;
}
if (sdl->sdl_alen) {
u_char *cp = LLADDR(sdl);
mAddr = [NSString stringWithFormat:#"%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]];
// ether_print((u_char *)LLADDR(sdl));
}
else
mAddr = nil;
}
if (found_entry == 0) {
return nil;
} else {
return mAddr;
}
}
#end
Then import the MacFinder.h file in your ViewController
Example how to use it for each host you want to find the MAC Address:
MacFinder *mc = [[MacFinder alloc]init];
NSString *mac = [mc ip2mac:"192.168.10.24"];
NSLog(#"Mac:%#",mac);
If you still having trouble here is tutorial and here the full working project (Including the necessary files)
Related
When I have the following C source code, which is running on an IBM i Midrange, then I get a non-zero result from pthread_create, specifically 3025, which is ENOENT (No such path or directory), which doesn't make any sense to me. Anyone have any thoughts on what the error actually means in this context.
#define _MULTI_THREADED
#define _XOPEN_SOURCE 520
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
void* workerThread(void* parm) {
// Do some work here
pthread_exit(NULL);
}
int main(int argc, char* argv[]) {
pthread_t t;
int rc;
rc = pthread_create(&t, NULL, workerThread, NULL);
if (rc != 0) {
char *msg = strerror(errno);
perror("pthread_create failed");
}
// Other code here
return 0;
}
pthread_create doesn't set errno. You should be checking strerror of rc.
http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_create.html
char *msg = strerror(rc);
Lets say I have two different active network cards (A and B) on my system and also know their network interfaces information.
How would you connect to Card A for instance using FreePascal?
I just compiled it and executed it, it seems to work. You just need to change the IP addresses and ports and add more error checking.
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#define MY_PORT 8564
#define THEIR_PORT 8090
int main()
{
int sockfd;
struct sockaddr_in myaddr;
struct sockaddr_in theiraddr;
int res;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&myaddr, 0, sizeof(struct sockaddr_in));
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons((unsigned short)MY_PORT);
//myaddr.sin_addr = INADDR_ANY; //for any interface
res = inet_pton(AF_INET, "127.0.0.1", &myaddr.sin_addr);
if (1 == res)
{
res = bind(sockfd, (const struct sockaddr *)&myaddr, sizeof(struct sockaddr_in));
if (0 == res)
{
printf("PASO-1\n");
theiraddr.sin_family = AF_INET;
theiraddr.sin_port = htons((unsigned short)THEIR_PORT);
inet_pton(AF_INET, "10.0.2.78", &theiraddr.sin_addr);
printf("PASO-2\n");
connect(sockfd, (const struct sockaddr *)&theiraddr, sizeof(struct sockaddr_in));
}
}
return 0;
}
I got the D-Bus server.c and client.c code, and made some modification.
I want the result that when type for example "hi" from client.c
server will print "receive message hi", and reply "reply_content!!!!!!" to client.c
But it seems that now client.c cannot get the reply message.
Anyone have the idea?
Thanks in advance.
"server.c"
/* server.c */
#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
static DBusHandlerResult
filter_func(DBusConnection *connection, DBusMessage *message, void *usr_data)
{
DBusMessage *reply;
dbus_bool_t handled = false;
char *word = NULL;
DBusError dberr;
dbus_error_init(&dberr);
dbus_message_get_args(message, &dberr, DBUS_TYPE_STRING, &word, DBUS_TYPE_INVALID);
printf("receive message: %s\n", word);
handled = true;
reply = dbus_message_new_method_return(message);
char * reply_content = "reply_content!!!!!!";
dbus_message_append_args(reply, DBUS_TYPE_STRING, &reply_content, DBUS_TYPE_INVALID);
dbus_connection_send(connection, reply, NULL);
dbus_connection_flush(connection);
dbus_message_unref(reply);
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
int main(int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
dbus_error_init(&dberr);
dbconn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);
if (!dbus_connection_add_filter(dbconn, filter_func, NULL, NULL)) {
return -1;
}
dbus_bus_add_match(dbconn, "type='signal',interface='client.signal.Type'", &dberr);
while(dbus_connection_read_write_dispatch(dbconn, -1)) {
/* loop */
}
return 0;
}
Here is client.c
#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
static DBusHandlerResult
filter_func(DBusConnection *connection, DBusMessage *message, void *usr_data)
{
dbus_bool_t handled = false;
char *word = NULL;
DBusError dberr;
dbus_error_init(&dberr);
dbus_message_get_args(message, &dberr, DBUS_TYPE_STRING, &word, DBUS_TYPE_INVALID);
printf("receive message %s\n", word);
handled = true;
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
int db_send(DBusConnection *dbconn)
{
DBusMessage *dbmsg;
char *word = (char *)malloc(sizeof(char));
int i;
dbmsg = dbus_message_new_signal("/client/signal/Object", "client.signal.Type", "Test");
scanf("%s", word);
if (!dbus_message_append_args(dbmsg, DBUS_TYPE_STRING, &word, DBUS_TYPE_INVALID)) {
return -1;
}
if (!dbus_connection_send(dbconn, dbmsg, NULL)) {
return -1;
}
dbus_connection_flush(dbconn);
printf("send message %s\n", word);
dbus_message_unref(dbmsg);
return 0;
}
int main(int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
dbus_error_init(&dberr);
dbconn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);
if (!dbus_connection_add_filter(dbconn, filter_func, NULL, NULL)) {
return -1;
}
db_send(dbconn);
while(dbus_connection_read_write_dispatch(dbconn, -1)) {
db_send(dbconn);
}
dbus_connection_unref(dbconn);
return 0;
}
You're communicating only with signals at the moment, which don't have a return value.
In client.c, use dbus_message_new_method_call instead of dbus_message_new_signal, and in server.c you probably have to change type='signal' to type='method_call'.
So I am getting started with SCTP and have written the basics of the SCTP server application(which I intend to modify to make it a peer-to-peer app). The code is incomplete but I compiled and ran it to test the socket options and the first setsockopt returns error 10042(protocol not supported). I have determined that it's the first call of setsockopt() that returns an error. So here is the incomplete code:
#include "stdafx.h"
#include <iostream>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <WS2spi.h>
#include <ws2sctp.h>
#include <wsipv6ok.h>
#include <if.h>
#include "ws2isatap.h"
#include "if_tunnel.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "sctpsp.lib")
using namespace std;
using namespace System;
static int LISTENQ = 5;
void isatap_enable(void);
int main(int argc, char* argv[]){
WSADATA wsaData;
int iResult;
int optv = 10;
u_long imode = 1;
bool connected = false;
char *optval = (char*)&optv;
int optlen = sizeof(optval);
sockaddr_in6 servAddr;
sctp_sndrcvinfo sr;
sctp_event_subscribe evnts;
sctp_initmsg init;
memset(&sr,0,sizeof(sr));
memset(&evnts,0,sizeof(evnts));
memset(&init,0,sizeof(init));
memset(&servAddr,0,sizeof(servAddr));
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return 1;
}
SOCKET servSock = socket(AF_INET6,SOCK_STREAM,IPPROTO_SCTP);
if(servSock==INVALID_SOCKET){
printf("Socket function failed with error: %d\n",GetLastError());
return 1;
}
if(setsockopt(servSock,IPPROTO_IPV6,IPV6_PROTECTION_LEVEL,optval,sizeof(optval))<0){
printf("setsockopt function failed with error: %d\n", GetLastError());
return 1;
}
u_int servPort = 5000;
servAddr.sin6_family = AF_INET6;
servAddr.sin6_addr = in6addr_any;
servAddr.sin6_port = htons(servPort);
if(setsockopt(servSock,IPPROTO_SCTP,SCTP_EVENTS,(const char*)&evnts,sizeof(evnts)) < 0){
printf("setsockopt function failed with error: %d\n", GetLastError());
return 1;
}
ioctlsocket(servSock,FIONBIO, &imode);
if(bind(servSock,(struct sockaddr*)&servAddr,sizeof(servAddr))<0){
printf("Bind function failed with error: %d\n", GetLastError());
return 1;
}
evnts.sctp_data_io_event = 1;
evnts.sctp_association_event = *(u_char*)optval;
for(;;){
if(listen(servSock,LISTENQ) < 0){
printf("Listen function failed with error: %d/n",GetLastError());
return 1;
}else{
printf("Listening on port %d\n",servPort);
}
}
}
If it's related to python packages nameko/kombu/amqp, then it's reported here Issue with 2.1.4 version.
Temporary soln: Roll-back the version to 2.1.3 till it's fixed.
OK guys, I fixed it(for now lol). What I did is substitute the IPPROTO_IPV6 with IPPROTO_SCTP and it seems to work.
I am trying to use CodeBook method for OpenCV to subtract the background. So far so good, but I am not sure if I can update the codebook for moving objects after some time span, say 5 minutes, I need to update the codebook after which I get lots of moving objects. How do I make sure that after 5 minutes I have a background that needs to be updated?
Thanks for the tips!
kim's algorithm supposedly has a cache layer, i did not dig deep enough into opencv implementation to know how to have a workable version that works with exposure problem.
notes
opencv book(which i havent read) should have the info you need if it's there at all
this is only 1 channel and not in yuv although it can be extended
needs more work on speed/testing (you can of course turn on optimization in compiler)
background subtraction is a buzzy word. try "change detection"
bgfg_cb.h
#ifndef __bgfg_cb_h__
#define __bgfg_cb_h__
//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.148.9778&rep=rep1&type=pdf
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <time.h>
using namespace cv;
using namespace std;
struct codeword {
float min;
float max;
float f;
float l;
int first;
int last;
bool isStale;
};
extern int alpha ;
extern float beta ;
extern int Tdel ,Tadd , Th;
void initializeCodebook(int w,int h);
void update_cb(Mat& frame);
void fg_cb(Mat& frame,Mat& fg);
#endif
bgfg_cb.cpp
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <time.h>
#include "bgfg_cb.h"
using namespace cv;
using namespace std;
vector<codeword> **cbMain;
vector<codeword> **cbCache;
int t=0;
int alpha = 10;//knob
float beta =1;
int Tdel = 200,Tadd = 150, Th= 200;//knobs
void initializeCodebook(int w,int h)
{
cbMain = new vector<codeword>*[w];
for(int i = 0; i < w; ++i)
cbMain[i] = new vector<codeword>[h];
cbCache = new vector<codeword>*[w];
for(int i = 0; i < w; ++i)
cbCache[i] = new vector<codeword>[h];
}
void update_cb(Mat& frame)
{
if(t>10) return;
for(int i=0;i<frame.rows;i++)
{
for(int j=0;j<frame.cols;j++)
{
int pix = frame.at<uchar>(i,j);
vector<codeword>& cm =cbMain[i][j];
bool found = false;
for(int k=0;k<cm.size();k++)
{
if(cm[k].min<=pix && pix<=cm[k].max && !found)
{
found=true;
cm[k].min = ((pix-alpha)+(cm[k].f*cm[k].min))/(cm[k].f+1);
cm[k].max = ((pix+alpha)+(cm[k].f*cm[k].max))/(cm[k].f+1);
cm[k].l=0;
cm[k].last=t;
cm[k].f++;
}else
{
cm[k].l++;
}
}
if(!found)
{
codeword n={};
n.min=max(0,pix-alpha);
n.max=min(255,pix+alpha);
n.f=1;
n.l=0;
n.first=t;
n.last=t;
cm.push_back(n);
}
}
}
t++;
}
void fg_cb(Mat& frame,Mat& fg)
{
fg=Mat::zeros(frame.size(),CV_8UC1);
if(cbMain==0) initializeCodebook(frame.rows,frame.cols);
if(t<10)
{
update_cb(frame);
return;
}
for(int i=0;i<frame.rows;i++)
{
for(int j=0;j<frame.cols;j++)
{
int pix = frame.at<uchar>(i,j);
vector<codeword>& cm = cbMain[i][j];
bool found = false;
for(int k=0;k<cm.size();k++)
{
if(cm[k].min<=pix && pix<=cm[k].max && !found)
{
cm[k].min = ((1-beta)*(pix-alpha)) + (beta*cm[k].min);
cm[k].max = ((1-beta)*(pix+alpha)) + (beta*cm[k].max);
cm[k].l=0;
cm[k].first=t;
cm[k].f++;
found=true;
}else
{
cm[k].l++;
}
}
cm.erase( remove_if(cm.begin(), cm.end(), [](codeword& c) { return c.l>=Tdel;} ), cm.end() );
fg.at<uchar>(i,j) = found?0:255;
if(found) continue;
found = false;
vector<codeword>& cc = cbCache[i][j];
for(int k=0;k<cc.size();k++)
{
if(cc[k].min<=pix && pix<=cc[k].max && !found)
{
cc[k].min = ((1-beta)*(pix-alpha)) + (beta*cc[k].min);
cc[k].max = ((1-beta)*(pix+alpha)) + (beta*cc[k].max);
cc[k].l=0;
cc[k].first=t;
cc[k].f++;
found=true;
}else
{
cc[k].l++;
}
}
if(!found)
{
codeword n={};
n.min=max(0,pix-alpha);
n.max=min(255,pix+alpha);
n.f=1;
n.l=0;
n.first=t;
n.last=t;
cc.push_back(n);
}
cc.erase( remove_if(cc.begin(), cc.end(), [](codeword& c) { return c.l>=Th;} ), cc.end() );
for(vector<codeword>::iterator it=cc.begin();it!=cc.end();it++)
{
if(it->f>Tadd)
{
cm.push_back(*it);
}
}
cc.erase( remove_if(cc.begin(), cc.end(), [](codeword& c) { return c.f>Tadd;} ), cc.end() );
}
}
}
main.cpp
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "bgfg_cb.h"
#include <iostream>
using namespace cv;
using namespace std;
void proc()
{
Mat frame,fg,gray;
VideoCapture cap("C:/Downloads/S2_L1.tar/S2_L1/Crowd_PETS09/S2/L1/Time_12-34/View_001/frame_%04d.jpg");
cap >> frame;
initializeCodebook(frame.rows,frame.cols);
for(;;)
{
cap>>frame;
cvtColor(frame,gray,CV_BGR2GRAY);
fg_cb(gray,fg);
Mat cc;
imshow("fg",fg);
waitKey(1);
}
}
int main(int argc, char ** argv)
{
proc();
cin.ignore(1);
return 0;
}