2014-04-08 39 views
2

我正在Mac OS X中進行一些插入(基本上攔截C調用),我注意到ping應用程序試圖調用addrlen值爲16的sendto函數。在sys/socket.h中,我可以清楚地看到,sa_data陣列只可容納多達14個字節:struct sockaddr.sa_data看起來太小

/* 
* [XSI] Structure used by kernel to store most addresses. 
*/ 
struct sockaddr { 
    __uint8_t sa_len;  /* total length */ 
    sa_family_t sa_family; /* [XSI] address family */ 
    char  sa_data[14]; /* [XSI] addr value (actually larger) */ 
}; 

這讓我樂不可支的評論說,「其實大」,但並沒有太多我可以做的。

反正,男人頁面顯示sendto函數簽名看起來是這樣的:

ssize_t 
sendto(int socket, 
    const void *buffer, 
    size_t length, 
    int flags, 
    const struct sockaddr *dest_addr, 
    socklen_t dest_len); 

然後該男子頁特別提出做什麼,如果長度值過長的消息是自動交付。它忽略了dest_len大於dest_addr.sa_data可容納的情況。

如果我嘗試將16字節的數據複製到調用方的另一個dest_addr.sa_data中,它將失敗並且應用程序崩潰,因爲它應該如此。我誤解了這個領域是如何使用的?爲什麼標題中的註釋會說「實際上較大」,但是會爲該數組指定一個固定大小?

+2

好的,'sockaddr'是一種通用結構,實際上你會通過'sockaddr_in'等。如果你的測試崩潰了,你確定你有正確的地址族設置?請發佈您使用的代碼 - 或者只是相關的位。 – trojanfoe

回答

1

你從來沒有真的應該使用struct sockaddr。這就像voidvoid *,這是一個實際sockaddr_foo結構的替身。

+0

謝謝,現在開始變得更有意義了。像sendto這樣的函數在被調用時如何知道使用哪個結構?它是否會查看'sa_family',然後根據它選擇正確的'sockaddr_foo'?有沒有一個頭文件將'sa_family'映射到'sockaddr_foo'? –

+0

我要爲此添加一個新問題。您的答案正是我需要開始找到合適的資源。 –