1

so ... context: Я делаю протокол уровня 2 для гибкой пересылки в среде транспортного средства (пока мой тестовый стенд находится на виртуальных машинах), это должно с учетом разного количества интерфейсов (для многопользовательских) и многопоточного.Не удается прочитать полученный пакет, когда секция данных начинается с 2

Итак, что у меня есть: Способ вещания hop-by-hop поставщиком услуг.

Что я triyng сделать: Пути зарегистрировать сеанс всего пути от клиента к провайдеру (А вот проблема)

Проблема: У меня есть два типа пакетов первый являются правильно прослушивается, а полезная нагрузка данных начинается с 1 . 2-й по какой-то причине не обнаружен, но я вижу, что пакет отправлен и исправлен с помощью tcpdump

Поскольку я должен зарегистрировать в приложении интерфейс, в котором происходит соединение, я использовал select(), который, кажется, является частью проблемы, поскольку я только догадывался, как он был использован, и я как бы в темноте об этом.

ОБНОВЛЕНО v3:

Хорошо, так как только я удалил большую часть материала о только отправка на определенный интерфейс весь материал работал отлично (мне все еще нужно очистить этот код ... это своего рода грязный) , Вот код, если кто-то интересуется:

#define __STDC_FORMAT_MACROS 
#include <inttypes.h> 
#include <time.h> 

#include <stdlib.h> 
#include <stdio.h> 
#include <stdint.h> 
#include <string.h> 
#include <ifaddrs.h> 

#include <signal.h> 
#include <unistd.h> 
#include <errno.h> 

#include <arpa/inet.h> 
#include <linux/if_packet.h> 

#include <net/ethernet.h> 
#include <sys/socket.h> 
#include <sys/ioctl.h> 
#include <net/if.h> 
#include <netinet/in.h> 

#define ETH_P_CUSTOM 0x0801 /* EtherType of Current Used Protocol*/ 
#define BUF_SIZE  1024 

typedef enum { 
    false, true 
} Bool; /* Boolean Definition*/ 

typedef struct Stat { 
    uint8_t maxSocket; /*Number of sockets to use in receive*/ 
    uint8_t nInterfaces; /*Number of interfaces owned by this machine*/ 
    uint8_t nSession; /*Number of Sessions Known in the linked list*/ 

    uint8_t upMac[ETH_ALEN]; /*MAC of this host upstream parent*/ 
    uint8_t nHops; /*Hops to Provider*/ 
    char ifName[IF_NAMESIZE + 1]; /*Interface to Provider*/ 
} Stat; 

typedef struct Node { 
    uint64_t session; /*Client Session*/ 
    uint8_t nextHop[ETH_ALEN]; /*Next-Hop to Client*/ 
    char ifName[IF_NAMESIZE + 1]; /*Outgoing Interface that connects to Next-Hop*/ 
    struct Node * next; /*Next Session*/ 
} Node; 

typedef struct ifNode { 
    uint8_t ifIndex; /*Interface index*/ 
    uint8_t sock; /*Index in array of sockets*/ 
    uint8_t mac[ETH_ALEN]; /*Interface MAC*/ 
    char ifName[IF_NAMESIZE + 1]; /*Interface Name*/ 

    struct ifNode * next; /*Next Session*/ 
} ifNode; 

Stat * op; /* Variable which tracks status of certain structures/variables*/ 
Node * first = NULL, *last = NULL; /* Edges of linked list */ 
ifNode * iffirst = NULL, *iflast = NULL; /* Edges of interface linked list */ 
int cargc; 
char **cargv; 

int receiveP(); 
int broadServ(); 
int announceSelf(); 

Node* create(uint64_t sess, uint8_t n[ETH_ALEN], char interface[IF_NAMESIZE]); 
void insert_node(Node * p); 
Node* search(uint64_t session); 
void update(uint64_t session, Node * p); 

ifNode* createif(uint8_t idx, uint8_t sock, uint8_t ifmac[ETH_ALEN], 
     char interface[IF_NAMESIZE]); 
void insert_ifnode(ifNode * p); 
ifNode* searchif(uint8_t idx, uint8_t mode); 
void updateif(uint8_t idx, ifNode * p); 

