diff options
Diffstat (limited to 'mactelnetd.c')
-rw-r--r-- | mactelnetd.c | 223 |
1 files changed, 115 insertions, 108 deletions
diff --git a/mactelnetd.c b/mactelnetd.c index ed9c3f9..9e88679 100644 --- a/mactelnetd.c +++ b/mactelnetd.c @@ -35,7 +35,11 @@ #include <sys/types.h> #include <sys/socket.h> #include <string.h> +#ifdef __linux__ #include <linux/if_ether.h> +#else +#include <sys/time.h> +#endif #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/sysinfo.h> @@ -45,9 +49,8 @@ #include <sys/utsname.h> #include "md5.h" #include "protocol.h" -#include "udp.h" #include "console.h" -#include "devices.h" +#include "interfaces.h" #include "users.h" #include "config.h" @@ -61,22 +64,13 @@ /* Max ~5 pings per second */ #define MT_MAXPPS MT_MNDP_BROADCAST_INTERVAL * 5 -struct mt_socket { - unsigned char ip[4]; - unsigned char mac[ETH_ALEN]; - char name[MT_INTERFACE_LEN]; - int sockfd; - int device_index; -}; - static int sockfd; static int insockfd; static int mndpsockfd; static int pings = 0; -static struct mt_socket sockets[MAX_INSOCKETS]; -static int sockets_count = 0; +struct net_interface interfaces[MAX_INTERFACES]; static int use_raw_socket = 0; @@ -101,7 +95,7 @@ enum mt_connection_state { /** Connection struct */ struct mt_connection { - struct mt_socket *socket; + struct net_interface *interface; unsigned short seskey; unsigned int incounter; unsigned int outcounter; @@ -117,10 +111,10 @@ struct mt_connection { char username[30]; unsigned char trypassword[17]; - unsigned char srcip[4]; - unsigned char srcmac[6]; + unsigned char srcip[IPV4_ALEN]; + unsigned char srcmac[ETH_ALEN]; unsigned short srcport; - unsigned char dstmac[6]; + unsigned char dstmac[ETH_ALEN]; unsigned char enckey[16]; unsigned short terminal_width; unsigned short terminal_height; @@ -187,7 +181,7 @@ static struct mt_connection *list_find_connection(unsigned short seskey, unsigne } for (p = connections_head; p != NULL; p = p->next) { - if (p->seskey == seskey && memcmp(srcmac, p->srcmac, 6) == 0) { + if (p->seskey == seskey && memcmp(srcmac, p->srcmac, ETH_ALEN) == 0) { return p; } } @@ -198,8 +192,8 @@ static struct mt_connection *list_find_connection(unsigned short seskey, unsigne static int find_socket(unsigned char *mac) { int i; - for (i = 0; i < sockets_count; ++i) { - if (memcmp(mac, sockets[i].mac, ETH_ALEN) == 0) { + for (i = 0; i < MAX_INTERFACES; ++i) { + if (interfaces[i].in_use && memcmp(mac, interfaces[i].mac_addr, ETH_ALEN) == 0) { return i; } } @@ -207,60 +201,51 @@ static int find_socket(unsigned char *mac) { } static void setup_sockets() { - struct sockaddr_in myip; - char devicename[MT_INTERFACE_LEN]; - unsigned char mac[ETH_ALEN]; unsigned char emptymac[ETH_ALEN]; - int success; + int i; - memset(emptymac, 0, ETH_ALEN); + bzero(emptymac, ETH_ALEN); - while ((success = get_macs(insockfd, devicename, MT_INTERFACE_LEN, mac))) { - if (memcmp(mac, emptymac, ETH_ALEN) != 0 && find_socket(mac) < 0) { - int optval = 1; - struct sockaddr_in si_me; - struct mt_socket *mysocket = &(sockets[sockets_count]); + if (net_get_interfaces(interfaces, MAX_INTERFACES) <= 0) { + fprintf(stderr, "Error: No suitable devices found\n"); + exit(1); + } - memcpy(mysocket->mac, mac, ETH_ALEN); - strncpy(mysocket->name, devicename, MT_INTERFACE_LEN - 1); - mysocket->name[MT_INTERFACE_LEN - 1] = '\0'; + for (i = 0; i < MAX_INTERFACES; ++i) { + if (interfaces[i].in_use == 0 || memcmp(interfaces[i].mac_addr, emptymac, ETH_ALEN) == 0) { + continue; + } - if (get_device_ip(insockfd, devicename, &myip) > 0) { + int optval = 1; + struct sockaddr_in si_me; - mysocket->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (mysocket->sockfd < 0) { - close(mysocket->sockfd); - continue; - } + interfaces[i].socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (interfaces[i].socketfd < 0) { + continue; + } - if (setsockopt(mysocket->sockfd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval))==-1) { - perror("SO_BROADCAST"); - continue; - } + if (setsockopt(interfaces[i].socketfd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval))==-1) { + perror("SO_BROADCAST"); + continue; + } - setsockopt(mysocket->sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + setsockopt(interfaces[i].socketfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); - /* Initialize receiving socket on the device chosen */ - si_me.sin_family = AF_INET; - si_me.sin_port = htons(MT_MACTELNET_PORT); - memcpy(&(si_me.sin_addr), &(myip.sin_addr), 4); + /* Initialize receiving socket on the device chosen */ + si_me.sin_family = AF_INET; + si_me.sin_port = htons(MT_MACTELNET_PORT); + memcpy(&(si_me.sin_addr.s_addr), interfaces[i].ipv4_addr, IPV4_ALEN); - if (bind(mysocket->sockfd, (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)); - continue; - } - memcpy(mysocket->ip, &(myip.sin_addr), 4); - } - mysocket->device_index = get_device_index(insockfd, devicename); - - sockets_count++; + if (bind(interfaces[i].socketfd, (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)); + continue; } } } static int send_udp(const struct mt_connection *conn, const struct mt_packet *packet) { if (use_raw_socket) { - return send_custom_udp(sockfd, conn->socket->device_index, conn->dstmac, conn->srcmac, &sourceip, sourceport, &destip, conn->srcport, packet->data, packet->size); + return net_send_udp(sockfd, conn->interface, conn->dstmac, conn->srcmac, &sourceip, sourceport, &destip, conn->srcport, packet->data, packet->size); } else { /* Init SendTo struct */ struct sockaddr_in socket_address; @@ -268,16 +253,16 @@ static int send_udp(const struct mt_connection *conn, const struct mt_packet *pa socket_address.sin_port = htons(conn->srcport); socket_address.sin_addr.s_addr = htonl(INADDR_BROADCAST); - return sendto(conn->socket->sockfd, packet->data, packet->size, 0, (struct sockaddr*)&socket_address, sizeof(socket_address)); + return sendto(conn->interface->socketfd, packet->data, packet->size, 0, (struct sockaddr*)&socket_address, sizeof(socket_address)); } } -static int send_special_udp(const struct mt_socket *sock, unsigned short port, const struct mt_packet *packet) { - unsigned char dstmac[6]; - +static int send_special_udp(struct net_interface *interface, unsigned short port, const struct mt_packet *packet) { + unsigned char dstmac[ETH_ALEN]; + if (use_raw_socket) { - memset(dstmac, 0xff, 6); - return send_custom_udp(sockfd, sock->device_index, sock->mac, dstmac, (const struct in_addr *)sock->ip, port, &destip, port, packet->data, packet->size); + memset(dstmac, 0xff, ETH_ALEN); + return net_send_udp(sockfd, interface, interface->mac_addr, dstmac, (const struct in_addr *)&interface->ipv4_addr, port, &destip, port, packet->data, packet->size); } else { /* Init SendTo struct */ struct sockaddr_in socket_address; @@ -285,7 +270,7 @@ static int send_special_udp(const struct mt_socket *sock, unsigned short port, c socket_address.sin_port = htons(port); socket_address.sin_addr.s_addr = htonl(INADDR_BROADCAST); - return sendto(sock->sockfd, packet->data, packet->size, 0, (struct sockaddr*)&socket_address, sizeof(socket_address)); + return sendto(interface->socketfd, packet->data, packet->size, 0, (struct sockaddr*)&socket_address, sizeof(socket_address)); } } @@ -472,8 +457,10 @@ static void user_login(struct mt_connection *curconn, struct mt_mactelnet_hdr *p setenv("SHELL", user->pw_shell, 1); setenv("TERM", curconn->terminal_type, 1); close(sockfd); - for (i = 0; i < sockets_count; ++i) { - close(sockets[i].sockfd); + close(insockfd); + for (i = 0; i < MAX_INTERFACES; ++i) { + if (interfaces[i].in_use && interfaces[i].socketfd > 0) + close(interfaces[i].socketfd); } setsid(); @@ -621,13 +608,12 @@ static void handle_packet(unsigned char *data, int data_len, const struct sockad struct mt_mactelnet_hdr pkthdr; struct mt_connection *curconn = NULL; struct mt_packet pdata; - int socketnum; - int i; + int interface_index; parse_packet(data, &pkthdr); /* Drop packets not belonging to us */ - if ((socketnum = find_socket(pkthdr.dstaddr)) < 0) { + if ((interface_index = find_socket(pkthdr.dstaddr)) < 0) { return; } @@ -639,11 +625,9 @@ static void handle_packet(unsigned char *data, int data_len, const struct sockad } init_pongpacket(&pdata, (unsigned char *)&(pkthdr.dstaddr), (unsigned char *)&(pkthdr.srcaddr)); add_packetdata(&pdata, pkthdr.data - 4, data_len - (MT_HEADER_LEN - 4)); - for (i = 0; i < sockets_count; ++i) { - struct mt_socket *socket = &(sockets[i]); - if (memcmp(&(socket->mac), &(pkthdr.dstaddr), ETH_ALEN) == 0) { - send_special_udp(socket, MT_MACTELNET_PORT, &pdata); - break; + { + if (index >= 0) { + send_special_udp(&interfaces[interface_index], MT_MACTELNET_PORT, &pdata); } } break; @@ -654,11 +638,11 @@ static void handle_packet(unsigned char *data, int data_len, const struct sockad curconn->seskey = pkthdr.seskey; curconn->lastdata = time(NULL); curconn->state = STATE_AUTH; - curconn->socket = &(sockets[socketnum]); - memcpy(curconn->srcmac, pkthdr.srcaddr, 6); - memcpy(curconn->srcip, &(address->sin_addr), 4); + curconn->interface = &interfaces[interface_index]; + memcpy(curconn->srcmac, pkthdr.srcaddr, ETH_ALEN); + memcpy(curconn->srcip, &(address->sin_addr), IPV4_ALEN); curconn->srcport = htons(address->sin_port); - memcpy(curconn->dstmac, pkthdr.dstaddr, 6); + memcpy(curconn->dstmac, pkthdr.dstaddr, ETH_ALEN); list_add_connection(curconn); @@ -763,13 +747,11 @@ static void print_version() { void mndp_broadcast() { struct mt_packet pdata; struct utsname s_uname; - struct sysinfo s_sysinfo; + unsigned char emptymac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; int i; unsigned int uptime; - - if (uname(&s_uname) != 0) { - return; - } +#ifdef __linux__ + struct sysinfo s_sysinfo; if (sysinfo(&s_sysinfo) != 0) { return; @@ -777,13 +759,28 @@ void mndp_broadcast() { /* Seems like ping uptime is transmitted as little endian? */ uptime = htole32(s_sysinfo.uptime); +#else + struct timespec ts; + + if (clock_gettime(CLOCK_UPTIME, &ts) != -1) { + uptime = htole32(((unsigned int)ts.tv_sec)); + } +#endif - for (i = 0; i < sockets_count; ++i) { + if (uname(&s_uname) != 0) { + return; + } + + for (i = 0; i < MAX_INTERFACES; ++i) { + struct net_interface *interface = &interfaces[i]; struct mt_mndp_hdr *header = (struct mt_mndp_hdr *)&(pdata.data); - struct mt_socket *socket = &(sockets[i]); + + if (interfaces[i].in_use == 0 || memcmp(emptymac, interfaces[i].mac_addr, ETH_ALEN) == 0) { + continue; + } mndp_init_packet(&pdata, 0, 1); - mndp_add_attribute(&pdata, MT_MNDPTYPE_ADDRESS, socket->mac, 6); + mndp_add_attribute(&pdata, MT_MNDPTYPE_ADDRESS, interface->mac_addr, ETH_ALEN); mndp_add_attribute(&pdata, MT_MNDPTYPE_IDENTITY, s_uname.nodename, strlen(s_uname.nodename)); mndp_add_attribute(&pdata, MT_MNDPTYPE_VERSION, s_uname.release, strlen(s_uname.release)); mndp_add_attribute(&pdata, MT_MNDPTYPE_PLATFORM, PLATFORM_NAME, strlen(PLATFORM_NAME)); @@ -791,8 +788,7 @@ void mndp_broadcast() { mndp_add_attribute(&pdata, MT_MNDPTYPE_TIMESTAMP, &uptime, 4); header->cksum = in_cksum((unsigned short *)&(pdata.data), pdata.size); - - send_special_udp(socket, MT_MNDP_PORT, &pdata); + send_special_udp(interface, MT_MNDP_PORT, &pdata); } } @@ -809,6 +805,7 @@ int main (int argc, char **argv) { int c,optval = 1; int print_help = 0; int foreground = 0; + int interface_count = 0; while ((c = getopt(argc, argv, "fnvh?")) != -1) { switch (c) { @@ -860,11 +857,7 @@ int main (int argc, char **argv) { if (use_raw_socket) { /* Transmit raw packets with this socket */ - sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (sockfd < 0) { - perror("sockfd"); - return 1; - } + sockfd = net_init_raw_socket(); } /* Receive regular udp packets with this socket */ @@ -874,7 +867,7 @@ int main (int argc, char **argv) { return 1; } - /* Set random source port */ + /* Set source port */ sourceport = MT_MACTELNET_PORT; /* Listen address*/ @@ -887,7 +880,7 @@ int main (int argc, char **argv) { memset((char *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons(sourceport); - memcpy(&(si_me.sin_addr), &sourceip, 4); + memcpy(&(si_me.sin_addr), &sourceip, IPV4_ALEN); setsockopt(insockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval)); @@ -901,24 +894,29 @@ int main (int argc, char **argv) { /* Receive mndp udp packets with this socket */ mndpsockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (insockfd < 0) { - perror("insockfd"); + if (mndpsockfd < 0) { + perror("mndpsockfd"); return 1; } memset((char *)&si_me_mndp, 0, sizeof(si_me_mndp)); si_me_mndp.sin_family = AF_INET; si_me_mndp.sin_port = htons(MT_MNDP_PORT); - memcpy(&(si_me_mndp.sin_addr), &sourceip, 4); + memcpy(&(si_me_mndp.sin_addr), &sourceip, IPV4_ALEN); setsockopt(mndpsockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval)); /* Bind to udp port */ if (bind(mndpsockfd, (struct sockaddr *)&si_me_mndp, sizeof(si_me_mndp))==-1) { - fprintf(stderr, "Error binding to %s:%d, %s\n", inet_ntoa(si_me_mndp.sin_addr), MT_MNDP_PORT, strerror(errno)); + fprintf(stderr, "MNDP: Error binding to %s:%d, %s\n", inet_ntoa(si_me_mndp.sin_addr), MT_MNDP_PORT, strerror(errno)); } - setup_sockets(); + /* Enumerate available interfaces */ + net_get_interfaces(interfaces, MAX_INTERFACES); + + if (!use_raw_socket) { + setup_sockets(); + } if (!foreground) { daemonize(); @@ -934,13 +932,19 @@ int main (int argc, char **argv) { syslog(LOG_NOTICE, "Bound to %s:%d", inet_ntoa(si_me.sin_addr), sourceport); - for (i = 0; i < sockets_count; ++i) { - struct mt_socket *socket = &(sockets[i]); - syslog(LOG_NOTICE, "Listening on %s for %16s\n", socket->name, ether_ntoa((struct ether_addr *)socket->mac)); + for (i = 0; i < MAX_INTERFACES; ++i) { + unsigned char emptymac[ETH_ALEN]; + bzero(emptymac, ETH_ALEN); + + if (interfaces[i].in_use && memcmp(interfaces[i].mac_addr, emptymac, ETH_ALEN) != 0) { + struct ether_addr *mac = (struct ether_addr *)&(interfaces[i].mac_addr); + syslog(LOG_NOTICE, "Listening on %s for %16s\n", interfaces[i].name, ether_ntoa(mac)); + interface_count++; + } } - if (sockets_count == 0) { - syslog(LOG_ERR, "Unable to find the mac-address on any interfaces\n"); + if (interface_count == 0) { + syslog(LOG_ERR, "Unable to find any valid network interfaces\n"); exit(1); } @@ -1005,7 +1009,7 @@ int main (int argc, char **argv) { /* Read it */ datalen = read(p->ptsfd, &keydata, 1024); - if (datalen != -1) { + if (datalen > 0) { /* Send it */ init_packet(&pdata, MT_PTYPE_DATA, p->dstmac, p->srcmac, p->seskey, p->outcounter); plen = add_control_packet(&pdata, MT_CPTYPE_PLAINDATA, &keydata, datalen); @@ -1061,8 +1065,11 @@ int main (int argc, char **argv) { close(sockfd); close(insockfd); - for (i = 0; i < sockets_count; ++i) { - close(sockets[i].sockfd); + if (!use_raw_socket) { + for (i = 0; i < MAX_INTERFACES; ++i) { + if (interfaces[i].in_use && interfaces[i].socketfd > 0) + close(interfaces[i].socketfd); + } } closelog(); return 0; |