2012-11-28 13 views
5

Tôi biết rằng âm thanh lạ. printf không nên thay đổi bất cứ điều gì, nhưng không có nó sendTo thất bại. Chương trình được sao chép từ mã c và được biên dịch bởi trình biên dịch cpp trên ubuntux86. Tôi có một chương trình gửi yêu cầu arp. nếu không có printf này thì sendTo không thành công. Điều kỳ lạ là tôi đã làm một chương trình tối thiểu mà không sử dụng trong biến printf ở tất cả (chỉ trong printf) và với printf nó hoạt động và không có printf nó không hoạt động (nhận lỗi đối số không hợp lệ trên sendTo) .Thêm thay đổi printf gửiĐến kết quả từ lỗi thành công

Các đính kèm là một phiên bản tối thiểu chỉ cho thấy vấn đề:

sendto này thất bại:

int retVal = sendto(arp_fd, &pkt, sizeof(pkt), 0, (struct sockaddr *) &sa,sizeof(sa)); 
if (retVal < 0) { 
    perror("sendto"); 
    close(arp_fd); 
    exit(1); 
} 

khi thêm nó này công việc:

struct ifreq ifr;//There is no use except in the printf 
printf("MAC address: is %02x:%02x:%02x:%02x:%02x:%02x \n", 
     ifr.ifr_hwaddr.sa_data[0]&0xFF, 
     ifr.ifr_hwaddr.sa_data[1]&0xFF, 
     ifr.ifr_hwaddr.sa_data[2]&0xFF, 
     ifr.ifr_hwaddr.sa_data[3]&0xFF, 
     ifr.ifr_hwaddr.sa_data[5]&0xFF, 
     ifr.ifr_hwaddr.sa_data[4]&0xFF); 

hoàn chỉnh chương trình:

#include "sys/socket.h" 
#include "sys/types.h" 
#include "stdio.h" 
#include "unistd.h" 
#include "string.h" 
#include "net/if.h" 
#include "stdlib.h" 
#include "arpa/inet.h" 
#include "netinet/in.h" 
#include "sys/ioctl.h" 
#include "netpacket/packet.h" 
#include "net/ethernet.h" 

#define ETHER_TYPE_FOR_ARP 0x0806 
#define HW_TYPE_FOR_ETHER 0x0001 
#define OP_CODE_FOR_ARP_REQ 0x0001 
#define HW_LEN_FOR_ETHER 0x06 
#define HW_LEN_FOR_IP 0x04 
#define PROTO_TYPE_FOR_IP 0x0800 

typedef unsigned char byte1; 
typedef unsigned short int byte2; 
typedef unsigned long int byte4; 

// For Proper memory allocation in the structure 
#pragma pack(1) 
typedef struct arp_packet { 
// ETH Header 
    byte1 dest_mac[6]; 
    byte1 src_mac[6]; 
    byte2 ether_type; 
// ARP Header 
    byte2 hw_type; 
    byte2 proto_type; 
    byte1 hw_size; 
    byte1 proto_size; 
    byte2 arp_opcode; 
    byte1 sender_mac[6]; 
    byte4 sender_ip; 
    byte1 target_mac[6]; 
    byte4 target_ip; 
// Paddign 
    char padding[18]; 
} ARP_PKT; 

int main() { 
    struct sockaddr_ll sa; 

// Ethernet Header 
    ARP_PKT pkt; 
    memset(pkt.dest_mac, 0xFF, (6 * sizeof(byte1))); 
    memset(pkt.src_mac, 0x1, (6 * sizeof(byte1))); 
    pkt.ether_type = htons(ETHER_TYPE_FOR_ARP); 
// ARP Header 
    pkt.hw_type = htons(HW_TYPE_FOR_ETHER); 
    pkt.proto_type = htons(PROTO_TYPE_FOR_IP); 
    pkt.hw_size = HW_LEN_FOR_ETHER; 
    pkt.proto_size = HW_LEN_FOR_IP; 
    pkt.arp_opcode = htons(OP_CODE_FOR_ARP_REQ); 
    memcpy(pkt.sender_mac, pkt.src_mac, (6 * sizeof(byte1))); 
    pkt.sender_ip = 2449647808; 
    memset(pkt.target_mac, 0, (6 * sizeof(byte1))); 
    pkt.target_ip = inet_addr("10.0.0.10"); 
// Padding 
    memset(pkt.padding, 0, 18 * sizeof(byte1)); 

    sa.sll_family = AF_PACKET; 
    sa.sll_ifindex = 3; 
    sa.sll_protocol = htons(ETH_P_ARP); 

    /* Send it! */ 
    int arp_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); 
    struct ifreq ifr; 
    printf("MAC address: is %02x:%02x:%02x:%02x:%02x:%02x \n", 
      ifr.ifr_hwaddr.sa_data[0]&0xFF, 
      ifr.ifr_hwaddr.sa_data[1]&0xFF, 
      ifr.ifr_hwaddr.sa_data[2]&0xFF, 
      ifr.ifr_hwaddr.sa_data[3]&0xFF, 
      ifr.ifr_hwaddr.sa_data[5]&0xFF, 
      ifr.ifr_hwaddr.sa_data[4]&0xFF); 
    int retVal = sendto(arp_fd, &pkt, sizeof(pkt), 0, (struct sockaddr *) &sa,sizeof(sa)); 
    if (retVal < 0) { 
     perror("sendto"); 
     close(arp_fd); 
     exit(1); 
    } 

    printf("\n=========PACKET=========\n"); 
    return 0; 
} 
+0

Điều gì đã xảy ra khi không thành công? Bạn có gặp lỗi do mã của bạn in không? – unwind

+0

Lỗi là: sendto: Đối số không hợp lệ được in bởi perror ("sendto"); –

+0

thêm 'printf (" [% d] ", errno)' sau 'perror'. Bạn có thấy mã nào không? –

Trả lời

2

Điều này là do bạn có giá trị chưa được khởi tạo trong struct sockaddr_ll sa. Cụ thể hơn, lệnh gọi printf của bạn buộc trình biên dịch lưu ba thanh ghi trên ngăn xếp do đó di chuyển sa vị trí và giá trị của nó. Bạn có thể printf("halen %p %d\n", &sa.sll_halen, sa.sll_halen);trướcprintf để xem thay đổi tùy thuộc vào thời điểm bạn thêm printf của mình hay không.

Chỉ cần thêm sa.sll_halen = 0; để xem sự khác biệt ... Và đối với chương trình thực sự của bạn, hãy khởi tạo toàn bộ cấu trúc.

+0

Bạn có thể mở rộng câu trả lời của mình không. Tôi không hiểu lý do, nhưng dammm bạn là chính xác và không phải tất cả các công cụ byte :) –