void display(); 
void displayif(); 

void ctrlcoverride(int sig) { 
    printf("\nCtrl-C - Signal Caught - Exiting\n\n"); 
    printf(
      "Current Upstream MAC: %02x:%02x:%02x:%02x:%02x:%02x - NHops : %u - At Interface %s\n\n", 
      op->upMac[0], op->upMac[1], op->upMac[2], op->upMac[3], 
      op->upMac[4], op->upMac[5], op->nHops, op->ifName); 
    display(); 
    exit(EXIT_SUCCESS); 
} 

Node* create(uint64_t sess, uint8_t n[ETH_ALEN], char interface[IF_NAMESIZE]) { 
    Node * new = (Node *) malloc(sizeof(Node)); 
    if (new == NULL) { 
     printf("Could not create new node\n"); 
     return NULL; 
    } else { 
     strcpy(new->ifName, interface); 
     new->session = sess; 
     int i; 
     for (i = 0; i < ETH_ALEN; i++) 
      new->nextHop[i] = n[i]; 
     new->next = NULL; 
     return new; 
    } 
} 

ifNode* createif(uint8_t idx, uint8_t sock, uint8_t ifmac[ETH_ALEN], 
     char interface[IF_NAMESIZE]) { 
    ifNode * new = (ifNode *) malloc(sizeof(ifNode)); 
    if (new == NULL) { 
     printf("Could not create new interface node\n"); 
     return NULL; 
    } else { 
     new->ifIndex = idx; 
     new->sock = sock; 
     strcpy(new->ifName, interface); 

     int i; 
     for (i = 0; i < ETH_ALEN; i++) 
      new->mac[i] = ifmac[i]; 
     new->next = NULL; 
     return new; 
    } 
} 

void insert_node(Node * p) { 
    if (first == last && last == NULL) { 
     first = last = p; 
     first->next = NULL; 
     last->next = NULL; 
    } else { 
     last->next = p; 
     last = last->next; 
     last->next = NULL; 
    } 
} 

void insert_ifnode(ifNode * p) { 
    if (iffirst == iflast && iflast == NULL) { 
     iffirst = iflast = p; 
     iffirst->next = NULL; 
     iflast->next = NULL; 
    } else { 
     iflast->next = p; 
     iflast = iflast->next; 
     iflast->next = NULL; 
    } 
} 

Node* search(uint64_t session) { 
    if (first == last && last == NULL) { 
     return NULL; 
    } else { 
     Node * temp; 
     for (temp = first; temp != NULL; temp = temp->next) { 
      if (temp->session == session) { 
       return temp; 
      } 
     } 
     return NULL; 
    } 
} 

ifNode* searchif(uint8_t idx, uint8_t mode) { 
    if (iffirst == iflast && iflast == NULL) { 
     return NULL; 
    } else { 
     ifNode * temp; 
     for (temp = iffirst; temp != NULL; temp = temp->next) { 
      if (temp->ifIndex == idx && mode == 0) { 
       return temp; 
      } else if (temp->sock == idx && mode == 1) { 
       return temp; 
      } 
     } 
     return NULL; 
    } 
} 

void update(uint64_t session, Node * p) { 
    if (first == last && last == NULL) { 
     return; 
    } else { 
     Node * temp; 
     for (temp = first; temp != NULL; temp = temp->next) { 
      if (temp->session == session) { 
       strcpy(temp->ifName, p->ifName); 
       temp->next = p->next; 
       int i; 
       for (i = 0; i < ETH_ALEN; i++) 
        temp->nextHop[i] = p->nextHop[i]; 
       return; 
      } 
     } 
    } 
} 

void updateif(uint8_t idx, ifNode * p) { 
    if (iffirst == iflast && iflast == NULL) { 
     return; 
    } else { 
     ifNode * temp; 
     for (temp = iffirst; temp != NULL; temp = temp->next) { 
      if (temp->ifIndex == idx) { 
       strcpy(temp->ifName, p->ifName); 
       temp->sock = p->sock; 
       temp->next = p->next; 
       int i; 
       for (i = 0; i < ETH_ALEN; i++) 
        temp->mac[i] = p->mac[i]; 
       return; 
      } 
     } 
    } 
} 

