пакет mmap отправляет формат пакета - PullRequest
1 голос
/ 29 ноября 2011

Я хочу улучшить производительность передачи пакетов.До этого я использовал необработанные сокеты и сейчас изучаю package_mmap.У меня есть пакеты (кадры), которые я уже захватил из модуля ядра с другого компьютера, поместил на текущий компьютер, и теперь я хочу повторно передать их на локальный интерфейс с последующей пересылкой.Я получил пример packet_mmap, интегрировал его в свой проект, но я отправляю

fd_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
memset(&my_addr, 0, sizeof(struct sockaddr_ll));
my_addr.sll_family = PF_PACKET;
my_addr.sll_protocol = htons(ETH_P_ALL);
strcpy(str_devname, "eth0");
strncpy(s_ifr.ifr_name, str_devname, sizeof(s_ifr.ifr_name));
ec = ioctl(fd_socket, SIOCGIFINDEX, &s_ifr);
i_ifindex = s_ifr.ifr_ifindex;
memset(&my_addr, 0, sizeof(struct sockaddr_ll));
my_addr.sll_family = AF_PACKET;
my_addr.sll_protocol = ETH_P_ALL;
my_addr.sll_ifindex = i_ifindex;
bind(fd_socket, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_ll)
s_packet_req.tp_block_size = c_buffer_sz;
s_packet_req.tp_frame_size = c_buffer_sz;
s_packet_req.tp_block_nr = c_buffer_nb;
s_packet_req.tp_frame_nr = c_buffer_nb;
size = s_packet_req.tp_block_size * s_packet_req.tp_block_nr;
if (setsockopt(fd_socket, SOL_PACKET, PACKET_TX_RING, (char *) &s_packet_req, sizeof(s_packet_req)) < 0) {
 perror("setsockopt: PACKET_TX_RING");
 return;
}

if (c_sndbuf_sz) {
 printf("send buff size = %d\n", c_sndbuf_sz);
 if (setsockopt(fd_socket, SOL_SOCKET, SO_SNDBUF, &c_sndbuf_sz, sizeof(c_sndbuf_sz)) < 0){
  perror("getsockopt: SO_SNDBUF");
  exit(1);
 }
}

data_offset = TPACKET_HDRLEN - sizeof(struct sockaddr_ll);
printf("data offset = %d bytes\n", data_offset);
ps_header_start = (tpacket_hdr *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_socket, 0);
if (ps_header_start == (void*) -1) {
 perror("mmap");
 exit(1);
}

Затем я заполняю данные

ps_header = ((struct tpacket_hdr *) ((char *) ps_header_start + (c_buffer_sz * i_index)));
if (!ps_header) {
 perror("ps_header") ;
 return NULL;
}
data = ((char*) ps_header) + data_offset;
switch ((volatile uint32_t) ps_header->tp_status) {
  case TP_STATUS_AVAILABLE:
      printf("TP_STATUS_AVAILABLE, index=%d\n",i_index) ;
      memcpy(data, packet_data, size);

pthread_mutex_lock(&index_locker) ;
i_index++;
pthread_mutex_unlock(&index_locker) ;

if (i_index >= c_buffer_nb) {
    i_index = 0;
    first_loop = 0;
}

/* update packet len */
ps_header->tp_len = size;
/* set header flag to USER (trigs xmit)*/
ps_header->tp_status = TP_STATUS_SEND_REQUEST;

, затем отправляю

ec_send = sendto(fd_socket, NULL, 0, 0, (struct sockaddr *) ps_sockaddr, sizeof(struct sockaddr_ll));

У меня нет ошибок, ec_send = не нулевой размер отправленных данных.Но нет данных, направленных на хост назначения.

Итак, я спрашиваю - какие данные я должен передать кольцевому буферу, теперь я включаю заголовки ip, tcp, мне следует включить заголовок MAC?- Может быть, мне нужно установить дополнительные флаги для маршрутизации моих пакетов.

1 Ответ

2 голосов
/ 11 сентября 2015

Вы создаете сокет, используя SOCK_RAW.Это означает, что вы уполномочены предоставлять информацию уровня 2 (адрес Ethernet / MAC).Вы можете создать сокет с SOCK_DGRAM.Ядро будет обрабатывать информацию Уровня 2, чтобы поместить адрес Ethernet следующего перехода.Попробуйте это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...