聘我网

新概念招聘3.0

sendto error!: Permission denied是怎么回事?

vote up0vote downstar
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>

int in_cksum(u_short *p, int n);

int main (int argc, char **argv)
{
    int icmp_socket, ret;
    char buffer[1024];
    struct sockaddr_in you_addr, your_addr;
    struct icmp *p,*icmp;
    unsigned int sl;
    struct ip *ip;
    int hlen;

    if ((icmp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP))<0) {
        perror("socket error :");
        exit(0);
    }

    memset(buffer, 0x00, 1024);

    // make icmp packet
    p = (struct icmp *) buffer;
    p->icmp_type = ICMP_ECHO;
    p->icmp_code = 0;
    p->icmp_cksum = 0;
    p->icmp_seq = 15;
    p->icmp_id = getpid();

    p->icmp_cksum = in_cksum((u_short *)p, 1000);
    memset(&you_addr,0,sizeof(0));
    you_addr.sin_addr.s_addr = inet_addr(argv[1]);
    you_addr.sin_family = AF_INET;

    //sent icmp packet to d host
    ret = sendto(icmp_socket, p, sizeof(*p), MSG_DONTWAIT, (struct sockaddr *)&you_addr, sizeof(you_addr));
    if (ret<0){
        perror("sendto error!");
    }

    //wait icmp reply 
    sl= sizeof(your_addr);
    ret= recvfrom(icmp_socket, buffer, 1024,0,(struct sockaddr *)&your_addr, &sl);
    if(ret<0){
        printf("%d %d %d\n", ret,errno, EAGAIN);
        perror("recvfrom error!");
    }

    //when receive the reply output the ip and icmp packet info.
    ip = (struct ip *)buffer;
    hlen= ip->ip_hl*4;
    icmp = (struct icmp *)(buffer+hlen);
    printf("reply from %s\n", inet_ntoa(your_addr.sin_addr));
    printf("TYPE: %d \n", icmp->icmp_type);
    printf("CODE: %d \n", icmp->icmp_code);
    printf("SEQ: %d \n", icmp->icmp_seq);
    printf("ID: %d \n", icmp->icmp_id);
    return 1;
}

int in_cksum(u_short *p, int n)
{
    register u_short answer;
    register long sum = 0;
    u_short odd_byte = 0;

    while(n >1)
    {
        sum += *p++;
        n-=2;
    }

    if (n==1)
    {
        *(u_char*)(&odd_byte)=*(u_char*)p;
        sum+=odd_byte;
    }

    sum = (sum>>16)+(sum&0xffff);
    sum+=(sum>>16);

    answer = ~sum;

    return (answer);
}

上面这段代码,我以root运行,而且iptables所有禁止ICMP的规则都已注释,但运行:

./ping baidu.com

时还是会报:

sendto error!: Permission denied

这是怎么回事呢?

 

1 个答复

vote up0vote downcheck

inet_addr的参数必须是IP地址,不能是域名。

所以这个程序只可以这样运行:

./ping 220.181.111.85

或者将inet_addr替换成这个函数:

in_addr_t inet_addr_wrapper(const char *cp){
    if(-1 == inet_network(cp)){
        struct hostent *hp;
        hp = gethostbyname (cp);
        return *(in_addr_t *)hp->h_addr_list[0];
    }
    else{
        return inet_addr(cp);
    }
}
链接

您的回答





不是您要找的问题? 浏览其他含有标签 的问题或者 自己问个.