Added domain socket handling and transmit.

master
Mark Qvist 2014-05-24 18:34:12 +02:00
parent 739b234cc5
commit 476d2149cb
2 changed files with 126 additions and 19 deletions

View File

@ -1,5 +1,5 @@
test:
gcc main.c if_helper.c -o bin/wipacket -liw
gcc main.c if_helper.c -o bin/wipacket
clean:
rm wipacket

143
main.c
View File

@ -1,32 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <iwlib.h>
#include <sys/un.h>
#include <signal.h>
#include <unistd.h>
#include <net/ethernet.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include "if_helper.h"
//#include <linux/if_ether.h>
//#include <linux/if_arp.h>
// Forward declarations
void init();
void registerSockets();
void configureInterface();
void interfaceInfo(int sd, struct ifreq *req);
void prepeareBroadcastHeader();
bool transmit(char *payload, size_t len);
void cleanup();
void sigHandler(int s);
// Domain socket path & descriptor
#define SOCKET_PATH "./wipacket.sock"
int domainSocket;
// Ethernet protocol ID
#define PROTOCOL_IDENTIFIER 0x9f77
// Max payload length
#define PAYLOAD_LENGTH 4096
// ESSID and frequency for network
#define ESSID "wipacket"
#define ESSID "wipkt"
#define FREQUENCY 2412
// The ethernet broadcast address
@ -34,18 +45,19 @@ const unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
// Socket descriptor for network access
static int netSocket;
// Socket for controlling 802.11 hardware
static int iwSocket;
// Interface name
static char *if_name;
static size_t if_name_len;
// Interface index of selected interface
static int if_index;
// Hardware (MAC) address of selected interface
static unsigned char *hw_addr;
static unsigned char hw_addr[ETHER_ADDR_LEN];
// A sockaddr_ll struct for creating frame headers
static struct sockaddr_ll broadcast = {0};
// Whether to keep running
bool run = true;
int main(int argc, char **argv) {
// Get interface name from command line argument
if (argc > 1) {
@ -58,12 +70,54 @@ int main(int argc, char **argv) {
init();
configureInterface();
registerSockets();
char incomingBuffer[PAYLOAD_LENGTH];
while (run) {
int connection;
struct sockaddr_un remote;
int structLen = sizeof(remote);
printf("Waiting for connection...\n");
connection = accept(domainSocket, (struct sockaddr*)&remote, &structLen);
if (connection == -1) {
if (run) printf("Error while accepting client connection\n");
cleanup();
exit(1);
} else {
printf("Accepted client connection\n");
int readLength = 0;
bool connectionOk = true;
while (connectionOk) {
readLength = recv(connection, incomingBuffer, PAYLOAD_LENGTH, 0);
if (readLength < 0) {
printf("Error while reading from client\n");
connectionOk = false;
} else {
if (readLength > 0) {
transmit(incomingBuffer, readLength);
}
if (readLength == 0) {
printf("Client disconnect\n");
connectionOk = false;
}
}
}
}
}
cleanup();
exit(0);
}
void init() {
// Register signal handler
struct sigaction handler;
handler.sa_handler = sigHandler;
sigemptyset(&handler.sa_mask);
handler.sa_flags = 0;
sigaction(SIGINT, &handler, NULL);
// Open raw AF_PACKET socket
netSocket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
@ -72,13 +126,6 @@ void init() {
exit(1);
}
// Open iw control socket
iwSocket = iw_sockets_open();
if (iwSocket == -1) {
printf("Error creating hardware control socket\n");
exit(1);
}
// Get info for selected interface
struct ifreq interfaceRequest;
size_t max_if_name_len = sizeof(interfaceRequest.ifr_name);
@ -101,6 +148,57 @@ void init() {
prepeareBroadcastHeader();
}
void registerSockets() {
struct sockaddr_un local;
int len;
domainSocket = socket(AF_UNIX, SOCK_STREAM, 0);
if (domainSocket == -1) {
printf("Could not create domain socket\n");
cleanup();
exit(1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCKET_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(domainSocket, (struct sockaddr *)&local, len) == -1) {
printf("Could not bind to domain socket\n");
cleanup();
exit(1);
}
if (listen(domainSocket, 1) == -1) {
printf("Unable to start listening on domain socket\n");
cleanup();
exit(1);
}
}
bool transmit(char *payload, size_t len) {
size_t frameLen = len+2*ETHER_ADDR_LEN+2;
char *buffer = malloc(frameLen);
memcpy(buffer, broadcast_addr, ETHER_ADDR_LEN);
memcpy(buffer+ETHER_ADDR_LEN, &hw_addr, ETHER_ADDR_LEN);
memcpy(buffer+ETHER_ADDR_LEN*2+2, payload, len);
memcpy(buffer+ETHER_ADDR_LEN*2, &broadcast.sll_protocol, 2);
int result = sendto(netSocket, buffer, frameLen, 0, (struct sockaddr*)&broadcast, sizeof(broadcast));
free(buffer);
if (result == -1) {
return false;
} else {
return true;
}
}
void interfaceInfo(int sd, struct ifreq *req) {
// Query for interface index
if (ioctl(sd, SIOCGIFINDEX, req)==-1) {
@ -114,7 +212,8 @@ void interfaceInfo(int sd, struct ifreq *req) {
printf("%s\n", strerror(errno));
exit(1);
}
hw_addr = (unsigned char *)req->ifr_hwaddr.sa_data;
unsigned char *mac = (unsigned char *)req->ifr_hwaddr.sa_data;
memcpy(hw_addr, mac, ETHER_ADDR_LEN);
}
void prepeareBroadcastHeader() {
@ -136,5 +235,13 @@ void configureInterface() {
void cleanup() {
close(netSocket);
close(iwSocket);
close(domainSocket);
unlink(SOCKET_PATH);
}
void sigHandler(int s) {
if (s==2) {
printf("\nCaught SIGINT, exiting...\n");
run = false;
}
}