Added domain socket handling and transmit.
parent
739b234cc5
commit
476d2149cb
2
Makefile
2
Makefile
|
|
@ -1,5 +1,5 @@
|
||||||
test:
|
test:
|
||||||
gcc main.c if_helper.c -o bin/wipacket -liw
|
gcc main.c if_helper.c -o bin/wipacket
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm wipacket
|
rm wipacket
|
||||||
143
main.c
143
main.c
|
|
@ -1,32 +1,43 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <iwlib.h>
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <linux/if_packet.h>
|
#include <linux/if_packet.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
|
||||||
#include "if_helper.h"
|
#include "if_helper.h"
|
||||||
//#include <linux/if_ether.h>
|
|
||||||
//#include <linux/if_arp.h>
|
|
||||||
|
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
void init();
|
void init();
|
||||||
|
void registerSockets();
|
||||||
void configureInterface();
|
void configureInterface();
|
||||||
void interfaceInfo(int sd, struct ifreq *req);
|
void interfaceInfo(int sd, struct ifreq *req);
|
||||||
void prepeareBroadcastHeader();
|
void prepeareBroadcastHeader();
|
||||||
|
bool transmit(char *payload, size_t len);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
void sigHandler(int s);
|
||||||
|
|
||||||
|
// Domain socket path & descriptor
|
||||||
|
#define SOCKET_PATH "./wipacket.sock"
|
||||||
|
int domainSocket;
|
||||||
|
|
||||||
// Ethernet protocol ID
|
// Ethernet protocol ID
|
||||||
#define PROTOCOL_IDENTIFIER 0x9f77
|
#define PROTOCOL_IDENTIFIER 0x9f77
|
||||||
|
|
||||||
|
// Max payload length
|
||||||
|
#define PAYLOAD_LENGTH 4096
|
||||||
|
|
||||||
// ESSID and frequency for network
|
// ESSID and frequency for network
|
||||||
#define ESSID "wipacket"
|
#define ESSID "wipkt"
|
||||||
#define FREQUENCY 2412
|
#define FREQUENCY 2412
|
||||||
|
|
||||||
// The ethernet broadcast address
|
// The ethernet broadcast address
|
||||||
|
|
@ -34,18 +45,19 @@ const unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
|
|
||||||
// Socket descriptor for network access
|
// Socket descriptor for network access
|
||||||
static int netSocket;
|
static int netSocket;
|
||||||
// Socket for controlling 802.11 hardware
|
|
||||||
static int iwSocket;
|
|
||||||
// Interface name
|
// Interface name
|
||||||
static char *if_name;
|
static char *if_name;
|
||||||
static size_t if_name_len;
|
static size_t if_name_len;
|
||||||
// Interface index of selected interface
|
// Interface index of selected interface
|
||||||
static int if_index;
|
static int if_index;
|
||||||
// Hardware (MAC) address of selected interface
|
// 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
|
// A sockaddr_ll struct for creating frame headers
|
||||||
static struct sockaddr_ll broadcast = {0};
|
static struct sockaddr_ll broadcast = {0};
|
||||||
|
|
||||||
|
// Whether to keep running
|
||||||
|
bool run = true;
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
// Get interface name from command line argument
|
// Get interface name from command line argument
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
|
@ -58,12 +70,54 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
init();
|
init();
|
||||||
configureInterface();
|
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();
|
cleanup();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
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
|
// Open raw AF_PACKET socket
|
||||||
netSocket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
netSocket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||||
|
|
||||||
|
|
@ -72,13 +126,6 @@ void init() {
|
||||||
exit(1);
|
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
|
// Get info for selected interface
|
||||||
struct ifreq interfaceRequest;
|
struct ifreq interfaceRequest;
|
||||||
size_t max_if_name_len = sizeof(interfaceRequest.ifr_name);
|
size_t max_if_name_len = sizeof(interfaceRequest.ifr_name);
|
||||||
|
|
@ -101,6 +148,57 @@ void init() {
|
||||||
prepeareBroadcastHeader();
|
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) {
|
void interfaceInfo(int sd, struct ifreq *req) {
|
||||||
// Query for interface index
|
// Query for interface index
|
||||||
if (ioctl(sd, SIOCGIFINDEX, req)==-1) {
|
if (ioctl(sd, SIOCGIFINDEX, req)==-1) {
|
||||||
|
|
@ -114,7 +212,8 @@ void interfaceInfo(int sd, struct ifreq *req) {
|
||||||
printf("%s\n", strerror(errno));
|
printf("%s\n", strerror(errno));
|
||||||
exit(1);
|
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() {
|
void prepeareBroadcastHeader() {
|
||||||
|
|
@ -136,5 +235,13 @@ void configureInterface() {
|
||||||
|
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
close(netSocket);
|
close(netSocket);
|
||||||
close(iwSocket);
|
close(domainSocket);
|
||||||
|
unlink(SOCKET_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sigHandler(int s) {
|
||||||
|
if (s==2) {
|
||||||
|
printf("\nCaught SIGINT, exiting...\n");
|
||||||
|
run = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue