2013-01-15 40 views
1

我有一個C結構是這樣的...8位輸入給奇怪的行爲爲16/32位使小端/大端

struct icmp_prefixopt { 
    u_int8_t  icmpopt_type; 
    u_int8_t  icmpopt_len; 
    u_int8_t  prefixlen; 
    u_int8_t  lflag:1; 
    u_int8_t  aflag:1; 
    u_int8_t  reserved:6; 

}; 

,我已經同一個模塊中值提供給會員這樣 -

popt= (struct icmp_prefixopt *) 
        malloc(sizeof(struct icmp_prefixopt)); 

    popt->icmpopt_type = 3; 
    popt->icmpopt_len = 4; 
    popt->prefixlen = (u_int8_t)strtoul(arg, (char **)NULL, 0); 

    arg = index(arg, '+'); 
      if (arg) { 
        ++arg; 
        popt->lflag = ((u_int8_t)strtoul(arg, (char **)NULL, 0))&1; 
      } 


    arg = index(arg, '+'); 
      if (arg) { 
        ++arg; 
        popt->aflag = ((u_int8_t)strtoul(arg, (char **)NULL, 0))&1; 
      } 


    arg = index(arg, '+'); 
      if (arg) { 
        ++arg; 
       popt->reserved = 32; //((u_int8_t)strtoul(arg, (char **)NULL, 0))<<2; 
      } 

其中arg是傳遞給此模塊的命令行參數。

現在看看結構的內容執行後十六進制格式 - >

03 04 20 81 

    icmpopt_type: seems fine 
    icmpopt_len: seems fine 
    prefixlen: seems fine 

但位貌似轉回他們的其他3個字段構成針對字節

lflag:1; aflag:1; reserved:6 

所以它應該有已經 - 10100000=A0但實際上他們是=>81=10000001

它給我提出了很多問題...

  1. 與小端/大端有什麼關係?

  2. 如果是,那麼htonl和htons等8位函數對應的是什麼。

  3. 如果不是,可能是什麼問題或者我誤解了某些東西?

  4. 什麼是最佳方法?要修改結構
    本身內的這些字段的順序或應用一些位運算符和位本身的位移?

在命令啉

32+1+0+32 

該最終32提供的輸入這裏也是沒有用處的,因爲我已經在模塊本身用於測試固定32。 雖然我的實際目的也需要考慮這個領域。

請儘快以其他方式幫助我。

Thanx提前。

編輯:

enter image description here

這是實際的結構,我需要創建和創建一起,需要作出了規定,爲用戶通過圖形用戶界面中的所有字段指定值。 (現在只能通過linux命令行)。

我想我現在已經明確了這個問題,但如果需要更多的信息,我會很樂意補充。

回答

5

編譯器如何選擇打包位字段完全取決於實現。它不一定與字節順序有關。

htnol(以及類似的)不適用於比特字段。如果您需要保證訂單,那麼您需要自行手動打包uint8_t。例如:

struct icmp_prefixopt { 
    u_int8_t  icmpopt_type; 
    u_int8_t  icmpopt_len; 
    u_int8_t  prefixlen; 
    u_int8_t  stuff; 
} 

... 

popt->stuff = (lflag << 7) | (aflag << 6); 

當然,在實踐中,你應該用理智#define真是讓人不是魔術數字(6,7)。你可能會決定把它包裝在一堆setter和getter函數中。

+0

我編輯了這個問題......請看看..! –

+0

@UditGupta:好的。看到我更新的答案。 –

+0

謝謝...因爲我是一個開工者,所以你還可以提供一些標準的代碼片段示例或任何相關的鏈接,可以幫助我處理更復雜的問題,如更進一步......正如你所說的使用'#define's –