Добавить арп запись Linux - PullRequest
3 голосов
/ 23 июля 2011

Внимательно прочитайте вопрос, чтобы предложить решение, пожалуйста

Мне нужно как-то добавить постоянную запись arp в Linux.

Проблема в следующем: если я добавляю запись через оболочку или через сокеты, она всегда получает флаг 0x6 .Даже если я использую код, размещенный здесь, где я указываю флаг, он остается тем же, 0x6.

Я нашел эту информацию о флаге 0x6:

Обратите внимание на флаг ARP "0x6".Запись ASIC ARP с флагом 0x6 является связанной с MAC-кэшем записью.Это вызвано ошибкой поиска arp при установке сеанса.Сеанс попытается использовать исходный MAC-адрес входящего пакета, но это не обязательно для использования этого MAC-адреса.Мы можем получить MAC-адрес, когда приходит ответный пакет, отправив пакет ARP исходному хосту.

Поэтому, когда я добавляю любую запись arp, то я пингую один и тот же IP-адрес, это всегда приводит к Трансляция ARP-запроса .

Вопрос в том, есть ли способ, как добавить постоянную запись ARP с соответствующим флагом?Поэтому я добавляю запись, и в случае каких-либо сообщений впоследствии не будет никакой трансляции ARP?

Кстати, чтобы понять, что я собираюсь сделать: я отправляю трансляцию (L3) изПК1, содержащий IP-адрес и MAC-адрес ПК1, ПК2 получает пакет и добавляет их адреса в таблицу ARP и устанавливает сеанс TCP, но всегда сначала запускает трансляцию ARP.

через оболочку:

#!/bin/sh
arp -s $1 $2 2>/dev/null

через сокеты:

char *mac_ntoa(unsigned char *ptr){
    static char address[30];

    sprintf(address, "%02X:%02X:%02X:%02X:%02X:%02X",
        ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);

    return(address);
} /* End of mac_ntoa */

int mac_aton(char *addr, unsigned char *ptr){
    int i, v[6];
    if((i = sscanf(addr, "%x:%x:%x:%x:%x:%x", &v[0], &v[1], &v[2], &v[3],
            &v[4], &v[5])) !=6){

        fprintf(stderr, "arp: invalid Ethernet address '%s'\n", addr);
        return(1);
    } /* End of If*/

    for(i = 0; i < 6; i++){
        ptr[i] = v[i];
    } /* End of For */

    return(0);
}

int main(int argc, char* argv[]){
    if(argc < 3 || argc > 4){
        fprintf(stderr,"usage: %s <ip_addr> <hw_addr> [temp|pub|perm|trail]\n",
            argv[0]);
        fprintf(stderr, "default: temp.\n");
        exit(-1);
    } /* End of If */

    int s, flags;
    char *host = argv[1];

    struct arpreq req;
    struct hostent *hp;
    struct sockaddr_in *sin;

    bzero((caddr_t)&req, sizeof(req)); /* caddr_t is not really needed. */

    sin = (struct sockaddr_in *)&req.arp_pa;
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = inet_addr(host);

    if(sin->sin_addr.s_addr ==-1){
        if(!(hp = gethostbyname(host))){
            fprintf(stderr, "arp: %s ", host);
            herror((char *)NULL);
            return(-1);
        } /* End of If */
        bcopy((char *)hp->h_addr,
            (char *)&sin->sin_addr, sizeof(sin->sin_addr));
    } /* End of If */

    if(mac_aton(argv[2], req.arp_ha.sa_data)){ /* If address is valid... */
        return(-1);
    }

    argc -=2;
    argv +=2;

    flags = ATF_PERM | ATF_COM;

    while(argc-- > 0){
        if(!(strncmp(argv[0], "temp", 4))){
            flags &= ~ATF_PERM;
        } else if(!(strncmp(argv[0], "pub", 3))){
            flags |= ATF_PUBL;
        } else if(!(strncmp(argv[0], "trail", 5))){
            flags |= ATF_USETRAILERS;
        } else if(!(strncmp(argv[0], "dontpub", 7))){ /* Not working yet */
            flags |= ATF_DONTPUB;
        } else if(!(strncmp(argv[0], "perm", 4))){
            flags = ATF_PERM;
        } else {
            flags &= ~ATF_PERM;
        } /* End of Else*/
    argv++;
    }/* End of While */

    req.arp_flags = flags; /* Finally, asign the flags to the structure */
    strcpy(req.arp_dev, "eth0"); /* Asign the device.  */

    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
        perror("socket() failed.");
        exit(-1);
    } /* End of If */

    if(ioctl(s, SIOCSARP, (caddr_t)&req) <0){ /* caddr_t not really needed. */
        perror(host);
        exit(-1);
    } /* End of If */

    printf("ARP cache entry successfully added.\n");
    close(s);
    return(0);
}

1 Ответ

1 голос
/ 24 июля 2011
Значение флага

0x06 означает, что запись завершена и является постоянной.Поэтому я думаю, что ваш скрипт достаточно хорош для добавления статической записи arp.Вот соответствующие значения флага -

#define ATF_COM 0x02        /* completed entry (ha valid)   */
#define ATF_PERM    0x04        /* permanent entry      */

Определение отправленного вами флага 0x06 не связано с ядром Linux.

Причина, по которой вы видите запрос arp, может быть вызванак проблемам в вашей топологии или IP-адресации.Можете ли вы опубликовать эти детали?Или вы можете опубликовать трассировку пакета, где PC2 выполняет запрос arp, даже если у него есть статическая запись arp.

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