Browse Source

Added Windows stub support for autodetection.

git-svn-id: https://bucket.mit.edu/svn/nilm/acquisition/ethstream@7453 ddd99763-3ecb-0310-9145-efcb8ce7c51f
tags/ethstream-1.1
zacharyc 12 years ago
parent
commit
67163dc1a2
2 changed files with 88 additions and 84 deletions
  1. +81
    -84
      nerdjack.c
  2. +7
    -0
      netutil.h

+ 81
- 84
nerdjack.c View File

@@ -13,23 +13,8 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <math.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/wait.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include <net/if.h>
#include <sys/ioctl.h>
#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ(x) sizeof(x)
#endif

#include "netutil.h"
#include "compat.h"
@@ -92,6 +77,10 @@ nerdjack_choose_scan (double desired_rate, double *actual_rate,
return 0;
}

/**
* Create a discovered socket and add it to the socket list structure.
* All sockets in the structure should be created, bound, and ready for broadcasting
*/
static int discovered_sock_create(struct discover_t *ds, uint32_t local_ip, uint32_t subnet_mask)
{
if (ds->sock_count >= MAX_SOCKETS) {
@@ -104,10 +93,6 @@ static int discovered_sock_create(struct discover_t *ds, uint32_t local_ip, uint
return 0;
}

/* Set timeouts. */
//setsocktimeout(sock, SOL_SOCKET, SO_SNDTIMEO, 1000);
//setsocktimeout(sock, SOL_SOCKET, SO_RCVTIMEO, 1000);

/* Allow broadcast. */
int sock_opt = 1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));
@@ -138,7 +123,52 @@ static int discovered_sock_create(struct discover_t *ds, uint32_t local_ip, uint

return 1;
}
/**
* Enumerate all interfaces we can find and open sockets on each
*/
#if defined(USE_IPHLPAPI)
static void enumerate_interfaces(struct discover_t *ds)
{
PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);

DWORD Ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
if (Ret != NO_ERROR) {
free(pAdapterInfo);
if (Ret != ERROR_BUFFER_OVERFLOW) {
return;
}
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
Ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
if (Ret != NO_ERROR) {
free(pAdapterInfo);
return;
}
}

PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter) {
IP_ADDR_STRING *pIPAddr = &pAdapter->IpAddressList;
while (pIPAddr) {
uint32_t local_ip = ntohl(inet_addr(pIPAddr->IpAddress.String));
uint32_t mask = ntohl(inet_addr(pIPAddr->IpMask.String));

if (local_ip == 0) {
pIPAddr = pIPAddr->Next;
continue;
}

discovered_sock_create(ds, local_ip, mask);
pIPAddr = pIPAddr->Next;
}

pAdapter = pAdapter->Next;
}

free(pAdapterInfo);
}

#else
static void enumerate_interfaces(struct discover_t *ds) {
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1) {
@@ -147,7 +177,6 @@ static void enumerate_interfaces(struct discover_t *ds) {

struct ifconf ifc;
uint8_t buf[8192];
//char stringbuffer[INET_ADDRSTRLEN];
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (char *)buf;

@@ -174,10 +203,6 @@ static void enumerate_interfaces(struct discover_t *ds) {
continue;
}

//inet_ntop(AF_INET, &addr_in->sin_addr,
// stringbuffer, INET_ADDRSTRLEN);
//printf("%s\n",stringbuffer);

if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) {
continue;
}
@@ -188,6 +213,21 @@ static void enumerate_interfaces(struct discover_t *ds) {
discovered_sock_create(ds, local_ip, mask);
}
}
#endif
/**
* Close all sockets previously enumerated and free the struct
*/
static void destroy_socks(struct discover_t *ds)
{
unsigned int i;
for (i = 0; i < ds->sock_count; i++) {
struct discovered_socket *dss = &ds->socks[i];
close(dss->sock);
}

free(ds);
}


/* Perform autodetection. Returns 0 on success, -1 on error
* Sets ipAddress to the detected address
@@ -195,51 +235,20 @@ static void enumerate_interfaces(struct discover_t *ds) {
int
nerdjack_detect (char *ipAddress)
{
int32_t sock, receivesock;
int32_t receivesock;
struct sockaddr_in sa, receiveaddr, sFromAddr;
int buffer_length;
char buffer[200];
char incomingData[10];
unsigned int lFromLen;
//char stringbuffer[INET_ADDRSTRLEN];

sprintf (buffer, "TEST");
buffer_length = strlen (buffer) + 1;

net_init ();
struct discover_t *ds = (struct discover_t *)calloc(1, sizeof(struct discover_t));
if (!ds) {
return -1;
}

/* Create a routable socket. */
if (!discovered_sock_create(ds, 0, 0)) {
free(ds);
return -1;
}

