summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHåkon Nessjøen <haakon.nessjoen@gmail.com>2010-11-03 02:49:33 +0100
committerHåkon Nessjøen <haakon.nessjoen@gmail.com>2010-11-03 02:49:33 +0100
commit3103d2c9c237101abf143dd19e9998a426c0d9ec (patch)
treedd5fdeeb4a36feb1ffb911a184b09173698d8eb6
parent40362c46806d033316e859db772f46c5652fbea3 (diff)
downloadMAC-Telnet-3103d2c9c237101abf143dd19e9998a426c0d9ec.tar.gz
MAC-Telnet-3103d2c9c237101abf143dd19e9998a426c0d9ec.zip
Started code for auto-detecting interface. Working proof of concept version. Raw socket version not updated yet.
-rw-r--r--devices.c46
-rw-r--r--devices.h1
-rw-r--r--mactelnet.c144
3 files changed, 131 insertions, 60 deletions
diff --git a/devices.c b/devices.c
index c380ead..bb1822d 100644
--- a/devices.c
+++ b/devices.c
@@ -19,13 +19,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <malloc.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <sys/ioctl.h>
#include <net/if.h>
+#include <malloc.h>
+#include <ifaddrs.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netpacket/packet.h>
+#include <netinet/in.h>
+
+
/* Functions using NETDEVICE api */
int getDeviceIndex(int sockfd, unsigned char *deviceName) {
@@ -98,3 +105,40 @@ int getDeviceIp(const int sockfd, const unsigned char *deviceName, struct sockad
free(ifr);
return -1;
}
+
+int getIps(char *name, int nameLen, struct sockaddr_in *ip) {
+ static int first = 1;
+ static struct ifaddrs *int_addrs;
+ static const struct ifaddrs *int_cursor;
+ const struct sockaddr_in *dlAddr;
+
+ if (first == 1) {
+ first = 0;
+ if (getifaddrs(&int_addrs) == 0) {
+ int_cursor = int_addrs;
+ } else {
+ first = 1;
+ return 0;
+ }
+ }
+ if (int_cursor != NULL) {
+ while (int_cursor != NULL) {
+ dlAddr = (const struct sockaddr_in *) int_cursor->ifa_addr;
+ if (dlAddr->sin_family == AF_INET) {
+ memcpy(ip, dlAddr, sizeof(struct sockaddr_in));
+ strncpy(name, int_cursor->ifa_name, nameLen - 1);
+ name[nameLen - 1] = '\0';
+ int_cursor = int_cursor->ifa_next;
+ return 1;
+ }
+ int_cursor = int_cursor->ifa_next;
+ }
+ }
+ if (int_cursor == NULL) {
+ if (int_addrs != NULL) {
+ freeifaddrs(int_addrs);
+ int_addrs = NULL;
+ }
+ return 0;
+ }
+}
diff --git a/devices.h b/devices.h
index e2c260c..ab83821 100644
--- a/devices.h
+++ b/devices.h
@@ -1,3 +1,4 @@
extern int getDeviceIndex(int sockfd, unsigned char *deviceName);
extern int getDeviceMAC(const int sockfd, const unsigned char *deviceName, unsigned char *mac);
extern int getDeviceIp(const int sockfd, const unsigned char *deviceName, struct sockaddr_in *ip);
+int getIps(char *name, int nameLen, struct sockaddr_in *ip);
diff --git a/mactelnet.c b/mactelnet.c
index 2175d65..762d7b5 100644
--- a/mactelnet.c
+++ b/mactelnet.c
@@ -37,6 +37,7 @@
#include "console.h"
#include "devices.h"
#include "config.h"
+#include "mactelnet.h"
int sockfd;
int insockfd;
@@ -56,6 +57,8 @@ struct in_addr sourceip;
struct in_addr destip;
int sourceport;
+int connect_timeout = CONNECT_TIMEOUT;
+
unsigned char encryptionkey[128];
unsigned char username[255];
unsigned char password[255];
@@ -63,6 +66,8 @@ unsigned char password[255];
/* Protocol data direction */
unsigned char mt_direction_fromserver = 0;
+unsigned int sendSocket;
+
int sendUDP(struct mt_packet *packet) {
if (broadcastMode) {
@@ -72,7 +77,7 @@ int sendUDP(struct mt_packet *packet) {
socket_address.sin_port = htons(MT_MACTELNET_PORT);
socket_address.sin_addr.s_addr = htonl(INADDR_BROADCAST);
- return sendto(insockfd, packet->data, packet->size, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
+ return sendto(sendSocket, packet->data, packet->size, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
} else {
return sendCustomUDP(sockfd, deviceIndex, srcmac, dstmac, &sourceip, sourceport, &destip, MT_MACTELNET_PORT, packet->data, packet->size);
}
@@ -228,6 +233,63 @@ void handlePacket(unsigned char *data, int data_len) {
}
}
+int findInterface() {
+ struct mt_packet data;
+ struct sockaddr_in myip;
+ int success;
+ unsigned char devicename[128];
+ int testsocket;
+ fd_set read_fds;
+ struct timeval timeout;
+ int optval = 1;
+ int i,ii, selected;
+
+ while (success = getIps(devicename, 128, &myip)) {
+ char str[INET_ADDRSTRLEN];
+
+ inet_ntop(AF_INET, &(myip.sin_addr), str, INET_ADDRSTRLEN);
+
+ /* Initialize receiving socket on the device chosen */
+ myip.sin_port = htons(sourceport);
+
+ /* Bind to udp port */
+ if ((testsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ continue;
+ }
+
+ setsockopt(testsocket, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval));
+ setsockopt(testsocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+
+ if (bind(testsocket, (struct sockaddr *)&myip, sizeof(struct sockaddr_in)) == -1) {
+ close(testsocket);
+ continue;
+ }
+
+ if (getDeviceMAC(testsocket, devicename, srcmac) < 0) {
+ close(testsocket);
+ continue;
+ }
+
+ sendSocket = testsocket;
+ initPacket(&data, MT_PTYPE_SESSIONSTART, srcmac, dstmac, sessionkey, 0);
+ sendUDP(&data);
+
+ timeout.tv_sec = connect_timeout;
+ timeout.tv_usec = 0;
+
+ FD_ZERO(&read_fds);
+ FD_SET(insockfd, &read_fds);
+ select(insockfd + 1, &read_fds, NULL, NULL, &timeout);
+ if (FD_ISSET(insockfd, &read_fds)) {
+ return 1;
+ }
+
+ close(testsocket);
+ }
+
+ return 0;
+}
+
/*
* TODO: Rewrite main() when all sub-functionality is tested
*/
@@ -243,9 +305,10 @@ int main (int argc, char **argv) {
unsigned char devicename[30];
unsigned char printHelp = 0, haveUsername = 0, havePassword = 0;
int c;
+ int optval = 1;
while (1) {
- c = getopt(argc, argv, "nu:p:h?");
+ c = getopt(argc, argv, "nt:u:p:h?");
if (c == -1)
break;
@@ -270,6 +333,10 @@ int main (int argc, char **argv) {
havePassword = 1;
break;
+ case 't':
+ connect_timeout = atoi(optarg);
+ break;
+
case 'h':
case '?':
printHelp = 1;
@@ -277,8 +344,8 @@ int main (int argc, char **argv) {
}
}
- if (argc - optind < 2 || printHelp) {
- fprintf(stderr, "Usage: %s <ifname> <MAC|identity> [-h] [-n] [-u <username>] [-p <password>]\n", argv[0]);
+ if (argc - optind < 1 || printHelp) {
+ fprintf(stderr, "Usage: %s <MAC|identity> [-h] [-n] [-t <timeout>] [-u <username>] [-p <password>]\n", argv[0]);
if (printHelp) {
fprintf(stderr, "\nParameters:\n");
@@ -286,6 +353,7 @@ int main (int argc, char **argv) {
fprintf(stderr, " MAC MAC-Address of the RouterOS device. Use mndp to discover them.\n");
fprintf(stderr, " identity The identity/name of your RouterOS device. Uses MNDP protocol to find it.\n");
fprintf(stderr, " -n Do not use broadcast packets. Less insecure but requires root privileges.\n");
+ fprintf(stderr, " -t Amount of seconds to wait for a response on each interface.\n");
fprintf(stderr, " -u Specify username on command line.\n");
fprintf(stderr, " -p Specify password on command line.\n");
fprintf(stderr, " -h This help.\n");
@@ -294,10 +362,6 @@ int main (int argc, char **argv) {
return 1;
}
- /* Save device name */
- strncpy(devicename, argv[optind++], sizeof(devicename) - 1);
- devicename[sizeof(devicename) - 1] = '\0';
-
/* Seed randomizer */
srand(time(NULL));
@@ -323,36 +387,14 @@ int main (int argc, char **argv) {
}
if (broadcastMode) {
- int optval = 1;
if (setsockopt(insockfd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval))==-1) {
perror("SO_BROADCAST");
return 1;
}
}
- /* Find device index number for specified interface */
- deviceIndex = getDeviceIndex(insockfd, devicename);
- if (deviceIndex < 0) {
- fprintf(stderr, "Device %s not found.\n", devicename);
- return 1;
- }
-
- /*
- * We want to show who we are (ip), even though the server only cares
- * about it's own MAC address in the headers.
- */
- result = getDeviceIp(insockfd, devicename, &si_me);
- if (result < 0) {
- fprintf(stderr, "Cannot determine IP of device %s\n", devicename);
- return 1;
- }
-
- /* Determine source mac address */
- result = getDeviceMAC(insockfd, devicename, srcmac);
- if (result < 0) {
- fprintf(stderr, "Cannot determine MAC address of device %s\n", devicename);
- return 1;
- }
+ /* Need to use, to be able to autodetect which interface to use */
+ setsockopt(insockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval));
/* Check for identity name or mac address */
{
@@ -369,12 +411,12 @@ int main (int argc, char **argv) {
/* Search for Router by identity name, using MNDP */
if (!queryMNDP(argv[optind], dstmac)) {
- fprintf(stderr, "not found.\n");
+ fprintf(stderr, "not found\n");
return 1;
}
/* Router found, display mac and continue */
- fprintf(stderr, "%s\n", ether_ntoa((struct ether_addr *)dstmac));
+ fprintf(stderr, "found\n");
} else {
/* Convert mac address string to ether_addr struct */
@@ -408,17 +450,6 @@ int main (int argc, char **argv) {
inet_pton(AF_INET, (char *)"255.255.255.255", &destip);
memcpy(&sourceip, &(si_me.sin_addr), 4);
- /* Initialize receiving socket on the device chosen */
- memset((char *) &si_me, 0, sizeof(si_me));
- si_me.sin_family = AF_INET;
- si_me.sin_port = htons(sourceport);
-
- /* Bind to udp port */
- if (bind(insockfd, (struct sockaddr *)&si_me, sizeof(si_me)) == -1) {
- fprintf(stderr, "Error binding to %s:%d, %s\n", inet_ntoa(si_me.sin_addr), sourceport, strerror(errno));
- return 1;
- }
-
/* Sessioon key */
sessionkey = rand() % 65535;
@@ -427,23 +458,18 @@ int main (int argc, char **argv) {
printf("Connecting to %s...", ether_ntoa((struct ether_addr *)dstmac));
- plen = initPacket(&data, MT_PTYPE_SESSIONSTART, srcmac, dstmac, sessionkey, 0);
- result = sendUDP(&data);
-
- /* Try to connect with a timeout */
- FD_ZERO(&read_fds);
- FD_SET(insockfd, &read_fds);
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- select(insockfd+1, &read_fds, NULL, NULL, &timeout);
+ /* Initialize receiving socket on the device chosen */
+ memset((char *) &si_me, 0, sizeof(si_me));
+ si_me.sin_family = AF_INET;
+ si_me.sin_port = htons(sourceport);
- if (!FD_ISSET(insockfd, &read_fds)) {
- fprintf(stderr, "Connection timed out\n");
- exit(1);
+ /* Bind to udp port */
+ if (bind(insockfd, (struct sockaddr *)&si_me, sizeof(si_me)) == -1) {
+ fprintf(stderr, "Error binding to %s:%d, %s\n", inet_ntoa(si_me.sin_addr), sourceport, strerror(errno));
+ return 1;
}
- result = recvfrom(insockfd, buff, 1400, 0, 0, 0);
- if (result < 1) {
+ if (!findInterface() || recvfrom(insockfd, buff, 1400, 0, 0, 0) < 1) {
fprintf(stderr, "Connection failed.\n");
return 1;
}