2011-07-23 33 views
3

仔細閱讀問題,以提出解決方案,請添加ARP表項的Linux

我需要在Linux中增添永久 ARP表項莫名其妙。

問題是:如果我通過shell或通過套接字添加一個條目,它總是得到標誌0x6。即使我使用在其中指定標誌的代碼發佈,它仍然是相同的,0x6。

我發現了大約爲0x6將此信息:

的通知 「爲0x6」 的ARP標誌。具有標誌0x6的ASIC ARP條目是 MAC-cache相關條目。這是由安裝會話的 時arp查找失敗引起的。會話將嘗試使用傳入數據包的源MAC 地址,但使用此地址不是必需的。當回覆數據包到達時,我們可以獲得MAC地址 發送ARP數據包到源主機。

所以我隨時添加任何ARP表項,然後我平相同的IP地址,它總是導致ARP請求廣播

問題是,有沒有辦法如何添加一個永久的ARP條目與適當的標誌?因此,我添加一個條目,並在事後任何通信的情況下,不會是任何ARP廣播?

順便說一句,要進什麼我最多:我發送含有PC1的IP和MAC PC1廣播(L3),PC2獲取數據包,並添加地址,他們到ARP表,建立TCP會話,但總是首先運行ARP廣播。

通過shell:

#!/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

0×06的標誌值表示該條目是完全和永久。所以我猜你的shell腳本足以添加靜態arp條目。這裏是相關的標誌值 -

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

您發佈的標誌0x06的定義與linux內核無關。

您看到arp請求的原因可能是由於拓撲或IP尋址中的問題。你能發佈這些細節嗎?或者,您可以在PC2執行arp請求的地方發佈數據包跟蹤,即使它具有靜態arp條目。