我仍然在努力让我的示例代码在64位计算机上运行。由于缺少/过时的标头/库,我之前的问题得到了解决。
我编译此代码如下:gcc -Wall -g -o server server.c和gcc -Wall -g -o client client.c 我在2台Linux机器上运行它们(均为32位),它运行正常。当我在64位计算机上重新编译此代码时,似乎没有数据包从客户端传递到服务器。将tcpdump放在客户端上似乎它发送的格式错误的标头一直被拒绝。有人可以开导我吗?
#include "client.h"
#include "util.h"
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <asm/types.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#define BUF_SIZE ETH_FRAME_TOTALLEN
#define NUMBER_OF_MESUREMENTS_PER_AMOUNT_OF_DATA 100000 /*how often to measure travelling time with one certain amount of data*/
int s = 0; /*Socketdescriptor*/
void* buffer = NULL;
long total_sent_packets = 0;
int main(int argc, char* argv[])
{
buffer = (void*)malloc(BUF_SIZE); /*Buffer for ethernet frame*/
unsigned char* etherhead = buffer; /*Pointer to ethenet header*/
unsigned char* data = buffer + 14; /*Userdata in ethernet frame*/
struct ethhdr *eh = (struct ethhdr *)etherhead; /*Another pointer to ethernet header*/
unsigned char src_mac[6]; /*our MAC address */
unsigned char dest_mac[6] = {0x00, 0x1E, 0x4F, 0xB1, 0xCB, 0x43}; /*MAC address, hardcoded...... :-(*/
struct ifreq ifr;
struct sockaddr_ll socket_address;
int ifindex = 0; /*Ethernet Interface index*/
int i,j,k;
int length; /*length of received packet*/
int sent; /*length of sent packet*/
/*stuff for time measuring: */
struct timeval begin;
struct timeval end;
struct timeval result;
unsigned long long allovertime;
printf("Client started, entering initialiation phase...\n");
/*open socket*/
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (s == -1) {
perror("socket():");
exit(1);
}
printf("Successfully opened socket: %i\n", s);
/*retrieve ethernet interface index*/
strncpy(ifr.ifr_name, ETH0, IFNAMSIZ);
if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) {
perror("SIOCGIFINDEX");
exit(1);
}
ifindex = ifr.ifr_ifindex;
printf("Successfully got interface index: %i\n", ifindex);
/*retrieve corresponding MAC*/
if (ioctl(s, SIOCGIFHWADDR, &ifr) == -1) {
perror("SIOCGIFINDEX");
exit(1);
}
for (i = 0; i < 6; i++) {
src_mac[i] = ifr.ifr_hwaddr.sa_data[i];
}
printf("Successfully got our MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
src_mac[0],src_mac[1],src_mac[2],src_mac[3],src_mac[4],src_mac[5]);
/*prepare sockaddr_ll*/
socket_address.sll_family = PF_PACKET;
socket_address.sll_protocol = htons(ETH_P_IP);
socket_address.sll_ifindex = ifindex;
socket_address.sll_hatype = ARPHRD_ETHER;
socket_address.sll_pkttype = PACKET_OTHERHOST;
socket_address.sll_halen = ETH_ALEN;
socket_address.sll_addr[0] = dest_mac[0];
socket_address.sll_addr[1] = dest_mac[1];
socket_address.sll_addr[2] = dest_mac[2];
socket_address.sll_addr[3] = dest_mac[3];
socket_address.sll_addr[4] = dest_mac[4];
socket_address.sll_addr[5] = dest_mac[5];
socket_address.sll_addr[6] = 0x00;
socket_address.sll_addr[7] = 0x00;
/*establish signal handler*/
signal(SIGINT, sigint);
printf("Successfully established signal handler for SIGINT\n");
/*init random number generator*/
srand(time(NULL));
printf("We are in production state, sending packets to: %02X:%02X:%02X:%02X:%02X:%02X\n",
dest_mac[0],dest_mac[1],dest_mac[2],dest_mac[3],dest_mac[4],dest_mac[5]);
for (i = 50; i <= 1500; i += 50) {
allovertime = 0;
for (k = 0; k < NUMBER_OF_MESUREMENTS_PER_AMOUNT_OF_DATA; k++) {
/*prepare buffer*/
memcpy((void*)buffer, (void*)dest_mac, ETH_MAC_LEN);
memcpy((void*)(buffer+ETH_MAC_LEN), (void*)src_mac, ETH_MAC_LEN);
eh->h_proto = ETH_P_NULL;
/*fill it with random data....*/
for (j = 0; j < i; j++) {
data[j] = (unsigned char)((int) (256.0*rand()/(RAND_MAX+1.0)));
}
/*clear the timers:*/
timerclear(&begin);
timerclear(&end);
/*get time before sending.....*/
gettimeofday(&begin,NULL);
/*send packet*/
sent = sendto(s, buffer, i+ETH_HEADER_LEN, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
if (sent == -1) {
perror("sendto():");
exit(1);
}
/*Wait for incoming packet...*/
length = recvfrom(s, buffer, BUF_SIZE, 0, NULL, NULL);
if (length == -1) {
perror("recvfrom():");
exit(1);
}
/*get time after sending.....*/
gettimeofday(&end,NULL);
/*...and calculate difference.........*/
timersub(&end,&begin,&result);
allovertime += ((result.tv_sec * 1000000 ) + result.tv_usec );
total_sent_packets++;
}
printf("Sending %i bytes takes %lld microseconds in average\n",i ,allovertime/NUMBER_OF_MESUREMENTS_PER_AMOUNT_OF_DATA);
}
return (0);
}
void sigint(int signum) {
/*Clean up.......*/
struct ifreq ifr;
if (s == -1)
return;
strncpy(ifr.ifr_name, ETH0, IFNAMSIZ);
ioctl(s, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags &= ~IFF_PROMISC;
ioctl(s, SIOCSIFFLAGS, &ifr);
close(s);
free(buffer);
printf("Client terminating....\n");
printf("Totally sent: %ld packets\n", total_sent_packets);
exit(0);
}
------------------ server.c ---------------------
#include "server.h"
#include "util.h"
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <asm/types.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#define BUF_SIZE ETH_FRAME_TOTALLEN
int s = 0; /*Socketdescriptor*/
void* buffer = NULL;
long total_packets = 0;
long answered_packets = 0;
int main(int argc, char* argv[])
{
buffer = (void*)malloc(BUF_SIZE); /*Buffer for Ethernet Frame*/
unsigned char* etherhead = buffer; /*Pointer to Ethenet Header*/
struct ethhdr *eh = (struct ethhdr *)etherhead; /*Another pointer to ethernet header*/
unsigned char src_mac[6]; /*our MAC address*/
struct ifreq ifr;
struct sockaddr_ll socket_address;
int ifindex = 0; /*Ethernet Interface index*/
int i;
int length; /*length of received packet*/
int sent;
printf("Server started, entering initialiation phase...\n");
/*open socket*/
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (s == -1) {
perror("socket():");
exit(1);
}
printf("Successfully opened socket: %i\n", s);
/*retrieve ethernet interface index*/
strncpy(ifr.ifr_name, ETH0, IFNAMSIZ);
if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) {
perror("SIOCGIFINDEX");
exit(1);
}
ifindex = ifr.ifr_ifindex;
printf("Successfully got interface index: %i\n", ifindex);
/*retrieve corresponding MAC*/
if (ioctl(s, SIOCGIFHWADDR, &ifr) == -1) {
perror("SIOCGIFINDEX");
exit(1);
}
for (i = 0; i < 6; i++) {
src_mac[i] = ifr.ifr_hwaddr.sa_data[i];
}
printf("Successfully got our MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
src_mac[0],src_mac[1],src_mac[2],src_mac[3],src_mac[4],src_mac[5]);
/*prepare sockaddr_ll*/
socket_address.sll_family = PF_PACKET;
socket_address.sll_protocol = htons(ETH_P_IP);
socket_address.sll_ifindex = ifindex;
socket_address.sll_hatype = ARPHRD_ETHER;
socket_address.sll_pkttype = PACKET_OTHERHOST;
socket_address.sll_halen = ETH_ALEN;
socket_address.sll_addr[6] = 0x00;
socket_address.sll_addr[7] = 0x00;
/*establish signal handler (keyboard)*/
signal(SIGINT, sigint);
printf("Successfully established signal handler for SIGINT\n");
printf("We are in production state, waiting for incoming packets....\n");
while (1) {
/*Wait for incoming packet...*/
length = recvfrom(s, buffer, BUF_SIZE, 0, NULL, NULL);
if (length == -1) {
perror("recvfrom():");
exit(1);
}
/*See if we should answer (Ethertype == 0x0 && destination address == our MAC)*/
if (eh->h_proto == ETH_P_NULL && memcmp( (const void*)eh->h_dest, (const void*)src_mac, ETH_MAC_LEN) == 1 )
{
/*exchange addresses in buffer*/
memcpy( (void*)etherhead, (const void*)(etherhead+ETH_MAC_LEN), ETH_MAC_LEN);
memcpy( (void*)(etherhead+ETH_MAC_LEN), (const void*)src_mac, ETH_MAC_LEN);
/*prepare sockaddr_ll*/
socket_address.sll_addr[0] = eh->h_dest[0];
socket_address.sll_addr[1] = eh->h_dest[1];
socket_address.sll_addr[2] = eh->h_dest[2];
socket_address.sll_addr[3] = eh->h_dest[3];
socket_address.sll_addr[4] = eh->h_dest[4];
socket_address.sll_addr[5] = eh->h_dest[5];
/*send answer*/
sent = sendto(s, buffer, length-4, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
if (sent == -1) {
perror("sendto():");
exit(1);
}
answered_packets++;
}
total_packets++;
}
}
void sigint(int signum) {
/*Clean up.......*/
struct ifreq ifr;
if (s == -1)
return;
strncpy(ifr.ifr_name, ETH0, IFNAMSIZ);
ioctl(s, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags &= ~IFF_PROMISC;
ioctl(s, SIOCSIFFLAGS, &ifr);
close(s);
free(buffer);
printf("Server terminating....\n");
printf("Totally received: %ld packets\n", total_packets);
printf("Answered %ld packets\n", answered_packets);
exit(0);
}
答案 0 :(得分:0)
很抱歉所有的代码,但我不知道如何缩短它,因为我不知道错误在哪里。无论如何,我发现了这个问题,所以为“代码墙”家伙道歉!
事实证明问题在于我们的交换机是如何配置的。在同一个子网上有两台机器后,代码运行得很漂亮!