void display() { 
    Node * temp = first; 
    while (temp != NULL) { 
     printf("Session %" PRIu64 " Through %s - NextHop at ", temp->session, 
       temp->ifName); 
     int i; 
     for (i = 0; i < ETH_ALEN; i++) 
      printf("%02x ", temp->nextHop[i]); 
     printf("\n"); 
     temp = temp->next; 
    } 
} 

void displayif() { 
    ifNode * temp = iffirst; 
    while (temp != NULL) { 
     printf("Interface Index %u Socket Number %u - Name %s with MAC: ", 
       temp->ifIndex, temp->sock, temp->ifName); 
     int i; 
     for (i = 0; i < ETH_ALEN; i++) 
      printf("%02x ", temp->mac[i]); 
     printf("\n"); 
     temp = temp->next; 
    } 
} 

uint8_t counter() { 
    Node * temp = first; 
    uint8_t counter = 0; 
    while (temp != NULL) { 
     counter++; 
     temp = temp->next; 
    } 
    return counter; 
} 

fd_set rfds; 
int rec; 
int main(int argc, char **argv) { 
    setbuf(stdout, NULL); 
    signal(SIGINT, ctrlcoverride); 

    cargc = argc; 
    cargv = argv; 

    /*Setting Base Variables to Initial Values*/ 
    op = (Stat*) malloc(sizeof(Stat)); 
    op->nSession = 0; 

    memset(op->ifName, 0, IF_NAMESIZE); 
    op->maxSocket = 0; 
    op->nHops = UINT8_MAX - 1; 
    int i; 
    for (i = 0; i < ETH_ALEN; i++) { 
     op->upMac[i] = 0x00; 
    } 

    memset(&rfds, 0, sizeof(fd_set)); 
    FD_ZERO(&rfds); 

    if (argc != 2) { 
     printf("USAGE: sudo %s {provider|node|nodekey}\n", cargv[0]); 
     exit(EXIT_FAILURE); 
    } else if (!(strcmp(cargv[1], "provider") == 0 
      || strcmp(cargv[1], "node") == 0 || strcmp(cargv[1], "nodekey") == 0)) { 
     printf("USAGE: sudo %s {provider|node|nodekey}\n", cargv[0]); 
     exit(EXIT_FAILURE); 
    } 

    if (strcmp(cargv[1], "nodekey") == 0) { 
     srand(time(NULL)); 
     uint8_t myArray[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
     insert_node(
       create((uint64_t) (100 * ((float) rand()/RAND_MAX)), myArray, 
         "SOURCE")); 
    } 

    struct ifaddrs *ifaddr, *ifa; 

    if (getifaddrs(&ifaddr) == -1) { 
     perror("getifaddrs"); 
     exit(EXIT_FAILURE); 
    } 

    for (ifa = ifaddr, op->nInterfaces = 0; ifa != NULL; ifa = ifa->ifa_next) { 
     if (ifa->ifa_addr == NULL) 
      continue; 
     if (ifa->ifa_addr->sa_family == AF_PACKET 
       && strncmp(ifa->ifa_name, "lo", strlen("lo")) != 0 
       && strncmp(ifa->ifa_name, "tap", strlen("tap")) != 0) { 
      op->nInterfaces++; 
     } 
    } 

    rec = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_CUSTOM)); 

    int sockopt; 
    char ifName[IFNAMSIZ]; 
    struct ifreq ifr; 
    for (i = 1, ifa = ifaddr; ifa != NULL; 

    ifa = ifa->ifa_next, i++) { 

     if (ifa->ifa_addr == NULL) 
      continue; 
     if (ifa->ifa_addr->sa_family == AF_PACKET 
       && strncmp(ifa->ifa_name, "lo", strlen("lo")) != 0 
       && strncmp(ifa->ifa_name, "tap", strlen("tap")) != 0) { 

      uint8_t sock; 
      if ((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_CUSTOM))) 
        == -1) { 
       printf("socket() error: %u - %s\n", errno, strerror(errno)); 
       return EXIT_FAILURE; 
      } 

      if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, 
        sizeof sockopt) == -1) { 
       printf("SO_REUSEADDR error: %u - %s\n", errno, strerror(errno)); 
       close(sock); 
       return EXIT_FAILURE; 
      } 

      memset(&ifr, 0, sizeof(struct ifreq)); 
      ifr.ifr_ifindex = i; 

      strcpy(ifr.ifr_name, ifa->ifa_name); 

      if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifa->ifa_name, 
      IF_NAMESIZE) == -1) { 
       printf("SO_BINDTODEVICE error: %u - %s\n", errno, 
         strerror(errno)); 
       close(sock); 
       return EXIT_FAILURE; 

      } 

      struct sockaddr_ll sll; 
      sll.sll_family = AF_PACKET; 
      sll.sll_ifindex = i; 
      sll.sll_protocol = htons(ETH_P_CUSTOM); 
      if ((bind(sock, (struct sockaddr *) &sll, sizeof(sll))) == -1) { 
       perror("Error binding raw socket to interface\n"); 
       exit(-1); 
      } 

      if ((ioctl(sock, SIOCGIFHWADDR, &ifr)) != 0) { 
       printf("SIOCGIFHWADDR error: %u - %s\n", errno, 
         strerror(errno)); 
       return EXIT_FAILURE; 
      } 

      int j; 

      uint8_t ifmac[ETH_ALEN]; 
      for (j = 0; j < ETH_ALEN; j++) { 
       ifmac[j] = (uint8_t) (ifr.ifr_hwaddr.sa_data)[j]; 
      } 

      FD_SET(sock, &rfds); 

      op->maxSocket = (op->maxSocket < sock) ? sock : op->maxSocket; 

      insert_ifnode(createif(i, sock, ifmac, ifr.ifr_name)); 
     } 
    } 

    displayif(); 

    if (strcmp(cargv[1], "provider") == 0) { 

     struct ifreq if_mac; // interface 

     char * interface = "eth1"; 

     int sockfd; 

     if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_CUSTOM))) == -1) { 
      printf("socket() error: %u - %s\n", errno, strerror(errno)); 
      return EXIT_FAILURE; 
     } 

     memset(&if_mac, 0, sizeof(struct ifreq)); 
     strncpy(if_mac.ifr_name, interface, IFNAMSIZ - 1); 
     if ((ioctl(sockfd, SIOCGIFHWADDR, &if_mac)) != 0) { 
      printf("SIOCGIFHWADDR error: %u - %s\n", errno, strerror(errno)); 
      return EXIT_FAILURE; 
     } 

     int i; 
     for (i = 0; i < ETH_ALEN; i++) 
      op->upMac[i] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[i]; 

     op->nHops = 0; 

     close(sockfd); 
    } 

    freeifaddrs(ifaddr); 

    int stat = 0; 

    while (1) { 

     if (strcmp(cargv[1], "provider") == 0) { 

      if ((stat = receiveP()) != 0) 
       return stat; 

      if ((stat = broadServ()) != 0) 
       return stat; 

      display(); 

      usleep(100000); 
     } else if (strcmp(cargv[1], "node") == 0 
       || strcmp(cargv[1], "nodekey") == 0) { 

      if ((stat = receiveP()) != 0) 
       return stat; 

      if ((stat = announceSelf()) != 0){ 
       return stat; 
      } 

      if ((stat = broadServ()) != 0) 
       return stat; 

      display(); 

      usleep(100000); 
     } 

    } 

    ifNode * temp = iffirst; 
    while (temp != NULL) { 
     close(temp->sock); 
     temp = temp->next; 
    } 

    exit(stat); 

} 