/* Detect & create local sockets. */
enumerate_interfaces(ds);
//for(i = 0; i < ds->sock_count; i++) {
//inet_ntop(AF_INET, (struct sockaddr_in *) &ds->socks[i].local_ip,
// stringbuffer, INET_ADDRSTRLEN);
//printf("%s\n",stringbuffer);
//}
//return -1;

//sock = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
receivesock = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);

/* Set nonblocking */
//if (soblock (sock, 0) < 0)
// {
// verb ("can't set nonblocking\n");
// return -1;
// }

/* Set nonblocking */
if (soblock (receivesock, 0) < 0)
{
@@ -247,10 +256,6 @@ nerdjack_detect (char *ipAddress)
return -1;
}


//int opt = 1;
//setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (void *) &opt, sizeof (int));

if (-1 == receivesock) /* if socket failed to initialize, exit */
{
verb ("Error Creating Socket\n");
@@ -265,23 +270,25 @@ nerdjack_detect (char *ipAddress)
receiveaddr.sin_port = htons (NERDJACK_UDP_RECEIVE_PORT);
sa.sin_port = htons (NERDJACK_DATA_PORT);

//Receive from any IP address, Will send to broadcast
//Receive from any IP address
receiveaddr.sin_addr.s_addr = INADDR_ANY;
//sa.sin_addr.s_addr = INADDR_BROADCAST;

bind (receivesock, (struct sockaddr *) &receiveaddr,
sizeof (struct sockaddr_in));
struct discover_t *ds = (struct discover_t *)calloc(1, sizeof(struct discover_t));
if (!ds) {
return -1;
}

//bytes_sent =
// sendto (sock, buffer, buffer_length, 0, (struct sockaddr *) &sa,
// sizeof (struct sockaddr_in));
//if (bytes_sent < 0)
// {
// info ("Error sending packet: %s\n", strerror (errno));
// return -1;
// }
/* Create a routable broadcast socket. */
if (!discovered_sock_create(ds, 0, 0)) {
free(ds);
return -1;
}

//int result = 0;
/* Detect & create local sockets. */
enumerate_interfaces(ds);

/*
* Send subnet broadcast using each local ip socket.
@@ -294,18 +301,9 @@ nerdjack_detect (char *ipAddress)
sa.sin_addr.s_addr = htonl(target_ip);
sendto (dss->sock, buffer, buffer_length, 0, (struct sockaddr *) &sa,
sizeof (struct sockaddr_in));
//result |= hdhomerun_discover_send_internal(ds, dss, target_ip, device_type, device_id);
}

/*
* If no local ip sockets then fall back to sending a global broadcast letting the OS choose the interface.
*/
//if (!result) {
// struct hdhomerun_discover_sock_t *dss = &ds->socks[0];
// result = hdhomerun_discover_send_internal(ds, dss, 0xFFFFFFFF, device_type, device_id);
//}

//return result;
destroy_socks(ds);

lFromLen = sizeof (sFromAddr);

@@ -316,7 +314,7 @@ nerdjack_detect (char *ipAddress)
{
.tv_sec = NERDJACK_TIMEOUT}))
{
close(receivesock);
return -1;
}

@@ -325,7 +323,6 @@ nerdjack_detect (char *ipAddress)
//It isn't ipv6 friendly, but inet_ntop isn't on Windows...
strcpy (ipAddress, inet_ntoa (sFromAddr.sin_addr));

close (sock); /* close the socket */
close (receivesock);
return 0;
}


+ 7
- 0
netutil.h View File

@@ -11,11 +11,18 @@
# define socklen_t int
# define in_addr_t uint32_t
# define in_port_t uint16_t
# include <iphlpapi.h>
# define USE_IPHLPAPI 1
#else
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <net/if.h>
# include <sys/ioctl.h>
#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ(x) sizeof(x)
#endif
#endif

/* Initialize networking */


Loading…
Cancel
Save