ASN.1
ASN.1解析器要求
編譯器需要4個輸入文件:協議的ASN.1描述,.cnf文件和兩個模板文件。ASN.1規范可能必須進行編輯才能工作,但是正在進行工作,至少讀取所有ASN1規范。不建議更改ASN1文件,因為這會在更新協議時產生問題。H.248二進制編碼分解器是一個變化相對較小的分解器的好例子
構建基于ASN.1的插件
構建基于ASN.1的解析器的通常方法是將其放入 epan / dissectors / asn1子樹中。這種方法效果很好,并且比作為插件構建要簡單一些,但是有兩個原因可能導致人們希望將其構建為插件:
- 為了加快開發速度,因為只有插件需要重新編譯。
- 由于只需要分發插件,因此可以靈活地部署更新的插件。
原因之一可能不希望建立一個插件:
代碼有些復雜。
CMakeFile復雜得多。
在asn1子樹下進行構建可將所有此類解析器保持在一起。
了解錯誤消息
運行asn2wrs時,可能會出現以下錯誤:
LexToken錯誤(
*main*.ParseError: LexToken(DOT,'.',71))表示點(。)周圍的ASN1文件第71行中不理解的內容-可能是點本身。ParseError(
*main*.ParseError: LexToken(SEMICOLON,';',88))表示“;” (SEMICOLON)不被理解。也許刪除它會起作用?命令行語法
ASN.1到Wireshar解析器編譯器
asn2wrs [-h|?] [-d dbg] [-b] [-p proto] [-c cnf_file] [-e] input_file(s) ... -h|? : Usage -b : BER (default is PER) -u : Unaligned (default is aligned) -p proto : Protocol name (implies -S). Default is module-name from input_file (renamed by #.MODULE if present) -o name : Output files name core (default is <proto>) -O dir : Output directory for dissector -c cnf_file : Conformance file -I path : Path for conformance file includes -e : Create conformance file for exported types -E : Just create conformance file for exported types -S : Single output for multiple modules -s template : Single file output (template is input file without .c/.h extension) -k : Keep intermediate files though single file output is used -L : Suppress #line directive from .cnf file -D dir : Directory for input_file(s) (default: '.') -C : Add check for SIZE constraints -r prefix : Remove the prefix from type names input_file(s) : Input ASN.1 file(s) -d dbg : Debug output, dbg = [l][y][p][s][a][t][c][m][o] l - lex y - yacc p - parsing s - internal ASN.1 structure a - list of assignments t - tables c - conformance values m - list of compiled modules with dependency o - list of output files分步說明
- 在epan / dissectors / asn1目錄中為協議創建目錄,并將ASN.1文件放在此處。
- 從另一個ASN.1解剖器 復制CMakeLists.txt并對其進行編輯以適合您的需求。
- 通過復制現有文件并對其進行編輯,或者使用上面的空示例來創建.cnf文件。
- 通過復制合適的現有文件并進行編輯來創建模板文件,或者使用上面的示例,將協議名稱放在合適的位置。
- 將您的解剖器添加到epan / dissectors / asn1 / CMakeLists.txt
- 通過構建generate_dissector- * proto *目標來測試生成解剖器。
- 根據結果??,您可能需要編輯.cnf文件,ASN.1文件等…
- 構建Wireshark。
使用Asn2wrs的提示
Asn2wrs尚不支持所有ASN.1。這意味著您可能需要先修改ASN.1定義,然后才能進行編譯。本頁列出了一些提示和技巧,可能會使您的生活更輕松。COMPONENTS OF
Asn2wrs不支持COMPONENTS OF指令。這意味著您將必須修改asn定義以手動刪除所有COMPONENTS OF指令。幸運的是,這很容易。COMPONENTS OF是ASN.1中的指令,通過這些字段將引用的SEQUENCE中的所有指定字段包括在內,就好像它們已被明確指定一樣。例
假設您具有如下定義:
Foo ::= SEQUENCE {
field_1 INTEGER,
field_2 INTEGER
}
Bar ::= SEQUENCE {
COMPONENTS OF Foo,
field_3 INTEGER
}
Since Asn2wrs can not handle COMPONENTS OF you will have to modify the ASN.1 file so that instead Bar will look like this :
Bar ::= SEQUENCE {
field_1 INTEGER,
field_2 INTEGER,
field_3 INTEGER
}
參量
參數也必須被替換。像這樣:
PBAddressString ::= SEQUENCE {
extension INTEGER(1), natureOfAddressIndicator INTEGER, numberingPlanInd INTEGER, digits OCTET STRING (SIZE(0..19))
};
將必須替換為參數的實際值:
AChBillingChargingCharacteristics ::= OCTET STRING (SIZE (5 .. 177))
ANY和參數化類型
Asn2wrs可以處理ANY類型,但不能處理參數化類型。幸運的是,通過對ASN文件和一些一致性文件進行小的更改,這很容易解決。假設您有一個看起來像這樣的構造:
AlgorithmIdentifier ::= SEQUENCE {
algorithm ALGORITHM.&id({SupportedAlgorithms}),
parameters ALGORITHM.&Type({SupportedAlgorithms}{@algorithm}) OPTIONAL
}
它本質上是一個結構,它包含兩個字段,一個字段是對象標識符,第二個字段幾乎可以是任何東西,具體取決于所使用的對象標識符。在這里,我們只需要稍微重寫一下這個SEQUENCE,就可以像這樣:
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY OPTIONAL
}
現在剩下的唯一事情就是添加實際代碼來管理此結構的分解。我們使用\#。FN_BODY一致性文件指令來執行此操作,該指令將用您在一致性文件中指定的內容替換解剖器的函數主體。為此,我們需要一個字符串,用于存儲來自AlgorithmIdentifier /算法的OID,以便我們可以將其提取并稍后從AlgorithmIdentifier /參數的解剖器內部進行操作。因此,我們必須添加以下內容:
static char algorithm_id[64]; /* 64 chars should be enough? */
to the template file. Then we add the following to the conformance file:
#.FN_BODY AlgorithmIdentifier/algorithmId
offset = dissect_ber_object_identifier(FALSE, pinfo, tree, tvb, offset,
hf_x509af_algorithm_id, algorithm_id);
#.FN_BODY AlgorithmIdentifier/parameters
offset=call_ber_oid_callback(algorithm_id, tvb, offset, pinfo, tree);
標記作業
當前在Asn2wrs中存在一個錯誤,該錯誤使得在使用標記的分配的情況下,它會生成錯誤的代碼。該錯誤有兩個方面,首先是所生成的代碼“forgets”以去除實際標簽和長度,其次是未能正確指定“ implicit_tag”。
標記的分配類似于FTAM asn規范中的以下示例:
Degree-Of-Overlap ::=
[APPLICATION 30] IMPLICIT INTEGER {
normal(0), consecutive(1), concurrent(2)
}
即,還指定標簽值的分配。
在增強Asn2wrs的能力以處理這些構造之前,您必須為它添加一個變通方法到一致性文件中:
#.FN_BODY Degree-Of-Overlap
gint8 class;
gboolean pc, ind_field;
gint32 tag;
gint32 len1;
/*
* XXX asn2wrs can not yet handle tagged assignment yes so this
* is some conformance file magic to work around that bug
*/
offset = get_ber_identifier(tvb, offset, &class, &pc, &tag);
offset = get_ber_length(tree, tvb, offset, &len1, &ind_field);
offset = dissect_ber_integer(TRUE, pinfo, tree, tvb, offset, hf_index, NULL);
這告訴Asn2wrs根本不為重疊度對象自動生成任何代碼,而是應使用此處指定的代碼。請注意,我們確實必須顯式地指定hidden_??tag值,并且不能使用從調用方傳遞給函數的參數(也是由于Asn2wrs中的錯誤),這是對dissect_ber_integer()的調用中的TRUE參數。我們在此處指定TRUE,因為“重疊程度”的定義使用的是IMPLICIT標簽,如果沒有使用,則將指定為FALSE。
上面的代碼可以很容易地被剪切-粘貼到一致性文件中,除了最后一行實際上調用了下一個Dissector Helper(在這種情況下是… dissect_ber_integer …)。找出確切的最后一行在一致性文件中應該是什么樣的最簡單方法;只需先生成解析器即可,無需解決此問題,然后查看生成了什么調用。然后將該行放入一致性指令中,并implicit_tag根據是否使用IMPLICIT 替換 為TRUE或FALSE。
未標記選項
Asn2wrs無法處理SET或SEQUENCE中的未標記的CHOICE。例如:
MessageTransferEnvelope ::= SET {
...
content-type ContentType,
...
}
ContentType ::= CHOICE {
built-in BuiltInContentType,
extended ExtendedContentType
}
BuiltInContentType ::= [APPLICATION 6] INTEGER {
unidentified(0), external(1), interpersonal-messaging-1984(2), interpersonal-messaging-1988(22),
edi-messaging(35), voice-messaging(40)}
ExtendedContentType ::= OBJECT IDENTIFIER
Asn2wrs的SET / SEQUENCE解析僅對解剖樹深一層,無法訪問CHOICE中元素的類/標記。
與COMPONENTS OF一樣,解決方案是在SET或SEQUENCE中內聯擴展CHOICE,但要確保 CHOICE的每個元素都標記為OPTIONAL。例如,
MessageTransferEnvelope ::= SET {
...
built-in BuiltInContentType OPTIONAL,
extended ExtendedContentType OPTIONAL
...
}
導入的模塊名稱沖突
在一致性文件中使用#.INCLUDE導入模塊時,這可能會從模塊中引入一個定義,該定義與當前ASN.1文件中使用的定義相矛盾。例如,X.509身份驗證框架將時間定義為:
Time ::= CHOICE {utcTime UTCTime,
generalizedTime GeneralizedTime
}
而X.411將時間定義為
Time ::= UTCTime
這可能導致無法解碼ASN.1,因為在此示例中,當嘗試解碼X.411時間時,Asn2wrs將傳遞錯誤的屬性。為了解決此問題,(如果您不想全局更改ASN.1模塊中的沖突名稱),則必須在#.INCLUDE行之前將適當的#.TYPE_ATTR添加到一致性文件中。例如
#.TYPE_ATTR
Time TYPE = FT_STRING DISPLAY = BASE_NONE STRING = NULL BITMASK = 0
Wireshark中文使用教程(開發版)