2014-10-09 107 views
2

我正在使用IPv6中的RSVP協議併爲了使其工作,我必須在發送的消息中設置IPv6路由器警報。我在互聯網上做了大量的研究,但沒有運氣,也許以前有人已經這樣做過。你可以在下面找到我用於測試的代碼。如何在消息中設置IPv6路由器警報選項

#include <stdio.h> 
#include <string.h> 
#include <errno.h> 

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

#define DATA_LENGTH  124 

int main() { 
    int data_length = DATA_LENGTH; 

    unsigned char data[DATA_LENGTH] = {0x10, 0x01, 0xb0, 0x16, 0xff, 0x00, 0x00, 0x7c, 0x00, 0x18, 
     0x01, 0x02, 0x20, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     0x00, 0x10, 0x32, 0x00, 0x20, 0xc2, 0x00, 0x18, 0x03, 0x02, 0x20, 0x02, 0x00, 0x01, 0x00, 0x00, 
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
     0x0b, 0x02, 0x20, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     0x00, 0x20, 0x00, 0x00, 0x5d, 0x27, 0x00, 0x08, 0x05, 0x01, 0x00, 0x00, 0x75, 0x30, 0x00, 0x24, 
     0x0c, 0x02, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x06, 0x7f, 0x00, 0x00, 0x05, 0x49, 0x55, 
     0x9f, 0x80, 0x4a, 0xba, 0xeb, 0x90, 0x4c, 0xee, 0xa8, 0x31, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 
     0x05, 0xdc}; 

    unsigned char dest_address[16] = {0x20, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05}; 

    int socket_descriptor; 
    struct sockaddr_in6 dest; 
    const int yes = 1; 
    const int router_alert_value = 0; 

    socket_descriptor = socket(AF_INET6, SOCK_RAW, IPPROTO_RSVP); 

    if (socket_descriptor < 0) { 
     perror("Can't open socket to send path message\n"); 
    } 

    memset(&dest, 0, sizeof(dest)); 

    dest.sin6_family = AF_INET6; 
    memcpy(dest.sin6_addr.s6_addr, dest_address, sizeof(struct in6_addr)); 

    dest.sin6_port = 0; 
    dest.sin6_flowinfo = 0; 

    if (setsockopt(socket_descriptor, SOL_SOCKET, 
      SO_REUSEADDR,(const void *)&yes, sizeof(yes)) < 0) { 
     printf("setsockopt(%d): %s\n", SO_REUSEADDR, strerror(errno)); 
    } 

    if(setsockopt(socket_descriptor, IPPROTO_IPV6, 
      IPV6_HOPOPTS, &yes, sizeof(yes)) < 0) { 
     printf("Can't set Hop-by-hop Option: %s\n", strerror(errno)); 
    } 

    if(setsockopt(socket_descriptor, IPPROTO_IPV6, IPV6_ROUTER_ALERT, 
      (const void *) &router_alert_value, sizeof(router_alert_value)) < 0) { 
     printf("Can't set IP Options: %s\n", strerror(errno)); 
    } 

    if(sendto(socket_descriptor, data, data_length, 0, 
      (struct sockaddr*) &dest, sizeof(dest)) < 0) { 
     printf("Error in sending message : %s (%d)\n", strerror(errno), errno); 
    } 

    close(socket_descriptor); 

    return(0); 
} 

上述代碼編譯併發送RSVP Path消息,但沒有IPv6路由器警報選項。由於我沒有回,當我使用setsockopt方法來得到錯誤,我可以爲你提供控制檯輸出是:

Can't set Hop-by-hop Option: Invalid argument 
Can't set IP Options: Protocol not available 

我一直在使用一個插座與協議0做了一些嘗試(爲了使用逐跳下一個標題),並將路由器警報選項直接添加到數據中,但仍不起作用。

任何想法或主角是讚賞。

+0

我不確定IPv6套接字,但除此之外,當您使用SOCK_RAW時,您必須創建您發送的完整數據包,標題和全部數據包。除非'data'包含一個完整的IPv6數據包(帶有IPv6標頭,RSVP標頭,*和* RSVP數據),否則它將不起作用。 – 2014-10-09 11:42:33

+0

是的,我也這麼認爲,但是我的信息是用正確的IPv6標題和正確的有效載荷出去的。這只是缺少的路由器警報選項。沒有'data'只包含RSVP頭和RSVP數據,它只是我的消息的數據有效載荷。 – grattmandu03 2014-10-09 11:45:42

+0

好的,閱讀[本手冊頁](http://man7.org/linux/man-pages/man7/ipv6.7.html)'IPV6_ROUTER_ALERT'選項不會設置*路由器警報跳轉 - hop選項,而不是該選項使帶有逐跳警報的傳入數據包被髮送到套接字。 – 2014-10-09 11:53:30

回答

0

在帶有WinSock的Windows上,您可以使用IPV6_HDRINCL來構建IP標頭並設置路由器警報標誌。在Linux和類似平臺上,這根本不可用,您只需使用類似於Wireshark和tcpdumpAF_PACKET即可下載到raw packets,並根據您的要求手動構建手工包。

當然的替代方案是在內核中提出並實現新的接口來設置IPv6路由器警報。