+++ /dev/null
-/*
- * File: raw_ethernet.cpp
- * Author: fredo-local
- *
- * Created on 28 janvier 2009, 16:46
- */
-
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-#include "tools.h"
-
-#include "raw_ethernet.h"
-
-raw_ethernet::raw_ethernet() {
-}
-
-int raw_ethernet::Open(const char *ifname, const char *mac_address, unsigned short EthType) {
- this->mac_address = strdup(mac_address);
-
- parse_mac(mac_address, this->remote_mac);
-
- sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- if (sock < 0) {
- VERBOSE (VERBOSE_ERROR, printf ("socket(): %s\n", strerror (errno)));
- VERBOSE (VERBOSE_ERROR, printf("Warning: you must be root to have raw access to sockets\n"));
- return -1;
- }
-
- memset(&sock_addr, 0, sizeof (struct sockaddr_ll));
-
- sock_addr.sll_family = PF_PACKET;
- sock_addr.sll_protocol = htons(EthType);
- sock_addr.sll_ifindex = Get_IfaceIndex(ifname);
- if (sock_addr.sll_ifindex < 0) return -1;
- sock_addr.sll_hatype = ARPHRD_ETHER;
- sock_addr.sll_pkttype = PACKET_OTHERHOST;
- sock_addr.sll_halen = ETH_ALEN;
- if (Get_MacAddress(ifname, sock_addr.sll_addr) != 0) {
- printf("Cannot get local mac address for %s\n", ifname);
- return -1;
- }
-
- int res = bind(sock, (struct sockaddr *) & sock_addr, sizeof (sock_addr));
- if (res != 0) {
- VERBOSE (VERBOSE_ERROR, printf ("bind(): %s\n", strerror (errno)));
- return -1;
- }
-
- printf("I/O on %s local=[", ifname);
- for (int i = 0; i < 6; i++) {
- printf("%02x", sock_addr.sll_addr[i]);
- if (i < 5) printf(":");
- }
- printf("]\n");
-
- eth_type = htons(EthType);
- memset(TxBuf, 0, sizeof (TxBuf));
- memcpy(TxBuf, (void *) remote_mac, 6);
- memcpy(TxBuf + 6, sock_addr.sll_addr, 6);
- memcpy(TxBuf + 12, (void *) & eth_type, 2);
-
- return 0;
-}
-
-raw_ethernet::~raw_ethernet() {
-}
-
-int raw_ethernet::parse_mac(const char *hexa, unsigned char *result) {
- if (strlen(hexa) != 17) return -1;
- for (int i = 0; i < 6; i++) {
- char one_byte[] = "xx";
- memcpy(one_byte, hexa + 3 * i, 2);
- result[i] = strtoul(one_byte, NULL, 16);
- }
- return 0;
-}
-
-int raw_ethernet::Get_IfaceIndex(const char *ifname) {
- struct ifreq ifr;
-
- memset(&ifr, 0, sizeof (ifr));
- strcpy(ifr.ifr_name, ifname);
- int res = ioctl(sock, SIOCGIFINDEX, &ifr);
- if (res != 0) {
- VERBOSE (VERBOSE_ERROR, printf ("Get ethernet interface index: %s\n", strerror (errno)));
- return -1;
- }
- return ifr.ifr_ifindex;
-}
-
-int raw_ethernet::Get_MacAddress(const char *ifname, unsigned char *mac) {
- struct ifreq ifr;
- memset(&ifr, 0, sizeof (ifr));
- strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- int res = ioctl(sock, SIOCGIFHWADDR, &ifr);
- if (res != 0) {
- VERBOSE (VERBOSE_ERROR, printf ("Get ethernet mac address: %s\n", strerror (errno)));
- return -1;
- }
-
- unsigned char *p = (unsigned char *)ifr.ifr_hwaddr.sa_data;
- for (int i = 0; i < 6; i++) {
- //while (*p == 0xFF) p++;
- mac[i] = *p++;
- }
- return 0;
-}
-
-unsigned char *raw_ethernet::RxData(int nb) {
- while (1) {
- struct sockaddr_ll addr;
-
- unsigned int sock_addr_len = sizeof (addr);
-
- int len = recvfrom(sock, RxBuf, sizeof (RxBuf), 0, (struct sockaddr *) & addr, &sock_addr_len);
- if (len != 14 + nb) continue; // Not for us, length is bad
- unsigned short rx_ethtype;
- memcpy(&rx_ethtype, RxBuf+12, 2);
- if (rx_ethtype != eth_type) continue; // Not for us, bad ethtype
-#if 1
- bool is_correct_mac_addr_source = true;
- for (int i = 0; i < 6; i++)
- if (remote_mac[i] != RxBuf[i + 6])
- is_correct_mac_addr_source = false;
- if (!is_correct_mac_addr_source) continue; // Not from our source
-#endif
- return RxBuf+14;
- }
-}
-
-int raw_ethernet::TxData(int nb) {
- int rc = sendto(sock, TxBuf, nb + 14, 0, (struct sockaddr *) &sock_addr,
- sizeof (sock_addr));
- if (rc < 14) return -1;
- return rc-14;
-}
-
-int raw_ethernet::SetNonBlocking ()
-{
- int flags = fcntl (sock, F_GETFL, 0);
- return fcntl (sock, F_SETFL, flags | O_NONBLOCK);
-}
+++ /dev/null
-/* -*- C++ -*- */
-
-/*
- * File: raw_ethernet.h
- * Author: fredo-local
- *
- * Created on 28 janvier 2009, 16:46
- */
-
-#ifndef _RAW_ETHERNET_H
-#define _RAW_ETHERNET_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <linux/if_arp.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <sys/ioctl.h>
-
-class raw_ethernet {
-public:
- raw_ethernet();
- virtual ~raw_ethernet();
- int Open(const char *ifname, const char *mac_address, unsigned short EthType);
- unsigned char *GetTxBuf() { return TxBuf +14; };
- unsigned char *RxData(int nb);
- int TxData(int nb);
- int SetNonBlocking ();
-
-private:
- char *mac_address;
- int sock;
- unsigned char TxBuf[9014]; // extended for jumbo frame (standard was 1514)
- unsigned char RxBuf[9014]; // extended for jumbo frame (standard was 1514)
- unsigned short eth_type;
- unsigned char remote_mac[6];
- struct sockaddr_ll sock_addr;
-
- int parse_mac(const char *hexa, unsigned char *result);
- int Get_MacAddress(const char *ifname, unsigned char *mac);
- int Get_IfaceIndex(const char *ifname);
-};
-
-#endif /* _RAW_ETHERNET_H */
-