int receiveP() { 
    int stat = 0; 
    struct ifreq ifr; 

    struct sockaddr saddr; 

    long unsigned int numbytes = 0; 
    char buf[BUF_SIZE]; 
    memset(buf, 0, BUF_SIZE); 
    struct ether_header *eh = (struct ether_header *) buf; 

    unsigned int saddr_size = sizeof saddr; 

    struct timeval tv; 

    tv.tv_sec = 3; /* 3 Secs Timeout */ 
    tv.tv_usec = 0; 


    setsockopt(rec, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, 
      sizeof(struct timeval)); 

    numbytes = recvfrom(rec, buf, BUF_SIZE, 0, &saddr, &saddr_size); 

    int len; 
    int ntable; 

    switch (buf[sizeof(struct ether_header)]) { 
    case 1: 
     if (buf[sizeof(struct ether_header) + 1] < op->nHops) { 
      op->upMac[0] = eh->ether_shost[0]; 
      op->upMac[1] = eh->ether_shost[1]; 
      op->upMac[2] = eh->ether_shost[2]; 
      op->upMac[3] = eh->ether_shost[3]; 
      op->upMac[4] = eh->ether_shost[4]; 
      op->upMac[5] = eh->ether_shost[5]; 

      op->nHops = buf[sizeof(struct ether_header) + 1] + 1; 

      memset(&ifr, 0, sizeof(struct ifreq)); 
      memset(&ifr.ifr_name, 0, IF_NAMESIZE); 

      printf(
        "Server %u Hops Away - Through %02x:%02x:%02x:%02x:%02x:%02x At Interface %s\n", 
        op->nHops, eh->ether_shost[0], eh->ether_shost[1], 
        eh->ether_shost[2], eh->ether_shost[3], eh->ether_shost[4], 
        eh->ether_shost[5], op->ifName); 

      printf("\n\n"); 
     } 
     break; 
    case 2: 
     len = sizeof(struct ether_header) + 1; 
     ntable = buf[len++]; 
     int j; 

     for (j = 0; j < ntable; j++, len++) { 
      if (search(buf[len]) == NULL) { 
       insert_node(create(buf[len], eh->ether_shost, "")); 
      } 
     } 

     break; 
    } 

    return stat; 
} 

int broadServ() { 
    int stat = 0; 

    int tx_len = 0; 
    char sendbuf[BUF_SIZE]; 
    char ifName[IF_NAMESIZE - 1]; 
    struct ether_header *eh = (struct ether_header *) sendbuf; 
    struct sockaddr_ll socket_address; 
    int i; 
    struct ifreq ifr, if_mac; 
    ifNode * temp = iffirst; 
    while (temp != NULL) { 
     /* Get the index of the interface to send on */ 
     memset(&ifr, 0, sizeof(struct ifreq)); 
     ifr.ifr_ifindex = temp->ifIndex; 
     if (ioctl(temp->sock, SIOCGIFNAME, &ifr) < 0) 
      perror("SIOCGIFINDEX"); 
     memset(ifName, 0, IF_NAMESIZE - 1); 
     strncpy(ifName, ifr.ifr_name, IF_NAMESIZE - 1); 
     /* Get the MAC address of the interface to send on */ 
     memset(&if_mac, 0, sizeof(struct ifreq)); 
     strncpy(if_mac.ifr_name, ifName, IFNAMSIZ - 1); 
     if (ioctl(temp->sock, SIOCGIFHWADDR, &if_mac) < 0) 
      perror("SIOCGIFHWADDR"); 
     if (((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[0] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[1] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[2] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[3] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[4] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[5] == 0x00) 
      continue; 
     memset(sendbuf, 0, BUF_SIZE); 
     /* Ethernet header */ 
     eh->ether_shost[0] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[0]; 
     eh->ether_shost[1] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[1]; 
     eh->ether_shost[2] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[2]; 
     eh->ether_shost[3] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[3]; 
     eh->ether_shost[4] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[4]; 
     eh->ether_shost[5] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[5]; 
     eh->ether_dhost[0] = 0xff; 
     eh->ether_dhost[1] = 0xff; 
     eh->ether_dhost[2] = 0xff; 
     eh->ether_dhost[3] = 0xff; 
     eh->ether_dhost[4] = 0xff; 
     eh->ether_dhost[5] = 0xff; 
     /* Ethertype field */ 
     eh->ether_type = htons(ETH_P_CUSTOM); 
     tx_len = sizeof(struct ether_header); 

     /* Packet data */ 
     sendbuf[tx_len++] = 1; 
     sendbuf[tx_len++] = op->nHops;  //+1; 

     /* Index of the network device */ 
     socket_address.sll_ifindex = temp->ifIndex; 
     /* Address length*/ 
     socket_address.sll_halen = ETH_ALEN; 
     /* Destination MAC */ 
     socket_address.sll_addr[0] = 0xff; 
     socket_address.sll_addr[1] = 0xff; 
     socket_address.sll_addr[2] = 0xff; 
     socket_address.sll_addr[3] = 0xff; 
     socket_address.sll_addr[4] = 0xff; 
     socket_address.sll_addr[5] = 0xff; 

     /* Send packet */ 
     if (sendto(temp->sock, sendbuf, tx_len, 0, 
       (struct sockaddr*) &socket_address, sizeof(struct sockaddr_ll)) 
       < 0) 
      printf("Send failed\n"); 
     temp = temp->next; 
    } 
    return stat; 
} 

int announceSelf() { 

    if (op->upMac[0] == 0x00 && op->upMac[1] == 0x00 && op->upMac[2] == 0x00 
      && op->upMac[3] == 0x00 && op->upMac[4] == 0x00 
      && op->upMac[5] == 0x00) 
     return EXIT_SUCCESS; 

    int stat = 0; 

    int tx_len = 0; 
    char sendbuf[BUF_SIZE]; 
    char ifName[IF_NAMESIZE - 1]; 
    struct ether_header *eh = (struct ether_header *) sendbuf; 
    struct sockaddr_ll socket_address; 
    int i; 
    struct ifreq ifr, if_mac; 
    ifNode * temp = iffirst; 
    while (temp != NULL) { 

     memset(&ifr, 0, sizeof(struct ifreq)); 
     ifr.ifr_ifindex = temp->ifIndex; 
     if (ioctl(temp->sock, SIOCGIFNAME, &ifr) < 0) 
      perror("SIOCGIFINDEX"); 
     memset(ifName, 0, IF_NAMESIZE - 1); 
     strncpy(ifName, ifr.ifr_name, IF_NAMESIZE - 1); 
     /* Get the MAC address of the interface to send on */ 
     memset(&if_mac, 0, sizeof(struct ifreq)); 
     strncpy(if_mac.ifr_name, ifName, IFNAMSIZ - 1); 
     if (ioctl(temp->sock, SIOCGIFHWADDR, &if_mac) < 0) 
      perror("SIOCGIFHWADDR"); 
     if (((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[0] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[1] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[2] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[3] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[4] == 0x00 
       && ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[5] == 0x00) 
      continue; 
     memset(sendbuf, 0, BUF_SIZE); 

     /* Ethernet header */ 
     eh->ether_shost[0] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[0]; 
     eh->ether_shost[1] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[1]; 
     eh->ether_shost[2] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[2]; 
     eh->ether_shost[3] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[3]; 
     eh->ether_shost[4] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[4]; 
     eh->ether_shost[5] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[5]; 
     eh->ether_dhost[0] = op->upMac[0]; 
     eh->ether_dhost[1] = op->upMac[1]; 
     eh->ether_dhost[2] = op->upMac[2]; 
     eh->ether_dhost[3] = op->upMac[3]; 
     eh->ether_dhost[4] = op->upMac[4]; 
     eh->ether_dhost[5] = op->upMac[5]; 
     /* Ethertype field */ 
     eh->ether_type = htons(ETH_P_CUSTOM); 
     tx_len = sizeof(struct ether_header); 

     /* Packet data */ 
     sendbuf[tx_len++] = 2; 
     sendbuf[tx_len++] = counter(); 



     Node *temp1 = first; 
     for (; temp1 != NULL; temp1 = temp1->next) { 
      sendbuf[tx_len++] = temp1->session; 
     } 

     socket_address.sll_ifindex = temp->ifIndex; 
     /* Address length*/ 
     socket_address.sll_halen = ETH_ALEN; 
     /* Destination MAC */ 
     socket_address.sll_addr[0] = op->upMac[0]; 
     socket_address.sll_addr[1] = op->upMac[1]; 
     socket_address.sll_addr[2] = op->upMac[2]; 
     socket_address.sll_addr[3] = op->upMac[3]; 
     socket_address.sll_addr[4] = op->upMac[4]; 
     socket_address.sll_addr[5] = op->upMac[5]; 

     /* Send packet */ 
     if (sendto(temp->sock, sendbuf, tx_len, 0, 
       (struct sockaddr*) &socket_address, sizeof(struct sockaddr_ll)) 
       < 0) 
      printf("Send failed\n"); 

     temp = temp->next; 
    } 
    return stat; 
} 

Таким образом, чтобы проверить это вы можете иметь VM с Linux, связанных как это (например): Поставщик ----- ----- Узел Узел --- - Nodekey

У меня все еще была проблема при создании нескольких сеансов, я не увеличивал буфер при чтении, и я читал несколько раз одну и ту же позицию. Теперь он работает хорошо

+0

Извините, но где же цикл, который гарантирует, что ваш код вернется к вашему выбору? Если нет петли, имеет смысл, что вы получите первый кадр, но не второй. – rodolk

+0

oh ... Я не опубликовал весь код ... цикл внутри в основной функции ... EDIT: Уже отправлено это ... node и nodekey те же, за исключением того, что nodekey имеет элемент в структуре ... предполагается, что узел должен распространять структуру через сеть до тех пор, пока не дойдет до провайдера –

+0

Итак, какой-то прогресс? – rodolk

ответ

0

Хорошо, давайте начнем с самых простых рекомендаций, но я не уверен, что это решит проблему сразу. Я сделал такую ​​систему много лет назад для разных плат с разными процессорными архитектурами, общающимися друг с другом. Все платы работали в телекоммуникационном коммутаторе. Это очень хорошая проблема, и вы сталкиваетесь с ней надлежащим образом с одноранговым распределенным решением.

Я не прошел весь код, но кажется, что каждый узел обнаруживает соседние узлы в сети, и каждый создает дерево.

  1. В выбрать, первый аргумент не должен быть FD_SETSIZE но с наибольшим номером дескриптор файла в любом из трех наборов (в данном случае установлено для чтения), плюс 1.

  2. бесконечный цикл вызывает getSession, который снова создает все сокеты, а затем читает. Если кадр с вашим конкретным протоколом уровня 2 прибывает посередине, и нет сокета, слушающего его, он будет отброшен. Может быть, ваша проблема может быть здесь.

  3. При передаче кадров Ethernet непосредственно, аппаратные средства будут завершить фрейм до минимального размера Ethernet: 64 октета (так что вы можете получить дополняющие данные до 46 октетов - Октетное не Bytes) Пожалуйста, читайте здесь:

    http://en.wikipedia.org/wiki/Ethernet_frame

  4. это хорошо вы выбрали EtherType ETH_P_CUSTOM выше, чем 1536, который уже не используется, но может быть, вы хотите использовать гораздо большее количество, чтобы свести к минимуму возможности столкновения с другими протоколами.

  5. Что-то важное. Теперь ваш тестовый стенд состоит из VM, которые обычно представляют собой архитектуры x86, 64 бит. Когда вы запускаете свое программное обеспечение на реальных устройствах с разными процессорами, это может быть не так. Это очень важно, потому что у вас могут быть разные архитектуры с различной ориентацией и разными целыми размерами. Это повлияет на целые числа, которые вы отправляете, особенно в ether_header, и размер ваших структур. Вы должны использовать макросы ntohs, ntohl, htons, htonl для изменения между основной и сетевой континентностью (session is uint64_t). Вы должны отправлять данные в сетевую систему. Это не решает вашу текущую проблему, но у вас может возникнуть эта проблема в будущем.

+0

Это именно он ... Он создает дерево от провайдера до конечных узлов, а затем узлы будут инициализировать сеансы, которые должны быть известны у поставщика. Я попробую все, что вы здесь сказали ... это звучит как солидный хороший совет. Не уверен, что это так, но обязательно обновит –

+0

Что-то дополнительное: вы проверили с tcpdump, что второй кадр прибывает на узел назначения (тот, кто прослушивает)? – rodolk

+0

да ... 2-й кадр поступает с правильной структурой и в правильном интерфейсе ... единственное, что программа не может переименовать ... это странно, потому что я не думаю, что это проблема синхронизации, потому что она может прослушивать все остальные пакеты. –