mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-06-06 17:43:25 +08:00
Update to FreeBSD stable/12 2020-02-10
Git mirror commit 0d1c391321b34b3025cf0e72f2231d836ff76da8.
This commit is contained in:
parent
18cc38e73e
commit
46b3858b27
@ -1 +1 @@
|
||||
Subproject commit 7e8d1444023128d34fb9aa4e4515928a4f794d1b
|
||||
Subproject commit 0d1c391321b34b3025cf0e72f2231d836ff76da8
|
@ -1,5 +1,33 @@
|
||||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define ASCII_A 0x41
|
||||
|
@ -1,36 +1,64 @@
|
||||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
|
||||
/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
|
||||
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
|
||||
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
|
||||
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
|
||||
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
|
||||
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
|
||||
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
|
||||
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
|
||||
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
|
||||
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
|
||||
/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
|
||||
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
|
||||
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
|
||||
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
|
||||
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
|
||||
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
|
||||
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
|
||||
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
|
||||
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
|
||||
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
|
@ -1,19 +1,38 @@
|
||||
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef Expat_INCLUDED
|
||||
#define Expat_INCLUDED 1
|
||||
|
||||
#ifdef __VMS
|
||||
/* 0 1 2 3 0 1 2 3
|
||||
1234567890123456789012345678901 1234567890123456789012345678901 */
|
||||
#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
|
||||
#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler
|
||||
#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler
|
||||
#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "expat_external.h"
|
||||
|
||||
@ -24,10 +43,9 @@ extern "C" {
|
||||
struct XML_ParserStruct;
|
||||
typedef struct XML_ParserStruct *XML_Parser;
|
||||
|
||||
/* Should this be defined using stdbool.h when C99 is available? */
|
||||
typedef unsigned char XML_Bool;
|
||||
#define XML_TRUE ((XML_Bool) 1)
|
||||
#define XML_FALSE ((XML_Bool) 0)
|
||||
#define XML_TRUE ((XML_Bool)1)
|
||||
#define XML_FALSE ((XML_Bool)0)
|
||||
|
||||
/* The XML_Status enum gives the possible return values for several
|
||||
API functions. The preprocessor #defines are included so this
|
||||
@ -95,7 +113,9 @@ enum XML_Error {
|
||||
/* Added in 2.0. */
|
||||
XML_ERROR_RESERVED_PREFIX_XML,
|
||||
XML_ERROR_RESERVED_PREFIX_XMLNS,
|
||||
XML_ERROR_RESERVED_NAMESPACE_URI
|
||||
XML_ERROR_RESERVED_NAMESPACE_URI,
|
||||
/* Added in 2.2.1. */
|
||||
XML_ERROR_INVALID_ARGUMENT
|
||||
};
|
||||
|
||||
enum XML_Content_Type {
|
||||
@ -135,25 +155,23 @@ enum XML_Content_Quant {
|
||||
typedef struct XML_cp XML_Content;
|
||||
|
||||
struct XML_cp {
|
||||
enum XML_Content_Type type;
|
||||
enum XML_Content_Quant quant;
|
||||
XML_Char * name;
|
||||
unsigned int numchildren;
|
||||
XML_Content * children;
|
||||
enum XML_Content_Type type;
|
||||
enum XML_Content_Quant quant;
|
||||
XML_Char *name;
|
||||
unsigned int numchildren;
|
||||
XML_Content *children;
|
||||
};
|
||||
|
||||
|
||||
/* This is called for an element declaration. See above for
|
||||
description of the model argument. It's the caller's responsibility
|
||||
to free model when finished with it.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
|
||||
const XML_Char *name,
|
||||
XML_Content *model);
|
||||
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData,
|
||||
const XML_Char *name,
|
||||
XML_Content *model);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetElementDeclHandler(XML_Parser parser,
|
||||
XML_ElementDeclHandler eldecl);
|
||||
XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl);
|
||||
|
||||
/* The Attlist declaration handler is called for *each* attribute. So
|
||||
a single Attlist declaration with multiple attributes declared will
|
||||
@ -163,17 +181,12 @@ XML_SetElementDeclHandler(XML_Parser parser,
|
||||
value will be NULL in the case of "#REQUIRED". If "isrequired" is
|
||||
true and default is non-NULL, then this is a "#FIXED" default.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_AttlistDeclHandler) (
|
||||
void *userData,
|
||||
const XML_Char *elname,
|
||||
const XML_Char *attname,
|
||||
const XML_Char *att_type,
|
||||
const XML_Char *dflt,
|
||||
int isrequired);
|
||||
typedef void(XMLCALL *XML_AttlistDeclHandler)(
|
||||
void *userData, const XML_Char *elname, const XML_Char *attname,
|
||||
const XML_Char *att_type, const XML_Char *dflt, int isrequired);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetAttlistDeclHandler(XML_Parser parser,
|
||||
XML_AttlistDeclHandler attdecl);
|
||||
XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl);
|
||||
|
||||
/* The XML declaration handler is called for *both* XML declarations
|
||||
and text declarations. The way to distinguish is that the version
|
||||
@ -183,15 +196,13 @@ XML_SetAttlistDeclHandler(XML_Parser parser,
|
||||
was no standalone parameter in the declaration, that it was given
|
||||
as no, or that it was given as yes.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData,
|
||||
const XML_Char *version,
|
||||
const XML_Char *encoding,
|
||||
int standalone);
|
||||
typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData,
|
||||
const XML_Char *version,
|
||||
const XML_Char *encoding,
|
||||
int standalone);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetXmlDeclHandler(XML_Parser parser,
|
||||
XML_XmlDeclHandler xmldecl);
|
||||
|
||||
XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl);
|
||||
|
||||
typedef struct {
|
||||
void *(*malloc_fcn)(size_t size);
|
||||
@ -219,7 +230,6 @@ XML_ParserCreate(const XML_Char *encoding);
|
||||
XMLPARSEAPI(XML_Parser)
|
||||
XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
|
||||
|
||||
|
||||
/* Constructs a new parser using the memory management suite referred to
|
||||
by memsuite. If memsuite is NULL, then use the standard library memory
|
||||
suite. If namespaceSeparator is non-NULL it creates a parser with
|
||||
@ -235,7 +245,7 @@ XML_ParserCreate_MM(const XML_Char *encoding,
|
||||
const XML_Char *namespaceSeparator);
|
||||
|
||||
/* Prepare a parser object to be re-used. This is particularly
|
||||
valuable when memory allocation overhead is disproportionatly high,
|
||||
valuable when memory allocation overhead is disproportionately high,
|
||||
such as when a large number of small documnents need to be parsed.
|
||||
All handlers are cleared from the parser, except for the
|
||||
unknownEncodingHandler. The parser's external state is re-initialized
|
||||
@ -249,31 +259,27 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
|
||||
/* atts is array of name/value pairs, terminated by 0;
|
||||
names and values are 0 terminated.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
|
||||
const XML_Char *name,
|
||||
const XML_Char **atts);
|
||||
|
||||
typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
|
||||
const XML_Char *name);
|
||||
typedef void(XMLCALL *XML_StartElementHandler)(void *userData,
|
||||
const XML_Char *name,
|
||||
const XML_Char **atts);
|
||||
|
||||
typedef void(XMLCALL *XML_EndElementHandler)(void *userData,
|
||||
const XML_Char *name);
|
||||
|
||||
/* s is not 0 terminated. */
|
||||
typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
|
||||
const XML_Char *s,
|
||||
int len);
|
||||
typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData,
|
||||
const XML_Char *s, int len);
|
||||
|
||||
/* target and data are 0 terminated */
|
||||
typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
|
||||
void *userData,
|
||||
const XML_Char *target,
|
||||
const XML_Char *data);
|
||||
typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData,
|
||||
const XML_Char *target,
|
||||
const XML_Char *data);
|
||||
|
||||
/* data is 0 terminated */
|
||||
typedef void (XMLCALL *XML_CommentHandler) (void *userData,
|
||||
const XML_Char *data);
|
||||
typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data);
|
||||
|
||||
typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
|
||||
typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
|
||||
typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData);
|
||||
typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData);
|
||||
|
||||
/* This is called for any characters in the XML document for which
|
||||
there is no applicable handler. This includes both characters that
|
||||
@ -288,25 +294,23 @@ typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
|
||||
default handler: for example, a comment might be split between
|
||||
multiple calls.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
|
||||
const XML_Char *s,
|
||||
int len);
|
||||
typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s,
|
||||
int len);
|
||||
|
||||
/* This is called for the start of the DOCTYPE declaration, before
|
||||
any DTD or internal subset is parsed.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
|
||||
void *userData,
|
||||
const XML_Char *doctypeName,
|
||||
const XML_Char *sysid,
|
||||
const XML_Char *pubid,
|
||||
int has_internal_subset);
|
||||
typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData,
|
||||
const XML_Char *doctypeName,
|
||||
const XML_Char *sysid,
|
||||
const XML_Char *pubid,
|
||||
int has_internal_subset);
|
||||
|
||||
/* This is called for the start of the DOCTYPE declaration when the
|
||||
closing > is encountered, but after processing any external
|
||||
subset.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
|
||||
typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
|
||||
|
||||
/* This is called for entity declarations. The is_parameter_entity
|
||||
argument will be non-zero if the entity is a parameter entity, zero
|
||||
@ -326,20 +330,14 @@ typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
|
||||
Note that is_parameter_entity can't be changed to XML_Bool, since
|
||||
that would break binary compatibility.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_EntityDeclHandler) (
|
||||
void *userData,
|
||||
const XML_Char *entityName,
|
||||
int is_parameter_entity,
|
||||
const XML_Char *value,
|
||||
int value_length,
|
||||
const XML_Char *base,
|
||||
const XML_Char *systemId,
|
||||
const XML_Char *publicId,
|
||||
const XML_Char *notationName);
|
||||
typedef void(XMLCALL *XML_EntityDeclHandler)(
|
||||
void *userData, const XML_Char *entityName, int is_parameter_entity,
|
||||
const XML_Char *value, int value_length, const XML_Char *base,
|
||||
const XML_Char *systemId, const XML_Char *publicId,
|
||||
const XML_Char *notationName);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetEntityDeclHandler(XML_Parser parser,
|
||||
XML_EntityDeclHandler handler);
|
||||
XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler);
|
||||
|
||||
/* OBSOLETE -- OBSOLETE -- OBSOLETE
|
||||
This handler has been superseded by the EntityDeclHandler above.
|
||||
@ -350,24 +348,20 @@ XML_SetEntityDeclHandler(XML_Parser parser,
|
||||
entityName, systemId and notationName arguments will never be
|
||||
NULL. The other arguments may be.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
|
||||
void *userData,
|
||||
const XML_Char *entityName,
|
||||
const XML_Char *base,
|
||||
const XML_Char *systemId,
|
||||
const XML_Char *publicId,
|
||||
const XML_Char *notationName);
|
||||
typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)(
|
||||
void *userData, const XML_Char *entityName, const XML_Char *base,
|
||||
const XML_Char *systemId, const XML_Char *publicId,
|
||||
const XML_Char *notationName);
|
||||
|
||||
/* This is called for a declaration of notation. The base argument is
|
||||
whatever was set by XML_SetBase. The notationName will never be
|
||||
NULL. The other arguments can be.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_NotationDeclHandler) (
|
||||
void *userData,
|
||||
const XML_Char *notationName,
|
||||
const XML_Char *base,
|
||||
const XML_Char *systemId,
|
||||
const XML_Char *publicId);
|
||||
typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData,
|
||||
const XML_Char *notationName,
|
||||
const XML_Char *base,
|
||||
const XML_Char *systemId,
|
||||
const XML_Char *publicId);
|
||||
|
||||
/* When namespace processing is enabled, these are called once for
|
||||
each namespace declaration. The call to the start and end element
|
||||
@ -375,14 +369,12 @@ typedef void (XMLCALL *XML_NotationDeclHandler) (
|
||||
declaration handlers. For an xmlns attribute, prefix will be
|
||||
NULL. For an xmlns="" attribute, uri will be NULL.
|
||||
*/
|
||||
typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
|
||||
void *userData,
|
||||
const XML_Char *prefix,
|
||||
const XML_Char *uri);
|
||||
typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData,
|
||||
const XML_Char *prefix,
|
||||
const XML_Char *uri);
|
||||
|
||||
typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
|
||||
void *userData,
|
||||
const XML_Char *prefix);
|
||||
typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData,
|
||||
const XML_Char *prefix);
|
||||
|
||||
/* This is called if the document is not standalone, that is, it has an
|
||||
external subset or a reference to a parameter entity, but does not
|
||||
@ -393,7 +385,7 @@ typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
|
||||
conditions above this handler will only be called if the referenced
|
||||
entity was actually read.
|
||||
*/
|
||||
typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
|
||||
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData);
|
||||
|
||||
/* This is called for a reference to an external parsed general
|
||||
entity. The referenced entity is not automatically parsed. The
|
||||
@ -429,12 +421,11 @@ typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
|
||||
Note that unlike other handlers the first argument is the parser,
|
||||
not userData.
|
||||
*/
|
||||
typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
|
||||
XML_Parser parser,
|
||||
const XML_Char *context,
|
||||
const XML_Char *base,
|
||||
const XML_Char *systemId,
|
||||
const XML_Char *publicId);
|
||||
typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser,
|
||||
const XML_Char *context,
|
||||
const XML_Char *base,
|
||||
const XML_Char *systemId,
|
||||
const XML_Char *publicId);
|
||||
|
||||
/* This is called in two situations:
|
||||
1) An entity reference is encountered for which no declaration
|
||||
@ -446,10 +437,9 @@ typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
|
||||
the event would be out of sync with the reporting of the
|
||||
declarations or attribute values
|
||||
*/
|
||||
typedef void (XMLCALL *XML_SkippedEntityHandler) (
|
||||
void *userData,
|
||||
const XML_Char *entityName,
|
||||
int is_parameter_entity);
|
||||
typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData,
|
||||
const XML_Char *entityName,
|
||||
int is_parameter_entity);
|
||||
|
||||
/* This structure is filled in by the XML_UnknownEncodingHandler to
|
||||
provide information to the parser about encodings that are unknown
|
||||
@ -506,8 +496,8 @@ typedef void (XMLCALL *XML_SkippedEntityHandler) (
|
||||
typedef struct {
|
||||
int map[256];
|
||||
void *data;
|
||||
int (XMLCALL *convert)(void *data, const char *s);
|
||||
void (XMLCALL *release)(void *data);
|
||||
int(XMLCALL *convert)(void *data, const char *s);
|
||||
void(XMLCALL *release)(void *data);
|
||||
} XML_Encoding;
|
||||
|
||||
/* This is called for an encoding that is unknown to the parser.
|
||||
@ -525,23 +515,19 @@ typedef struct {
|
||||
If info does not describe a suitable encoding, then the parser will
|
||||
return an XML_UNKNOWN_ENCODING error.
|
||||
*/
|
||||
typedef int (XMLCALL *XML_UnknownEncodingHandler) (
|
||||
void *encodingHandlerData,
|
||||
const XML_Char *name,
|
||||
XML_Encoding *info);
|
||||
typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData,
|
||||
const XML_Char *name,
|
||||
XML_Encoding *info);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetElementHandler(XML_Parser parser,
|
||||
XML_StartElementHandler start,
|
||||
XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
|
||||
XML_EndElementHandler end);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetStartElementHandler(XML_Parser parser,
|
||||
XML_StartElementHandler handler);
|
||||
XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetEndElementHandler(XML_Parser parser,
|
||||
XML_EndElementHandler handler);
|
||||
XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetCharacterDataHandler(XML_Parser parser,
|
||||
@ -551,8 +537,7 @@ XMLPARSEAPI(void)
|
||||
XML_SetProcessingInstructionHandler(XML_Parser parser,
|
||||
XML_ProcessingInstructionHandler handler);
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetCommentHandler(XML_Parser parser,
|
||||
XML_CommentHandler handler);
|
||||
XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetCdataSectionHandler(XML_Parser parser,
|
||||
@ -572,20 +557,17 @@ XML_SetEndCdataSectionHandler(XML_Parser parser,
|
||||
default handler, or to the skipped entity handler, if one is set.
|
||||
*/
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetDefaultHandler(XML_Parser parser,
|
||||
XML_DefaultHandler handler);
|
||||
XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler);
|
||||
|
||||
/* This sets the default handler but does not inhibit expansion of
|
||||
internal entities. The entity reference will not be passed to the
|
||||
default handler.
|
||||
*/
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetDefaultHandlerExpand(XML_Parser parser,
|
||||
XML_DefaultHandler handler);
|
||||
XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetDoctypeDeclHandler(XML_Parser parser,
|
||||
XML_StartDoctypeDeclHandler start,
|
||||
XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
|
||||
XML_EndDoctypeDeclHandler end);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
@ -593,16 +575,14 @@ XML_SetStartDoctypeDeclHandler(XML_Parser parser,
|
||||
XML_StartDoctypeDeclHandler start);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
|
||||
XML_EndDoctypeDeclHandler end);
|
||||
XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
|
||||
XML_UnparsedEntityDeclHandler handler);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetNotationDeclHandler(XML_Parser parser,
|
||||
XML_NotationDeclHandler handler);
|
||||
XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetNamespaceDeclHandler(XML_Parser parser,
|
||||
@ -630,8 +610,7 @@ XML_SetExternalEntityRefHandler(XML_Parser parser,
|
||||
instead of the parser object.
|
||||
*/
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
|
||||
void *arg);
|
||||
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetSkippedEntityHandler(XML_Parser parser,
|
||||
@ -706,11 +685,11 @@ XML_UseParserAsHandlerArg(XML_Parser parser);
|
||||
be called, despite an external subset being parsed.
|
||||
Note: If XML_DTD is not defined when Expat is compiled, returns
|
||||
XML_ERROR_FEATURE_REQUIRES_XML_DTD.
|
||||
Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT.
|
||||
*/
|
||||
XMLPARSEAPI(enum XML_Error)
|
||||
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
|
||||
|
||||
|
||||
/* Sets the base to be used for resolving relative URIs in system
|
||||
identifiers in declarations. Resolving relative identifiers is
|
||||
left to the application: this value will be passed through as the
|
||||
@ -729,15 +708,16 @@ XML_GetBase(XML_Parser parser);
|
||||
to the XML_StartElementHandler that were specified in the start-tag
|
||||
rather than defaulted. Each attribute/value pair counts as 2; thus
|
||||
this correspondds to an index into the atts array passed to the
|
||||
XML_StartElementHandler.
|
||||
XML_StartElementHandler. Returns -1 if parser == NULL.
|
||||
*/
|
||||
XMLPARSEAPI(int)
|
||||
XML_GetSpecifiedAttributeCount(XML_Parser parser);
|
||||
|
||||
/* Returns the index of the ID attribute passed in the last call to
|
||||
XML_StartElementHandler, or -1 if there is no ID attribute. Each
|
||||
attribute/value pair counts as 2; thus this correspondds to an
|
||||
index into the atts array passed to the XML_StartElementHandler.
|
||||
XML_StartElementHandler, or -1 if there is no ID attribute or
|
||||
parser == NULL. Each attribute/value pair counts as 2; thus this
|
||||
correspondds to an index into the atts array passed to the
|
||||
XML_StartElementHandler.
|
||||
*/
|
||||
XMLPARSEAPI(int)
|
||||
XML_GetIdAttributeIndex(XML_Parser parser);
|
||||
@ -749,10 +729,10 @@ XML_GetIdAttributeIndex(XML_Parser parser);
|
||||
info->valueEnd - info->valueStart = 4 bytes.
|
||||
*/
|
||||
typedef struct {
|
||||
XML_Index nameStart; /* Offset to beginning of the attribute name. */
|
||||
XML_Index nameEnd; /* Offset after the attribute name's last byte. */
|
||||
XML_Index valueStart; /* Offset to beginning of the attribute value. */
|
||||
XML_Index valueEnd; /* Offset after the attribute value's last byte. */
|
||||
XML_Index nameStart; /* Offset to beginning of the attribute name. */
|
||||
XML_Index nameEnd; /* Offset after the attribute name's last byte. */
|
||||
XML_Index valueStart; /* Offset to beginning of the attribute value. */
|
||||
XML_Index valueEnd; /* Offset after the attribute value's last byte. */
|
||||
} XML_AttrInfo;
|
||||
|
||||
/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
|
||||
@ -788,20 +768,20 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
|
||||
(resumable = 0) an already suspended parser. Some call-backs may
|
||||
still follow because they would otherwise get lost. Examples:
|
||||
- endElementHandler() for empty elements when stopped in
|
||||
startElementHandler(),
|
||||
- endNameSpaceDeclHandler() when stopped in endElementHandler(),
|
||||
startElementHandler(),
|
||||
- endNameSpaceDeclHandler() when stopped in endElementHandler(),
|
||||
and possibly others.
|
||||
|
||||
Can be called from most handlers, including DTD related call-backs,
|
||||
except when parsing an external parameter entity and resumable != 0.
|
||||
Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
|
||||
Possible error codes:
|
||||
Possible error codes:
|
||||
- XML_ERROR_SUSPENDED: when suspending an already suspended parser.
|
||||
- XML_ERROR_FINISHED: when the parser has already finished.
|
||||
- XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
|
||||
|
||||
When resumable != 0 (true) then parsing is suspended, that is,
|
||||
XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
|
||||
When resumable != 0 (true) then parsing is suspended, that is,
|
||||
XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
|
||||
Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
|
||||
return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
|
||||
|
||||
@ -812,7 +792,7 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
|
||||
the externalEntityRefHandler() to call XML_StopParser() on the parent
|
||||
parser (recursively), if one wants to stop parsing altogether.
|
||||
|
||||
When suspended, parsing can be resumed by calling XML_ResumeParser().
|
||||
When suspended, parsing can be resumed by calling XML_ResumeParser().
|
||||
*/
|
||||
XMLPARSEAPI(enum XML_Status)
|
||||
XML_StopParser(XML_Parser parser, XML_Bool resumable);
|
||||
@ -820,7 +800,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable);
|
||||
/* Resumes parsing after it has been suspended with XML_StopParser().
|
||||
Must not be called from within a handler call-back. Returns same
|
||||
status codes as XML_Parse() or XML_ParseBuffer().
|
||||
Additional error code XML_ERROR_NOT_SUSPENDED possible.
|
||||
Additional error code XML_ERROR_NOT_SUSPENDED possible.
|
||||
|
||||
*Note*:
|
||||
This must be called on the most deeply nested child parser instance
|
||||
@ -832,12 +812,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable);
|
||||
XMLPARSEAPI(enum XML_Status)
|
||||
XML_ResumeParser(XML_Parser parser);
|
||||
|
||||
enum XML_Parsing {
|
||||
XML_INITIALIZED,
|
||||
XML_PARSING,
|
||||
XML_FINISHED,
|
||||
XML_SUSPENDED
|
||||
};
|
||||
enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED };
|
||||
|
||||
typedef struct {
|
||||
enum XML_Parsing parsing;
|
||||
@ -869,8 +844,7 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
|
||||
Otherwise returns a new XML_Parser object.
|
||||
*/
|
||||
XMLPARSEAPI(XML_Parser)
|
||||
XML_ExternalEntityParserCreate(XML_Parser parser,
|
||||
const XML_Char *context,
|
||||
XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context,
|
||||
const XML_Char *encoding);
|
||||
|
||||
enum XML_ParamEntityParsing {
|
||||
@ -901,6 +875,7 @@ enum XML_ParamEntityParsing {
|
||||
entities is requested; otherwise it will return non-zero.
|
||||
Note: If XML_SetParamEntityParsing is called after XML_Parse or
|
||||
XML_ParseBuffer, then it has no effect and will always return 0.
|
||||
Note: If parser == NULL, the function will do nothing and return 0.
|
||||
*/
|
||||
XMLPARSEAPI(int)
|
||||
XML_SetParamEntityParsing(XML_Parser parser,
|
||||
@ -910,10 +885,10 @@ XML_SetParamEntityParsing(XML_Parser parser,
|
||||
Helps in preventing DoS attacks based on predicting hash
|
||||
function behavior. This must be called before parsing is started.
|
||||
Returns 1 if successful, 0 when called after parsing has started.
|
||||
Note: If parser == NULL, the function will do nothing and return 0.
|
||||
*/
|
||||
XMLPARSEAPI(int)
|
||||
XML_SetHashSalt(XML_Parser parser,
|
||||
unsigned long hash_salt);
|
||||
XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt);
|
||||
|
||||
/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
|
||||
XML_GetErrorCode returns information about the error.
|
||||
@ -930,12 +905,16 @@ XML_GetErrorCode(XML_Parser parser);
|
||||
be within the relevant markup. When called outside of the callback
|
||||
functions, the position indicated will be just past the last parse
|
||||
event (regardless of whether there was an associated callback).
|
||||
|
||||
|
||||
They may also be called after returning from a call to XML_Parse
|
||||
or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then
|
||||
the location is the location of the character at which the error
|
||||
was detected; otherwise the location is the location of the last
|
||||
parse event, as described above.
|
||||
|
||||
Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber
|
||||
return 0 to indicate an error.
|
||||
Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
|
||||
*/
|
||||
XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
|
||||
XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
|
||||
@ -958,14 +937,12 @@ XML_GetCurrentByteCount(XML_Parser parser);
|
||||
the handler that makes the call.
|
||||
*/
|
||||
XMLPARSEAPI(const char *)
|
||||
XML_GetInputContext(XML_Parser parser,
|
||||
int *offset,
|
||||
int *size);
|
||||
XML_GetInputContext(XML_Parser parser, int *offset, int *size);
|
||||
|
||||
/* For backwards compatibility with previous versions. */
|
||||
#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
|
||||
#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
|
||||
#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
|
||||
#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
|
||||
#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
|
||||
|
||||
/* Frees the content model passed to the element declaration handler */
|
||||
XMLPARSEAPI(void)
|
||||
@ -1025,21 +1002,20 @@ enum XML_FeatureEnum {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum XML_FeatureEnum feature;
|
||||
const XML_LChar *name;
|
||||
long int value;
|
||||
enum XML_FeatureEnum feature;
|
||||
const XML_LChar *name;
|
||||
long int value;
|
||||
} XML_Feature;
|
||||
|
||||
XMLPARSEAPI(const XML_Feature *)
|
||||
XML_GetFeatureList(void);
|
||||
|
||||
|
||||
/* Expat follows the semantic versioning convention.
|
||||
See http://semver.org.
|
||||
*/
|
||||
#define XML_MAJOR_VERSION 2
|
||||
#define XML_MINOR_VERSION 2
|
||||
#define XML_MICRO_VERSION 0
|
||||
#define XML_MICRO_VERSION 9
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,33 @@
|
||||
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef Expat_External_INCLUDED
|
||||
@ -7,10 +35,6 @@
|
||||
|
||||
/* External API definitions */
|
||||
|
||||
#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
|
||||
#define XML_USE_MSC_EXTENSIONS 1
|
||||
#endif
|
||||
|
||||
/* Expat tries very hard to make the API boundary very specifically
|
||||
defined. There are two macros defined to control this boundary;
|
||||
each of these can be defined before including this header to
|
||||
@ -34,11 +58,11 @@
|
||||
system headers may assume the cdecl convention.
|
||||
*/
|
||||
#ifndef XMLCALL
|
||||
#if defined(_MSC_VER)
|
||||
#define XMLCALL __cdecl
|
||||
#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
|
||||
#define XMLCALL __attribute__((cdecl))
|
||||
#else
|
||||
# if defined(_MSC_VER)
|
||||
# define XMLCALL __cdecl
|
||||
# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
|
||||
# define XMLCALL __attribute__((cdecl))
|
||||
# else
|
||||
/* For any platform which uses this definition and supports more than
|
||||
one calling convention, we need to extend this definition to
|
||||
declare the convention used on that platform, if it's possible to
|
||||
@ -49,41 +73,46 @@
|
||||
pre-processor and how to specify the same calling convention as the
|
||||
platform's malloc() implementation.
|
||||
*/
|
||||
#define XMLCALL
|
||||
#endif
|
||||
#endif /* not defined XMLCALL */
|
||||
# define XMLCALL
|
||||
# endif
|
||||
#endif /* not defined XMLCALL */
|
||||
|
||||
|
||||
#if !defined(XML_STATIC) && !defined(XMLIMPORT)
|
||||
#ifndef XML_BUILDING_EXPAT
|
||||
#if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
|
||||
# ifndef XML_BUILDING_EXPAT
|
||||
/* using Expat from an application */
|
||||
|
||||
#ifdef XML_USE_MSC_EXTENSIONS
|
||||
#define XMLIMPORT __declspec(dllimport)
|
||||
# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
|
||||
# define XMLIMPORT __declspec(dllimport)
|
||||
# endif
|
||||
|
||||
# endif
|
||||
#endif /* not defined XML_STATIC */
|
||||
|
||||
#ifndef XML_ENABLE_VISIBILITY
|
||||
# define XML_ENABLE_VISIBILITY 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* not defined XML_STATIC */
|
||||
|
||||
#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
#define XMLIMPORT __attribute__ ((visibility ("default")))
|
||||
#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
|
||||
# define XMLIMPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
/* If we didn't define it above, define it away: */
|
||||
#ifndef XMLIMPORT
|
||||
#define XMLIMPORT
|
||||
# define XMLIMPORT
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
|
||||
#define XML_ATTR_MALLOC __attribute__((__malloc__))
|
||||
#if defined(__GNUC__) \
|
||||
&& (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
|
||||
# define XML_ATTR_MALLOC __attribute__((__malloc__))
|
||||
#else
|
||||
#define XML_ATTR_MALLOC
|
||||
# define XML_ATTR_MALLOC
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
|
||||
#if defined(__GNUC__) \
|
||||
&& ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
|
||||
#else
|
||||
#define XML_ATTR_ALLOC_SIZE(x)
|
||||
# define XML_ATTR_ALLOC_SIZE(x)
|
||||
#endif
|
||||
|
||||
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
|
||||
@ -93,30 +122,30 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
#define XML_UNICODE
|
||||
# ifndef XML_UNICODE
|
||||
# define XML_UNICODE
|
||||
# endif
|
||||
# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
|
||||
# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
|
||||
# ifdef XML_UNICODE_WCHAR_T
|
||||
typedef wchar_t XML_Char;
|
||||
typedef wchar_t XML_LChar;
|
||||
#else
|
||||
# else
|
||||
typedef unsigned short XML_Char;
|
||||
typedef char XML_LChar;
|
||||
#endif /* XML_UNICODE_WCHAR_T */
|
||||
#else /* Information is UTF-8 encoded. */
|
||||
# endif /* XML_UNICODE_WCHAR_T */
|
||||
#else /* Information is UTF-8 encoded. */
|
||||
typedef char XML_Char;
|
||||
typedef char XML_LChar;
|
||||
#endif /* XML_UNICODE */
|
||||
#endif /* XML_UNICODE */
|
||||
|
||||
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
|
||||
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
|
||||
typedef __int64 XML_Index;
|
||||
typedef unsigned __int64 XML_Size;
|
||||
#else
|
||||
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
|
||||
typedef long long XML_Index;
|
||||
typedef unsigned long long XML_Size;
|
||||
#endif
|
||||
#else
|
||||
typedef long XML_Index;
|
||||
typedef unsigned long XML_Size;
|
||||
|
@ -1,37 +1,65 @@
|
||||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
|
||||
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
|
||||
/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
|
||||
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
|
||||
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
|
||||
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
|
||||
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
|
||||
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
|
||||
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
|
||||
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
|
||||
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
|
||||
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
|
||||
/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
|
||||
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
|
||||
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
|
||||
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
|
||||
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
|
||||
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
|
||||
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
|
||||
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
|
||||
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
|
||||
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
|
@ -18,9 +18,38 @@
|
||||
|
||||
Note: Use of these macros is based on judgement, not hard rules,
|
||||
and therefore subject to change.
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
|
||||
#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__)
|
||||
/* We'll use this version by default only where we know it helps.
|
||||
|
||||
regparm() generates warnings on Solaris boxes. See SF bug #692878.
|
||||
@ -30,8 +59,8 @@
|
||||
#define FASTCALL __attribute__((stdcall, regparm(3)))
|
||||
and let's try this:
|
||||
*/
|
||||
#define FASTCALL __attribute__((regparm(3)))
|
||||
#define PTRFASTCALL __attribute__((regparm(3)))
|
||||
# define FASTCALL __attribute__((regparm(3)))
|
||||
# define PTRFASTCALL __attribute__((regparm(3)))
|
||||
#endif
|
||||
|
||||
/* Using __fastcall seems to have an unexpected negative effect under
|
||||
@ -45,50 +74,49 @@
|
||||
/* Make sure all of these are defined if they aren't already. */
|
||||
|
||||
#ifndef FASTCALL
|
||||
#define FASTCALL
|
||||
# define FASTCALL
|
||||
#endif
|
||||
|
||||
#ifndef PTRCALL
|
||||
#define PTRCALL
|
||||
# define PTRCALL
|
||||
#endif
|
||||
|
||||
#ifndef PTRFASTCALL
|
||||
#define PTRFASTCALL
|
||||
# define PTRFASTCALL
|
||||
#endif
|
||||
|
||||
#ifndef XML_MIN_SIZE
|
||||
#if !defined(__cplusplus) && !defined(inline)
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline
|
||||
#endif /* __GNUC__ */
|
||||
#endif
|
||||
# if ! defined(__cplusplus) && ! defined(inline)
|
||||
# ifdef __GNUC__
|
||||
# define inline __inline
|
||||
# endif /* __GNUC__ */
|
||||
# endif
|
||||
#endif /* XML_MIN_SIZE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define inline inline
|
||||
# define inline inline
|
||||
#else
|
||||
#ifndef inline
|
||||
#define inline
|
||||
#endif
|
||||
# ifndef inline
|
||||
# define inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UNUSED_P
|
||||
# ifdef __GNUC__
|
||||
# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
|
||||
# else
|
||||
# define UNUSED_P(p) UNUSED_ ## p
|
||||
# endif
|
||||
# define UNUSED_P(p) (void)p
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XML_ENABLE_VISIBILITY
|
||||
# if XML_ENABLE_VISIBILITY
|
||||
__attribute__((visibility("default")))
|
||||
# endif
|
||||
#endif
|
||||
void
|
||||
align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);
|
||||
|
||||
_INTERNAL_trim_to_complete_utf8_characters(const char *from,
|
||||
const char **fromLimRef);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,36 +1,64 @@
|
||||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
|
||||
/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
|
||||
/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
|
@ -1,150 +1,136 @@
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
static const unsigned namingBitmap[] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
|
||||
0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
|
||||
0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
|
||||
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
|
||||
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
|
||||
0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
|
||||
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
|
||||
0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
|
||||
0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
|
||||
0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
|
||||
0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
|
||||
0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
|
||||
0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
|
||||
0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
|
||||
0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
|
||||
0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
|
||||
0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
|
||||
0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
|
||||
0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
|
||||
0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
|
||||
0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
|
||||
0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
|
||||
0x40000000, 0xF580C900, 0x00000007, 0x02010800,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
|
||||
0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
|
||||
0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
|
||||
0x00000000, 0x00004C40, 0x00000000, 0x00000000,
|
||||
0x00000007, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
|
||||
0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
|
||||
0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
|
||||
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
|
||||
0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
|
||||
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
|
||||
0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
|
||||
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
|
||||
0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
|
||||
0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
|
||||
0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
|
||||
0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
|
||||
0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
|
||||
0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
|
||||
0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
|
||||
0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
|
||||
0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
|
||||
0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
|
||||
0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
|
||||
0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
|
||||
0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
|
||||
0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
|
||||
0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
|
||||
0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000,
|
||||
0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
|
||||
0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
|
||||
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF,
|
||||
0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
|
||||
0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE,
|
||||
0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
|
||||
0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF,
|
||||
0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
|
||||
0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF,
|
||||
0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
|
||||
0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF,
|
||||
0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF,
|
||||
0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
|
||||
0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000,
|
||||
0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
|
||||
0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40,
|
||||
0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE,
|
||||
0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
|
||||
0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000,
|
||||
0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB,
|
||||
0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
|
||||
0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000,
|
||||
0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
|
||||
0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF,
|
||||
0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
|
||||
0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF,
|
||||
0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
|
||||
0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718,
|
||||
0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
|
||||
0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF,
|
||||
0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE,
|
||||
0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
|
||||
0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
|
||||
0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE,
|
||||
0xFFFFFFFF, 0x77FFFFFF,
|
||||
};
|
||||
static const unsigned char nmstrtPages[] = {
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
|
||||
0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B,
|
||||
0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
static const unsigned char namePages[] = {
|
||||
0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
|
||||
0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
|
||||
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
|
||||
0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21,
|
||||
0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
@ -1,37 +1,64 @@
|
||||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
|
||||
/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
|
||||
/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
|
||||
/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,33 @@
|
||||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XmlRole_INCLUDED
|
||||
@ -8,7 +36,7 @@
|
||||
#ifdef __VMS
|
||||
/* 0 1 2 3 0 1 2 3
|
||||
1234567890123456789012345678901 1234567890123456789012345678901 */
|
||||
#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
|
||||
# define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
|
||||
#endif
|
||||
|
||||
#include "xmltok.h"
|
||||
@ -85,11 +113,8 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct prolog_state {
|
||||
int (PTRCALL *handler) (struct prolog_state *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc);
|
||||
int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr,
|
||||
const char *end, const ENCODING *enc);
|
||||
unsigned level;
|
||||
int role_none;
|
||||
#ifdef XML_DTD
|
||||
@ -104,8 +129,8 @@ void XmlPrologStateInit(PROLOG_STATE *);
|
||||
void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#define XmlTokenRole(state, tok, ptr, end, enc) \
|
||||
(((state)->handler)(state, tok, ptr, end, enc))
|
||||
#define XmlTokenRole(state, tok, ptr, end, enc) \
|
||||
(((state)->handler)(state, tok, ptr, end, enc))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,33 @@
|
||||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XmlTok_INCLUDED
|
||||
@ -10,16 +38,18 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* The following token may be returned by XmlContentTok */
|
||||
#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
|
||||
start of illegal ]]> sequence */
|
||||
#define XML_TOK_TRAILING_RSQB \
|
||||
-5 /* ] or ]] at the end of the scan; might be \
|
||||
start of illegal ]]> sequence */
|
||||
/* The following tokens may be returned by both XmlPrologTok and
|
||||
XmlContentTok.
|
||||
*/
|
||||
#define XML_TOK_NONE -4 /* The string to be scanned is empty */
|
||||
#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
|
||||
might be part of CRLF sequence */
|
||||
#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
|
||||
#define XML_TOK_PARTIAL -1 /* only part of a token */
|
||||
#define XML_TOK_NONE -4 /* The string to be scanned is empty */
|
||||
#define XML_TOK_TRAILING_CR \
|
||||
-3 /* A CR at the end of the scan; \
|
||||
might be part of CRLF sequence */
|
||||
#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
|
||||
#define XML_TOK_PARTIAL -1 /* only part of a token */
|
||||
#define XML_TOK_INVALID 0
|
||||
|
||||
/* The following tokens are returned by XmlContentTok; some are also
|
||||
@ -34,24 +64,24 @@ extern "C" {
|
||||
#define XML_TOK_DATA_NEWLINE 7
|
||||
#define XML_TOK_CDATA_SECT_OPEN 8
|
||||
#define XML_TOK_ENTITY_REF 9
|
||||
#define XML_TOK_CHAR_REF 10 /* numeric character reference */
|
||||
#define XML_TOK_CHAR_REF 10 /* numeric character reference */
|
||||
|
||||
/* The following tokens may be returned by both XmlPrologTok and
|
||||
XmlContentTok.
|
||||
*/
|
||||
#define XML_TOK_PI 11 /* processing instruction */
|
||||
#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
|
||||
#define XML_TOK_PI 11 /* processing instruction */
|
||||
#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
|
||||
#define XML_TOK_COMMENT 13
|
||||
#define XML_TOK_BOM 14 /* Byte order mark */
|
||||
#define XML_TOK_BOM 14 /* Byte order mark */
|
||||
|
||||
/* The following tokens are returned only by XmlPrologTok */
|
||||
#define XML_TOK_PROLOG_S 15
|
||||
#define XML_TOK_DECL_OPEN 16 /* <!foo */
|
||||
#define XML_TOK_DECL_CLOSE 17 /* > */
|
||||
#define XML_TOK_DECL_OPEN 16 /* <!foo */
|
||||
#define XML_TOK_DECL_CLOSE 17 /* > */
|
||||
#define XML_TOK_NAME 18
|
||||
#define XML_TOK_NMTOKEN 19
|
||||
#define XML_TOK_POUND_NAME 20 /* #name */
|
||||
#define XML_TOK_OR 21 /* | */
|
||||
#define XML_TOK_POUND_NAME 20 /* #name */
|
||||
#define XML_TOK_OR 21 /* | */
|
||||
#define XML_TOK_PERCENT 22
|
||||
#define XML_TOK_OPEN_PAREN 23
|
||||
#define XML_TOK_CLOSE_PAREN 24
|
||||
@ -62,14 +92,14 @@ extern "C" {
|
||||
#define XML_TOK_INSTANCE_START 29
|
||||
|
||||
/* The following occur only in element type declarations */
|
||||
#define XML_TOK_NAME_QUESTION 30 /* name? */
|
||||
#define XML_TOK_NAME_ASTERISK 31 /* name* */
|
||||
#define XML_TOK_NAME_PLUS 32 /* name+ */
|
||||
#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
|
||||
#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
|
||||
#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
|
||||
#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
|
||||
#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
|
||||
#define XML_TOK_NAME_QUESTION 30 /* name? */
|
||||
#define XML_TOK_NAME_ASTERISK 31 /* name* */
|
||||
#define XML_TOK_NAME_PLUS 32 /* name+ */
|
||||
#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
|
||||
#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
|
||||
#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
|
||||
#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
|
||||
#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
|
||||
#define XML_TOK_COMMA 38
|
||||
|
||||
/* The following token is returned only by XmlAttributeValueTok */
|
||||
@ -84,20 +114,20 @@ extern "C" {
|
||||
#define XML_TOK_PREFIXED_NAME 41
|
||||
|
||||
#ifdef XML_DTD
|
||||
#define XML_TOK_IGNORE_SECT 42
|
||||
# define XML_TOK_IGNORE_SECT 42
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#ifdef XML_DTD
|
||||
#define XML_N_STATES 4
|
||||
# define XML_N_STATES 4
|
||||
#else /* not XML_DTD */
|
||||
#define XML_N_STATES 3
|
||||
# define XML_N_STATES 3
|
||||
#endif /* not XML_DTD */
|
||||
|
||||
#define XML_PROLOG_STATE 0
|
||||
#define XML_CONTENT_STATE 1
|
||||
#define XML_CDATA_SECTION_STATE 2
|
||||
#ifdef XML_DTD
|
||||
#define XML_IGNORE_SECTION_STATE 3
|
||||
# define XML_IGNORE_SECTION_STATE 3
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#define XML_N_LITERAL_TYPES 2
|
||||
@ -125,55 +155,41 @@ typedef struct {
|
||||
struct encoding;
|
||||
typedef struct encoding ENCODING;
|
||||
|
||||
typedef int (PTRCALL *SCANNER)(const ENCODING *,
|
||||
const char *,
|
||||
const char *,
|
||||
const char **);
|
||||
typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *,
|
||||
const char **);
|
||||
|
||||
enum XML_Convert_Result {
|
||||
XML_CONVERT_COMPLETED = 0,
|
||||
XML_CONVERT_INPUT_INCOMPLETE = 1,
|
||||
XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */
|
||||
XML_CONVERT_OUTPUT_EXHAUSTED
|
||||
= 2 /* and therefore potentially input remaining as well */
|
||||
};
|
||||
|
||||
struct encoding {
|
||||
SCANNER scanners[XML_N_STATES];
|
||||
SCANNER literalScanners[XML_N_LITERAL_TYPES];
|
||||
int (PTRCALL *sameName)(const ENCODING *,
|
||||
const char *,
|
||||
const char *);
|
||||
int (PTRCALL *nameMatchesAscii)(const ENCODING *,
|
||||
const char *,
|
||||
const char *,
|
||||
const char *);
|
||||
int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
|
||||
int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *,
|
||||
const char *);
|
||||
int(PTRFASTCALL *nameLength)(const ENCODING *, const char *);
|
||||
const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
|
||||
int (PTRCALL *getAtts)(const ENCODING *enc,
|
||||
const char *ptr,
|
||||
int attsMax,
|
||||
ATTRIBUTE *atts);
|
||||
int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
|
||||
int (PTRCALL *predefinedEntityName)(const ENCODING *,
|
||||
const char *,
|
||||
const char *);
|
||||
void (PTRCALL *updatePosition)(const ENCODING *,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
POSITION *);
|
||||
int (PTRCALL *isPublicId)(const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr);
|
||||
enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim,
|
||||
char **toP,
|
||||
const char *toLim);
|
||||
enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim,
|
||||
unsigned short **toP,
|
||||
const unsigned short *toLim);
|
||||
int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
|
||||
ATTRIBUTE *atts);
|
||||
int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
|
||||
int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *,
|
||||
const char *);
|
||||
void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr,
|
||||
const char *end, POSITION *);
|
||||
int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr,
|
||||
const char *end, const char **badPtr);
|
||||
enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim, char **toP,
|
||||
const char *toLim);
|
||||
enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim,
|
||||
unsigned short **toP,
|
||||
const unsigned short *toLim);
|
||||
int minBytesPerChar;
|
||||
char isUtf8;
|
||||
char isUtf16;
|
||||
@ -200,68 +216,62 @@ struct encoding {
|
||||
the prolog outside literals, comments and processing instructions.
|
||||
*/
|
||||
|
||||
|
||||
#define XmlTok(enc, state, ptr, end, nextTokPtr) \
|
||||
#define XmlTok(enc, state, ptr, end, nextTokPtr) \
|
||||
(((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
|
||||
|
||||
#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
|
||||
#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlContentTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
|
||||
#define XmlContentTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
|
||||
#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#ifdef XML_DTD
|
||||
|
||||
#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
|
||||
# define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#endif /* XML_DTD */
|
||||
|
||||
/* This is used for performing a 2nd-level tokenization on the content
|
||||
of a literal that has already been returned by XmlTok.
|
||||
*/
|
||||
#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
|
||||
#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
|
||||
(((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
|
||||
|
||||
#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
|
||||
#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
|
||||
#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
|
||||
|
||||
#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
|
||||
#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
|
||||
(((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
|
||||
|
||||
#define XmlNameLength(enc, ptr) \
|
||||
(((enc)->nameLength)(enc, ptr))
|
||||
#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr))
|
||||
|
||||
#define XmlSkipS(enc, ptr) \
|
||||
(((enc)->skipS)(enc, ptr))
|
||||
#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr))
|
||||
|
||||
#define XmlGetAttributes(enc, ptr, attsMax, atts) \
|
||||
#define XmlGetAttributes(enc, ptr, attsMax, atts) \
|
||||
(((enc)->getAtts)(enc, ptr, attsMax, atts))
|
||||
|
||||
#define XmlCharRefNumber(enc, ptr) \
|
||||
(((enc)->charRefNumber)(enc, ptr))
|
||||
#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr))
|
||||
|
||||
#define XmlPredefinedEntityName(enc, ptr, end) \
|
||||
#define XmlPredefinedEntityName(enc, ptr, end) \
|
||||
(((enc)->predefinedEntityName)(enc, ptr, end))
|
||||
|
||||
#define XmlUpdatePosition(enc, ptr, end, pos) \
|
||||
#define XmlUpdatePosition(enc, ptr, end, pos) \
|
||||
(((enc)->updatePosition)(enc, ptr, end, pos))
|
||||
|
||||
#define XmlIsPublicId(enc, ptr, end, badPtr) \
|
||||
#define XmlIsPublicId(enc, ptr, end, badPtr) \
|
||||
(((enc)->isPublicId)(enc, ptr, end, badPtr))
|
||||
|
||||
#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
|
||||
#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
|
||||
(((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
|
||||
|
||||
#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
|
||||
#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
|
||||
(((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
|
||||
|
||||
typedef struct {
|
||||
@ -269,16 +279,11 @@ typedef struct {
|
||||
const ENCODING **encPtr;
|
||||
} INIT_ENCODING;
|
||||
|
||||
int XmlParseXmlDecl(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc,
|
||||
const char *ptr, const char *end, const char **badPtr,
|
||||
const char **versionPtr, const char **versionEndPtr,
|
||||
const char **encodingNamePtr,
|
||||
const ENCODING **namedEncodingPtr,
|
||||
int *standalonePtr);
|
||||
const ENCODING **namedEncodingPtr, int *standalonePtr);
|
||||
|
||||
int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
|
||||
const ENCODING *XmlGetUtf8InternalEncoding(void);
|
||||
@ -287,34 +292,22 @@ int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
|
||||
int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
|
||||
int XmlSizeOfUnknownEncoding(void);
|
||||
|
||||
typedef int(XMLCALL *CONVERTER)(void *userData, const char *p);
|
||||
|
||||
typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
|
||||
ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
|
||||
void *userData);
|
||||
|
||||
ENCODING *
|
||||
XmlInitUnknownEncoding(void *mem,
|
||||
int *table,
|
||||
CONVERTER convert,
|
||||
void *userData);
|
||||
|
||||
int XmlParseXmlDeclNS(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc,
|
||||
const char *ptr, const char *end, const char **badPtr,
|
||||
const char **versionPtr, const char **versionEndPtr,
|
||||
const char **encodingNamePtr,
|
||||
const ENCODING **namedEncodingPtr,
|
||||
int *standalonePtr);
|
||||
const ENCODING **namedEncodingPtr, int *standalonePtr);
|
||||
|
||||
int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
|
||||
const ENCODING *XmlGetUtf8InternalEncodingNS(void);
|
||||
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
|
||||
ENCODING *
|
||||
XmlInitUnknownEncodingNS(void *mem,
|
||||
int *table,
|
||||
CONVERTER convert,
|
||||
void *userData);
|
||||
ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
|
||||
void *userData);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,46 +1,73 @@
|
||||
/*
|
||||
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
enum {
|
||||
BT_NONXML,
|
||||
BT_MALFORM,
|
||||
BT_LT,
|
||||
BT_AMP,
|
||||
BT_RSQB,
|
||||
BT_LEAD2,
|
||||
BT_LEAD3,
|
||||
BT_LEAD4,
|
||||
BT_TRAIL,
|
||||
BT_CR,
|
||||
BT_LF,
|
||||
BT_GT,
|
||||
BT_QUOT,
|
||||
BT_APOS,
|
||||
BT_EQUALS,
|
||||
BT_QUEST,
|
||||
BT_EXCL,
|
||||
BT_SOL,
|
||||
BT_SEMI,
|
||||
BT_NUM,
|
||||
BT_LSQB,
|
||||
BT_S,
|
||||
BT_NMSTRT,
|
||||
BT_COLON,
|
||||
BT_HEX,
|
||||
BT_DIGIT,
|
||||
BT_NAME,
|
||||
BT_MINUS,
|
||||
BT_OTHER, /* known not to be a name or name start character */
|
||||
BT_NONXML, /* e.g. noncharacter-FFFF */
|
||||
BT_MALFORM, /* illegal, with regard to encoding */
|
||||
BT_LT, /* less than = "<" */
|
||||
BT_AMP, /* ampersand = "&" */
|
||||
BT_RSQB, /* right square bracket = "[" */
|
||||
BT_LEAD2, /* lead byte of a 2-byte UTF-8 character */
|
||||
BT_LEAD3, /* lead byte of a 3-byte UTF-8 character */
|
||||
BT_LEAD4, /* lead byte of a 4-byte UTF-8 character */
|
||||
BT_TRAIL, /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */
|
||||
BT_CR, /* carriage return = "\r" */
|
||||
BT_LF, /* line feed = "\n" */
|
||||
BT_GT, /* greater than = ">" */
|
||||
BT_QUOT, /* quotation character = "\"" */
|
||||
BT_APOS, /* aposthrophe = "'" */
|
||||
BT_EQUALS, /* equal sign = "=" */
|
||||
BT_QUEST, /* question mark = "?" */
|
||||
BT_EXCL, /* exclamation mark = "!" */
|
||||
BT_SOL, /* solidus, slash = "/" */
|
||||
BT_SEMI, /* semicolon = ";" */
|
||||
BT_NUM, /* number sign = "#" */
|
||||
BT_LSQB, /* left square bracket = "[" */
|
||||
BT_S, /* white space, e.g. "\t", " "[, "\r"] */
|
||||
BT_NMSTRT, /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */
|
||||
BT_COLON, /* colon = ":" */
|
||||
BT_HEX, /* hex letter = "A".."F" + "a".."f" */
|
||||
BT_DIGIT, /* digit = "0".."9" */
|
||||
BT_NAME, /* dot and middle dot = "." + chr(0xb7) */
|
||||
BT_MINUS, /* minus = "-" */
|
||||
BT_OTHER, /* known not to be a name or name start character */
|
||||
BT_NONASCII, /* might be a name or name start character */
|
||||
BT_PERCNT,
|
||||
BT_LPAR,
|
||||
BT_RPAR,
|
||||
BT_AST,
|
||||
BT_PLUS,
|
||||
BT_COMMA,
|
||||
BT_VERBAR
|
||||
BT_PERCNT, /* percent sign = "%" */
|
||||
BT_LPAR, /* left parenthesis = "(" */
|
||||
BT_RPAR, /* right parenthesis = "(" */
|
||||
BT_AST, /* asterisk = "*" */
|
||||
BT_PLUS, /* plus sign = "+" */
|
||||
BT_COMMA, /* comma = "," */
|
||||
BT_VERBAR /* vertical bar = "|" */
|
||||
};
|
||||
|
||||
#include <stddef.h>
|
||||
|
@ -1,63 +1,81 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
/* This file is included!
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
|
||||
Copyright (c) 2000-2017 Expat development team
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file is included! */
|
||||
#ifdef XML_TOK_NS_C
|
||||
|
||||
const ENCODING *
|
||||
NS(XmlGetUtf8InternalEncoding)(void)
|
||||
{
|
||||
NS(XmlGetUtf8InternalEncoding)(void) {
|
||||
return &ns(internal_utf8_encoding).enc;
|
||||
}
|
||||
|
||||
const ENCODING *
|
||||
NS(XmlGetUtf16InternalEncoding)(void)
|
||||
{
|
||||
#if BYTEORDER == 1234
|
||||
NS(XmlGetUtf16InternalEncoding)(void) {
|
||||
# if BYTEORDER == 1234
|
||||
return &ns(internal_little2_encoding).enc;
|
||||
#elif BYTEORDER == 4321
|
||||
# elif BYTEORDER == 4321
|
||||
return &ns(internal_big2_encoding).enc;
|
||||
#else
|
||||
# else
|
||||
const short n = 1;
|
||||
return (*(const char *)&n
|
||||
? &ns(internal_little2_encoding).enc
|
||||
: &ns(internal_big2_encoding).enc);
|
||||
#endif
|
||||
return (*(const char *)&n ? &ns(internal_little2_encoding).enc
|
||||
: &ns(internal_big2_encoding).enc);
|
||||
# endif
|
||||
}
|
||||
|
||||
static const ENCODING * const NS(encodings)[] = {
|
||||
&ns(latin1_encoding).enc,
|
||||
&ns(ascii_encoding).enc,
|
||||
&ns(utf8_encoding).enc,
|
||||
&ns(big2_encoding).enc,
|
||||
&ns(big2_encoding).enc,
|
||||
&ns(little2_encoding).enc,
|
||||
&ns(utf8_encoding).enc /* NO_ENC */
|
||||
static const ENCODING *const NS(encodings)[] = {
|
||||
&ns(latin1_encoding).enc, &ns(ascii_encoding).enc,
|
||||
&ns(utf8_encoding).enc, &ns(big2_encoding).enc,
|
||||
&ns(big2_encoding).enc, &ns(little2_encoding).enc,
|
||||
&ns(utf8_encoding).enc /* NO_ENC */
|
||||
};
|
||||
|
||||
static int PTRCALL
|
||||
NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
|
||||
const char **nextTokPtr)
|
||||
{
|
||||
return initScan(NS(encodings), (const INIT_ENCODING *)enc,
|
||||
XML_PROLOG_STATE, ptr, end, nextTokPtr);
|
||||
const char **nextTokPtr) {
|
||||
return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE,
|
||||
ptr, end, nextTokPtr);
|
||||
}
|
||||
|
||||
static int PTRCALL
|
||||
NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
|
||||
const char **nextTokPtr)
|
||||
{
|
||||
return initScan(NS(encodings), (const INIT_ENCODING *)enc,
|
||||
XML_CONTENT_STATE, ptr, end, nextTokPtr);
|
||||
const char **nextTokPtr) {
|
||||
return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE,
|
||||
ptr, end, nextTokPtr);
|
||||
}
|
||||
|
||||
int
|
||||
NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
|
||||
const char *name)
|
||||
{
|
||||
const char *name) {
|
||||
int i = getEncodingIndex(name);
|
||||
if (i == UNKNOWN_ENC)
|
||||
return 0;
|
||||
@ -71,9 +89,8 @@ NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
|
||||
}
|
||||
|
||||
static const ENCODING *
|
||||
NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
|
||||
{
|
||||
#define ENCODING_MAX 128
|
||||
NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) {
|
||||
# define ENCODING_MAX 128
|
||||
char buf[ENCODING_MAX];
|
||||
char *p = buf;
|
||||
int i;
|
||||
@ -90,28 +107,14 @@ NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
|
||||
}
|
||||
|
||||
int
|
||||
NS(XmlParseXmlDecl)(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
const char **encodingName,
|
||||
const ENCODING **encoding,
|
||||
int *standalone)
|
||||
{
|
||||
return doParseXmlDecl(NS(findEncoding),
|
||||
isGeneralTextEntity,
|
||||
enc,
|
||||
ptr,
|
||||
end,
|
||||
badPtr,
|
||||
versionPtr,
|
||||
versionEndPtr,
|
||||
encodingName,
|
||||
encoding,
|
||||
standalone);
|
||||
NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc,
|
||||
const char *ptr, const char *end, const char **badPtr,
|
||||
const char **versionPtr, const char **versionEndPtr,
|
||||
const char **encodingName, const ENCODING **encoding,
|
||||
int *standalone) {
|
||||
return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end,
|
||||
badPtr, versionPtr, versionEndPtr, encodingName,
|
||||
encoding, standalone);
|
||||
}
|
||||
|
||||
#endif /* XML_TOK_NS_C */
|
||||
|
@ -120,13 +120,14 @@
|
||||
* shadowing the global declaration.
|
||||
*
|
||||
* So, if the compiler warns about that, we turn off -Wshadow warnings.
|
||||
*
|
||||
* In addition, the generated code may have functions with unreachable
|
||||
* code, so suppress warnings about those.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
/*
|
||||
* This is Microsoft Visual Studio; we can use
|
||||
* __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
|
||||
*
|
||||
* Suppress unreachable code warnings.
|
||||
*/
|
||||
#define DIAG_OFF_BISON_BYACC \
|
||||
__pragma(warning(push)) \
|
||||
@ -166,6 +167,9 @@
|
||||
#else
|
||||
/*
|
||||
* Bison.
|
||||
*
|
||||
* The generated code may have functions with unreachable code, so
|
||||
* suppress warnings about those.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
/*
|
||||
|
@ -67,11 +67,6 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
size_t msglen;
|
||||
char *p;
|
||||
size_t errbuflen_remaining;
|
||||
#if defined(HAVE_STRERROR_S)
|
||||
errno_t err;
|
||||
#elif defined(HAVE_STRERROR_R)
|
||||
int err;
|
||||
#endif
|
||||
|
||||
va_start(ap, fmt);
|
||||
pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
|
||||
@ -98,7 +93,10 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
* Now append the string for the error code.
|
||||
*/
|
||||
#if defined(HAVE_STRERROR_S)
|
||||
err = strerror_s(p, errbuflen_remaining, errnum);
|
||||
/*
|
||||
* We have a Windows-style strerror_s().
|
||||
*/
|
||||
errno_t err = strerror_s(p, errbuflen_remaining, errnum);
|
||||
if (err != 0) {
|
||||
/*
|
||||
* It doesn't appear to be documented anywhere obvious
|
||||
@ -106,8 +104,24 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
*/
|
||||
pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
|
||||
}
|
||||
#elif defined(HAVE_STRERROR_R)
|
||||
err = strerror_r(errnum, p, errbuflen_remaining);
|
||||
#elif defined(HAVE_GNU_STRERROR_R)
|
||||
/*
|
||||
* We have a GNU-style strerror_r(), which is *not* guaranteed to
|
||||
* do anything to the buffer handed to it, and which returns a
|
||||
* pointer to the error string, which may or may not be in
|
||||
* the buffer.
|
||||
*
|
||||
* It is, however, guaranteed to succeed.
|
||||
*/
|
||||
char strerror_buf[PCAP_ERRBUF_SIZE];
|
||||
char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s", errstring);
|
||||
#elif defined(HAVE_POSIX_STRERROR_R)
|
||||
/*
|
||||
* We have a POSIX-style strerror_r(), which is guaranteed to fill
|
||||
* in the buffer, but is not guaranteed to succeed.
|
||||
*/
|
||||
int err = strerror_r(errnum, p, errbuflen_remaining);
|
||||
if (err == EINVAL) {
|
||||
/*
|
||||
* UNIX 03 says this isn't guaranteed to produce a
|
||||
@ -131,3 +145,72 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Generate an error message based on a format, arguments, and a
|
||||
* Win32 error, with a message for the Win32 error after the formatted output.
|
||||
*/
|
||||
void
|
||||
pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
size_t msglen;
|
||||
char *p;
|
||||
size_t errbuflen_remaining;
|
||||
DWORD retval;
|
||||
char win32_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
va_start(ap, fmt);
|
||||
pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
|
||||
va_end(ap);
|
||||
msglen = strlen(errbuf);
|
||||
|
||||
/*
|
||||
* Do we have enough space to append ": "?
|
||||
* Including the terminating '\0', that's 3 bytes.
|
||||
*/
|
||||
if (msglen + 3 > errbuflen) {
|
||||
/* No - just give them what we've produced. */
|
||||
return;
|
||||
}
|
||||
p = errbuf + msglen;
|
||||
errbuflen_remaining = errbuflen - msglen;
|
||||
*p++ = ':';
|
||||
*p++ = ' ';
|
||||
*p = '\0';
|
||||
msglen += 2;
|
||||
errbuflen_remaining -= 2;
|
||||
|
||||
/*
|
||||
* Now append the string for the error code.
|
||||
*
|
||||
* XXX - what language ID to use?
|
||||
*
|
||||
* For UN*Xes, pcap_strerror() may or may not return localized
|
||||
* strings.
|
||||
*
|
||||
* We currently don't have localized messages for libpcap, but
|
||||
* we might want to do so. On the other hand, if most of these
|
||||
* messages are going to be read by libpcap developers and
|
||||
* perhaps by developers of libpcap-based applications, English
|
||||
* might be a better choice, so the developer doesn't have to
|
||||
* get the message translated if it's in a language they don't
|
||||
* happen to understand.
|
||||
*/
|
||||
retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
win32_errbuf, PCAP_ERRBUF_SIZE, NULL);
|
||||
if (retval == 0) {
|
||||
/*
|
||||
* Failed.
|
||||
*/
|
||||
pcap_snprintf(p, errbuflen_remaining,
|
||||
"Couldn't get error message for error (%lu)", errnum);
|
||||
return;
|
||||
}
|
||||
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum);
|
||||
}
|
||||
#endif
|
||||
|
@ -43,6 +43,11 @@ extern "C" {
|
||||
void pcap_fmt_errmsg_for_errno(char *, size_t, int,
|
||||
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
|
||||
|
||||
#ifdef _WIN32
|
||||
void pcap_fmt_errmsg_for_win32_err(char *, size_t, DWORD,
|
||||
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -85,20 +85,14 @@
|
||||
*/
|
||||
#elif defined(__linux__) || defined(linux) || defined(__linux)
|
||||
/*
|
||||
* We can't turn _GNU_SOURCE on because some versions of GNU Libc
|
||||
* will give the GNU version of strerror_r(), which returns a
|
||||
* string pointer and doesn't necessarily fill in the buffer,
|
||||
* rather than the standard version of strerror_r(), which
|
||||
* returns 0 or an errno and always fills in the buffer. We
|
||||
* require both of the latter behaviors.
|
||||
* Turn on _GNU_SOURCE to get everything GNU libc has to offer,
|
||||
* including asprintf().
|
||||
*
|
||||
* So we try turning everything else on that we can. This includes
|
||||
* defining _XOPEN_SOURCE as 600, because we want to force crypt()
|
||||
* to be declared on systems that use GNU libc, such as most Linux
|
||||
* distributions.
|
||||
* Unfortunately, one thing it has to offer is a strerror_r()
|
||||
* that's not POSIX-compliant, but we deal with that in
|
||||
* pcap_fmt_errmsg_for_errno().
|
||||
*/
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#define _GNU_SOURCE
|
||||
|
||||
/*
|
||||
* We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -113,16 +113,14 @@
|
||||
#define Q_ISIS_L2 32
|
||||
/* PDU types */
|
||||
#define Q_ISIS_IIH 33
|
||||
#define Q_ISIS_LAN_IIH 34
|
||||
#define Q_ISIS_PTP_IIH 35
|
||||
#define Q_ISIS_SNP 36
|
||||
#define Q_ISIS_CSNP 37
|
||||
#define Q_ISIS_PSNP 38
|
||||
#define Q_ISIS_LSP 39
|
||||
#define Q_ISIS_SNP 34
|
||||
#define Q_ISIS_CSNP 35
|
||||
#define Q_ISIS_PSNP 36
|
||||
#define Q_ISIS_LSP 37
|
||||
|
||||
#define Q_RADIO 40
|
||||
#define Q_RADIO 38
|
||||
|
||||
#define Q_CARP 41
|
||||
#define Q_CARP 39
|
||||
|
||||
/* Directional qualifiers. */
|
||||
|
||||
@ -299,8 +297,8 @@ void gen_or(struct block *, struct block *);
|
||||
void gen_not(struct block *);
|
||||
|
||||
struct block *gen_scode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual);
|
||||
struct block *gen_acode(compiler_state_t *, const u_char *, struct qual);
|
||||
struct block *gen_ecode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_acode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_mcode(compiler_state_t *, const char *, const char *,
|
||||
unsigned int, struct qual);
|
||||
#ifdef INET6
|
||||
@ -326,13 +324,13 @@ struct block *gen_llc_u(compiler_state_t *);
|
||||
struct block *gen_llc_s_subtype(compiler_state_t *, bpf_u_int32);
|
||||
struct block *gen_llc_u_subtype(compiler_state_t *, bpf_u_int32);
|
||||
|
||||
struct block *gen_vlan(compiler_state_t *, int);
|
||||
struct block *gen_mpls(compiler_state_t *, int);
|
||||
struct block *gen_vlan(compiler_state_t *, bpf_u_int32, int);
|
||||
struct block *gen_mpls(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_pppoed(compiler_state_t *);
|
||||
struct block *gen_pppoes(compiler_state_t *, int);
|
||||
struct block *gen_pppoes(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_geneve(compiler_state_t *, int);
|
||||
struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
|
||||
bpf_u_int32, int);
|
||||
@ -343,29 +341,11 @@ struct block *gen_mtp2type_abbrev(compiler_state_t *, int type);
|
||||
struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
|
||||
bpf_u_int32, int);
|
||||
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_ifname(compiler_state_t *, const char *);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_rnr(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_srnr(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_ruleset(compiler_state_t *, char *);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_reason(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_action(compiler_state_t *, int);
|
||||
|
||||
struct block *gen_p80211_type(compiler_state_t *, int, int);
|
||||
@ -386,16 +366,15 @@ struct icode {
|
||||
int cur_mark;
|
||||
};
|
||||
|
||||
void bpf_optimize(compiler_state_t *, struct icode *ic);
|
||||
void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *);
|
||||
void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
|
||||
int bpf_optimize(struct icode *, char *);
|
||||
void bpf_set_error(compiler_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
void finish_parse(compiler_state_t *, struct block *);
|
||||
int finish_parse(compiler_state_t *, struct block *);
|
||||
char *sdup(compiler_state_t *, const char *);
|
||||
|
||||
struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
|
||||
struct block *, u_int *);
|
||||
struct bpf_insn *icode_to_fcode(struct icode *, struct block *, u_int *,
|
||||
char *);
|
||||
void sappend(struct slist *, struct slist *);
|
||||
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -114,9 +114,10 @@
|
||||
#define HOPC 370
|
||||
#define HDPC 371
|
||||
#define HSLS 372
|
||||
#define OR 373
|
||||
#define AND 374
|
||||
#define UMINUS 375
|
||||
#define LEX_ERROR 373
|
||||
#define OR 374
|
||||
#define AND 375
|
||||
#define UMINUS 376
|
||||
#ifdef YYSTYPE
|
||||
#undef YYSTYPE_IS_DECLARED
|
||||
#define YYSTYPE_IS_DECLARED 1
|
||||
@ -126,7 +127,6 @@
|
||||
typedef union {
|
||||
int i;
|
||||
bpf_u_int32 h;
|
||||
u_char *e;
|
||||
char *s;
|
||||
struct stmt *stmt;
|
||||
struct arth *a;
|
||||
|
@ -216,13 +216,12 @@ str2tok(const char *str, const struct tok *toks)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
|
||||
static PCAP_NORETURN_DEF void
|
||||
static void
|
||||
yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
|
||||
{
|
||||
bpf_syntax_error(cstate, msg);
|
||||
/* NOTREACHED */
|
||||
bpf_set_error(cstate, "can't parse filter expression: %s", msg);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
@ -236,8 +235,8 @@ pfreason_to_num(compiler_state_t *cstate, const char *reason)
|
||||
if (pcap_strcasecmp(reason, reasons[i]) == 0)
|
||||
return (i);
|
||||
}
|
||||
bpf_error(cstate, "unknown PF reason");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "unknown PF reason");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -260,33 +259,38 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
|
||||
return (PF_NORDR);
|
||||
#endif
|
||||
else {
|
||||
bpf_error(cstate, "unknown PF action");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "unknown PF action");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#else /* !HAVE_NET_PFVAR_H */
|
||||
static PCAP_NORETURN_DEF int
|
||||
static int
|
||||
pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
|
||||
{
|
||||
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static PCAP_NORETURN_DEF int
|
||||
static int
|
||||
pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
|
||||
{
|
||||
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
return (-1);
|
||||
}
|
||||
#endif /* HAVE_NET_PFVAR_H */
|
||||
|
||||
/*
|
||||
* For calls that might return an "an error occurred" value.
|
||||
*/
|
||||
#define CHECK_INT_VAL(val) if (val == -1) YYABORT
|
||||
#define CHECK_PTR_VAL(val) if (val == NULL) YYABORT
|
||||
|
||||
DIAG_OFF_BISON_BYACC
|
||||
%}
|
||||
|
||||
%union {
|
||||
int i;
|
||||
bpf_u_int32 h;
|
||||
u_char *e;
|
||||
char *s;
|
||||
struct stmt *stmt;
|
||||
struct arth *a;
|
||||
@ -340,11 +344,9 @@ DIAG_OFF_BISON_BYACC
|
||||
%token RADIO
|
||||
%token FISU LSSU MSU HFISU HLSSU HMSU
|
||||
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
|
||||
%token LEX_ERROR
|
||||
|
||||
|
||||
%type <s> ID
|
||||
%type <e> EID
|
||||
%type <e> AID
|
||||
%type <s> ID EID AID
|
||||
%type <s> HID HID6
|
||||
%type <i> NUM action reason type subtype type_subtype dir
|
||||
|
||||
@ -359,7 +361,7 @@ DIAG_OFF_BISON_BYACC
|
||||
%%
|
||||
prog: null expr
|
||||
{
|
||||
finish_parse(cstate, $2.b);
|
||||
CHECK_INT_VAL(finish_parse(cstate, $2.b));
|
||||
}
|
||||
| null
|
||||
;
|
||||
@ -376,64 +378,58 @@ and: AND { $$ = $<blk>0; }
|
||||
or: OR { $$ = $<blk>0; }
|
||||
;
|
||||
id: nid
|
||||
| pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q); }
|
||||
| pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| paren pid ')' { $$ = $2; }
|
||||
;
|
||||
nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); }
|
||||
| HID '/' NUM { $$.b = gen_mcode(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q); }
|
||||
| HID NETMASK HID { $$.b = gen_mcode(cstate, $1, $3, 0,
|
||||
$$.q = $<blk>0.q); }
|
||||
nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| HID '/' NUM { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| HID NETMASK HID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| HID {
|
||||
CHECK_PTR_VAL($1);
|
||||
/* Decide how to parse HID based on proto */
|
||||
$$.q = $<blk>0.q;
|
||||
if ($$.q.addr == Q_PORT)
|
||||
bpf_error(cstate, "'port' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PORTRANGE)
|
||||
bpf_error(cstate, "'portrange' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PROTO)
|
||||
bpf_error(cstate, "'proto' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PROTOCHAIN)
|
||||
bpf_error(cstate, "'protochain' modifier applied to ip host");
|
||||
$$.b = gen_ncode(cstate, $1, 0, $$.q);
|
||||
if ($$.q.addr == Q_PORT) {
|
||||
bpf_set_error(cstate, "'port' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PORTRANGE) {
|
||||
bpf_set_error(cstate, "'portrange' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PROTO) {
|
||||
bpf_set_error(cstate, "'proto' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PROTOCHAIN) {
|
||||
bpf_set_error(cstate, "'protochain' modifier applied to ip host");
|
||||
YYABORT;
|
||||
}
|
||||
CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q)));
|
||||
}
|
||||
| HID6 '/' NUM {
|
||||
CHECK_PTR_VAL($1);
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q);
|
||||
CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q)));
|
||||
#else
|
||||
bpf_error(cstate, "'ip6addr/prefixlen' not supported "
|
||||
bpf_set_error(cstate, "'ip6addr/prefixlen' not supported "
|
||||
"in this configuration");
|
||||
YYABORT;
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| HID6 {
|
||||
CHECK_PTR_VAL($1);
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6(cstate, $1, 0, 128,
|
||||
$$.q = $<blk>0.q);
|
||||
CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 0, 128,
|
||||
$$.q = $<blk>0.q)));
|
||||
#else
|
||||
bpf_error(cstate, "'ip6addr' not supported "
|
||||
bpf_set_error(cstate, "'ip6addr' not supported "
|
||||
"in this configuration");
|
||||
YYABORT;
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| EID {
|
||||
$$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q);
|
||||
/*
|
||||
* $1 was allocated by "pcap_ether_aton()",
|
||||
* so we must free it now that we're done
|
||||
* with it.
|
||||
*/
|
||||
free($1);
|
||||
}
|
||||
| AID {
|
||||
$$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q);
|
||||
/*
|
||||
* $1 was allocated by "pcap_ether_aton()",
|
||||
* so we must free it now that we're done
|
||||
* with it.
|
||||
*/
|
||||
free($1);
|
||||
}
|
||||
| EID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| AID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| not id { gen_not($2.b); $$ = $2; }
|
||||
;
|
||||
not: '!' { $$ = $<blk>0; }
|
||||
@ -444,8 +440,8 @@ pid: nid
|
||||
| qid and id { gen_and($1.b, $3.b); $$ = $3; }
|
||||
| qid or id { gen_or($1.b, $3.b); $$ = $3; }
|
||||
;
|
||||
qid: pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q); }
|
||||
qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| pid
|
||||
;
|
||||
term: rterm
|
||||
@ -455,21 +451,28 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
|
||||
| pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
|
||||
| pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
|
||||
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
|
||||
| pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
|
||||
| pqual PROTOCHAIN {
|
||||
#ifdef NO_PROTOCHAIN
|
||||
bpf_set_error(cstate, "protochain not supported");
|
||||
YYABORT;
|
||||
#else
|
||||
QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN);
|
||||
#endif
|
||||
}
|
||||
| pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
|
||||
;
|
||||
rterm: head id { $$ = $2; }
|
||||
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
|
||||
| pname { $$.b = gen_proto_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| arth relop arth { $$.b = gen_relation(cstate, $2, $1, $3, 0);
|
||||
| pname { CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| arth relop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0)));
|
||||
$$.q = qerr; }
|
||||
| arth irelop arth { $$.b = gen_relation(cstate, $2, $1, $3, 1);
|
||||
| arth irelop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 1)));
|
||||
$$.q = qerr; }
|
||||
| other { $$.b = $1; $$.q = qerr; }
|
||||
| atmtype { $$.b = gen_atmtype_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| atmmultitype { $$.b = gen_atmmulti_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| atmtype { CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| atmmultitype { CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
|
||||
| mtp2type { $$.b = gen_mtp2type_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| mtp2type { CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
/* protocol level qualifiers */
|
||||
@ -539,65 +542,69 @@ pname: LINK { $$ = Q_LINK; }
|
||||
| NETBEUI { $$ = Q_NETBEUI; }
|
||||
| RADIO { $$ = Q_RADIO; }
|
||||
;
|
||||
other: pqual TK_BROADCAST { $$ = gen_broadcast(cstate, $1); }
|
||||
| pqual TK_MULTICAST { $$ = gen_multicast(cstate, $1); }
|
||||
| LESS NUM { $$ = gen_less(cstate, $2); }
|
||||
| GREATER NUM { $$ = gen_greater(cstate, $2); }
|
||||
| CBYTE NUM byteop NUM { $$ = gen_byteop(cstate, $3, $2, $4); }
|
||||
| INBOUND { $$ = gen_inbound(cstate, 0); }
|
||||
| OUTBOUND { $$ = gen_inbound(cstate, 1); }
|
||||
| VLAN pnum { $$ = gen_vlan(cstate, $2); }
|
||||
| VLAN { $$ = gen_vlan(cstate, -1); }
|
||||
| MPLS pnum { $$ = gen_mpls(cstate, $2); }
|
||||
| MPLS { $$ = gen_mpls(cstate, -1); }
|
||||
| PPPOED { $$ = gen_pppoed(cstate); }
|
||||
| PPPOES pnum { $$ = gen_pppoes(cstate, $2); }
|
||||
| PPPOES { $$ = gen_pppoes(cstate, -1); }
|
||||
| GENEVE pnum { $$ = gen_geneve(cstate, $2); }
|
||||
| GENEVE { $$ = gen_geneve(cstate, -1); }
|
||||
other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
|
||||
| pqual TK_MULTICAST { CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); }
|
||||
| LESS NUM { CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); }
|
||||
| GREATER NUM { CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); }
|
||||
| CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
|
||||
| INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
|
||||
| OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
|
||||
| VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
|
||||
| MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
|
||||
| PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
|
||||
| PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
|
||||
| GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
|
||||
| pfvar { $$ = $1; }
|
||||
| pqual p80211 { $$ = $2; }
|
||||
| pllc { $$ = $1; }
|
||||
;
|
||||
|
||||
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname(cstate, $2); }
|
||||
| PF_RSET ID { $$ = gen_pf_ruleset(cstate, $2); }
|
||||
| PF_RNR NUM { $$ = gen_pf_rnr(cstate, $2); }
|
||||
| PF_SRNR NUM { $$ = gen_pf_srnr(cstate, $2); }
|
||||
| PF_REASON reason { $$ = gen_pf_reason(cstate, $2); }
|
||||
| PF_ACTION action { $$ = gen_pf_action(cstate, $2); }
|
||||
pfvar: PF_IFNAME ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); }
|
||||
| PF_RSET ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); }
|
||||
| PF_RNR NUM { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
|
||||
| PF_SRNR NUM { CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); }
|
||||
| PF_REASON reason { CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); }
|
||||
| PF_ACTION action { CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); }
|
||||
;
|
||||
|
||||
p80211: TYPE type SUBTYPE subtype
|
||||
{ $$ = gen_p80211_type(cstate, $2 | $4,
|
||||
{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2 | $4,
|
||||
IEEE80211_FC0_TYPE_MASK |
|
||||
IEEE80211_FC0_SUBTYPE_MASK);
|
||||
IEEE80211_FC0_SUBTYPE_MASK)));
|
||||
}
|
||||
| TYPE type { $$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK);
|
||||
| TYPE type { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK)));
|
||||
}
|
||||
| SUBTYPE type_subtype { $$ = gen_p80211_type(cstate, $2,
|
||||
| SUBTYPE type_subtype { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK |
|
||||
IEEE80211_FC0_SUBTYPE_MASK);
|
||||
IEEE80211_FC0_SUBTYPE_MASK)));
|
||||
}
|
||||
| DIR dir { $$ = gen_p80211_fcdir(cstate, $2); }
|
||||
| DIR dir { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); }
|
||||
;
|
||||
|
||||
type: NUM
|
||||
| ID { $$ = str2tok($1, ieee80211_types);
|
||||
if ($$ == -1)
|
||||
bpf_error(cstate, "unknown 802.11 type name");
|
||||
| ID { CHECK_PTR_VAL($1);
|
||||
$$ = str2tok($1, ieee80211_types);
|
||||
if ($$ == -1) {
|
||||
bpf_set_error(cstate, "unknown 802.11 type name");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
subtype: NUM
|
||||
| ID { const struct tok *types = NULL;
|
||||
int i;
|
||||
CHECK_PTR_VAL($1);
|
||||
for (i = 0;; i++) {
|
||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||
/* Ran out of types */
|
||||
bpf_error(cstate, "unknown 802.11 type");
|
||||
break;
|
||||
bpf_set_error(cstate, "unknown 802.11 type");
|
||||
YYABORT;
|
||||
}
|
||||
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
|
||||
types = ieee80211_type_subtypes[i].tok;
|
||||
@ -606,17 +613,20 @@ subtype: NUM
|
||||
}
|
||||
|
||||
$$ = str2tok($1, types);
|
||||
if ($$ == -1)
|
||||
bpf_error(cstate, "unknown 802.11 subtype name");
|
||||
if ($$ == -1) {
|
||||
bpf_set_error(cstate, "unknown 802.11 subtype name");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
type_subtype: ID { int i;
|
||||
CHECK_PTR_VAL($1);
|
||||
for (i = 0;; i++) {
|
||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||
/* Ran out of types */
|
||||
bpf_error(cstate, "unknown 802.11 type name");
|
||||
break;
|
||||
bpf_set_error(cstate, "unknown 802.11 type name");
|
||||
YYABORT;
|
||||
}
|
||||
$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
|
||||
if ($$ != -1) {
|
||||
@ -627,33 +637,37 @@ type_subtype: ID { int i;
|
||||
}
|
||||
;
|
||||
|
||||
pllc: LLC { $$ = gen_llc(cstate); }
|
||||
| LLC ID { if (pcap_strcasecmp($2, "i") == 0)
|
||||
$$ = gen_llc_i(cstate);
|
||||
else if (pcap_strcasecmp($2, "s") == 0)
|
||||
$$ = gen_llc_s(cstate);
|
||||
else if (pcap_strcasecmp($2, "u") == 0)
|
||||
$$ = gen_llc_u(cstate);
|
||||
else {
|
||||
pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
|
||||
| LLC ID { CHECK_PTR_VAL($2);
|
||||
if (pcap_strcasecmp($2, "i") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_i(cstate)));
|
||||
} else if (pcap_strcasecmp($2, "s") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_s(cstate)));
|
||||
} else if (pcap_strcasecmp($2, "u") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_u(cstate)));
|
||||
} else {
|
||||
int subtype;
|
||||
|
||||
subtype = str2tok($2, llc_s_subtypes);
|
||||
if (subtype != -1)
|
||||
$$ = gen_llc_s_subtype(cstate, subtype);
|
||||
else {
|
||||
if (subtype != -1) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype)));
|
||||
} else {
|
||||
subtype = str2tok($2, llc_u_subtypes);
|
||||
if (subtype == -1)
|
||||
bpf_error(cstate, "unknown LLC type name \"%s\"", $2);
|
||||
$$ = gen_llc_u_subtype(cstate, subtype);
|
||||
if (subtype == -1) {
|
||||
bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
|
||||
YYABORT;
|
||||
}
|
||||
CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* sigh, "rnr" is already a keyword for PF */
|
||||
| LLC PF_RNR { $$ = gen_llc_s_subtype(cstate, LLC_RNR); }
|
||||
| LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
|
||||
;
|
||||
|
||||
dir: NUM
|
||||
| ID { if (pcap_strcasecmp($1, "nods") == 0)
|
||||
| ID { CHECK_PTR_VAL($1);
|
||||
if (pcap_strcasecmp($1, "nods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_NODS;
|
||||
else if (pcap_strcasecmp($1, "tods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_TODS;
|
||||
@ -661,16 +675,18 @@ dir: NUM
|
||||
$$ = IEEE80211_FC1_DIR_FROMDS;
|
||||
else if (pcap_strcasecmp($1, "dstods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_DSTODS;
|
||||
else
|
||||
bpf_error(cstate, "unknown 802.11 direction");
|
||||
else {
|
||||
bpf_set_error(cstate, "unknown 802.11 direction");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
reason: NUM { $$ = $1; }
|
||||
| ID { $$ = pfreason_to_num(cstate, $1); }
|
||||
| ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfreason_to_num(cstate, $1))); }
|
||||
;
|
||||
|
||||
action: ID { $$ = pfaction_to_num(cstate, $1); }
|
||||
action: ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfaction_to_num(cstate, $1))); }
|
||||
;
|
||||
|
||||
relop: '>' { $$ = BPF_JGT; }
|
||||
@ -681,24 +697,24 @@ irelop: LEQ { $$ = BPF_JGT; }
|
||||
| '<' { $$ = BPF_JGE; }
|
||||
| NEQ { $$ = BPF_JEQ; }
|
||||
;
|
||||
arth: pnum { $$ = gen_loadi(cstate, $1); }
|
||||
arth: pnum { CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); }
|
||||
| narth
|
||||
;
|
||||
narth: pname '[' arth ']' { $$ = gen_load(cstate, $1, $3, 1); }
|
||||
| pname '[' arth ':' NUM ']' { $$ = gen_load(cstate, $1, $3, $5); }
|
||||
| arth '+' arth { $$ = gen_arth(cstate, BPF_ADD, $1, $3); }
|
||||
| arth '-' arth { $$ = gen_arth(cstate, BPF_SUB, $1, $3); }
|
||||
| arth '*' arth { $$ = gen_arth(cstate, BPF_MUL, $1, $3); }
|
||||
| arth '/' arth { $$ = gen_arth(cstate, BPF_DIV, $1, $3); }
|
||||
| arth '%' arth { $$ = gen_arth(cstate, BPF_MOD, $1, $3); }
|
||||
| arth '&' arth { $$ = gen_arth(cstate, BPF_AND, $1, $3); }
|
||||
| arth '|' arth { $$ = gen_arth(cstate, BPF_OR, $1, $3); }
|
||||
| arth '^' arth { $$ = gen_arth(cstate, BPF_XOR, $1, $3); }
|
||||
| arth LSH arth { $$ = gen_arth(cstate, BPF_LSH, $1, $3); }
|
||||
| arth RSH arth { $$ = gen_arth(cstate, BPF_RSH, $1, $3); }
|
||||
| '-' arth %prec UMINUS { $$ = gen_neg(cstate, $2); }
|
||||
narth: pname '[' arth ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); }
|
||||
| pname '[' arth ':' NUM ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); }
|
||||
| arth '+' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); }
|
||||
| arth '-' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); }
|
||||
| arth '*' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); }
|
||||
| arth '/' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); }
|
||||
| arth '%' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); }
|
||||
| arth '&' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); }
|
||||
| arth '|' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); }
|
||||
| arth '^' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); }
|
||||
| arth LSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); }
|
||||
| arth RSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); }
|
||||
| '-' arth %prec UMINUS { CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); }
|
||||
| paren narth ')' { $$ = $2; }
|
||||
| LEN { $$ = gen_loadlen(cstate); }
|
||||
| LEN { CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); }
|
||||
;
|
||||
byteop: '&' { $$ = '&'; }
|
||||
| '|' { $$ = '|'; }
|
||||
@ -727,15 +743,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
|
||||
| VCI { $$.atmfieldtype = A_VCI; }
|
||||
;
|
||||
atmvalue: atmfieldvalue
|
||||
| relop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
|
||||
| relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0))); }
|
||||
| irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1))); }
|
||||
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
atmfieldvalue: NUM {
|
||||
$$.atmfieldtype = $<blk>0.atmfieldtype;
|
||||
if ($$.atmfieldtype == A_VPI ||
|
||||
$$.atmfieldtype == A_VCI)
|
||||
$$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
|
||||
CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0)));
|
||||
}
|
||||
;
|
||||
atmlistvalue: atmfieldvalue
|
||||
@ -760,8 +776,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
|
||||
| HSLS { $$.mtp3fieldtype = MH_SLS; }
|
||||
;
|
||||
mtp3value: mtp3fieldvalue
|
||||
| relop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
|
||||
| relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0))); }
|
||||
| irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1))); }
|
||||
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
mtp3fieldvalue: NUM {
|
||||
@ -774,7 +790,7 @@ mtp3fieldvalue: NUM {
|
||||
$$.mtp3fieldtype == MH_OPC ||
|
||||
$$.mtp3fieldtype == MH_DPC ||
|
||||
$$.mtp3fieldtype == MH_SLS)
|
||||
$$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0)));
|
||||
}
|
||||
;
|
||||
mtp3listvalue: mtp3fieldvalue
|
||||
|
@ -233,7 +233,22 @@ pcap_nametonetaddr(const char *name)
|
||||
int h_errnoval;
|
||||
int err;
|
||||
|
||||
err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
|
||||
/*
|
||||
* Apparently, the man page at
|
||||
*
|
||||
* http://man7.org/linux/man-pages/man3/getnetbyname_r.3.html
|
||||
*
|
||||
* lies when it says
|
||||
*
|
||||
* If the function call successfully obtains a network record,
|
||||
* then *result is set pointing to result_buf; otherwise, *result
|
||||
* is set to NULL.
|
||||
*
|
||||
* and, in fact, at least in some versions of GNU libc, it does
|
||||
* *not* always get set if getnetbyname_r() succeeds.
|
||||
*/
|
||||
np = NULL;
|
||||
err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
|
||||
&h_errnoval);
|
||||
if (err != 0) {
|
||||
/*
|
||||
@ -308,7 +323,8 @@ pcap_nametoport(const char *name, int *port, int *proto)
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
error = getaddrinfo(NULL, name, &hints, &res);
|
||||
if (error != 0) {
|
||||
if (error != EAI_NONAME) {
|
||||
if (error != EAI_NONAME &&
|
||||
error != EAI_SERVICE) {
|
||||
/*
|
||||
* This is a real error, not just "there's
|
||||
* no such service name".
|
||||
@ -351,7 +367,8 @@ pcap_nametoport(const char *name, int *port, int *proto)
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
error = getaddrinfo(NULL, name, &hints, &res);
|
||||
if (error != 0) {
|
||||
if (error != EAI_NONAME) {
|
||||
if (error != EAI_NONAME &&
|
||||
error != EAI_SERVICE) {
|
||||
/*
|
||||
* This is a real error, not just "there's
|
||||
* no such service name".
|
||||
@ -638,8 +655,15 @@ __pcap_atoin(const char *s, bpf_u_int32 *addr)
|
||||
len = 0;
|
||||
for (;;) {
|
||||
n = 0;
|
||||
while (*s && *s != '.')
|
||||
while (*s && *s != '.') {
|
||||
if (n > 25) {
|
||||
/* The result will be > 255 */
|
||||
return -1;
|
||||
}
|
||||
n = n * 10 + *s++ - '0';
|
||||
}
|
||||
if (n > 255)
|
||||
return -1;
|
||||
*addr <<= 8;
|
||||
*addr |= n & 0xff;
|
||||
len += 8;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
@ -228,6 +229,16 @@ struct vmapinfo {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Place to longjmp to on an error.
|
||||
*/
|
||||
jmp_buf top_ctx;
|
||||
|
||||
/*
|
||||
* The buffer into which to put error message.
|
||||
*/
|
||||
char *errbuf;
|
||||
|
||||
/*
|
||||
* A flag to indicate that further optimization is needed.
|
||||
* Iterative passes are continued until a given pass yields no
|
||||
@ -254,19 +265,19 @@ typedef struct {
|
||||
* True if a is in uset {p}
|
||||
*/
|
||||
#define SET_MEMBER(p, a) \
|
||||
((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
|
||||
((p)[(unsigned)(a) / BITS_PER_WORD] & ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD)))
|
||||
|
||||
/*
|
||||
* Add 'a' to uset p.
|
||||
*/
|
||||
#define SET_INSERT(p, a) \
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] |= ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
|
||||
/*
|
||||
* Delete 'a' from uset p.
|
||||
*/
|
||||
#define SET_DELETE(p, a) \
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] &= ~((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
|
||||
/*
|
||||
* a := a intersect b
|
||||
@ -313,6 +324,16 @@ typedef struct {
|
||||
} opt_state_t;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Place to longjmp to on an error.
|
||||
*/
|
||||
jmp_buf top_ctx;
|
||||
|
||||
/*
|
||||
* The buffer into which to put error message.
|
||||
*/
|
||||
char *errbuf;
|
||||
|
||||
/*
|
||||
* Some pointers used to convert the basic block form of the code,
|
||||
* into the array form that BPF requires. 'fstart' will point to
|
||||
@ -323,14 +344,16 @@ typedef struct {
|
||||
struct bpf_insn *ftail;
|
||||
} conv_state_t;
|
||||
|
||||
static void opt_init(compiler_state_t *, opt_state_t *, struct icode *);
|
||||
static void opt_init(opt_state_t *, struct icode *);
|
||||
static void opt_cleanup(opt_state_t *);
|
||||
static void PCAP_NORETURN opt_error(opt_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
static void intern_blocks(opt_state_t *, struct icode *);
|
||||
|
||||
static void find_inedges(opt_state_t *, struct block *);
|
||||
#ifdef BDEBUG
|
||||
static void opt_dump(compiler_state_t *, struct icode *);
|
||||
static void opt_dump(opt_state_t *, struct icode *);
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
@ -663,7 +686,7 @@ F(opt_state_t *opt_state, int code, int v0, int v1)
|
||||
int val;
|
||||
struct valnode *p;
|
||||
|
||||
hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
|
||||
hash = (u_int)code ^ ((u_int)v0 << 4) ^ ((u_int)v1 << 8);
|
||||
hash %= MODULUS;
|
||||
|
||||
for (p = opt_state->hashtbl[hash]; p; p = p->next)
|
||||
@ -701,8 +724,7 @@ vstore(struct stmt *s, int *valp, int newval, int alter)
|
||||
* (Unary operators are handled elsewhere.)
|
||||
*/
|
||||
static void
|
||||
fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct stmt *s, int v0, int v1)
|
||||
fold_op(opt_state_t *opt_state, struct stmt *s, int v0, int v1)
|
||||
{
|
||||
bpf_u_int32 a, b;
|
||||
|
||||
@ -724,13 +746,13 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
|
||||
case BPF_DIV:
|
||||
if (b == 0)
|
||||
bpf_error(cstate, "division by zero");
|
||||
opt_error(opt_state, "division by zero");
|
||||
a /= b;
|
||||
break;
|
||||
|
||||
case BPF_MOD:
|
||||
if (b == 0)
|
||||
bpf_error(cstate, "modulus by zero");
|
||||
opt_error(opt_state, "modulus by zero");
|
||||
a %= b;
|
||||
break;
|
||||
|
||||
@ -747,11 +769,39 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
break;
|
||||
|
||||
case BPF_LSH:
|
||||
a <<= b;
|
||||
/*
|
||||
* A left shift of more than the width of the type
|
||||
* is undefined in C; we'll just treat it as shifting
|
||||
* all the bits out.
|
||||
*
|
||||
* XXX - the BPF interpreter doesn't check for this,
|
||||
* so its behavior is dependent on the behavior of
|
||||
* the processor on which it's running. There are
|
||||
* processors on which it shifts all the bits out
|
||||
* and processors on which it does no shift.
|
||||
*/
|
||||
if (b < 32)
|
||||
a <<= b;
|
||||
else
|
||||
a = 0;
|
||||
break;
|
||||
|
||||
case BPF_RSH:
|
||||
a >>= b;
|
||||
/*
|
||||
* A right shift of more than the width of the type
|
||||
* is undefined in C; we'll just treat it as shifting
|
||||
* all the bits out.
|
||||
*
|
||||
* XXX - the BPF interpreter doesn't check for this,
|
||||
* so its behavior is dependent on the behavior of
|
||||
* the processor on which it's running. There are
|
||||
* processors on which it shifts all the bits out
|
||||
* and processors on which it does no shift.
|
||||
*/
|
||||
if (b < 32)
|
||||
a >>= b;
|
||||
else
|
||||
a = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1043,8 +1093,7 @@ opt_peep(opt_state_t *opt_state, struct block *b)
|
||||
* evaluation and code transformations weren't folded together.
|
||||
*/
|
||||
static void
|
||||
opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct stmt *s, int val[], int alter)
|
||||
opt_stmt(opt_state_t *opt_state, struct stmt *s, int val[], int alter)
|
||||
{
|
||||
int op;
|
||||
int v;
|
||||
@ -1096,7 +1145,23 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
case BPF_ALU|BPF_NEG:
|
||||
if (alter && opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
s->code = BPF_LD|BPF_IMM;
|
||||
s->k = -opt_state->vmap[val[A_ATOM]].const_val;
|
||||
/*
|
||||
* Do this negation as unsigned arithmetic; that's
|
||||
* what modern BPF engines do, and it guarantees
|
||||
* that all possible values can be negated. (Yeah,
|
||||
* negating 0x80000000, the minimum signed 32-bit
|
||||
* two's-complement value, results in 0x80000000,
|
||||
* so it's still negative, but we *should* be doing
|
||||
* all unsigned arithmetic here, to match what
|
||||
* modern BPF engines do.)
|
||||
*
|
||||
* Express it as 0U - (unsigned value) so that we
|
||||
* don't get compiler warnings about negating an
|
||||
* unsigned value and don't get UBSan warnings
|
||||
* about the result of negating 0x80000000 being
|
||||
* undefined.
|
||||
*/
|
||||
s->k = 0U - (bpf_u_int32)(opt_state->vmap[val[A_ATOM]].const_val);
|
||||
val[A_ATOM] = K(s->k);
|
||||
}
|
||||
else
|
||||
@ -1116,9 +1181,17 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
op = BPF_OP(s->code);
|
||||
if (alter) {
|
||||
if (s->k == 0) {
|
||||
/* don't optimize away "sub #0"
|
||||
/*
|
||||
* Optimize operations where the constant
|
||||
* is zero.
|
||||
*
|
||||
* Don't optimize away "sub #0"
|
||||
* as it may be needed later to
|
||||
* fixup the generated math code */
|
||||
* fixup the generated math code.
|
||||
*
|
||||
* Fail if we're dividing by zero or taking
|
||||
* a modulus by zero.
|
||||
*/
|
||||
if (op == BPF_ADD ||
|
||||
op == BPF_LSH || op == BPF_RSH ||
|
||||
op == BPF_OR || op == BPF_XOR) {
|
||||
@ -1130,9 +1203,15 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
val[A_ATOM] = K(s->k);
|
||||
break;
|
||||
}
|
||||
if (op == BPF_DIV)
|
||||
opt_error(opt_state,
|
||||
"division by zero");
|
||||
if (op == BPF_MOD)
|
||||
opt_error(opt_state,
|
||||
"modulus by zero");
|
||||
}
|
||||
if (opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
fold_op(cstate, opt_state, s, val[A_ATOM], K(s->k));
|
||||
fold_op(opt_state, s, val[A_ATOM], K(s->k));
|
||||
val[A_ATOM] = K(s->k);
|
||||
break;
|
||||
}
|
||||
@ -1153,12 +1232,22 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
op = BPF_OP(s->code);
|
||||
if (alter && opt_state->vmap[val[X_ATOM]].is_const) {
|
||||
if (opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
fold_op(cstate, opt_state, s, val[A_ATOM], val[X_ATOM]);
|
||||
fold_op(opt_state, s, val[A_ATOM], val[X_ATOM]);
|
||||
val[A_ATOM] = K(s->k);
|
||||
}
|
||||
else {
|
||||
s->code = BPF_ALU|BPF_K|op;
|
||||
s->k = opt_state->vmap[val[X_ATOM]].const_val;
|
||||
/*
|
||||
* XXX - we need to make up our minds
|
||||
* as to what integers are signed and
|
||||
* what integers are unsigned in BPF
|
||||
* programs and in our IR.
|
||||
*/
|
||||
if ((op == BPF_LSH || op == BPF_RSH) &&
|
||||
(s->k < 0 || s->k > 31))
|
||||
opt_error(opt_state,
|
||||
"shift by more than 31 bits");
|
||||
opt_state->done = 0;
|
||||
val[A_ATOM] =
|
||||
F(opt_state, s->code, val[A_ATOM], K(s->k));
|
||||
@ -1277,8 +1366,7 @@ opt_deadstores(opt_state_t *opt_state, register struct block *b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct block *b, int do_stmts)
|
||||
opt_blk(opt_state_t *opt_state, struct block *b, int do_stmts)
|
||||
{
|
||||
struct slist *s;
|
||||
struct edge *p;
|
||||
@ -1328,7 +1416,7 @@ opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
aval = b->val[A_ATOM];
|
||||
xval = b->val[X_ATOM];
|
||||
for (s = b->stmts; s; s = s->next)
|
||||
opt_stmt(cstate, opt_state, &s->s, b->val, do_stmts);
|
||||
opt_stmt(opt_state, &s->s, b->val, do_stmts);
|
||||
|
||||
/*
|
||||
* This is a special case: if we don't use anything from this
|
||||
@ -1482,7 +1570,7 @@ opt_j(opt_state_t *opt_state, struct edge *ep)
|
||||
|
||||
while (x != 0) {
|
||||
k = lowest_set_bit(x);
|
||||
x &=~ (1 << k);
|
||||
x &=~ ((bpf_u_int32)1 << k);
|
||||
k += i * BITS_PER_WORD;
|
||||
|
||||
target = fold_edge(ep->succ, opt_state->edges[k]);
|
||||
@ -1689,8 +1777,7 @@ and_pullup(opt_state_t *opt_state, struct block *b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
int do_stmts)
|
||||
opt_blks(opt_state_t *opt_state, struct icode *ic, int do_stmts)
|
||||
{
|
||||
int i, maxlevel;
|
||||
struct block *p;
|
||||
@ -1701,7 +1788,7 @@ opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
find_inedges(opt_state, ic->root);
|
||||
for (i = maxlevel; i >= 0; --i)
|
||||
for (p = opt_state->levels[i]; p; p = p->link)
|
||||
opt_blk(cstate, opt_state, p, do_stmts);
|
||||
opt_blk(opt_state, p, do_stmts);
|
||||
|
||||
if (do_stmts)
|
||||
/*
|
||||
@ -1779,14 +1866,13 @@ opt_root(struct block **b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
int do_stmts)
|
||||
opt_loop(opt_state_t *opt_state, struct icode *ic, int do_stmts)
|
||||
{
|
||||
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("opt_loop(root, %d) begin\n", do_stmts);
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
@ -1796,11 +1882,11 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
find_closure(opt_state, ic->root);
|
||||
find_ud(opt_state, ic->root);
|
||||
find_edom(opt_state, ic->root);
|
||||
opt_blks(cstate, opt_state, ic, do_stmts);
|
||||
opt_blks(opt_state, ic, do_stmts);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done);
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
} while (!opt_state->done);
|
||||
@ -1808,30 +1894,38 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
|
||||
/*
|
||||
* Optimize the filter code in its dag representation.
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
void
|
||||
bpf_optimize(compiler_state_t *cstate, struct icode *ic)
|
||||
int
|
||||
bpf_optimize(struct icode *ic, char *errbuf)
|
||||
{
|
||||
opt_state_t opt_state;
|
||||
|
||||
opt_init(cstate, &opt_state, ic);
|
||||
opt_loop(cstate, &opt_state, ic, 0);
|
||||
opt_loop(cstate, &opt_state, ic, 1);
|
||||
memset(&opt_state, 0, sizeof(opt_state));
|
||||
opt_state.errbuf = errbuf;
|
||||
if (setjmp(opt_state.top_ctx)) {
|
||||
opt_cleanup(&opt_state);
|
||||
return -1;
|
||||
}
|
||||
opt_init(&opt_state, ic);
|
||||
opt_loop(&opt_state, ic, 0);
|
||||
opt_loop(&opt_state, ic, 1);
|
||||
intern_blocks(&opt_state, ic);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("after intern_blocks()\n");
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(&opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
opt_root(&ic->root);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("after opt_root()\n");
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(&opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
opt_cleanup(&opt_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1945,6 +2039,24 @@ opt_cleanup(opt_state_t *opt_state)
|
||||
free((void *)opt_state->blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
* For optimizer errors.
|
||||
*/
|
||||
static void PCAP_NORETURN
|
||||
opt_error(opt_state_t *opt_state, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opt_state->errbuf != NULL) {
|
||||
va_start(ap, fmt);
|
||||
(void)pcap_vsnprintf(opt_state->errbuf,
|
||||
PCAP_ERRBUF_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
longjmp(opt_state->top_ctx, 1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of stmts in 's'.
|
||||
*/
|
||||
@ -2029,7 +2141,7 @@ count_stmts(struct icode *ic, struct block *p)
|
||||
* from the total number of blocks and/or statements.
|
||||
*/
|
||||
static void
|
||||
opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
opt_init(opt_state_t *opt_state, struct icode *ic)
|
||||
{
|
||||
bpf_u_int32 *p;
|
||||
int i, n, max_stmts;
|
||||
@ -2042,22 +2154,24 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
n = count_blocks(ic, ic->root);
|
||||
opt_state->blocks = (struct block **)calloc(n, sizeof(*opt_state->blocks));
|
||||
if (opt_state->blocks == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
opt_error(opt_state, "malloc");
|
||||
unMarkAll(ic);
|
||||
opt_state->n_blocks = 0;
|
||||
number_blks_r(opt_state, ic, ic->root);
|
||||
|
||||
opt_state->n_edges = 2 * opt_state->n_blocks;
|
||||
opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges));
|
||||
if (opt_state->edges == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->edges == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
|
||||
/*
|
||||
* The number of levels is bounded by the number of nodes.
|
||||
*/
|
||||
opt_state->levels = (struct block **)calloc(opt_state->n_blocks, sizeof(*opt_state->levels));
|
||||
if (opt_state->levels == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->levels == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
|
||||
opt_state->edgewords = opt_state->n_edges / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
opt_state->nodewords = opt_state->n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
@ -2065,8 +2179,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
/* XXX */
|
||||
opt_state->space = (bpf_u_int32 *)malloc(2 * opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->space)
|
||||
+ opt_state->n_edges * opt_state->edgewords * sizeof(*opt_state->space));
|
||||
if (opt_state->space == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->space == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
p = opt_state->space;
|
||||
opt_state->all_dom_sets = p;
|
||||
for (i = 0; i < n; ++i) {
|
||||
@ -2103,9 +2218,13 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
*/
|
||||
opt_state->maxval = 3 * max_stmts;
|
||||
opt_state->vmap = (struct vmapinfo *)calloc(opt_state->maxval, sizeof(*opt_state->vmap));
|
||||
if (opt_state->vmap == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
opt_state->vnode_base = (struct valnode *)calloc(opt_state->maxval, sizeof(*opt_state->vnode_base));
|
||||
if (opt_state->vmap == NULL || opt_state->vnode_base == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->vnode_base == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2117,6 +2236,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
int bids[NBIDS];
|
||||
#endif
|
||||
|
||||
static void PCAP_NORETURN conv_error(conv_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
/*
|
||||
* Returns true if successful. Returns false if a branch has
|
||||
* an offset that is too large. If so, we have marked that
|
||||
@ -2124,8 +2246,7 @@ int bids[NBIDS];
|
||||
* properly.
|
||||
*/
|
||||
static int
|
||||
convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
struct icode *ic, struct block *p)
|
||||
convert_code_r(conv_state_t *conv_state, struct icode *ic, struct block *p)
|
||||
{
|
||||
struct bpf_insn *dst;
|
||||
struct slist *src;
|
||||
@ -2138,9 +2259,9 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
return (1);
|
||||
Mark(ic, p);
|
||||
|
||||
if (convert_code_r(cstate, conv_state, ic, JF(p)) == 0)
|
||||
if (convert_code_r(conv_state, ic, JF(p)) == 0)
|
||||
return (0);
|
||||
if (convert_code_r(cstate, conv_state, ic, JT(p)) == 0)
|
||||
if (convert_code_r(conv_state, ic, JT(p)) == 0)
|
||||
return (0);
|
||||
|
||||
slen = slength(p->stmts);
|
||||
@ -2153,7 +2274,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
if (slen) {
|
||||
offset = (struct slist **)calloc(slen, sizeof(struct slist *));
|
||||
if (!offset) {
|
||||
bpf_error(cstate, "not enough core");
|
||||
conv_error(conv_state, "not enough core");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@ -2177,7 +2298,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
|
||||
#if 0
|
||||
if (src->s.jt || src->s.jf) {
|
||||
bpf_error(cstate, "illegal jmp destination");
|
||||
free(offset);
|
||||
conv_error(conv_state, "illegal jmp destination");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
@ -2197,7 +2319,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
#endif
|
||||
|
||||
if (!src->s.jt || !src->s.jf) {
|
||||
bpf_error(cstate, ljerr, "no jmp destination", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "no jmp destination", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
@ -2205,12 +2328,14 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
for (i = 0; i < slen; i++) {
|
||||
if (offset[i] == src->s.jt) {
|
||||
if (jt) {
|
||||
bpf_error(cstate, ljerr, "multiple matches", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "multiple matches", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (i - off - 1 >= 256) {
|
||||
bpf_error(cstate, ljerr, "out-of-range jump", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "out-of-range jump", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jt = (u_char)(i - off - 1);
|
||||
@ -2218,11 +2343,13 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
if (offset[i] == src->s.jf) {
|
||||
if (jf) {
|
||||
bpf_error(cstate, ljerr, "multiple matches", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "multiple matches", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (i - off - 1 >= 256) {
|
||||
bpf_error(cstate, ljerr, "out-of-range jump", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "out-of-range jump", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jf = (u_char)(i - off - 1);
|
||||
@ -2230,7 +2357,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
}
|
||||
if (!jt || !jf) {
|
||||
bpf_error(cstate, ljerr, "no destination found", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "no destination found", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@ -2259,7 +2387,7 @@ filled:
|
||||
}
|
||||
/* branch if T to following jump */
|
||||
if (extrajmps >= 256) {
|
||||
bpf_error(cstate, "too many extra jumps");
|
||||
conv_error(conv_state, "too many extra jumps");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jt = (u_char)extrajmps;
|
||||
@ -2280,7 +2408,7 @@ filled:
|
||||
/* branch if F to following jump */
|
||||
/* if two jumps are inserted, F goes to second one */
|
||||
if (extrajmps >= 256) {
|
||||
bpf_error(cstate, "too many extra jumps");
|
||||
conv_error(conv_state, "too many extra jumps");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jf = (u_char)extrajmps;
|
||||
@ -2314,13 +2442,20 @@ filled:
|
||||
* done with the filter program. See the pcap man page.
|
||||
*/
|
||||
struct bpf_insn *
|
||||
icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
struct block *root, u_int *lenp)
|
||||
icode_to_fcode(struct icode *ic, struct block *root, u_int *lenp,
|
||||
char *errbuf)
|
||||
{
|
||||
u_int n;
|
||||
struct bpf_insn *fp;
|
||||
conv_state_t conv_state;
|
||||
|
||||
conv_state.fstart = NULL;
|
||||
conv_state.errbuf = errbuf;
|
||||
if (setjmp(conv_state.top_ctx) != 0) {
|
||||
free(conv_state.fstart);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop doing convert_code_r() until no branches remain
|
||||
* with too-large offsets.
|
||||
@ -2330,14 +2465,18 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
n = *lenp = count_stmts(ic, root);
|
||||
|
||||
fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
|
||||
if (fp == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (fp == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc");
|
||||
free(fp);
|
||||
return NULL;
|
||||
}
|
||||
memset((char *)fp, 0, sizeof(*fp) * n);
|
||||
conv_state.fstart = fp;
|
||||
conv_state.ftail = fp + n;
|
||||
|
||||
unMarkAll(ic);
|
||||
if (convert_code_r(cstate, &conv_state, ic, root))
|
||||
if (convert_code_r(&conv_state, ic, root))
|
||||
break;
|
||||
free(fp);
|
||||
}
|
||||
@ -2345,6 +2484,22 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
return fp;
|
||||
}
|
||||
|
||||
/*
|
||||
* For iconv_to_fconv() errors.
|
||||
*/
|
||||
static void PCAP_NORETURN
|
||||
conv_error(conv_state_t *conv_state, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void)pcap_vsnprintf(conv_state->errbuf,
|
||||
PCAP_ERRBUF_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
longjmp(conv_state->top_ctx, 1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of a BPF program and put it in the "fcode" member of
|
||||
* a "pcap_t".
|
||||
@ -2454,14 +2609,16 @@ dot_dump_edge(struct icode *ic, struct block *block, FILE *out)
|
||||
* After install graphviz on http://www.graphviz.org/, save it as bpf.dot
|
||||
* and run `dot -Tpng -O bpf.dot' to draw the graph.
|
||||
*/
|
||||
static void
|
||||
dot_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
static int
|
||||
dot_dump(struct icode *ic, char *errbuf)
|
||||
{
|
||||
struct bpf_program f;
|
||||
FILE *out = stdout;
|
||||
|
||||
memset(bids, 0, sizeof bids);
|
||||
f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
|
||||
f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
|
||||
if (f.bf_insns == NULL)
|
||||
return -1;
|
||||
|
||||
fprintf(out, "digraph BPF {\n");
|
||||
unMarkAll(ic);
|
||||
@ -2471,30 +2628,39 @@ dot_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
fprintf(out, "}\n");
|
||||
|
||||
free((char *)f.bf_insns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
plain_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
static int
|
||||
plain_dump(struct icode *ic, char *errbuf)
|
||||
{
|
||||
struct bpf_program f;
|
||||
|
||||
memset(bids, 0, sizeof bids);
|
||||
f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
|
||||
f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
|
||||
if (f.bf_insns == NULL)
|
||||
return -1;
|
||||
bpf_dump(&f, 1);
|
||||
putchar('\n');
|
||||
free((char *)f.bf_insns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
opt_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
opt_dump(opt_state_t *opt_state, struct icode *ic)
|
||||
{
|
||||
int status;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
/*
|
||||
* If the CFG, in DOT format, is requested, output it rather than
|
||||
* the code that would be generated from that graph.
|
||||
*/
|
||||
if (pcap_print_dot_graph)
|
||||
dot_dump(cstate, ic);
|
||||
status = dot_dump(ic, errbuf);
|
||||
else
|
||||
plain_dump(cstate, ic);
|
||||
status = plain_dump(ic, errbuf);
|
||||
if (status == -1)
|
||||
opt_error(opt_state, "opt_dump: icode_to_fcode failed: %s", errbuf);
|
||||
}
|
||||
#endif
|
||||
|
@ -208,7 +208,7 @@ static int monitor_mode(pcap_t *, int);
|
||||
# endif
|
||||
|
||||
# if defined(__APPLE__)
|
||||
static void remove_en(pcap_t *);
|
||||
static void remove_non_802_11(pcap_t *);
|
||||
static void remove_802_11(pcap_t *);
|
||||
# endif
|
||||
|
||||
@ -739,10 +739,10 @@ get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
struct utsname osinfo;
|
||||
struct ifreq ifr;
|
||||
int fd;
|
||||
@ -801,8 +801,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
errno, "socket");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
|
||||
strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
|
||||
pcap_strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
|
||||
pcap_strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
|
||||
/*
|
||||
* No such device?
|
||||
@ -882,7 +882,11 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
close(fd);
|
||||
#endif /* BIOCGDLTLIST */
|
||||
return (0);
|
||||
}
|
||||
#elif defined(HAVE_BSD_IEEE80211)
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = monitor_mode(p, 0);
|
||||
@ -891,10 +895,14 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
if (ret == 0)
|
||||
return (1); /* success */
|
||||
return (ret);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p _U_)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
|
||||
@ -1014,18 +1022,21 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
case EWOULDBLOCK:
|
||||
return (0);
|
||||
|
||||
case ENXIO:
|
||||
case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */
|
||||
case EIO: /* OpenBSD */
|
||||
/* NetBSD appears not to return an error in this case */
|
||||
/*
|
||||
* The device on which we're capturing
|
||||
* went away.
|
||||
*
|
||||
* XXX - we should really return
|
||||
* PCAP_ERROR_IFACE_NOT_UP, but
|
||||
* pcap_dispatch() etc. aren't
|
||||
* defined to retur that.
|
||||
* an appropriate error for that,
|
||||
* but pcap_dispatch() etc. aren't
|
||||
* documented as having error returns
|
||||
* other than PCAP_ERROR or PCAP_ERROR_BREAK.
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The interface went down");
|
||||
"The interface disappeared");
|
||||
return (PCAP_ERROR);
|
||||
|
||||
#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4)
|
||||
@ -1360,8 +1371,8 @@ bpf_load(char *errbuf)
|
||||
|
||||
/* Check if the driver is loaded */
|
||||
memset(&cfg_ld, 0x0, sizeof(cfg_ld));
|
||||
pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
cfg_ld.path = buf;
|
||||
pcap_snprintf(cfg_ld.path, sizeof(cfg_ld.path), "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
|
||||
(cfg_ld.kmid == 0)) {
|
||||
/* Driver isn't loaded, load it now */
|
||||
@ -1471,7 +1482,7 @@ pcap_cleanup_bpf(pcap_t *p)
|
||||
|
||||
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
strlcpy(ifr.ifr_name, pb->device,
|
||||
pcap_strlcpy(ifr.ifr_name, pb->device,
|
||||
sizeof(ifr.ifr_name));
|
||||
ioctl(s, SIOCIFDESTROY, &ifr);
|
||||
close(s);
|
||||
@ -1534,9 +1545,9 @@ check_setif_failure(pcap_t *p, int error)
|
||||
*/
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd != -1) {
|
||||
strlcpy(ifr.ifr_name, "en",
|
||||
pcap_strlcpy(ifr.ifr_name, "en",
|
||||
sizeof(ifr.ifr_name));
|
||||
strlcat(ifr.ifr_name, p->opt.device + 3,
|
||||
pcap_strlcat(ifr.ifr_name, p->opt.device + 3,
|
||||
sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
|
||||
/*
|
||||
@ -1723,7 +1734,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
goto bad;
|
||||
}
|
||||
znamelen = zonesep - p->opt.device;
|
||||
(void) strlcpy(path_zname, p->opt.device, znamelen + 1);
|
||||
(void) pcap_strlcpy(path_zname, p->opt.device, znamelen + 1);
|
||||
ifr.lifr_zoneid = getzoneidbyname(path_zname);
|
||||
if (ifr.lifr_zoneid == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -1788,7 +1799,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
*/
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd != -1) {
|
||||
strlcpy(ifrname,
|
||||
pcap_strlcpy(ifrname,
|
||||
p->opt.device, ifnamsiz);
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS,
|
||||
(char *)&ifr) < 0) {
|
||||
@ -1890,7 +1901,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
/*
|
||||
* Create the interface.
|
||||
*/
|
||||
strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
|
||||
pcap_strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) {
|
||||
if (errno == EINVAL) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -2189,7 +2200,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
* of link-layer types, as selecting
|
||||
* it will keep monitor mode off.
|
||||
*/
|
||||
remove_en(p);
|
||||
remove_non_802_11(p);
|
||||
|
||||
/*
|
||||
* If the new mode we want isn't
|
||||
@ -2750,12 +2761,21 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
|
||||
strncpy(req.ifm_name, name, sizeof(req.ifm_name));
|
||||
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY ||
|
||||
errno == ENODEV) {
|
||||
errno == ENODEV || errno == EPERM) {
|
||||
/*
|
||||
* Not supported, so we can't provide any
|
||||
* additional information. Assume that
|
||||
* this means that "connected" vs.
|
||||
* "disconnected" doesn't apply.
|
||||
*
|
||||
* The ioctl routine for Apple's pktap devices,
|
||||
* annoyingly, checks for "are you root?" before
|
||||
* checking whether the ioctl is valid, so it
|
||||
* returns EPERM, rather than ENOTSUP, for the
|
||||
* invalid SIOCGIFMEDIA, unless you're root.
|
||||
* So, just as we do for some ethtool ioctls
|
||||
* on Linux, which makes the same mistake, we
|
||||
* also treat EPERM as meaning "not supported".
|
||||
*/
|
||||
*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
|
||||
close(sock);
|
||||
@ -2892,7 +2912,7 @@ monitor_mode(pcap_t *p, int set)
|
||||
|
||||
default:
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "SIOCGIFMEDIA 1");
|
||||
errno, "SIOCGIFMEDIA");
|
||||
close(sock);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
@ -3034,8 +3054,12 @@ find_802_11(struct bpf_dltlist *bdlp)
|
||||
new_dlt = bdlp->bfl_list[i];
|
||||
break;
|
||||
|
||||
#ifdef DLT_PRISM_HEADER
|
||||
case DLT_PRISM_HEADER:
|
||||
#endif
|
||||
#ifdef DLT_AIRONET_HEADER
|
||||
case DLT_AIRONET_HEADER:
|
||||
#endif
|
||||
case DLT_IEEE802_11_RADIO_AVS:
|
||||
/*
|
||||
* 802.11 with radio, but not radiotap.
|
||||
@ -3070,24 +3094,25 @@ find_802_11(struct bpf_dltlist *bdlp)
|
||||
|
||||
#if defined(__APPLE__) && defined(BIOCGDLTLIST)
|
||||
/*
|
||||
* Remove DLT_EN10MB from the list of DLT_ values, as we're in monitor mode,
|
||||
* and DLT_EN10MB isn't supported in monitor mode.
|
||||
* Remove non-802.11 header types from the list of DLT_ values, as we're in
|
||||
* monitor mode, and those header types aren't supported in monitor mode.
|
||||
*/
|
||||
static void
|
||||
remove_en(pcap_t *p)
|
||||
remove_non_802_11(pcap_t *p)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
* Scan the list of DLT_ values and discard DLT_EN10MB.
|
||||
* Scan the list of DLT_ values and discard non-802.11 ones.
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < p->dlt_count; i++) {
|
||||
switch (p->dlt_list[i]) {
|
||||
|
||||
case DLT_EN10MB:
|
||||
case DLT_RAW:
|
||||
/*
|
||||
* Don't offer this one.
|
||||
* Not 802.11. Don't offer this one.
|
||||
*/
|
||||
continue;
|
||||
|
||||
@ -3129,10 +3154,17 @@ remove_802_11(pcap_t *p)
|
||||
switch (p->dlt_list[i]) {
|
||||
|
||||
case DLT_IEEE802_11:
|
||||
#ifdef DLT_PRISM_HEADER
|
||||
case DLT_PRISM_HEADER:
|
||||
#endif
|
||||
#ifdef DLT_AIRONET_HEADER
|
||||
case DLT_AIRONET_HEADER:
|
||||
#endif
|
||||
case DLT_IEEE802_11_RADIO:
|
||||
case DLT_IEEE802_11_RADIO_AVS:
|
||||
#ifdef DLT_PPI
|
||||
case DLT_PPI:
|
||||
#endif
|
||||
/*
|
||||
* 802.11. Don't offer this one.
|
||||
*/
|
||||
@ -3224,10 +3256,10 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
|
||||
* Set direction flag: Which packets do we accept on a forwarding
|
||||
* single device? IN, OUT or both?
|
||||
*/
|
||||
#if defined(BIOCSDIRECTION)
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
#if defined(BIOCSDIRECTION)
|
||||
u_int direction;
|
||||
|
||||
direction = (d == PCAP_D_IN) ? BPF_D_IN :
|
||||
@ -3240,7 +3272,11 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#elif defined(BIOCSSEESENT)
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
u_int seesent;
|
||||
|
||||
/*
|
||||
@ -3260,25 +3296,35 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d _U_)
|
||||
{
|
||||
(void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"This system doesn't support BIOCSSEESENT, so the direction can't be set");
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BIOCSDLT
|
||||
static int
|
||||
pcap_set_datalink_bpf(pcap_t *p, int dlt)
|
||||
{
|
||||
#ifdef BIOCSDLT
|
||||
if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
||||
errno, "Cannot set DLT %d", dlt);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_set_datalink_bpf(pcap_t *p _U_, int dlt _U_)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Platform-specific information.
|
||||
|
@ -516,11 +516,20 @@
|
||||
#define LINKTYPE_RAIF1 198
|
||||
|
||||
/*
|
||||
* IPMB packet for IPMI, beginning with the I2C slave address, followed
|
||||
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
|
||||
* <chanthy.toeung@ca.kontron.com>.
|
||||
* IPMB packet for IPMI, beginning with a 2-byte header, followed by
|
||||
* the I2C slave address, followed by the netFn and LUN, etc..
|
||||
* Requested by Chanthy Toeung <chanthy.toeung@ca.kontron.com>.
|
||||
*
|
||||
* XXX - its DLT_ value used to be called DLT_IPMB, back when we got the
|
||||
* impression from the email thread requesting it that the packet
|
||||
* had no extra 2-byte header. We've renamed it; if anybody used
|
||||
* DLT_IPMB and assumed no 2-byte header, this will cause the compile
|
||||
* to fail, at which point we'll have to figure out what to do about
|
||||
* the two header types using the same DLT_/LINKTYPE_ value. If that
|
||||
* doesn't happen, we'll assume nobody used it and that the redefinition
|
||||
* is safe.
|
||||
*/
|
||||
#define LINKTYPE_IPMB 199
|
||||
#define LINKTYPE_IPMB_KONTRON 199
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
@ -551,15 +560,35 @@
|
||||
*/
|
||||
#define LINKTYPE_LAPD 203
|
||||
|
||||
|
||||
/*
|
||||
* Variants of various link-layer headers, with a one-byte direction
|
||||
* pseudo-header prepended - zero means "received by this host",
|
||||
* non-zero (any non-zero value) means "sent by this host" - as per
|
||||
* Will Barker <w.barker@zen.co.uk>.
|
||||
* PPP, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host", non-zero (any non-zero value) means "sent by
|
||||
* this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_PPP_WITH_DIR 204 /* Don't confuse with LINKTYPE_PPP_PPPD */
|
||||
|
||||
/*
|
||||
* Cisco HDLC, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host", non-zero (any non-zero value) means
|
||||
* "sent by this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_PPP_WITH_DIR 204 /* PPP */
|
||||
#define LINKTYPE_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
|
||||
|
||||
/*
|
||||
* Frame Relay, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host" (DCE -> DTE), non-zero (any non-zero
|
||||
* value) means "sent by this host" (DTE -> DCE) - as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_FRELAY_WITH_DIR 206 /* Frame Relay */
|
||||
|
||||
/*
|
||||
* LAPB, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host" (DCE -> DTE), non-zero (any non-zero value)
|
||||
* means "sent by this host" (DTE -> DCE)- as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_LAPB_WITH_DIR 207 /* LAPB */
|
||||
|
||||
/*
|
||||
@ -1083,7 +1112,21 @@
|
||||
*/
|
||||
#define LINKTYPE_DISPLAYPORT_AUX 275
|
||||
|
||||
#define LINKTYPE_MATCHING_MAX 275 /* highest value in the "matching" range */
|
||||
/*
|
||||
* Linux cooked sockets v2.
|
||||
*/
|
||||
#define LINKTYPE_LINUX_SLL2 276
|
||||
|
||||
#define LINKTYPE_MATCHING_MAX 276 /* highest value in the "matching" range */
|
||||
|
||||
/*
|
||||
* The DLT_ and LINKTYPE_ values in the "matching" range should be the
|
||||
* same, so DLT_MATCHING_MAX and LINKTYPE_MATCHING_MAX should be the
|
||||
* same.
|
||||
*/
|
||||
#if LINKTYPE_MATCHING_MAX != DLT_MATCHING_MAX
|
||||
#error The LINKTYPE_ matching range does not match the DLT_ matching range
|
||||
#endif
|
||||
|
||||
static struct linktype_map {
|
||||
int dlt;
|
||||
@ -1233,18 +1276,30 @@ linktype_to_dlt(int linktype)
|
||||
/*
|
||||
* Return the maximum snapshot length for a given DLT_ value.
|
||||
*
|
||||
* For most link-layer types, we use MAXIMUM_SNAPLEN, but for DLT_DBUS,
|
||||
* the maximum is 134217728, as per
|
||||
* For most link-layer types, we use MAXIMUM_SNAPLEN.
|
||||
*
|
||||
* For DLT_DBUS, the maximum is 128MiB, as per
|
||||
*
|
||||
* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
|
||||
*
|
||||
* For DLT_USBPCAP, the maximum is 1MiB, as per
|
||||
*
|
||||
* https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=15985
|
||||
*/
|
||||
u_int
|
||||
max_snaplen_for_dlt(int dlt)
|
||||
{
|
||||
if (dlt == DLT_DBUS)
|
||||
return 134217728;
|
||||
else
|
||||
switch (dlt) {
|
||||
|
||||
case DLT_DBUS:
|
||||
return 128*1024*1024;
|
||||
|
||||
case DLT_USBPCAP:
|
||||
return 1024*1024;
|
||||
|
||||
default:
|
||||
return MAXIMUM_SNAPLEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -35,9 +35,13 @@
|
||||
* machine (if the file was written in little-end order).
|
||||
*/
|
||||
#define SWAPLONG(y) \
|
||||
((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
|
||||
(((((u_int)(y))&0xff)<<24) | \
|
||||
((((u_int)(y))&0xff00)<<8) | \
|
||||
((((u_int)(y))&0xff0000)>>8) | \
|
||||
((((u_int)(y))>>24)&0xff))
|
||||
#define SWAPSHORT(y) \
|
||||
( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
|
||||
((u_short)(((((u_int)(y))&0xff)<<8) | \
|
||||
((((u_int)(y))&0xff00)>>8)))
|
||||
|
||||
extern int dlt_to_linktype(int dlt);
|
||||
|
||||
|
@ -86,7 +86,12 @@ extern "C" {
|
||||
* 2) small enough not to cause attempts to allocate huge amounts of
|
||||
* memory; some applications might use the snapshot length in a
|
||||
* savefile header to control the size of the buffer they allocate,
|
||||
* so a size of, say, 2^31-1 might not work well.
|
||||
* so a size of, say, 2^31-1 might not work well. (libpcap uses it
|
||||
* as a hint, but doesn't start out allocating a buffer bigger than
|
||||
* 2 KiB, and grows the buffer as necessary, but not beyond the
|
||||
* per-linktype maximum snapshot length. Other code might naively
|
||||
* use it; we want to avoid writing a too-large snapshot length,
|
||||
* in order not to cause that code problems.)
|
||||
*
|
||||
* We don't enforce this in pcap_set_snaplen(), but we use it internally.
|
||||
*/
|
||||
@ -472,13 +477,38 @@ int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
|
||||
* "pcap_open_offline_common()" allocates and fills in a pcap_t, for use
|
||||
* by pcap_open_offline routines.
|
||||
*
|
||||
* "pcap_adjust_snapshot()" adjusts the snapshot to be non-zero and
|
||||
* fit within an int.
|
||||
*
|
||||
* "sf_cleanup()" closes the file handle associated with a pcap_t, if
|
||||
* appropriate, and frees all data common to all modules for handling
|
||||
* savefile types.
|
||||
*/
|
||||
pcap_t *pcap_open_offline_common(char *ebuf, size_t size);
|
||||
bpf_u_int32 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen);
|
||||
void sf_cleanup(pcap_t *p);
|
||||
|
||||
/*
|
||||
* Internal interfaces for doing user-mode filtering of packets and
|
||||
* validating filter programs.
|
||||
*/
|
||||
/*
|
||||
* Auxiliary data, for use when interpreting a filter intended for the
|
||||
* Linux kernel when the kernel rejects the filter (requiring us to
|
||||
* run it in userland). It contains VLAN tag information.
|
||||
*/
|
||||
struct bpf_aux_data {
|
||||
u_short vlan_tag_present;
|
||||
u_short vlan_tag;
|
||||
};
|
||||
|
||||
/*
|
||||
* Filtering routine that takes the auxiliary data as an additional
|
||||
* argument.
|
||||
*/
|
||||
u_int bpf_filter_with_aux_data(const struct bpf_insn *,
|
||||
const u_char *, u_int, u_int, const struct bpf_aux_data *);
|
||||
|
||||
/*
|
||||
* Internal interfaces for both "pcap_create()" and routines that
|
||||
* open savefiles.
|
||||
@ -488,10 +518,6 @@ void sf_cleanup(pcap_t *p);
|
||||
*/
|
||||
void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
|
||||
#ifdef _WIN32
|
||||
void pcap_win32_err_to_str(DWORD, char *);
|
||||
#endif
|
||||
|
||||
int install_bpf_program(pcap_t *, struct bpf_program *);
|
||||
|
||||
int pcap_strcasecmp(const char *, const char *);
|
||||
|
@ -141,7 +141,7 @@ BOOL WINAPI DllMain(
|
||||
|
||||
/*
|
||||
* Start WinSock.
|
||||
* Exported in case some applications using WinPcap called it,
|
||||
* Exported in case some applications using WinPcap/Npcap called it,
|
||||
* even though it wasn't exported.
|
||||
*/
|
||||
int
|
||||
@ -188,76 +188,165 @@ pcap_wsockinit(void)
|
||||
PCAP_API char pcap_version[];
|
||||
PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION;
|
||||
|
||||
static int
|
||||
pcap_not_initialized(pcap_t *pcap)
|
||||
static void
|
||||
pcap_set_not_initialized_message(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (PCAP_ERROR);
|
||||
return;
|
||||
}
|
||||
/* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_read_not_initialized(pcap_t *pcap, int cnt _U_, pcap_handler callback _U_,
|
||||
u_char *user _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_not_initialized(pcap_t *pcap, const void * buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setfilter_not_initialized(pcap_t *pcap, struct bpf_program *fp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setdirection_not_initialized(pcap_t *pcap, pcap_direction_t d _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_set_datalink_not_initialized(pcap_t *pcap, int dlt _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_getnonblock_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_not_initialized(pcap_t *pcap, struct pcap_stat *ps _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void *
|
||||
pcap_not_initialized_ptr(pcap_t *pcap)
|
||||
struct pcap_stat *
|
||||
pcap_stats_ex_not_initialized(pcap_t *pcap, int *pcap_stat_size _U_)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (NULL);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setbuff_not_initialized(pcap_t *pcap, int dim _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setmode_not_initialized(pcap_t *pcap, int mode _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setmintocopy_not_initialized(pcap_t *pcap, int size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static HANDLE
|
||||
pcap_getevent_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (INVALID_HANDLE_VALUE);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_oid_get_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
|
||||
void *data _U_, size_t *lenp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_oid_set_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
|
||||
const void *data _U_, size_t *lenp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static u_int
|
||||
pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (0);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setuserbuffer_not_initialized(pcap_t *pcap, int size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_live_dump_not_initialized(pcap_t *pcap, char *filename _U_, int maxsize _U_,
|
||||
int maxpacks _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_live_dump_ended_not_initialized(pcap_t *pcap, int sync _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static PAirpcapHandle
|
||||
pcap_get_airpcap_handle_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (NULL);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
@ -298,8 +387,17 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
|
||||
if (p->tstamp_type_count == 0) {
|
||||
/*
|
||||
* We don't support multiple time stamp types.
|
||||
* That means the only type we support is PCAP_TSTAMP_HOST;
|
||||
* set up a list containing only that type.
|
||||
*/
|
||||
*tstamp_typesp = NULL;
|
||||
*tstamp_typesp = (int*)malloc(sizeof(**tstamp_typesp));
|
||||
if (*tstamp_typesp == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
||||
errno, "malloc");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
**tstamp_typesp = PCAP_TSTAMP_HOST;
|
||||
return (1);
|
||||
} else {
|
||||
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
|
||||
p->tstamp_type_count);
|
||||
@ -310,8 +408,8 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
|
||||
}
|
||||
(void)memcpy(*tstamp_typesp, p->tstamp_type_list,
|
||||
sizeof(**tstamp_typesp) * p->tstamp_type_count);
|
||||
return (p->tstamp_type_count);
|
||||
}
|
||||
return (p->tstamp_type_count);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -661,7 +759,7 @@ get_if_description(const char *name)
|
||||
* Get the description for the interface.
|
||||
*/
|
||||
memset(&ifrdesc, 0, sizeof ifrdesc);
|
||||
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
|
||||
pcap_strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
#ifdef __FreeBSD__
|
||||
@ -712,7 +810,7 @@ get_if_description(const char *name)
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
close(s);
|
||||
if (description != NULL && strlen(description) == 0) {
|
||||
if (description != NULL && description[0] == '\0') {
|
||||
/*
|
||||
* Description is empty, so discard it.
|
||||
*/
|
||||
@ -743,20 +841,13 @@ get_if_description(const char *name)
|
||||
* OK, it's a valid number that's not
|
||||
* bigger than INT_MAX. Construct
|
||||
* a description from it.
|
||||
* (If that fails, we don't worry about
|
||||
* it, we just return NULL.)
|
||||
*/
|
||||
static const char descr_prefix[] = "USB bus number ";
|
||||
size_t descr_size;
|
||||
|
||||
/*
|
||||
* Allow enough room for a 32-bit bus number.
|
||||
* sizeof (descr_prefix) includes the
|
||||
* terminating NUL.
|
||||
*/
|
||||
descr_size = sizeof (descr_prefix) + 10;
|
||||
description = malloc(descr_size);
|
||||
if (description != NULL) {
|
||||
pcap_snprintf(description, descr_size,
|
||||
"%s%ld", descr_prefix, busnum);
|
||||
if (pcap_asprintf(&description,
|
||||
"USB bus number %ld", busnum) == -1) {
|
||||
/* Failed. */
|
||||
description = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1294,14 +1385,14 @@ pcap_lookupdev(char *errbuf)
|
||||
* on the list, there aren't any non-loopback devices,
|
||||
* so why not just supply it as the default device?
|
||||
*/
|
||||
(void)strlcpy(errbuf, "no suitable device found",
|
||||
(void)pcap_strlcpy(errbuf, "no suitable device found",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
ret = NULL;
|
||||
} else {
|
||||
/*
|
||||
* Return the name of the first device on the list.
|
||||
*/
|
||||
(void)strlcpy(device, alldevs->name, sizeof(device));
|
||||
(void)pcap_strlcpy(device, alldevs->name, sizeof(device));
|
||||
ret = device;
|
||||
}
|
||||
|
||||
@ -1368,7 +1459,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
|
||||
/* XXX Work around Linux kernel bug */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
#endif
|
||||
(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
(void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
|
||||
if (errno == EADDRNOTAVAIL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -1387,7 +1478,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
|
||||
/* XXX Work around Linux kernel bug */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
#endif
|
||||
(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
(void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "SIOCGIFNETMASK: %s", device);
|
||||
@ -1577,13 +1668,14 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
|
||||
* the pathname.
|
||||
*/
|
||||
if (pcap_strcasecmp(scheme, "file") == 0) {
|
||||
*schemep = scheme;
|
||||
*pathp = strdup(colonp + 3);
|
||||
if (*pathp == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "malloc");
|
||||
free(scheme);
|
||||
return (-1);
|
||||
}
|
||||
*schemep = scheme;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1686,7 +1778,12 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
|
||||
* Treat verything up to the closing square
|
||||
* bracket as the IP-Literal; we don't worry
|
||||
* about whether it's a valid IPv6address or
|
||||
* IPvFuture.
|
||||
* IPvFuture (or an IPv4address, for that
|
||||
* matter, just in case we get handed a
|
||||
* URL with an IPv4 IP-Literal, of the sort
|
||||
* that pcap_createsrcstr() used to generate,
|
||||
* and that pcap_parsesrcstr(), in the original
|
||||
* WinPcap code, accepted).
|
||||
*/
|
||||
bracketp = strchr(parsep, ']');
|
||||
if (bracketp == NULL) {
|
||||
@ -1807,9 +1904,9 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
switch (type) {
|
||||
|
||||
case PCAP_SRC_FILE:
|
||||
strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
|
||||
if (name != NULL && *name != '\0') {
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
return (0);
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -1818,7 +1915,7 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
}
|
||||
|
||||
case PCAP_SRC_IFREMOTE:
|
||||
strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
if (host != NULL && *host != '\0') {
|
||||
if (strchr(host, ':') != NULL) {
|
||||
/*
|
||||
@ -1826,18 +1923,18 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
* probably an IPv6 address, and needs to
|
||||
* be included in square brackets.
|
||||
*/
|
||||
strlcat(source, "[", PCAP_BUF_SIZE);
|
||||
strlcat(source, host, PCAP_BUF_SIZE);
|
||||
strlcat(source, "]", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "[", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, host, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "]", PCAP_BUF_SIZE);
|
||||
} else
|
||||
strlcat(source, host, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, host, PCAP_BUF_SIZE);
|
||||
|
||||
if (port != NULL && *port != '\0') {
|
||||
strlcat(source, ":", PCAP_BUF_SIZE);
|
||||
strlcat(source, port, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, ":", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, port, PCAP_BUF_SIZE);
|
||||
}
|
||||
|
||||
strlcat(source, "/", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "/", PCAP_BUF_SIZE);
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The host name cannot be NULL.");
|
||||
@ -1845,15 +1942,15 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
}
|
||||
|
||||
if (name != NULL && *name != '\0')
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
|
||||
return (0);
|
||||
|
||||
case PCAP_SRC_IFLOCAL:
|
||||
strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
|
||||
if (name != NULL && *name != '\0')
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
|
||||
return (0);
|
||||
|
||||
@ -1892,7 +1989,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* Local device.
|
||||
*/
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFLOCAL;
|
||||
free(tmppath);
|
||||
@ -1914,12 +2011,12 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s",
|
||||
tmpuserinfo, tmphost);
|
||||
else
|
||||
strlcpy(host, tmphost, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(host, tmphost, PCAP_BUF_SIZE);
|
||||
}
|
||||
if (port && tmpport)
|
||||
strlcpy(port, tmpport, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(port, tmpport, PCAP_BUF_SIZE);
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFREMOTE;
|
||||
free(tmppath);
|
||||
@ -1935,7 +2032,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* file://
|
||||
*/
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_FILE;
|
||||
free(tmppath);
|
||||
@ -1951,7 +2048,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* as a local device.
|
||||
*/
|
||||
if (name)
|
||||
strlcpy(name, source, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, source, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFLOCAL;
|
||||
free(tmppath);
|
||||
@ -1983,11 +2080,28 @@ pcap_create(const char *device, char *errbuf)
|
||||
else {
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* If the string appears to be little-endian UCS-2/UTF-16,
|
||||
* convert it to ASCII.
|
||||
* On Windows, for backwards compatibility reasons,
|
||||
* pcap_lookupdev() returns a pointer to a sequence of
|
||||
* pairs of UTF-16LE device names and local code page
|
||||
* description strings.
|
||||
*
|
||||
* XXX - to UTF-8 instead? Or report an error if any
|
||||
* character isn't ASCII?
|
||||
* This means that if a program uses pcap_lookupdev()
|
||||
* to get a default device, and hands that to an API
|
||||
* that opens devices, we'll get handed a UTF-16LE
|
||||
* string, not a string in the local code page.
|
||||
*
|
||||
* To work around that, we check whether the string
|
||||
* looks as if it might be a UTF-16LE strinh and, if
|
||||
* so, convert it back to the local code page's
|
||||
* extended ASCII.
|
||||
*
|
||||
* XXX - you *cannot* reliably detect whether a
|
||||
* string is UTF-16LE or not; "a" could either
|
||||
* be a one-character ASCII string or the first
|
||||
* character of a UTF-16LE string. This particular
|
||||
* version of this heuristic dates back to WinPcap
|
||||
* 4.1.1; PacketOpenAdapter() does uses the same
|
||||
* heuristic, with the exact same vulnerability.
|
||||
*/
|
||||
if (device[0] != '\0' && device[1] == '\0') {
|
||||
size_t length;
|
||||
@ -2079,25 +2193,25 @@ initialize_ops(pcap_t *p)
|
||||
* an activated pcap_t to point to a routine that returns
|
||||
* a "this isn't activated" error.
|
||||
*/
|
||||
p->read_op = (read_op_t)pcap_not_initialized;
|
||||
p->inject_op = (inject_op_t)pcap_not_initialized;
|
||||
p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
|
||||
p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
|
||||
p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
|
||||
p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
|
||||
p->stats_op = (stats_op_t)pcap_not_initialized;
|
||||
p->read_op = pcap_read_not_initialized;
|
||||
p->inject_op = pcap_inject_not_initialized;
|
||||
p->setfilter_op = pcap_setfilter_not_initialized;
|
||||
p->setdirection_op = pcap_setdirection_not_initialized;
|
||||
p->set_datalink_op = pcap_set_datalink_not_initialized;
|
||||
p->getnonblock_op = pcap_getnonblock_not_initialized;
|
||||
p->stats_op = pcap_stats_not_initialized;
|
||||
#ifdef _WIN32
|
||||
p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
|
||||
p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
|
||||
p->setmode_op = (setmode_op_t)pcap_not_initialized;
|
||||
p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
|
||||
p->stats_ex_op = pcap_stats_ex_not_initialized;
|
||||
p->setbuff_op = pcap_setbuff_not_initialized;
|
||||
p->setmode_op = pcap_setmode_not_initialized;
|
||||
p->setmintocopy_op = pcap_setmintocopy_not_initialized;
|
||||
p->getevent_op = pcap_getevent_not_initialized;
|
||||
p->oid_get_request_op = (oid_get_request_op_t)pcap_not_initialized;
|
||||
p->oid_set_request_op = (oid_set_request_op_t)pcap_not_initialized;
|
||||
p->oid_get_request_op = pcap_oid_get_request_not_initialized;
|
||||
p->oid_set_request_op = pcap_oid_set_request_not_initialized;
|
||||
p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized;
|
||||
p->setuserbuffer_op = (setuserbuffer_op_t)pcap_not_initialized;
|
||||
p->live_dump_op = (live_dump_op_t)pcap_not_initialized;
|
||||
p->live_dump_ended_op = (live_dump_ended_op_t)pcap_not_initialized;
|
||||
p->setuserbuffer_op = pcap_setuserbuffer_not_initialized;
|
||||
p->live_dump_op = pcap_live_dump_not_initialized;
|
||||
p->live_dump_ended_op = pcap_live_dump_ended_not_initialized;
|
||||
p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized;
|
||||
#endif
|
||||
|
||||
@ -2126,14 +2240,23 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
|
||||
* plus a structure following it of size "size". The
|
||||
* structure following it is a private data structure
|
||||
* for the routines that handle this pcap_t.
|
||||
*
|
||||
* The structure following it must be aligned on
|
||||
* the appropriate alignment boundary for this platform.
|
||||
* We align on an 8-byte boundary as that's probably what
|
||||
* at least some platforms do, even with 32-bit integers,
|
||||
* and because we can't be sure that some values won't
|
||||
* require 8-byte alignment even on platforms with 32-bit
|
||||
* integers.
|
||||
*/
|
||||
chunk = malloc(sizeof (pcap_t) + size);
|
||||
#define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7U) & ~0x7U)
|
||||
chunk = malloc(PCAP_T_ALIGNED_SIZE + size);
|
||||
if (chunk == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "malloc");
|
||||
return (NULL);
|
||||
}
|
||||
memset(chunk, 0, sizeof (pcap_t) + size);
|
||||
memset(chunk, 0, PCAP_T_ALIGNED_SIZE + size);
|
||||
|
||||
/*
|
||||
* Get a pointer to the pcap_t at the beginning.
|
||||
@ -2158,7 +2281,7 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
|
||||
* Set the pointer to the private data; that's the structure
|
||||
* of size "size" following the pcap_t.
|
||||
*/
|
||||
p->priv = (void *)(chunk + sizeof (pcap_t));
|
||||
p->priv = (void *)(chunk + PCAP_T_ALIGNED_SIZE);
|
||||
}
|
||||
|
||||
return (p);
|
||||
@ -2453,6 +2576,16 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
|
||||
char name[PCAP_BUF_SIZE + 1];
|
||||
int srctype;
|
||||
|
||||
/*
|
||||
* A null device name is equivalent to the "any" device -
|
||||
* which might not be supported on this platform, but
|
||||
* this means that you'll get a "not supported" error
|
||||
* rather than, say, a crash when we try to dereference
|
||||
* the null pointer.
|
||||
*/
|
||||
if (device == NULL)
|
||||
device = "any";
|
||||
|
||||
/*
|
||||
* Retrofit - we have to make older applications compatible with
|
||||
* remote capture.
|
||||
@ -2524,13 +2657,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
|
||||
return (p);
|
||||
fail:
|
||||
if (status == PCAP_ERROR)
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
|
||||
p->errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %.*s", device,
|
||||
PCAP_ERRBUF_SIZE - 3, p->errbuf);
|
||||
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
|
||||
status == PCAP_ERROR_PERM_DENIED ||
|
||||
status == PCAP_ERROR_PROMISC_PERM_DENIED)
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device,
|
||||
pcap_statustostr(status), p->errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)", device,
|
||||
pcap_statustostr(status), PCAP_ERRBUF_SIZE - 6, p->errbuf);
|
||||
else
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
|
||||
pcap_statustostr(status));
|
||||
@ -2843,7 +2976,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(FRELAY, "Frame Relay"),
|
||||
DLT_CHOICE(LOOP, "OpenBSD loopback"),
|
||||
DLT_CHOICE(ENC, "OpenBSD encapsulated IP"),
|
||||
DLT_CHOICE(LINUX_SLL, "Linux cooked"),
|
||||
DLT_CHOICE(LINUX_SLL, "Linux cooked v1"),
|
||||
DLT_CHOICE(LTALK, "Localtalk"),
|
||||
DLT_CHOICE(PFLOG, "OpenBSD pflog file"),
|
||||
DLT_CHOICE(PFSYNC, "Packet filter state syncing"),
|
||||
@ -2877,7 +3010,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(GPF_T, "GPF-T"),
|
||||
DLT_CHOICE(GPF_F, "GPF-F"),
|
||||
DLT_CHOICE(JUNIPER_PIC_PEER, "Juniper PIC Peer"),
|
||||
DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
|
||||
DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
|
||||
DLT_CHOICE(ERF_POS, "Packet-over-SONET with Endace ERF header"),
|
||||
DLT_CHOICE(LINUX_LAPD, "Linux vISDN LAPD"),
|
||||
DLT_CHOICE(JUNIPER_ETHER, "Juniper Ethernet"),
|
||||
@ -2901,10 +3034,11 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(SITA, "SITA pseudo-header"),
|
||||
DLT_CHOICE(ERF, "Endace ERF header"),
|
||||
DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-header"),
|
||||
DLT_CHOICE(IPMB, "IPMB"),
|
||||
DLT_CHOICE(IPMB_KONTRON, "IPMB with Kontron pseudo-header"),
|
||||
DLT_CHOICE(JUNIPER_ST, "Juniper Secure Tunnel"),
|
||||
DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
|
||||
DLT_CHOICE(AX25_KISS, "AX.25 with KISS header"),
|
||||
DLT_CHOICE(IPMB_LINUX, "IPMB with Linux/Pigeon Point pseudo-header"),
|
||||
DLT_CHOICE(IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
|
||||
DLT_CHOICE(MPLS, "MPLS with label as link-layer header"),
|
||||
DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"),
|
||||
@ -2961,6 +3095,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(DOCSIS31_XRA31, "Excentis XRA-31 DOCSIS 3.1 RF sniffer frames"),
|
||||
DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"),
|
||||
DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"),
|
||||
DLT_CHOICE(LINUX_SLL2, "Linux cooked v2"),
|
||||
DLT_CHOICE_SENTINEL
|
||||
};
|
||||
|
||||
@ -3000,6 +3135,21 @@ pcap_datalink_val_to_description(int dlt)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
pcap_datalink_val_to_description_or_dlt(int dlt)
|
||||
{
|
||||
static char unkbuf[40];
|
||||
const char *description;
|
||||
|
||||
description = pcap_datalink_val_to_description(dlt);
|
||||
if (description != NULL) {
|
||||
return description;
|
||||
} else {
|
||||
(void)pcap_snprintf(unkbuf, sizeof(unkbuf), "DLT %u", dlt);
|
||||
return unkbuf;
|
||||
}
|
||||
}
|
||||
|
||||
struct tstamp_type_choice {
|
||||
const char *name;
|
||||
const char *description;
|
||||
@ -3152,7 +3302,7 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
|
||||
* We copy the error message to errbuf, so callers
|
||||
* can find it in either place.
|
||||
*/
|
||||
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@ -3196,7 +3346,7 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
* We copy the error message to errbuf, so callers
|
||||
* can find it in either place.
|
||||
*/
|
||||
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@ -3232,35 +3382,6 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Generate a string for a Win32-specific error (i.e. an error generated when
|
||||
* calling a Win32 API).
|
||||
* For errors occurred during standard C calls, we still use pcap_strerror()
|
||||
*/
|
||||
void
|
||||
pcap_win32_err_to_str(DWORD error, char *errbuf)
|
||||
{
|
||||
size_t errlen;
|
||||
char *p;
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
|
||||
PCAP_ERRBUF_SIZE, NULL);
|
||||
|
||||
/*
|
||||
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
|
||||
* message. Get rid of it.
|
||||
*/
|
||||
errlen = strlen(errbuf);
|
||||
if (errlen >= 2) {
|
||||
errbuf[errlen - 1] = '\0';
|
||||
errbuf[errlen - 2] = '\0';
|
||||
}
|
||||
p = strchr(errbuf, '\0');
|
||||
pcap_snprintf (p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values.
|
||||
*/
|
||||
@ -3332,7 +3453,7 @@ pcap_strerror(int errnum)
|
||||
errno_t err = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
|
||||
|
||||
if (err != 0) /* err = 0 if successful */
|
||||
strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
|
||||
return (errbuf);
|
||||
#else
|
||||
return (strerror(errnum));
|
||||
@ -3554,7 +3675,7 @@ pcap_do_addexit(pcap_t *p)
|
||||
/*
|
||||
* "atexit()" failed; let our caller know.
|
||||
*/
|
||||
strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
|
||||
return (0);
|
||||
}
|
||||
did_atexit = 1;
|
||||
|
@ -160,4 +160,4 @@
|
||||
(__HP_aCC >= ((major)*10000 + (minor)*100))
|
||||
#endif
|
||||
|
||||
#endif /* lib_pcap_funcattrs_h */
|
||||
#endif /* lib_pcap_compiler_tests_h */
|
||||
|
@ -164,10 +164,11 @@
|
||||
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|
||||
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
|
||||
/*
|
||||
* Compiler with support for __attribute((noreturn)), or GCC 2.5 and
|
||||
* later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
|
||||
* and later (do any earlier versions of XL C support this?), or
|
||||
* HP aCC A.06.10 and later.
|
||||
* Compiler with support for __attribute((noreturn)), or GCC 2.5 or
|
||||
* later, or some compiler asserting compatibility with GCC 2.5 or
|
||||
* later, or Solaris Studio 12 (Sun C 5.9) or later, or IBM XL C 10.1
|
||||
* or later (do any earlier versions of XL C support this?), or HP aCC
|
||||
* A.06.10 or later.
|
||||
*/
|
||||
#define PCAP_NORETURN __attribute((noreturn))
|
||||
#define PCAP_NORETURN_DEF __attribute((noreturn))
|
||||
@ -193,7 +194,8 @@
|
||||
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|
||||
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
|
||||
/*
|
||||
* Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1
|
||||
* Compiler with support for it, or GCC 2.3 or later, or some compiler
|
||||
* asserting compatibility with GCC 2.3 or later, or IBM XL C 10.1
|
||||
* and later (do any earlier versions of XL C support this?),
|
||||
* or HP aCC A.06.10 and later.
|
||||
*/
|
||||
@ -216,7 +218,7 @@
|
||||
|| PCAP_IS_AT_LEAST_SUNC_VERSION(5,13)
|
||||
/*
|
||||
* Compiler that supports __has_attribute and __attribute__((deprecated)),
|
||||
* or GCC 4.5 and later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
|
||||
* or GCC 4.5 or later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
|
||||
*
|
||||
* Those support __attribute__((deprecated(msg))) (we assume, perhaps
|
||||
* incorrectly, that anything that supports __has_attribute() is
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
/*
|
||||
* Structure of an NFLOG header and TLV parts, as described at
|
||||
* http://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
|
||||
* https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
|
||||
*
|
||||
* The NFLOG header is big-endian.
|
||||
*
|
||||
@ -42,27 +42,27 @@
|
||||
* data, etc.).
|
||||
*/
|
||||
typedef struct nflog_hdr {
|
||||
uint8_t nflog_family; /* address family */
|
||||
uint8_t nflog_version; /* version */
|
||||
uint16_t nflog_rid; /* resource ID */
|
||||
uint8_t nflog_family; /* address family */
|
||||
uint8_t nflog_version; /* version */
|
||||
uint16_t nflog_rid; /* resource ID */
|
||||
} nflog_hdr_t;
|
||||
|
||||
typedef struct nflog_tlv {
|
||||
uint16_t tlv_length; /* tlv length */
|
||||
uint16_t tlv_type; /* tlv type */
|
||||
uint16_t tlv_length; /* tlv length */
|
||||
uint16_t tlv_type; /* tlv type */
|
||||
/* value follows this */
|
||||
} nflog_tlv_t;
|
||||
|
||||
typedef struct nflog_packet_hdr {
|
||||
uint16_t hw_protocol; /* hw protocol */
|
||||
uint8_t hook; /* netfilter hook */
|
||||
uint8_t pad; /* padding to 32 bits */
|
||||
uint8_t hook; /* netfilter hook */
|
||||
uint8_t pad; /* padding to 32 bits */
|
||||
} nflog_packet_hdr_t;
|
||||
|
||||
typedef struct nflog_hwaddr {
|
||||
uint16_t hw_addrlen; /* address length */
|
||||
uint16_t pad; /* padding to 32-bit boundary */
|
||||
uint8_t hw_addr[8]; /* address, up to 8 bytes */
|
||||
uint8_t hw_addr[8]; /* address, up to 8 bytes */
|
||||
} nflog_hwaddr_t;
|
||||
|
||||
typedef struct nflog_timestamp {
|
||||
|
@ -106,12 +106,23 @@
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MSVC's support library doesn't support %zu to print a size_t until
|
||||
* Visual Studio 2017, but supports %Iu earlier, so use that.
|
||||
*/
|
||||
#define PRIsize "Iu"
|
||||
#elif defined(__MINGW32__) || !defined(_WIN32)
|
||||
/*
|
||||
* Compiler is MinGW or target is UN*X or MS-DOS. Just use
|
||||
* <inttypes.h>.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Assume the support library supports %zu; it's required by C99.
|
||||
*/
|
||||
#define PRIsize "zu"
|
||||
#endif
|
||||
|
||||
#endif /* pcap/pcap-inttypes.h */
|
||||
|
@ -84,6 +84,7 @@
|
||||
#include <sys/time.h>
|
||||
#endif /* _WIN32/MSDOS/UN*X */
|
||||
|
||||
#include <pcap/socket.h> /* for SOCKET, as the active-mode rpcap APIs use it */
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <stdio.h>
|
||||
@ -346,7 +347,7 @@ PCAP_API const char *pcap_tstamp_type_val_to_name(int);
|
||||
PCAP_API const char *pcap_tstamp_type_val_to_description(int);
|
||||
|
||||
#ifdef __linux__
|
||||
PCAP_API int pcap_set_protocol(pcap_t *, int);
|
||||
PCAP_API int pcap_set_protocol_linux(pcap_t *, int);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -466,6 +467,7 @@ PCAP_API void pcap_free_datalinks(int *);
|
||||
PCAP_API int pcap_datalink_name_to_val(const char *);
|
||||
PCAP_API const char *pcap_datalink_val_to_name(int);
|
||||
PCAP_API const char *pcap_datalink_val_to_description(int);
|
||||
PCAP_API const char *pcap_datalink_val_to_description_or_dlt(int);
|
||||
PCAP_API int pcap_snapshot(pcap_t *);
|
||||
PCAP_API int pcap_is_swapped(pcap_t *);
|
||||
PCAP_API int pcap_major_version(pcap_t *);
|
||||
@ -481,7 +483,28 @@ PCAP_API int pcap_fileno(pcap_t *);
|
||||
#endif
|
||||
|
||||
PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||
PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||
#ifdef _WIN32
|
||||
PCAP_API pcap_dumper_t *pcap_dump_hopen(pcap_t *, intptr_t);
|
||||
/*
|
||||
* If we're building libpcap, this is an internal routine in sf-pcap.c, so
|
||||
* we must not define it as a macro.
|
||||
*
|
||||
* If we're not building libpcap, given that the version of the C runtime
|
||||
* with which libpcap was built might be different from the version
|
||||
* of the C runtime with which an application using libpcap was built,
|
||||
* and that a FILE structure may differ between the two versions of the
|
||||
* C runtime, calls to _fileno() must use the version of _fileno() in
|
||||
* the C runtime used to open the FILE *, not the version in the C
|
||||
* runtime with which libpcap was built. (Maybe once the Universal CRT
|
||||
* rules the world, this will cease to be a problem.)
|
||||
*/
|
||||
#ifndef BUILDING_PCAP
|
||||
#define pcap_dump_fopen(p,f) \
|
||||
pcap_dump_hopen(p, _get_osfhandle(_fileno(f)))
|
||||
#endif
|
||||
#else /*_WIN32*/
|
||||
PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||
#endif /*_WIN32*/
|
||||
PCAP_API pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *);
|
||||
PCAP_API FILE *pcap_dump_file(pcap_dumper_t *);
|
||||
PCAP_API long pcap_dump_ftell(pcap_dumper_t *);
|
||||
@ -857,8 +880,8 @@ PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host,
|
||||
* For listing remote capture devices, pcap_findalldevs_ex() is currently
|
||||
* the only API available.
|
||||
*/
|
||||
PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth,
|
||||
pcap_if_t **alldevs, char *errbuf);
|
||||
PCAP_API int pcap_findalldevs_ex(const char *source,
|
||||
struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
|
||||
|
||||
/*
|
||||
* Sampling methods.
|
||||
@ -936,27 +959,6 @@ PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p);
|
||||
/* Maximum length of an host name (needed for the RPCAP active mode) */
|
||||
#define RPCAP_HOSTLIST_SIZE 1024
|
||||
|
||||
/*
|
||||
* Some minor differences between UN*X sockets and and Winsock sockets.
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
/*!
|
||||
* \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
|
||||
* a file descriptor, and therefore a signed integer.
|
||||
* We define SOCKET to be a signed integer on UN*X, so that it can
|
||||
* be used on both platforms.
|
||||
*/
|
||||
#define SOCKET int
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
|
||||
* in UN*X, it's -1.
|
||||
* We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
|
||||
* both platforms.
|
||||
*/
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port,
|
||||
const char *hostlist, char *connectinghost,
|
||||
struct pcap_rmtauth *auth, char *errbuf);
|
||||
|
@ -74,27 +74,44 @@
|
||||
#ifndef lib_pcap_sll_h
|
||||
#define lib_pcap_sll_h
|
||||
|
||||
#include <pcap/pcap-inttypes.h>
|
||||
|
||||
/*
|
||||
* A DLT_LINUX_SLL fake link-layer header.
|
||||
*/
|
||||
#define SLL_HDR_LEN 16 /* total header length */
|
||||
#define SLL_ADDRLEN 8 /* length of address field */
|
||||
|
||||
#include <pcap/pcap-inttypes.h>
|
||||
|
||||
struct sll_header {
|
||||
uint16_t sll_pkttype; /* packet type */
|
||||
uint16_t sll_hatype; /* link-layer address type */
|
||||
uint16_t sll_halen; /* link-layer address length */
|
||||
uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
uint16_t sll_protocol; /* protocol */
|
||||
};
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
|
||||
* PACKET_ values on Linux, but are defined here so that they're
|
||||
* available even on systems other than Linux, and so that they
|
||||
* don't change even if the PACKET_ values change.
|
||||
* A DLT_LINUX_SLL2 fake link-layer header.
|
||||
*/
|
||||
#define SLL2_HDR_LEN 20 /* total header length */
|
||||
|
||||
struct sll2_header {
|
||||
uint16_t sll2_protocol; /* protocol */
|
||||
uint16_t sll2_reserved_mbz; /* reserved - must be zero */
|
||||
uint32_t sll2_if_index; /* 1-based interface index */
|
||||
uint16_t sll2_hatype; /* link-layer address type */
|
||||
uint8_t sll2_pkttype; /* packet type */
|
||||
uint8_t sll2_halen; /* link-layer address length */
|
||||
uint8_t sll2_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
};
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_pkttype" and LINUX_SLL2_ values for
|
||||
* "sll2_pkttype"; these correspond to the PACKET_ values on Linux,
|
||||
* which are defined by a header under include/uapi in the current
|
||||
* kernel source, and are thus not going to change on Linux. We
|
||||
* define them here so that they're available even on systems other
|
||||
* than Linux.
|
||||
*/
|
||||
#define LINUX_SLL_HOST 0
|
||||
#define LINUX_SLL_BROADCAST 1
|
||||
@ -103,10 +120,11 @@ struct sll_header {
|
||||
#define LINUX_SLL_OUTGOING 4
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the
|
||||
* ETH_P_ values on Linux, but are defined here so that they're
|
||||
* available even on systems other than Linux. We assume, for now,
|
||||
* that the ETH_P_ values won't change in Linux; if they do, then:
|
||||
* The LINUX_SLL_ values for "sll_protocol" and LINUX_SLL2_ values for
|
||||
* "sll2_protocol"; these correspond to the ETH_P_ values on Linux, but
|
||||
* are defined here so that they're available even on systems other than
|
||||
* Linux. We assume, for now, that the ETH_P_ values won't change in
|
||||
* Linux; if they do, then:
|
||||
*
|
||||
* if we don't translate them in "pcap-linux.c", capture files
|
||||
* won't necessarily be readable if captured on a system that
|
||||
|
93
freebsd/contrib/libpcap/pcap/socket.h
Normal file
93
freebsd/contrib/libpcap/pcap/socket.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Computer Systems
|
||||
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lib_pcap_socket_h
|
||||
#define lib_pcap_socket_h
|
||||
|
||||
/*
|
||||
* Some minor differences between sockets on various platforms.
|
||||
* We include whatever sockets are needed for Internet-protocol
|
||||
* socket access on UN*X and Windows.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
/* Need windef.h for defines used in winsock2.h under MingW32 */
|
||||
#ifdef __MINGW32__
|
||||
#include <windef.h>
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
/*
|
||||
* Winsock doesn't have this UN*X type; it's used in the UN*X
|
||||
* sockets API.
|
||||
*
|
||||
* XXX - do we need to worry about UN*Xes so old that *they*
|
||||
* don't have it, either?
|
||||
*/
|
||||
typedef int socklen_t;
|
||||
|
||||
/*
|
||||
* Winsock doesn't have this POSIX type; it's used for the
|
||||
* tv_usec value of struct timeval.
|
||||
*/
|
||||
typedef long suseconds_t;
|
||||
#else /* _WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h> /* for struct addrinfo/getaddrinfo() */
|
||||
#include <netinet/in.h> /* for sockaddr_in, in BSD at least */
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
|
||||
* a file descriptor, and therefore a signed integer.
|
||||
* We define SOCKET to be a signed integer on UN*X, so that it can
|
||||
* be used on both platforms.
|
||||
*/
|
||||
#ifndef SOCKET
|
||||
#define SOCKET int
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
|
||||
* in UN*X, it's -1.
|
||||
* We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
|
||||
* both platforms.
|
||||
*/
|
||||
#ifndef INVALID_SOCKET
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* lib_pcap_socket_h */
|
@ -38,6 +38,7 @@
|
||||
* Helpers for portability between Windows and UN*X and between different
|
||||
* flavors of UN*X.
|
||||
*/
|
||||
#include <stdarg.h> /* we declare varargs functions on some platforms */
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
@ -45,49 +46,45 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/*
|
||||
* Macro that does the same thing as strlcpy().
|
||||
*/
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
/*
|
||||
* strncpy_s() is supported at least back to Visual
|
||||
* Studio 2005.
|
||||
*/
|
||||
#define strlcpy(x, y, z) \
|
||||
strncpy_s((x), (z), (y), _TRUNCATE)
|
||||
|
||||
#else
|
||||
#define strlcpy(x, y, z) \
|
||||
(strncpy((x), (y), (z)), \
|
||||
((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \
|
||||
(void) strlen((y)))
|
||||
#endif
|
||||
#ifdef HAVE_STRLCAT
|
||||
#define pcap_strlcat strlcat
|
||||
#else
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
/*
|
||||
* strncat_s() is supported at least back to Visual
|
||||
* Studio 2005.
|
||||
*/
|
||||
#define pcap_strlcat(x, y, z) \
|
||||
strncat_s((x), (z), (y), _TRUNCATE)
|
||||
#else
|
||||
/*
|
||||
* Define it ourselves.
|
||||
*/
|
||||
extern size_t pcap_strlcat(char * restrict dst, const char * restrict src, size_t dstsize);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/*
|
||||
* Macro that does the same thing as strlcat().
|
||||
*/
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
/*
|
||||
* strncat_s() is supported at least back to Visual
|
||||
* Studio 2005.
|
||||
*/
|
||||
#define strlcat(x, y, z) \
|
||||
strncat_s((x), (z), (y), _TRUNCATE)
|
||||
#else
|
||||
/*
|
||||
* ANSI C says strncat() always null-terminates its first argument,
|
||||
* so 1) we don't need to explicitly null-terminate the string
|
||||
* ourselves and 2) we need to leave room for the null terminator.
|
||||
*/
|
||||
#define strlcat(x, y, z) \
|
||||
strncat((x), (y), (z) - strlen((x)) - 1)
|
||||
#endif
|
||||
#ifdef HAVE_STRLCPY
|
||||
#define pcap_strlcpy strlcpy
|
||||
#else
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
/*
|
||||
* strncpy_s() is supported at least back to Visual
|
||||
* Studio 2005.
|
||||
*/
|
||||
#define pcap_strlcpy(x, y, z) \
|
||||
strncpy_s((x), (z), (y), _TRUNCATE)
|
||||
#else
|
||||
/*
|
||||
* Define it ourselves.
|
||||
*/
|
||||
extern size_t pcap_strlcpy(char * restrict dst, const char * restrict src, size_t dstsize);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define isascii __isascii
|
||||
|
||||
/*
|
||||
* If <crtdbg.h> has been included, and _DEBUG is defined, and
|
||||
* __STDC__ is zero, <crtdbg.h> will define strdup() to call
|
||||
@ -134,6 +131,23 @@ extern int pcap_snprintf(char *, size_t, PCAP_FORMAT_STRING(const char *), ...)
|
||||
extern int pcap_vsnprintf(char *, size_t, const char *, va_list ap);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We also want asprintf(), for some cases where we use it to construct
|
||||
* dynamically-allocated variable-length strings.
|
||||
*/
|
||||
#ifdef HAVE_ASPRINTF
|
||||
#define pcap_asprintf asprintf
|
||||
#else
|
||||
extern int pcap_asprintf(char **, PCAP_FORMAT_STRING(const char *), ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VASPRINTF
|
||||
#define pcap_vasprintf vasprintf
|
||||
#else
|
||||
extern int pcap_vasprintf(char **, const char *, va_list ap);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRTOK_R
|
||||
#define pcap_strtok_r strtok_r
|
||||
#else
|
||||
@ -146,7 +160,6 @@ extern int pcap_vsnprintf(char *, size_t, const char *, va_list ap);
|
||||
/*
|
||||
* Define it ourselves.
|
||||
*/
|
||||
#define NEED_STRTOK_R
|
||||
extern char *pcap_strtok_r(char *, const char *, char **);
|
||||
#endif
|
||||
#endif /* HAVE_STRTOK_R */
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h> /* for INT_MAX */
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
@ -54,12 +55,13 @@
|
||||
|
||||
#include "sf-pcap.h"
|
||||
#include "sf-pcapng.h"
|
||||
#include "pcap-common.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* These aren't exported on Windows, because they would only work if both
|
||||
* WinPcap and the code using it were to use the Universal CRT; otherwise,
|
||||
* a FILE structure in WinPcap and a FILE structure in the code using it
|
||||
* WinPcap/Npcap and the code using it were to use the Universal CRT; otherwise,
|
||||
* a FILE structure in WinPcap/Npcap and a FILE structure in the code using it
|
||||
* could be different if they're using different versions of the C runtime.
|
||||
*
|
||||
* Instead, pcap/pcap.h defines them as macros that wrap the hopen versions,
|
||||
@ -181,7 +183,7 @@ sf_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
|
||||
static u_int
|
||||
sf_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue, int sync)
|
||||
{
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
|
||||
pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (0);
|
||||
}
|
||||
@ -220,7 +222,7 @@ sf_get_airpcap_handle(pcap_t *pcap)
|
||||
static int
|
||||
sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
|
||||
pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
@ -319,6 +321,7 @@ pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision,
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "_fdopen");
|
||||
_close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -333,7 +336,34 @@ pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
|
||||
}
|
||||
#endif
|
||||
|
||||
static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, u_int, char *, int *) = {
|
||||
/*
|
||||
* Given a link-layer header type and snapshot length, return a
|
||||
* snapshot length to use when reading the file; it's guaranteed
|
||||
* to be > 0 and <= INT_MAX.
|
||||
*
|
||||
* XXX - the only reason why we limit it to <= INT_MAX is so that
|
||||
* it fits in p->snapshot, and the only reason that p->snapshot is
|
||||
* signed is that pcap_snapshot() returns an int, not an unsigned int.
|
||||
*/
|
||||
bpf_u_int32
|
||||
pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen)
|
||||
{
|
||||
if (snaplen == 0 || snaplen > INT_MAX) {
|
||||
/*
|
||||
* Bogus snapshot length; use the maximum for this
|
||||
* link-layer type as a fallback.
|
||||
*
|
||||
* XXX - we don't clamp snapshot lengths that are
|
||||
* <= INT_MAX but > max_snaplen_for_dlt(linktype),
|
||||
* so a capture file could cause us to allocate
|
||||
* a Really Big Buffer.
|
||||
*/
|
||||
snaplen = max_snaplen_for_dlt(linktype);
|
||||
}
|
||||
return snaplen;
|
||||
}
|
||||
|
||||
static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = {
|
||||
pcap_check_header,
|
||||
pcap_ng_check_header
|
||||
};
|
||||
@ -348,7 +378,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
|
||||
char *errbuf)
|
||||
{
|
||||
register pcap_t *p;
|
||||
bpf_u_int32 magic;
|
||||
uint8_t magic[4];
|
||||
size_t amt_read;
|
||||
u_int i;
|
||||
int err;
|
||||
@ -360,16 +390,15 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
|
||||
* Windows Sniffer, and Microsoft Network Monitor) all have magic
|
||||
* numbers that are unique in their first 4 bytes.
|
||||
*/
|
||||
amt_read = fread((char *)&magic, 1, sizeof(magic), fp);
|
||||
amt_read = fread(&magic, 1, sizeof(magic), fp);
|
||||
if (amt_read != sizeof(magic)) {
|
||||
if (ferror(fp)) {
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "error reading dump file");
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %lu file header bytes, only got %lu",
|
||||
(unsigned long)sizeof(magic),
|
||||
(unsigned long)amt_read);
|
||||
"truncated dump file; tried to read %" PRIsize " file header bytes, only got %" PRIsize,
|
||||
sizeof(magic), amt_read);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -376,7 +376,7 @@ extern int pcap_lex \
|
||||
#undef YY_DECL
|
||||
#endif
|
||||
|
||||
#line 490 "scanner.l"
|
||||
#line 479 "scanner.l"
|
||||
|
||||
|
||||
#line 383 "scanner.h"
|
||||
|
@ -311,13 +311,7 @@ mask return NETMASK;
|
||||
port return PORT;
|
||||
portrange return PORTRANGE;
|
||||
proto return PROTO;
|
||||
protochain {
|
||||
#ifdef NO_PROTOCHAIN
|
||||
bpf_error(yyextra, "%s not supported", yytext);
|
||||
#else
|
||||
return PROTOCHAIN;
|
||||
#endif
|
||||
}
|
||||
protochain return PROTOCHAIN;
|
||||
|
||||
gateway return GATEWAY;
|
||||
|
||||
@ -397,14 +391,8 @@ hsls return HSLS;
|
||||
"==" return '=';
|
||||
"<<" return LSH;
|
||||
">>" return RSH;
|
||||
${B} { yylval->e = pcap_ether_aton(((char *)yytext)+1);
|
||||
if (yylval->e == NULL)
|
||||
bpf_error(yyextra, "malloc");
|
||||
return AID; }
|
||||
{MAC} { yylval->e = pcap_ether_aton((char *)yytext);
|
||||
if (yylval->e == NULL)
|
||||
bpf_error(yyextra, "malloc");
|
||||
return EID; }
|
||||
${B} { yylval->s = sdup(yyextra, yytext); return AID; }
|
||||
{MAC} { yylval->s = sdup(yyextra, yytext); return EID; }
|
||||
{N} { yylval->i = stoi((char *)yytext); return NUM; }
|
||||
({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
|
||||
yylval->s = sdup(yyextra, (char *)yytext); return HID; }
|
||||
@ -414,17 +402,20 @@ ${B} { yylval->e = pcap_ether_aton(((char *)yytext)+1);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET6;
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
if (getaddrinfo(yytext, NULL, &hints, &res))
|
||||
bpf_error(yyextra, "bogus IPv6 address %s", yytext);
|
||||
else {
|
||||
if (getaddrinfo(yytext, NULL, &hints, &res)) {
|
||||
bpf_set_error(yyextra, "bogus IPv6 address %s", yytext);
|
||||
yylval->s = NULL;
|
||||
} else {
|
||||
freeaddrinfo(res);
|
||||
yylval->s = sdup(yyextra, (char *)yytext); return HID6;
|
||||
yylval->s = sdup(yyextra, (char *)yytext);
|
||||
}
|
||||
#else
|
||||
bpf_error(yyextra, "IPv6 address %s not supported", yytext);
|
||||
bpf_set_error(yyextra, "IPv6 address %s not supported", yytext);
|
||||
yylval->s = NULL;
|
||||
#endif /*INET6*/
|
||||
return HID6;
|
||||
}
|
||||
{B}:+({B}:+)+ { bpf_error(yyextra, "bogus ethernet address %s", yytext); }
|
||||
{B}:+({B}:+)+ { bpf_set_error(yyextra, "bogus ethernet address %s", yytext); yylval->s = NULL; return EID; }
|
||||
icmptype { yylval->i = 0; return NUM; }
|
||||
icmpcode { yylval->i = 1; return NUM; }
|
||||
icmp-echoreply { yylval->i = 0; return NUM; }
|
||||
@ -484,9 +475,7 @@ tcp-cwr { yylval->i = 0x80; return NUM; }
|
||||
[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
|
||||
yylval->s = sdup(yyextra, (char *)yytext); return ID; }
|
||||
"\\"[^ !()\n\t]+ { yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
|
||||
[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ {
|
||||
bpf_error(yyextra, "illegal token: %s", yytext); }
|
||||
. { bpf_error(yyextra, "illegal char '%c'", *yytext); }
|
||||
. { return LEX_ERROR; }
|
||||
%%
|
||||
|
||||
/*
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h> /* for INT_MAX */
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
@ -111,6 +112,20 @@
|
||||
|
||||
static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* This isn't exported on Windows, because it would only work if both
|
||||
* libpcap and the code using it were using the same C runtime; otherwise they
|
||||
* would be using different definitions of a FILE structure.
|
||||
*
|
||||
* Instead we define this as a macro in pcap/pcap.h that wraps the hopen
|
||||
* version that we do export, passing it a raw OS HANDLE, as defined by the
|
||||
* Win32 / Win64 ABI, obtained from the _fileno() and _get_osfhandle()
|
||||
* functions of the appropriate CRT.
|
||||
*/
|
||||
static pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *f);
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
* Private data for reading pcap savefiles.
|
||||
*/
|
||||
@ -137,9 +152,10 @@ struct pcap_sf {
|
||||
* relevant information from the header.
|
||||
*/
|
||||
pcap_t *
|
||||
pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
|
||||
int *err)
|
||||
{
|
||||
bpf_u_int32 magic_int;
|
||||
struct pcap_file_header hdr;
|
||||
size_t amt_read;
|
||||
pcap_t *p;
|
||||
@ -156,11 +172,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* number for a pcap savefile, or for a byte-swapped pcap
|
||||
* savefile.
|
||||
*/
|
||||
if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
|
||||
magic != NSEC_TCPDUMP_MAGIC) {
|
||||
magic = SWAPLONG(magic);
|
||||
if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
|
||||
magic != NSEC_TCPDUMP_MAGIC)
|
||||
memcpy(&magic_int, magic, sizeof(magic_int));
|
||||
if (magic_int != TCPDUMP_MAGIC &&
|
||||
magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
|
||||
magic_int != NSEC_TCPDUMP_MAGIC) {
|
||||
magic_int = SWAPLONG(magic_int);
|
||||
if (magic_int != TCPDUMP_MAGIC &&
|
||||
magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
|
||||
magic_int != NSEC_TCPDUMP_MAGIC)
|
||||
return (NULL); /* nope */
|
||||
swapped = 1;
|
||||
}
|
||||
@ -169,7 +188,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* They are. Put the magic number in the header, and read
|
||||
* the rest of the header.
|
||||
*/
|
||||
hdr.magic = magic;
|
||||
hdr.magic = magic_int;
|
||||
amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
|
||||
sizeof(hdr) - sizeof(hdr.magic), fp);
|
||||
if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
|
||||
@ -178,9 +197,8 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
errno, "error reading dump file");
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %lu file header bytes, only got %lu",
|
||||
(unsigned long)sizeof(hdr),
|
||||
(unsigned long)amt_read);
|
||||
"truncated dump file; tried to read %" PRIsize " file header bytes, only got %" PRIsize,
|
||||
sizeof(hdr), amt_read);
|
||||
}
|
||||
*err = 1;
|
||||
return (NULL);
|
||||
@ -234,20 +252,9 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
p->version_major = hdr.version_major;
|
||||
p->version_minor = hdr.version_minor;
|
||||
p->tzoff = hdr.thiszone;
|
||||
p->snapshot = hdr.snaplen;
|
||||
if (p->snapshot <= 0) {
|
||||
/*
|
||||
* Bogus snapshot length; use the maximum for this
|
||||
* link-layer type as a fallback.
|
||||
*
|
||||
* XXX - the only reason why snapshot is signed is
|
||||
* that pcap_snapshot() returns an int, not an
|
||||
* unsigned int.
|
||||
*/
|
||||
p->snapshot = max_snaplen_for_dlt(hdr.linktype);
|
||||
}
|
||||
p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
|
||||
p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
|
||||
p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen);
|
||||
|
||||
p->next_packet_op = pcap_next_packet;
|
||||
|
||||
@ -262,7 +269,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
switch (precision) {
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_MICRO:
|
||||
if (magic == NSEC_TCPDUMP_MAGIC) {
|
||||
if (magic_int == NSEC_TCPDUMP_MAGIC) {
|
||||
/*
|
||||
* The file has nanoseconds, the user
|
||||
* wants microseconds; scale the
|
||||
@ -279,7 +286,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
break;
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_NANO:
|
||||
if (magic == NSEC_TCPDUMP_MAGIC) {
|
||||
if (magic_int == NSEC_TCPDUMP_MAGIC) {
|
||||
/*
|
||||
* The file has nanoseconds, the
|
||||
* user wants nanoseconds; nothing to do.
|
||||
@ -333,7 +340,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
break;
|
||||
}
|
||||
|
||||
if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
|
||||
if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) {
|
||||
/*
|
||||
* XXX - the patch that's in some versions of libpcap
|
||||
* changes the packet header but not the magic number,
|
||||
@ -373,8 +380,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* length will be misleading if you use it to figure
|
||||
* out why a capture doesn't have all the packet data,
|
||||
* but there's not much we can do to avoid that.
|
||||
*
|
||||
* But don't grow the snapshot length past the
|
||||
* maximum value of an int.
|
||||
*/
|
||||
p->snapshot += 14;
|
||||
if (p->snapshot <= INT_MAX - 14)
|
||||
p->snapshot += 14;
|
||||
else
|
||||
p->snapshot = INT_MAX;
|
||||
}
|
||||
} else
|
||||
ps->hdrsize = sizeof(struct pcap_sf_pkthdr);
|
||||
@ -452,9 +465,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
} else {
|
||||
if (amt_read != 0) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %lu header bytes, only got %lu",
|
||||
(unsigned long)ps->hdrsize,
|
||||
(unsigned long)amt_read);
|
||||
"truncated dump file; tried to read %" PRIsize " header bytes, only got %" PRIsize,
|
||||
ps->hdrsize, amt_read);
|
||||
return (-1);
|
||||
}
|
||||
/* EOF */
|
||||
@ -613,8 +625,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
* the read finished.
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %u captured bytes, only got %lu",
|
||||
p->snapshot, (unsigned long)amt_read);
|
||||
"truncated dump file; tried to read %u captured bytes, only got %" PRIsize,
|
||||
p->snapshot, amt_read);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
@ -637,8 +649,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
"error reading dump file");
|
||||
} else {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %u captured bytes, only got %lu",
|
||||
hdr->caplen, (unsigned long)bytes_read);
|
||||
"truncated dump file; tried to read %u captured bytes, only got %" PRIsize,
|
||||
hdr->caplen, bytes_read);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
@ -651,6 +663,9 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
*/
|
||||
hdr->caplen = p->snapshot;
|
||||
} else {
|
||||
/*
|
||||
* The packet is within the snapshot length for this file.
|
||||
*/
|
||||
if (hdr->caplen > p->bufsize) {
|
||||
/*
|
||||
* Grow the buffer to the next power of 2, or
|
||||
@ -686,8 +701,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
"error reading dump file");
|
||||
} else {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %u captured bytes, only got %lu",
|
||||
hdr->caplen, (unsigned long)amt_read);
|
||||
"truncated dump file; tried to read %u captured bytes, only got %" PRIsize,
|
||||
hdr->caplen, amt_read);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
@ -819,9 +834,42 @@ pcap_dump_open(pcap_t *p, const char *fname)
|
||||
return (pcap_setup_dump(p, linktype, f, fname));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Initialize so that sf_write() will output to a stream wrapping the given raw
|
||||
* OS file HANDLE.
|
||||
*/
|
||||
pcap_dumper_t *
|
||||
pcap_dump_hopen(pcap_t *p, intptr_t osfd)
|
||||
{
|
||||
int fd;
|
||||
FILE *file;
|
||||
|
||||
fd = _open_osfhandle(osfd, _O_APPEND);
|
||||
if (fd < 0) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "_open_osfhandle");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file = _fdopen(fd, "wb");
|
||||
if (file == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "_fdopen");
|
||||
_close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pcap_dump_fopen(p, file);
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
* Initialize so that sf_write() will output to the given stream.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
static
|
||||
#endif /* _WIN32 */
|
||||
pcap_dumper_t *
|
||||
pcap_dump_fopen(pcap_t *p, FILE *f)
|
||||
{
|
||||
@ -864,11 +912,19 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
return (pcap_setup_dump(p, linktype, stdout, "standard output"));
|
||||
|
||||
/*
|
||||
* "a" will cause the file *not* to be truncated if it exists
|
||||
* but will cause it to be created if it doesn't. It will
|
||||
* also cause all writes to be done at the end of the file,
|
||||
* but will allow reads to be done anywhere in the file. This
|
||||
* is what we need, because we need to read from the beginning
|
||||
* of the file to see if it already has a header and packets
|
||||
* or if it doesn't.
|
||||
*
|
||||
* "b" is supported as of C90, so *all* UN*Xes should support it,
|
||||
* even though it does nothing. It's required on Windows, as the
|
||||
* file is a binary file and must be read in binary mode.
|
||||
*/
|
||||
f = fopen(fname, "rb+");
|
||||
f = fopen(fname, "ab+");
|
||||
if (f == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "%s", fname);
|
||||
@ -877,18 +933,33 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
|
||||
/*
|
||||
* Try to read a pcap header.
|
||||
*
|
||||
* We do not assume that the file will be positioned at the
|
||||
* beginning immediately after we've opened it - we seek to
|
||||
* the beginning. ISO C says it's implementation-defined
|
||||
* whether the file position indicator is at the beginning
|
||||
* or the end of the file after an append-mode open, and
|
||||
* it wasn't obvious from the Single UNIX Specification
|
||||
* or the Microsoft documentation how that works on SUS-
|
||||
* compliant systems or on Windows.
|
||||
*/
|
||||
if (fseek(f, 0, SEEK_SET) == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't seek to the beginning of %s", fname);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
amt_read = fread(&ph, 1, sizeof (ph), f);
|
||||
if (amt_read != sizeof (ph)) {
|
||||
if (ferror(f)) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "%s", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
} else if (feof(f) && amt_read > 0) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: truncated pcap file header", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
@ -924,7 +995,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different time stamp precision, cannot append to file", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
break;
|
||||
@ -933,7 +1004,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different time stamp precision, cannot append to file", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
break;
|
||||
@ -942,7 +1013,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
case SWAPLONG(NSEC_TCPDUMP_MAGIC):
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different byte order, cannot append to file", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
|
||||
case KUZNETZOV_TCPDUMP_MAGIC:
|
||||
@ -951,13 +1022,13 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: not a pcap file to which we can append", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
|
||||
default:
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: not a pcap file", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -969,19 +1040,19 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: version is %u.%u, cannot append to file", fname,
|
||||
ph.version_major, ph.version_minor);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
if ((bpf_u_int32)linktype != ph.linktype) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different linktype, cannot append to file", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
if ((bpf_u_int32)p->snapshot != ph.snaplen) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different snaplen, cannot append to file", fname);
|
||||
fclose(f);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
@ -998,10 +1069,14 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
|
||||
/*
|
||||
* Start writing at the end of the file.
|
||||
*
|
||||
* XXX - this shouldn't be necessary, given that we're opening
|
||||
* the file in append mode, and ISO C specifies that all writes
|
||||
* are done at the end of the file in that mode.
|
||||
*/
|
||||
if (fseek(f, 0, SEEK_END) == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't seek to end of %s", fname);
|
||||
errno, "Can't seek to the end of %s", fname);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
#ifndef sf_pcap_h
|
||||
#define sf_pcap_h
|
||||
|
||||
extern pcap_t *pcap_check_header(bpf_u_int32 magic, FILE *fp,
|
||||
extern pcap_t *pcap_check_header(const uint8_t *magic, FILE *fp,
|
||||
u_int precision, char *errbuf, int *err);
|
||||
|
||||
#endif
|
||||
|
@ -87,7 +87,7 @@ struct option_header {
|
||||
* Section Header Block.
|
||||
*/
|
||||
#define BT_SHB 0x0A0D0D0A
|
||||
|
||||
#define BT_SHB_INSANE_MAX 1024U*1024U*1U /* 1MB should be enough */
|
||||
struct section_header_block {
|
||||
bpf_u_int32 byte_order_magic;
|
||||
u_short major_version;
|
||||
@ -199,9 +199,9 @@ typedef enum {
|
||||
* Per-interface information.
|
||||
*/
|
||||
struct pcap_ng_if {
|
||||
u_int tsresol; /* time stamp resolution */
|
||||
uint64_t tsresol; /* time stamp resolution */
|
||||
tstamp_scale_type_t scale_type; /* how to scale */
|
||||
u_int scale_factor; /* time stamp scale factor for power-of-10 tsresol */
|
||||
uint64_t scale_factor; /* time stamp scale factor for power-of-10 tsresol */
|
||||
uint64_t tsoffset; /* time stamp offset */
|
||||
};
|
||||
|
||||
@ -225,7 +225,7 @@ struct pcap_ng_if {
|
||||
* so we impose a limit regardless of the size of a pointer.
|
||||
*/
|
||||
struct pcap_ng_sf {
|
||||
u_int user_tsresol; /* time stamp resolution requested by the user */
|
||||
uint64_t user_tsresol; /* time stamp resolution requested by the user */
|
||||
u_int max_blocksize; /* don't grow buffer size past this */
|
||||
bpf_u_int32 ifcount; /* number of interfaces seen in this capture */
|
||||
bpf_u_int32 ifaces_size; /* size of array below */
|
||||
@ -233,16 +233,21 @@ struct pcap_ng_sf {
|
||||
};
|
||||
|
||||
/*
|
||||
* Maximum block size for a given maximum snapshot length; we calculate
|
||||
* this based
|
||||
*
|
||||
* We define it as the size of an EPB with a max_snaplen-sized
|
||||
* packet and 128KB of options.
|
||||
* The maximum block size we start with; we use an arbitrary value of
|
||||
* 16 MiB.
|
||||
*/
|
||||
#define MAX_BLOCKSIZE(max_snaplen) (sizeof (struct block_header) + \
|
||||
sizeof (struct enhanced_packet_block) + \
|
||||
(max_snaplen) + 131072 + \
|
||||
sizeof (struct block_trailer))
|
||||
#define INITIAL_MAX_BLOCKSIZE (16*1024*1024)
|
||||
|
||||
/*
|
||||
* Maximum block size for a given maximum snapshot length; we define it
|
||||
* as the size of an EPB with a max_snaplen-sized packet and 128KB of
|
||||
* options.
|
||||
*/
|
||||
#define MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen) \
|
||||
(sizeof (struct block_header) + \
|
||||
sizeof (struct enhanced_packet_block) + \
|
||||
(max_snaplen) + 131072 + \
|
||||
sizeof (struct block_trailer))
|
||||
|
||||
static void pcap_ng_cleanup(pcap_t *p);
|
||||
static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
|
||||
@ -263,9 +268,8 @@ read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof,
|
||||
if (amt_read == 0 && !fail_on_eof)
|
||||
return (0); /* EOF */
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %lu bytes, only got %lu",
|
||||
(unsigned long)bytes_to_read,
|
||||
(unsigned long)amt_read);
|
||||
"truncated pcapng dump file; tried to read %" PRIsize " bytes, only got %" PRIsize,
|
||||
bytes_to_read, amt_read);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
@ -278,6 +282,7 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
struct pcap_ng_sf *ps;
|
||||
int status;
|
||||
struct block_header bhdr;
|
||||
struct block_trailer *btrlr;
|
||||
u_char *bdata;
|
||||
size_t data_remaining;
|
||||
|
||||
@ -292,20 +297,6 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
bhdr.total_length = SWAPLONG(bhdr.total_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this block "too big"?
|
||||
*
|
||||
* We choose 16MB as "too big", for now, so that we handle
|
||||
* "reasonably" large buffers but don't chew up all the
|
||||
* memory if we read a malformed file.
|
||||
*/
|
||||
if (bhdr.total_length > 16*1024*1024) {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"pcapng block size %u > maximum %u",
|
||||
bhdr.total_length, 16*1024*1024);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this block "too small" - i.e., is it shorter than a block
|
||||
* header plus a block trailer?
|
||||
@ -313,9 +304,22 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
if (bhdr.total_length < sizeof(struct block_header) +
|
||||
sizeof(struct block_trailer)) {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"block in pcapng dump file has a length of %u < %lu",
|
||||
"block in pcapng dump file has a length of %u < %" PRIsize,
|
||||
bhdr.total_length,
|
||||
(unsigned long)(sizeof(struct block_header) + sizeof(struct block_trailer)));
|
||||
sizeof(struct block_header) + sizeof(struct block_trailer));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the block total length a multiple of 4?
|
||||
*/
|
||||
if ((bhdr.total_length % 4) != 0) {
|
||||
/*
|
||||
* No. Report that as an error.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"block in pcapng dump file has a length of %u that is not a multiple of 4" PRIsize,
|
||||
bhdr.total_length);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -324,12 +328,13 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
*/
|
||||
if (p->bufsize < bhdr.total_length) {
|
||||
/*
|
||||
* No - make it big enough, unless it's too big.
|
||||
* No - make it big enough, unless it's too big, in
|
||||
* which case we fail.
|
||||
*/
|
||||
void *bigger_buffer;
|
||||
|
||||
if (bhdr.total_length > ps->max_blocksize) {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "block is larger than maximum block size %u",
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "pcapng block size %u > maximum %u", bhdr.total_length,
|
||||
ps->max_blocksize);
|
||||
return (-1);
|
||||
}
|
||||
@ -351,6 +356,26 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
if (read_bytes(fp, bdata, data_remaining, 1, errbuf) == -1)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Get the block size from the trailer.
|
||||
*/
|
||||
btrlr = (struct block_trailer *)(bdata + data_remaining - sizeof (struct block_trailer));
|
||||
if (p->swapped)
|
||||
btrlr->total_length = SWAPLONG(btrlr->total_length);
|
||||
|
||||
/*
|
||||
* Is the total length from the trailer the same as the total
|
||||
* length from the header?
|
||||
*/
|
||||
if (bhdr.total_length != btrlr->total_length) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"block total length in header and trailer don't match");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the cursor.
|
||||
*/
|
||||
@ -433,13 +458,13 @@ get_optvalue_from_block_data(struct block_cursor *cursor,
|
||||
}
|
||||
|
||||
static int
|
||||
process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
|
||||
process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol,
|
||||
uint64_t *tsoffset, int *is_binary, char *errbuf)
|
||||
{
|
||||
struct option_header *opthdr;
|
||||
void *optvalue;
|
||||
int saw_tsresol, saw_tsoffset;
|
||||
u_char tsresol_opt;
|
||||
uint8_t tsresol_opt;
|
||||
u_int i;
|
||||
|
||||
saw_tsresol = 0;
|
||||
@ -497,32 +522,43 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
|
||||
/*
|
||||
* Resolution is negative power of 2.
|
||||
*/
|
||||
uint8_t tsresol_shift = (tsresol_opt & 0x7F);
|
||||
|
||||
if (tsresol_shift > 63) {
|
||||
/*
|
||||
* Resolution is too high; 2^-{res}
|
||||
* won't fit in a 64-bit value.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Interface Description Block if_tsresol option resolution 2^-%u is too high",
|
||||
tsresol_shift);
|
||||
return (-1);
|
||||
}
|
||||
*is_binary = 1;
|
||||
*tsresol = 1 << (tsresol_opt & 0x7F);
|
||||
*tsresol = ((uint64_t)1) << tsresol_shift;
|
||||
} else {
|
||||
/*
|
||||
* Resolution is negative power of 10.
|
||||
*/
|
||||
if (tsresol_opt > 19) {
|
||||
/*
|
||||
* Resolution is too high; 2^-{res}
|
||||
* won't fit in a 64-bit value (the
|
||||
* largest power of 10 that fits
|
||||
* in a 64-bit value is 10^19, as
|
||||
* the largest 64-bit unsigned
|
||||
* value is ~1.8*10^19).
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Interface Description Block if_tsresol option resolution 10^-%u is too high",
|
||||
tsresol_opt);
|
||||
return (-1);
|
||||
}
|
||||
*is_binary = 0;
|
||||
*tsresol = 1;
|
||||
for (i = 0; i < tsresol_opt; i++)
|
||||
*tsresol *= 10;
|
||||
}
|
||||
if (*tsresol == 0) {
|
||||
/*
|
||||
* Resolution is too high.
|
||||
*/
|
||||
if (tsresol_opt & 0x80) {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Interface Description Block if_tsresol option resolution 2^-%u is too high",
|
||||
tsresol_opt & 0x7F);
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Interface Description Block if_tsresol option resolution 10^-%u is too high",
|
||||
tsresol_opt);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case IF_TSOFFSET:
|
||||
@ -556,7 +592,7 @@ static int
|
||||
add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
{
|
||||
struct pcap_ng_sf *ps;
|
||||
u_int tsresol;
|
||||
uint64_t tsresol;
|
||||
uint64_t tsoffset;
|
||||
int is_binary;
|
||||
|
||||
@ -727,9 +763,10 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
* relevant information from the header.
|
||||
*/
|
||||
pcap_t *
|
||||
pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
int *err)
|
||||
pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision,
|
||||
char *errbuf, int *err)
|
||||
{
|
||||
bpf_u_int32 magic_int;
|
||||
size_t amt_read;
|
||||
bpf_u_int32 total_length;
|
||||
bpf_u_int32 byte_order_magic;
|
||||
@ -751,7 +788,8 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* Check whether the first 4 bytes of the file are the block
|
||||
* type for a pcapng savefile.
|
||||
*/
|
||||
if (magic != BT_SHB) {
|
||||
memcpy(&magic_int, magic, sizeof(magic_int));
|
||||
if (magic_int != BT_SHB) {
|
||||
/*
|
||||
* XXX - check whether this looks like what the block
|
||||
* type would be after being munged by mapping between
|
||||
@ -820,11 +858,14 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
/*
|
||||
* Check the sanity of the total length.
|
||||
*/
|
||||
if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)) {
|
||||
if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer) ||
|
||||
(total_length > BT_SHB_INSANE_MAX)) {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Section Header Block in pcapng dump file has a length of %u < %lu",
|
||||
"Section Header Block in pcapng dump file has invalid length %" PRIsize " < _%u_ < %u (BT_SHB_INSANE_MAX)",
|
||||
sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer),
|
||||
total_length,
|
||||
(unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
|
||||
BT_SHB_INSANE_MAX);
|
||||
|
||||
*err = 1;
|
||||
return (NULL);
|
||||
}
|
||||
@ -876,10 +917,10 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* leaving room for some options.
|
||||
*
|
||||
* If we find a bigger block, we reallocate the buffer, up to
|
||||
* the maximum size. We start out with a maximum size based
|
||||
* on a maximum snapshot length of MAXIMUM_SNAPLEN; if we see
|
||||
* any link-layer header types with a larger maximum snapshot
|
||||
* length, we boost the maximum.
|
||||
* the maximum size. We start out with a maximum size of
|
||||
* INITIAL_MAX_BLOCKSIZE; if we see any link-layer header types
|
||||
* with a maximum snapshot that results in a larger maximum
|
||||
* block length, we boost the maximum.
|
||||
*/
|
||||
p->bufsize = 2048;
|
||||
if (p->bufsize < total_length)
|
||||
@ -891,7 +932,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
*err = 1;
|
||||
return (NULL);
|
||||
}
|
||||
ps->max_blocksize = MAX_BLOCKSIZE(MAXIMUM_SNAPLEN);
|
||||
ps->max_blocksize = INITIAL_MAX_BLOCKSIZE;
|
||||
|
||||
/*
|
||||
* Copy the stuff we've read to the buffer, and read the rest
|
||||
@ -899,12 +940,12 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
*/
|
||||
bhdrp = (struct block_header *)p->buffer;
|
||||
shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header));
|
||||
bhdrp->block_type = magic;
|
||||
bhdrp->block_type = magic_int;
|
||||
bhdrp->total_length = total_length;
|
||||
shbp->byte_order_magic = byte_order_magic;
|
||||
if (read_bytes(fp,
|
||||
(u_char *)p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
|
||||
total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
|
||||
(u_char *)p->buffer + (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)),
|
||||
total_length - (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)),
|
||||
1, errbuf) == -1)
|
||||
goto fail;
|
||||
|
||||
@ -1001,19 +1042,8 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
|
||||
done:
|
||||
p->tzoff = 0; /* XXX - not used in pcap */
|
||||
p->snapshot = idbp->snaplen;
|
||||
if (p->snapshot <= 0) {
|
||||
/*
|
||||
* Bogus snapshot length; use the maximum for this
|
||||
* link-layer type as a fallback.
|
||||
*
|
||||
* XXX - the only reason why snapshot is signed is
|
||||
* that pcap_snapshot() returns an int, not an
|
||||
* unsigned int.
|
||||
*/
|
||||
p->snapshot = max_snaplen_for_dlt(idbp->linktype);
|
||||
}
|
||||
p->linktype = linktype_to_dlt(idbp->linktype);
|
||||
p->snapshot = pcap_adjust_snapshot(p->linktype, idbp->snaplen);
|
||||
p->linktype_ext = 0;
|
||||
|
||||
/*
|
||||
@ -1021,8 +1051,8 @@ done:
|
||||
* snapshot length for this DLT_ is bigger than the current
|
||||
* maximum block size, increase the maximum.
|
||||
*/
|
||||
if (MAX_BLOCKSIZE(max_snaplen_for_dlt(p->linktype)) > ps->max_blocksize)
|
||||
ps->max_blocksize = MAX_BLOCKSIZE(max_snaplen_for_dlt(p->linktype));
|
||||
if (MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype)) > ps->max_blocksize)
|
||||
ps->max_blocksize = MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype));
|
||||
|
||||
p->next_packet_op = pcap_ng_next_packet;
|
||||
p->cleanup_op = pcap_ng_cleanup;
|
||||
@ -1208,7 +1238,13 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
idbp->linktype);
|
||||
return (-1);
|
||||
}
|
||||
if ((bpf_u_int32)p->snapshot != idbp->snaplen) {
|
||||
|
||||
/*
|
||||
* Check against the *adjusted* value of this IDB's
|
||||
* snapshot length.
|
||||
*/
|
||||
if ((bpf_u_int32)p->snapshot !=
|
||||
pcap_adjust_snapshot(p->linktype, idbp->snaplen)) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"an interface has a snapshot length %u different from the type of the first interface",
|
||||
idbp->snaplen);
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef sf_pcapng_h
|
||||
#define sf_pcapng_h
|
||||
|
||||
extern pcap_t *pcap_ng_check_header(bpf_u_int32 magic, FILE *fp,
|
||||
extern pcap_t *pcap_ng_check_header(const uint8_t *magic, FILE *fp,
|
||||
u_int precision, char *errbuf, int *err);
|
||||
|
||||
#endif
|
||||
|
@ -131,7 +131,7 @@ win32_gethostbyaddr(const char *addr, int len, int type)
|
||||
hname, sizeof(hname), NULL, 0, 0)) {
|
||||
return NULL;
|
||||
} else {
|
||||
strcpy(host.h_name, hname);
|
||||
strlcpy(host.h_name, hname, NI_MAXHOST);
|
||||
return &host;
|
||||
}
|
||||
break;
|
||||
@ -1253,10 +1253,7 @@ dnaddr_string(netdissect_options *ndo, u_short dnaddr)
|
||||
|
||||
tp->addr = dnaddr;
|
||||
tp->nxt = newhnamemem(ndo);
|
||||
if (ndo->ndo_nflag)
|
||||
tp->name = dnnum_string(ndo, dnaddr);
|
||||
else
|
||||
tp->name = dnname_string(ndo, dnaddr);
|
||||
tp->name = dnnum_string(ndo, dnaddr);
|
||||
|
||||
return(tp->name);
|
||||
}
|
||||
|
@ -514,6 +514,7 @@ extern void hsrp_print(netdissect_options *, const u_char *, u_int);
|
||||
extern void http_print(netdissect_options *, const u_char *, u_int);
|
||||
extern void icmp6_print(netdissect_options *, const u_char *, u_int, const u_char *, int);
|
||||
extern void icmp_print(netdissect_options *, const u_char *, u_int, const u_char *, int);
|
||||
extern u_int ieee802_11_radio_print(netdissect_options *, const u_char *, u_int, u_int);
|
||||
extern void igmp_print(netdissect_options *, const u_char *, u_int);
|
||||
extern void igrp_print(netdissect_options *, const u_char *, u_int);
|
||||
extern void ip6_print(netdissect_options *, const u_char *, u_int);
|
||||
@ -641,7 +642,6 @@ extern int nextproto6_cksum(netdissect_options *, const struct ip6_hdr *, const
|
||||
extern int mask2plen(uint32_t);
|
||||
extern int mask62plen(const u_char *);
|
||||
|
||||
extern const char *dnname_string(netdissect_options *, u_short);
|
||||
extern const char *dnnum_string(netdissect_options *, u_short);
|
||||
|
||||
extern char *smb_errstr(int, int);
|
||||
|
@ -2064,6 +2064,10 @@ ieee802_11_print(netdissect_options *ndo,
|
||||
hdrlen = roundup2(hdrlen, 4);
|
||||
if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
|
||||
DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
|
||||
if (caplen < hdrlen + 1) {
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
return hdrlen;
|
||||
}
|
||||
meshdrlen = extract_mesh_header_length(p+hdrlen);
|
||||
hdrlen += meshdrlen;
|
||||
} else
|
||||
@ -3077,7 +3081,7 @@ print_in_radiotap_namespace(netdissect_options *ndo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u_int
|
||||
u_int
|
||||
ieee802_11_radio_print(netdissect_options *ndo,
|
||||
const u_char *p, u_int length, u_int caplen)
|
||||
{
|
||||
@ -3107,6 +3111,15 @@ ieee802_11_radio_print(netdissect_options *ndo,
|
||||
hdr = (const struct ieee80211_radiotap_header *)p;
|
||||
|
||||
len = EXTRACT_LE_16BITS(&hdr->it_len);
|
||||
if (len < sizeof(*hdr)) {
|
||||
/*
|
||||
* The length is the length of the entire header, so
|
||||
* it must be as large as the fixed-length part of
|
||||
* the header.
|
||||
*/
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
return caplen;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't have the entire radiotap header, just give up.
|
||||
|
@ -331,6 +331,7 @@ aoev1_reserve_print(netdissect_options *ndo,
|
||||
goto invalid;
|
||||
/* addresses */
|
||||
for (i = 0; i < nmacs; i++) {
|
||||
ND_TCHECK2(*cp, ETHER_ADDR_LEN);
|
||||
ND_PRINT((ndo, "\n\tEthernet Address %u: %s", i, etheraddr_string(ndo, cp)));
|
||||
cp += ETHER_ADDR_LEN;
|
||||
}
|
||||
@ -356,6 +357,7 @@ aoev1_print(netdissect_options *ndo,
|
||||
if (len < AOEV1_COMMON_HDR_LEN)
|
||||
goto invalid;
|
||||
/* Flags */
|
||||
ND_TCHECK2(*cp, 1);
|
||||
flags = *cp & 0x0F;
|
||||
ND_PRINT((ndo, ", Flags: [%s]", bittok2str(aoev1_flag_str, "none", flags)));
|
||||
cp += 1;
|
||||
|
@ -358,6 +358,8 @@ babel_print_v2(netdissect_options *ndo,
|
||||
goto invalid;
|
||||
bodylen = EXTRACT_16BITS(cp + 2);
|
||||
ND_PRINT((ndo, " (%u)", bodylen));
|
||||
if (4U + bodylen > length)
|
||||
goto invalid;
|
||||
|
||||
/* Process the TLVs in the body */
|
||||
i = 0;
|
||||
@ -486,7 +488,7 @@ babel_print_v2(netdissect_options *ndo,
|
||||
case MESSAGE_UPDATE: {
|
||||
if (!ndo->ndo_vflag) {
|
||||
ND_PRINT((ndo, " update"));
|
||||
if(len < 1)
|
||||
if(len < 10)
|
||||
ND_PRINT((ndo, "/truncated"));
|
||||
else
|
||||
ND_PRINT((ndo, "%s%s%s",
|
||||
|
@ -21,7 +21,10 @@
|
||||
|
||||
/* \summary: Bidirectional Forwarding Detection (BFD) printer */
|
||||
|
||||
/* specification: RFC 5880 (for version 1) and RFC 5881 */
|
||||
/*
|
||||
* specification: draft-ietf-bfd-base-01 for version 0,
|
||||
* RFC 5880 for version 1, and RFC 5881
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@ -35,12 +38,12 @@
|
||||
#include "udp.h"
|
||||
|
||||
/*
|
||||
* Control packet, BFDv0, draft-katz-ward-bfd-01.txt
|
||||
* Control packet, BFDv0, draft-ietf-bfd-base-01
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* |Vers | Diag |H|D|P|F| Rsvd | Detect Mult | Length |
|
||||
* |Vers | Diag |H|D|P|F|C|A|Rsv| Detect Mult | Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | My Discriminator |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
@ -132,12 +135,6 @@ enum auth_length {
|
||||
#define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5)
|
||||
#define BFD_EXTRACT_DIAG(x) ((x)&0x1f)
|
||||
|
||||
static const struct tok bfd_port_values[] = {
|
||||
{ BFD_CONTROL_PORT, "Control" },
|
||||
{ BFD_ECHO_PORT, "Echo" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const struct tok bfd_diag_values[] = {
|
||||
{ 0, "No Diagnostic" },
|
||||
{ 1, "Control Detection Time Expired" },
|
||||
@ -151,20 +148,20 @@ static const struct tok bfd_diag_values[] = {
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
#define BFD_FLAG_AUTH 0x04
|
||||
|
||||
static const struct tok bfd_v0_flag_values[] = {
|
||||
{ 0x80, "I Hear You" },
|
||||
{ 0x40, "Demand" },
|
||||
{ 0x20, "Poll" },
|
||||
{ 0x10, "Final" },
|
||||
{ 0x08, "Reserved" },
|
||||
{ 0x04, "Reserved" },
|
||||
{ 0x08, "Control Plane Independent" },
|
||||
{ BFD_FLAG_AUTH, "Authentication Present" },
|
||||
{ 0x02, "Reserved" },
|
||||
{ 0x01, "Reserved" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
#define BFD_FLAG_AUTH 0x04
|
||||
|
||||
static const struct tok bfd_v1_flag_values[] = {
|
||||
{ 0x20, "Poll" },
|
||||
{ 0x10, "Final" },
|
||||
@ -298,106 +295,124 @@ void
|
||||
bfd_print(netdissect_options *ndo, register const u_char *pptr,
|
||||
register u_int len, register u_int port)
|
||||
{
|
||||
const struct bfd_header_t *bfd_header;
|
||||
uint8_t version = 0;
|
||||
|
||||
bfd_header = (const struct bfd_header_t *)pptr;
|
||||
if (port == BFD_CONTROL_PORT) {
|
||||
/*
|
||||
* Control packet.
|
||||
*/
|
||||
const struct bfd_header_t *bfd_header;
|
||||
uint8_t version_diag;
|
||||
uint8_t version = 0;
|
||||
uint8_t flags;
|
||||
|
||||
bfd_header = (const struct bfd_header_t *)pptr;
|
||||
ND_TCHECK(*bfd_header);
|
||||
version = BFD_EXTRACT_VERSION(bfd_header->version_diag);
|
||||
version_diag = bfd_header->version_diag;
|
||||
version = BFD_EXTRACT_VERSION(version_diag);
|
||||
flags = bfd_header->flags;
|
||||
|
||||
switch (version) {
|
||||
|
||||
/* BFDv0 */
|
||||
case 0:
|
||||
if (ndo->ndo_vflag < 1)
|
||||
{
|
||||
ND_PRINT((ndo, "BFDv0, Control, Flags: [%s], length: %u",
|
||||
bittok2str(bfd_v0_flag_values, "none", flags),
|
||||
len));
|
||||
return;
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, "BFDv0, length: %u\n\tControl, Flags: [%s], Diagnostic: %s (0x%02x)",
|
||||
len,
|
||||
bittok2str(bfd_v0_flag_values, "none", flags),
|
||||
tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)),
|
||||
BFD_EXTRACT_DIAG(version_diag)));
|
||||
|
||||
ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
|
||||
bfd_header->detect_time_multiplier,
|
||||
bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
|
||||
bfd_header->length));
|
||||
|
||||
|
||||
ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)));
|
||||
ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)));
|
||||
ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000));
|
||||
ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000));
|
||||
ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000));
|
||||
|
||||
if (flags & BFD_FLAG_AUTH) {
|
||||
if (auth_print(ndo, pptr))
|
||||
goto trunc;
|
||||
}
|
||||
break;
|
||||
|
||||
/* BFDv1 */
|
||||
case 1:
|
||||
if (ndo->ndo_vflag < 1)
|
||||
{
|
||||
ND_PRINT((ndo, "BFDv1, Control, State %s, Flags: [%s], length: %u",
|
||||
tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6),
|
||||
bittok2str(bfd_v1_flag_values, "none", flags & 0x3f),
|
||||
len));
|
||||
return;
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, "BFDv1, length: %u\n\tControl, State %s, Flags: [%s], Diagnostic: %s (0x%02x)",
|
||||
len,
|
||||
tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6),
|
||||
bittok2str(bfd_v1_flag_values, "none", flags & 0x3f),
|
||||
tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)),
|
||||
BFD_EXTRACT_DIAG(version_diag)));
|
||||
|
||||
ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
|
||||
bfd_header->detect_time_multiplier,
|
||||
bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
|
||||
bfd_header->length));
|
||||
|
||||
|
||||
ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)));
|
||||
ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)));
|
||||
ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000));
|
||||
ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000));
|
||||
ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000));
|
||||
|
||||
if (flags & BFD_FLAG_AUTH) {
|
||||
if (auth_print(ndo, pptr))
|
||||
goto trunc;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ND_PRINT((ndo, "BFDv%u, Control, length: %u",
|
||||
version,
|
||||
len));
|
||||
if (ndo->ndo_vflag >= 1) {
|
||||
if(!print_unknown_data(ndo, pptr,"\n\t",len))
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (port == BFD_ECHO_PORT) {
|
||||
/* Echo is BFD v1 only */
|
||||
version = 1;
|
||||
}
|
||||
switch ((port << 8) | version) {
|
||||
|
||||
/* BFDv0 */
|
||||
case (BFD_CONTROL_PORT << 8):
|
||||
if (ndo->ndo_vflag < 1)
|
||||
{
|
||||
ND_PRINT((ndo, "BFDv%u, %s, Flags: [%s], length: %u",
|
||||
version,
|
||||
tok2str(bfd_port_values, "unknown (%u)", port),
|
||||
bittok2str(bfd_v0_flag_values, "none", bfd_header->flags),
|
||||
len));
|
||||
return;
|
||||
/*
|
||||
* Echo packet.
|
||||
*/
|
||||
ND_PRINT((ndo, "BFD, Echo, length: %u",
|
||||
len));
|
||||
if (ndo->ndo_vflag >= 1) {
|
||||
if(!print_unknown_data(ndo, pptr,"\n\t",len))
|
||||
return;
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, "BFDv%u, length: %u\n\t%s, Flags: [%s], Diagnostic: %s (0x%02x)",
|
||||
version,
|
||||
len,
|
||||
tok2str(bfd_port_values, "unknown (%u)", port),
|
||||
bittok2str(bfd_v0_flag_values, "none", bfd_header->flags),
|
||||
tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)),
|
||||
BFD_EXTRACT_DIAG(bfd_header->version_diag)));
|
||||
|
||||
ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
|
||||
bfd_header->detect_time_multiplier,
|
||||
bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
|
||||
bfd_header->length));
|
||||
|
||||
|
||||
ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)));
|
||||
ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)));
|
||||
ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000));
|
||||
ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000));
|
||||
ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000));
|
||||
break;
|
||||
|
||||
/* BFDv1 */
|
||||
case (BFD_CONTROL_PORT << 8 | 1):
|
||||
if (ndo->ndo_vflag < 1)
|
||||
{
|
||||
ND_PRINT((ndo, "BFDv%u, %s, State %s, Flags: [%s], length: %u",
|
||||
version,
|
||||
tok2str(bfd_port_values, "unknown (%u)", port),
|
||||
tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6),
|
||||
bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f),
|
||||
len));
|
||||
return;
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, "BFDv%u, length: %u\n\t%s, State %s, Flags: [%s], Diagnostic: %s (0x%02x)",
|
||||
version,
|
||||
len,
|
||||
tok2str(bfd_port_values, "unknown (%u)", port),
|
||||
tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6),
|
||||
bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f),
|
||||
tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)),
|
||||
BFD_EXTRACT_DIAG(bfd_header->version_diag)));
|
||||
|
||||
ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
|
||||
bfd_header->detect_time_multiplier,
|
||||
bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
|
||||
bfd_header->length));
|
||||
|
||||
|
||||
ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)));
|
||||
ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)));
|
||||
ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000));
|
||||
ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000));
|
||||
ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000));
|
||||
|
||||
if (bfd_header->flags & BFD_FLAG_AUTH) {
|
||||
if (auth_print(ndo, pptr))
|
||||
goto trunc;
|
||||
}
|
||||
break;
|
||||
|
||||
/* BFDv0 */
|
||||
case (BFD_ECHO_PORT << 8): /* not yet supported - fall through */
|
||||
/* BFDv1 */
|
||||
case (BFD_ECHO_PORT << 8 | 1):
|
||||
|
||||
default:
|
||||
ND_PRINT((ndo, "BFD, %s, length: %u",
|
||||
tok2str(bfd_port_values, "unknown (%u)", port),
|
||||
} else {
|
||||
/*
|
||||
* Unknown packet type.
|
||||
*/
|
||||
ND_PRINT((ndo, "BFD, unknown (%u), length: %u",
|
||||
port,
|
||||
len));
|
||||
if (ndo->ndo_vflag >= 1) {
|
||||
if(!print_unknown_data(ndo, pptr,"\n\t",len))
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include "af.h"
|
||||
#include "l2vpn.h"
|
||||
|
||||
static const char tstr[] = "[|BGP]";
|
||||
|
||||
struct bgp {
|
||||
uint8_t bgp_marker[16];
|
||||
uint16_t bgp_len;
|
||||
@ -1019,7 +1021,7 @@ trunc:
|
||||
*/
|
||||
#define UPDATE_BUF_BUFLEN(buf, buflen, stringlen) \
|
||||
if (stringlen<0) \
|
||||
buflen=0; \
|
||||
buflen=0; \
|
||||
else if ((u_int)stringlen>buflen) \
|
||||
buflen=0; \
|
||||
else { \
|
||||
@ -1365,7 +1367,7 @@ trunc:
|
||||
|
||||
static int
|
||||
bgp_attr_print(netdissect_options *ndo,
|
||||
u_int atype, const u_char *pptr, u_int len)
|
||||
u_int atype, const u_char *pptr, u_int len, const unsigned attr_set_level)
|
||||
{
|
||||
int i;
|
||||
uint16_t af;
|
||||
@ -1488,7 +1490,7 @@ bgp_attr_print(netdissect_options *ndo,
|
||||
}
|
||||
ND_TCHECK2(tptr[0], 8);
|
||||
ND_PRINT((ndo, " AS #%s, origin %s",
|
||||
as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
|
||||
as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
|
||||
ipaddr_string(ndo, tptr + 4)));
|
||||
break;
|
||||
case BGPTYPE_COMMUNITIES:
|
||||
@ -1704,10 +1706,12 @@ bgp_attr_print(netdissect_options *ndo,
|
||||
bgp_vpn_rd_print(ndo, tptr),
|
||||
isonsap_string(ndo, tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)));
|
||||
/* rfc986 mapped IPv4 address ? */
|
||||
if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601)
|
||||
if (tlen == BGP_VPN_RD_LEN + 4 + sizeof(struct in_addr)
|
||||
&& EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601)
|
||||
ND_PRINT((ndo, " = %s", ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN+4)));
|
||||
/* rfc1888 mapped IPv6 address ? */
|
||||
else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000)
|
||||
else if (tlen == BGP_VPN_RD_LEN + 3 + sizeof(struct in6_addr)
|
||||
&& EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000)
|
||||
ND_PRINT((ndo, " = %s", ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN+3)));
|
||||
tptr += tlen;
|
||||
tlen = 0;
|
||||
@ -2286,8 +2290,16 @@ bgp_attr_print(netdissect_options *ndo,
|
||||
ND_PRINT((ndo, "+%x", aflags & 0xf));
|
||||
ND_PRINT((ndo, "]: "));
|
||||
}
|
||||
/* FIXME check for recursion */
|
||||
if (!bgp_attr_print(ndo, atype, tptr, alen))
|
||||
/* The protocol encoding per se allows ATTR_SET to be nested as many times
|
||||
* as the message can accommodate. This printer used to be able to recurse
|
||||
* into ATTR_SET contents until the stack exhaustion, but now there is a
|
||||
* limit on that (if live protocol exchange goes that many levels deep,
|
||||
* something is probably wrong anyway). Feel free to refine this value if
|
||||
* you can find the spec with respective normative text.
|
||||
*/
|
||||
if (attr_set_level == 10)
|
||||
ND_PRINT((ndo, "(too many nested levels, not recursing)"));
|
||||
else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1))
|
||||
return 0;
|
||||
tptr += alen;
|
||||
len -= alen;
|
||||
@ -2348,6 +2360,8 @@ bgp_capabilities_print(netdissect_options *ndo,
|
||||
ND_TCHECK2(opt[i+2], cap_len);
|
||||
switch (cap_type) {
|
||||
case BGP_CAPCODE_MP:
|
||||
/* AFI (16 bits), Reserved (8 bits), SAFI (8 bits) */
|
||||
ND_TCHECK_8BITS(opt + i + 5);
|
||||
ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u)",
|
||||
tok2str(af_values, "Unknown",
|
||||
EXTRACT_16BITS(opt+i+2)),
|
||||
@ -2357,12 +2371,15 @@ bgp_capabilities_print(netdissect_options *ndo,
|
||||
opt[i+5]));
|
||||
break;
|
||||
case BGP_CAPCODE_RESTART:
|
||||
/* Restart Flags (4 bits), Restart Time in seconds (12 bits) */
|
||||
ND_TCHECK_16BITS(opt + i + 2);
|
||||
ND_PRINT((ndo, "\n\t\tRestart Flags: [%s], Restart Time %us",
|
||||
((opt[i+2])&0x80) ? "R" : "none",
|
||||
EXTRACT_16BITS(opt+i+2)&0xfff));
|
||||
tcap_len-=2;
|
||||
cap_offset=4;
|
||||
while(tcap_len>=4) {
|
||||
ND_TCHECK_8BITS(opt + i + cap_offset + 3);
|
||||
ND_PRINT((ndo, "\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
|
||||
tok2str(af_values,"Unknown",
|
||||
EXTRACT_16BITS(opt+i+cap_offset)),
|
||||
@ -2426,7 +2443,7 @@ bgp_capabilities_print(netdissect_options *ndo,
|
||||
return;
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[|BGP]"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2489,7 +2506,7 @@ bgp_open_print(netdissect_options *ndo,
|
||||
}
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[|BGP]"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2589,7 +2606,7 @@ bgp_update_print(netdissect_options *ndo,
|
||||
goto trunc;
|
||||
if (length < alen)
|
||||
goto trunc;
|
||||
if (!bgp_attr_print(ndo, atype, p, alen))
|
||||
if (!bgp_attr_print(ndo, atype, p, alen, 0))
|
||||
goto trunc;
|
||||
p += alen;
|
||||
len -= alen;
|
||||
@ -2626,7 +2643,7 @@ bgp_update_print(netdissect_options *ndo,
|
||||
}
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[|BGP]"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2707,7 +2724,7 @@ bgp_notification_print(netdissect_options *ndo,
|
||||
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[|BGP]"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2741,7 +2758,7 @@ bgp_route_refresh_print(netdissect_options *ndo,
|
||||
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[|BGP]"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2781,7 +2798,7 @@ bgp_header_print(netdissect_options *ndo,
|
||||
}
|
||||
return 1;
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[|BGP]"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2830,7 +2847,7 @@ bgp_print(netdissect_options *ndo,
|
||||
memcpy(&bgp, p, BGP_SIZE);
|
||||
|
||||
if (start != p)
|
||||
ND_PRINT((ndo, " [|BGP]"));
|
||||
ND_PRINT((ndo, " %s", tstr));
|
||||
|
||||
hlen = ntohs(bgp.bgp_len);
|
||||
if (hlen < BGP_SIZE) {
|
||||
@ -2856,7 +2873,7 @@ bgp_print(netdissect_options *ndo,
|
||||
return;
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo, " [|BGP]"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -364,7 +364,7 @@ bootp_print(netdissect_options *ndo,
|
||||
if (*bp->bp_sname) {
|
||||
ND_PRINT((ndo, "\n\t sname \""));
|
||||
if (fn_printztn(ndo, bp->bp_sname, (u_int)sizeof bp->bp_sname,
|
||||
ndo->ndo_snapend)) {
|
||||
ndo->ndo_snapend) == 0) {
|
||||
ND_PRINT((ndo, "\""));
|
||||
ND_PRINT((ndo, "%s", tstr + 1));
|
||||
return;
|
||||
@ -375,7 +375,7 @@ bootp_print(netdissect_options *ndo,
|
||||
if (*bp->bp_file) {
|
||||
ND_PRINT((ndo, "\n\t file \""));
|
||||
if (fn_printztn(ndo, bp->bp_file, (u_int)sizeof bp->bp_file,
|
||||
ndo->ndo_snapend)) {
|
||||
ndo->ndo_snapend) == 0) {
|
||||
ND_PRINT((ndo, "\""));
|
||||
ND_PRINT((ndo, "%s", tstr + 1));
|
||||
return;
|
||||
@ -384,7 +384,7 @@ bootp_print(netdissect_options *ndo,
|
||||
}
|
||||
|
||||
/* Decode the vendor buffer */
|
||||
ND_TCHECK(bp->bp_vend[0]);
|
||||
ND_TCHECK2(bp->bp_vend[0], 4);
|
||||
if (memcmp((const char *)bp->bp_vend, vm_rfc1048,
|
||||
sizeof(uint32_t)) == 0)
|
||||
rfc1048_print(ndo, bp->bp_vend);
|
||||
@ -394,6 +394,7 @@ bootp_print(netdissect_options *ndo,
|
||||
else {
|
||||
uint32_t ul;
|
||||
|
||||
ND_TCHECK_32BITS(&bp->bp_vend);
|
||||
ul = EXTRACT_32BITS(&bp->bp_vend);
|
||||
if (ul != 0)
|
||||
ND_PRINT((ndo, "\n\t Vendor-#0x%x", ul));
|
||||
|
@ -536,7 +536,8 @@ static const struct tok dccp_option_values[] = {
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen)
|
||||
static int
|
||||
dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen)
|
||||
{
|
||||
uint8_t optlen, i;
|
||||
|
||||
@ -629,16 +630,54 @@ static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_in
|
||||
}
|
||||
break;
|
||||
case 41:
|
||||
if (optlen == 4)
|
||||
/*
|
||||
* 13.1. Timestamp Option
|
||||
*
|
||||
* +--------+--------+--------+--------+--------+--------+
|
||||
* |00101001|00000110| Timestamp Value |
|
||||
* +--------+--------+--------+--------+--------+--------+
|
||||
* Type=41 Length=6
|
||||
*/
|
||||
if (optlen == 6)
|
||||
ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
|
||||
else
|
||||
ND_PRINT((ndo, " optlen != 4"));
|
||||
ND_PRINT((ndo, " [optlen != 6]"));
|
||||
break;
|
||||
case 42:
|
||||
if (optlen == 4)
|
||||
/*
|
||||
* 13.3. Timestamp Echo Option
|
||||
*
|
||||
* +--------+--------+--------+--------+--------+--------+
|
||||
* |00101010|00000110| Timestamp Echo |
|
||||
* +--------+--------+--------+--------+--------+--------+
|
||||
* Type=42 Len=6
|
||||
*
|
||||
* +--------+--------+------- ... -------+--------+--------+
|
||||
* |00101010|00001000| Timestamp Echo | Elapsed Time |
|
||||
* +--------+--------+------- ... -------+--------+--------+
|
||||
* Type=42 Len=8 (4 bytes)
|
||||
*
|
||||
* +--------+--------+------- ... -------+------- ... -------+
|
||||
* |00101010|00001010| Timestamp Echo | Elapsed Time |
|
||||
* +--------+--------+------- ... -------+------- ... -------+
|
||||
* Type=42 Len=10 (4 bytes) (4 bytes)
|
||||
*/
|
||||
switch (optlen) {
|
||||
case 6:
|
||||
ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
|
||||
else
|
||||
ND_PRINT((ndo, " optlen != 4"));
|
||||
break;
|
||||
case 8:
|
||||
ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
|
||||
ND_PRINT((ndo, " (elapsed time %u)", EXTRACT_16BITS(option + 6)));
|
||||
break;
|
||||
case 10:
|
||||
ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
|
||||
ND_PRINT((ndo, " (elapsed time %u)", EXTRACT_32BITS(option + 6)));
|
||||
break;
|
||||
default:
|
||||
ND_PRINT((ndo, " [optlen != 6 or 8 or 10]"));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 43:
|
||||
if (optlen == 6)
|
||||
@ -646,7 +685,7 @@ static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_in
|
||||
else if (optlen == 4)
|
||||
ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2)));
|
||||
else
|
||||
ND_PRINT((ndo, " optlen != 4 or 6"));
|
||||
ND_PRINT((ndo, " [optlen != 4 or 6]"));
|
||||
break;
|
||||
case 44:
|
||||
if (optlen > 2) {
|
||||
|
@ -36,10 +36,6 @@
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
|
||||
#ifdef HAVE_NETDNET_DNETDB_H
|
||||
#include <netdnet/dnetdb.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -81,12 +77,6 @@ typedef union etheraddress etheraddr; /* Ethernet address */
|
||||
#define AREASHIFT 10 /* bit-offset for area field */
|
||||
#define NODEMASK 01777 /* mask for node address field */
|
||||
|
||||
#define DN_MAXADDL 20 /* max size of DECnet address */
|
||||
struct dn_naddr {
|
||||
uint16_t a_len; /* length of address */
|
||||
uint8_t a_addr[DN_MAXADDL]; /* address as bytes */
|
||||
};
|
||||
|
||||
/*
|
||||
* Define long and short header formats.
|
||||
*/
|
||||
@ -498,10 +488,6 @@ static int print_elist(const char *, u_int);
|
||||
static int print_nsp(netdissect_options *, const u_char *, u_int);
|
||||
static void print_reason(netdissect_options *, int);
|
||||
|
||||
#ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA
|
||||
extern char *dnet_htoa(struct dn_naddr *);
|
||||
#endif
|
||||
|
||||
void
|
||||
decnet_print(netdissect_options *ndo,
|
||||
register const u_char *ap, register u_int length,
|
||||
@ -1258,25 +1244,6 @@ dnnum_string(netdissect_options *ndo, u_short dnaddr)
|
||||
snprintf(str, siz, "%d.%d", area, node);
|
||||
return(str);
|
||||
}
|
||||
|
||||
const char *
|
||||
dnname_string(netdissect_options *ndo, u_short dnaddr)
|
||||
{
|
||||
#ifdef HAVE_DNET_HTOA
|
||||
struct dn_naddr dna;
|
||||
char *dnname;
|
||||
|
||||
dna.a_len = sizeof(short);
|
||||
memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short));
|
||||
dnname = dnet_htoa(&dna);
|
||||
if(dnname != NULL)
|
||||
return (strdup(dnname));
|
||||
else
|
||||
return(dnnum_string(ndo, dnaddr));
|
||||
#else
|
||||
return(dnnum_string(ndo, dnaddr)); /* punt */
|
||||
#endif
|
||||
}
|
||||
#ifdef __rtems__
|
||||
#include "rtems-bsd-tcpdump-print-decnet-data.h"
|
||||
#endif /* __rtems__ */
|
||||
|
@ -588,6 +588,13 @@ ns_print(netdissect_options *ndo,
|
||||
register const u_char *cp;
|
||||
uint16_t b2;
|
||||
|
||||
if(length < sizeof(*np)) {
|
||||
ND_PRINT((ndo, "domain"));
|
||||
ND_PRINT((ndo, " [length %u < %zu]", length, sizeof(*np)));
|
||||
ND_PRINT((ndo, " (invalid)"));
|
||||
return;
|
||||
}
|
||||
|
||||
np = (const HEADER *)bp;
|
||||
ND_TCHECK(*np);
|
||||
/* get the byte-order right */
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "addrtoname.h"
|
||||
|
||||
/*
|
||||
* See: RFC 1075 and draft-ietf-idmr-dvmrp-v3
|
||||
*
|
||||
* DVMRP message types and flag values shamelessly stolen from
|
||||
* mrouted/dvmrp.h.
|
||||
*/
|
||||
@ -64,19 +66,18 @@
|
||||
static int print_probe(netdissect_options *, const u_char *, const u_char *, u_int);
|
||||
static int print_report(netdissect_options *, const u_char *, const u_char *, u_int);
|
||||
static int print_neighbors(netdissect_options *, const u_char *, const u_char *, u_int);
|
||||
static int print_neighbors2(netdissect_options *, const u_char *, const u_char *, u_int);
|
||||
static int print_neighbors2(netdissect_options *, const u_char *, const u_char *, u_int, uint8_t, uint8_t);
|
||||
static int print_prune(netdissect_options *, const u_char *);
|
||||
static int print_graft(netdissect_options *, const u_char *);
|
||||
static int print_graft_ack(netdissect_options *, const u_char *);
|
||||
|
||||
static uint32_t target_level;
|
||||
|
||||
void
|
||||
dvmrp_print(netdissect_options *ndo,
|
||||
register const u_char *bp, register u_int len)
|
||||
{
|
||||
register const u_char *ep;
|
||||
register u_char type;
|
||||
uint8_t major_version, minor_version;
|
||||
|
||||
ep = (const u_char *)ndo->ndo_snapend;
|
||||
if (bp >= ep)
|
||||
@ -124,15 +125,15 @@ dvmrp_print(netdissect_options *ndo,
|
||||
case DVMRP_NEIGHBORS2:
|
||||
ND_PRINT((ndo, " Neighbors2"));
|
||||
/*
|
||||
* extract version and capabilities from IGMP group
|
||||
* address field
|
||||
* extract version from IGMP group address field
|
||||
*/
|
||||
bp -= 4;
|
||||
ND_TCHECK2(bp[0], 4);
|
||||
target_level = (bp[0] << 24) | (bp[1] << 16) |
|
||||
(bp[2] << 8) | bp[3];
|
||||
major_version = *(bp + 3);
|
||||
minor_version = *(bp + 2);
|
||||
bp += 4;
|
||||
if (print_neighbors2(ndo, bp, ep, len) < 0)
|
||||
if (print_neighbors2(ndo, bp, ep, len, major_version,
|
||||
minor_version) < 0)
|
||||
goto trunc;
|
||||
break;
|
||||
|
||||
@ -236,7 +237,7 @@ print_probe(netdissect_options *ndo,
|
||||
ND_PRINT((ndo, " [|}"));
|
||||
return (0);
|
||||
}
|
||||
genid = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3];
|
||||
genid = EXTRACT_32BITS(bp);
|
||||
bp += 4;
|
||||
len -= 4;
|
||||
ND_PRINT((ndo, ndo->ndo_vflag > 1 ? "\n\t" : " "));
|
||||
@ -289,15 +290,14 @@ trunc:
|
||||
static int
|
||||
print_neighbors2(netdissect_options *ndo,
|
||||
register const u_char *bp, register const u_char *ep,
|
||||
register u_int len)
|
||||
register u_int len, uint8_t major_version,
|
||||
uint8_t minor_version)
|
||||
{
|
||||
const u_char *laddr;
|
||||
register u_char metric, thresh, flags;
|
||||
register int ncount;
|
||||
|
||||
ND_PRINT((ndo, " (v %d.%d):",
|
||||
(int)target_level & 0xff,
|
||||
(int)(target_level >> 8) & 0xff));
|
||||
ND_PRINT((ndo, " (v %d.%d):", major_version, minor_version));
|
||||
|
||||
while (len > 0 && bp < ep) {
|
||||
ND_TCHECK2(bp[0], 8);
|
||||
|
@ -359,6 +359,7 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
|
||||
}
|
||||
byte_length = (bit_length + 7) / 8; /* variable length encoding */
|
||||
memset(prefix, 0, 4);
|
||||
ND_TCHECK2(tlv_ptr.eigrp_tlv_ip_int->destination, byte_length);
|
||||
memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length);
|
||||
|
||||
ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ",
|
||||
@ -393,6 +394,7 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
|
||||
}
|
||||
byte_length = (bit_length + 7) / 8; /* variable length encoding */
|
||||
memset(prefix, 0, 4);
|
||||
ND_TCHECK2(tlv_ptr.eigrp_tlv_ip_ext->destination, byte_length);
|
||||
memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length);
|
||||
|
||||
ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ",
|
||||
|
@ -197,8 +197,8 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
|
||||
const u_char *iv;
|
||||
unsigned int len;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
unsigned int block_size, output_buffer_size;
|
||||
u_char *output_buffer;
|
||||
unsigned int block_size, buffer_size;
|
||||
u_char *input_buffer, *output_buffer;
|
||||
|
||||
/* initiator arg is any non-zero value */
|
||||
if(initiator) initiator=1;
|
||||
@ -233,19 +233,39 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
|
||||
(*ndo->ndo_warning)(ndo, "espkey init failed");
|
||||
set_cipher_parameters(ctx, NULL, NULL, iv, 0);
|
||||
/*
|
||||
* Allocate a buffer for the decrypted data.
|
||||
* The output buffer must be separate from the input buffer, and
|
||||
* its size must be a multiple of the cipher block size.
|
||||
* Allocate buffers for the encrypted and decrypted data.
|
||||
* Both buffers' sizes must be a multiple of the cipher block
|
||||
* size, and the output buffer must be separate from the input
|
||||
* buffer.
|
||||
*/
|
||||
block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
|
||||
output_buffer_size = len + (block_size - len % block_size);
|
||||
output_buffer = (u_char *)malloc(output_buffer_size);
|
||||
if (output_buffer == NULL) {
|
||||
(*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
|
||||
buffer_size = len + (block_size - len % block_size);
|
||||
|
||||
/*
|
||||
* Attempt to allocate the input buffer.
|
||||
*/
|
||||
input_buffer = (u_char *)malloc(buffer_size);
|
||||
if (input_buffer == NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return 0;
|
||||
(*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer");
|
||||
}
|
||||
EVP_Cipher(ctx, output_buffer, buf, len);
|
||||
/*
|
||||
* Copy the input data to the encrypted data buffer, and pad it
|
||||
* with zeroes.
|
||||
*/
|
||||
memcpy(input_buffer, buf, len);
|
||||
memset(input_buffer + len, 0, buffer_size - len);
|
||||
|
||||
/*
|
||||
* Attempt to allocate the output buffer.
|
||||
*/
|
||||
output_buffer = (u_char *)malloc(buffer_size);
|
||||
if (output_buffer == NULL) {
|
||||
free(input_buffer);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
(*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer");
|
||||
}
|
||||
EVP_Cipher(ctx, output_buffer, input_buffer, len);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
/*
|
||||
@ -253,6 +273,7 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
|
||||
* but changing this would require a more complicated fix.
|
||||
*/
|
||||
memcpy(__DECONST(u_char *, buf), output_buffer, len);
|
||||
free(input_buffer);
|
||||
free(output_buffer);
|
||||
|
||||
ndo->ndo_packetp = buf;
|
||||
@ -293,7 +314,6 @@ static u_int hexdigit(netdissect_options *ndo, char hex)
|
||||
return (hex - 'a' + 10);
|
||||
else {
|
||||
(*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,7 +424,7 @@ espprint_decode_encalgo(netdissect_options *ndo,
|
||||
USES_APPLE_RST
|
||||
|
||||
/*
|
||||
* for the moment, ignore the auth algorith, just hard code the authenticator
|
||||
* for the moment, ignore the auth algorithm, just hard code the authenticator
|
||||
* length. Need to research how openssl looks up HMAC stuff.
|
||||
*/
|
||||
static int
|
||||
@ -527,7 +547,6 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
|
||||
if (secretfile == NULL) {
|
||||
(*ndo->ndo_error)(ndo, "print_esp: can't open %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
|
||||
@ -557,6 +576,10 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
|
||||
uint32_t spino;
|
||||
|
||||
spistr = strsep(&spikey, "@");
|
||||
if (spistr == NULL) {
|
||||
(*ndo->ndo_warning)(ndo, "print_esp: failed to find the @ token");
|
||||
return;
|
||||
}
|
||||
|
||||
spino = strtoul(spistr, &foo, 0);
|
||||
if (spistr == foo || !spikey) {
|
||||
@ -669,8 +692,8 @@ esp_print(netdissect_options *ndo,
|
||||
const u_char *ivoff;
|
||||
const u_char *p;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
unsigned int block_size, output_buffer_size;
|
||||
u_char *output_buffer;
|
||||
unsigned int block_size, buffer_size;
|
||||
u_char *input_buffer, *output_buffer;
|
||||
#endif
|
||||
|
||||
esp = (const struct newesp *)bp;
|
||||
@ -786,21 +809,41 @@ esp_print(netdissect_options *ndo,
|
||||
len = ep - (p + ivlen);
|
||||
|
||||
/*
|
||||
* Allocate a buffer for the decrypted data.
|
||||
* The output buffer must be separate from the
|
||||
* input buffer, and its size must be a multiple
|
||||
* of the cipher block size.
|
||||
* Allocate buffers for the encrypted and decrypted
|
||||
* data. Both buffers' sizes must be a multiple of
|
||||
* the cipher block size, and the output buffer must
|
||||
* be separate from the input buffer.
|
||||
*/
|
||||
block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
|
||||
output_buffer_size = len + (block_size - len % block_size);
|
||||
output_buffer = (u_char *)malloc(output_buffer_size);
|
||||
if (output_buffer == NULL) {
|
||||
(*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
|
||||
buffer_size = len + (block_size - len % block_size);
|
||||
|
||||
/*
|
||||
* Attempt to allocate the input buffer.
|
||||
*/
|
||||
input_buffer = (u_char *)malloc(buffer_size);
|
||||
if (input_buffer == NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return -1;
|
||||
(*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer");
|
||||
}
|
||||
/*
|
||||
* Copy the input data to the encrypted data buffer,
|
||||
* and pad it with zeroes.
|
||||
*/
|
||||
memcpy(input_buffer, p + ivlen, len);
|
||||
memset(input_buffer + len, 0, buffer_size - len);
|
||||
|
||||
/*
|
||||
* Attempt to allocate the output buffer.
|
||||
*/
|
||||
output_buffer = (u_char *)malloc(buffer_size);
|
||||
if (output_buffer == NULL) {
|
||||
free(input_buffer);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
(*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer");
|
||||
}
|
||||
|
||||
EVP_Cipher(ctx, output_buffer, p + ivlen, len);
|
||||
EVP_Cipher(ctx, output_buffer, input_buffer, len);
|
||||
free(input_buffer);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
/*
|
||||
* XXX - of course this is wrong, because buf is a
|
||||
|
@ -463,6 +463,10 @@ mfr_print(netdissect_options *ndo,
|
||||
*/
|
||||
|
||||
ND_TCHECK2(*p, 4); /* minimum frame header length */
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "Message too short (%u bytes)", length));
|
||||
return length;
|
||||
}
|
||||
|
||||
if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) {
|
||||
ND_PRINT((ndo, "FRF.16 Control, Flags [%s], %s, length %u",
|
||||
@ -499,6 +503,11 @@ mfr_print(netdissect_options *ndo,
|
||||
switch (ie_type) {
|
||||
|
||||
case MFR_CTRL_IE_MAGIC_NUM:
|
||||
/* FRF.16.1 Section 3.4.3 Magic Number Information Element */
|
||||
if (ie_len != 4) {
|
||||
ND_PRINT((ndo, "(invalid length)"));
|
||||
break;
|
||||
}
|
||||
ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(tptr)));
|
||||
break;
|
||||
|
||||
|
@ -74,8 +74,8 @@ hncp_print(netdissect_options *ndo,
|
||||
#define HNCP_EXTERNAL_CONNECTION 33
|
||||
#define HNCP_DELEGATED_PREFIX 34
|
||||
#define HNCP_PREFIX_POLICY 43
|
||||
#define HNCP_DHCPV4_DATA 37
|
||||
#define HNCP_DHCPV6_DATA 38
|
||||
#define HNCP_DHCPV4_DATA 37 /* This is correct, see RFC 7788 Errata ID 5113. */
|
||||
#define HNCP_DHCPV6_DATA 38 /* idem */
|
||||
#define HNCP_ASSIGNED_PREFIX 35
|
||||
#define HNCP_NODE_ADDRESS 36
|
||||
#define HNCP_DNS_DELEGATED_ZONE 39
|
||||
@ -164,13 +164,13 @@ is_ipv4_mapped_address(const u_char *addr)
|
||||
static const char *
|
||||
format_nid(const u_char *data)
|
||||
{
|
||||
static char buf[4][11+5];
|
||||
static char buf[4][sizeof("01:01:01:01")];
|
||||
#ifdef __rtems__
|
||||
__section(".rtemsrwset.bsd_prog_tcpdump.content")
|
||||
#endif /* __rtems__ */
|
||||
static int i = 0;
|
||||
i = (i + 1) % 4;
|
||||
snprintf(buf[i], 16, "%02x:%02x:%02x:%02x",
|
||||
snprintf(buf[i], sizeof(buf[i]), "%02x:%02x:%02x:%02x",
|
||||
data[0], data[1], data[2], data[3]);
|
||||
return buf[i];
|
||||
}
|
||||
@ -178,13 +178,13 @@ format_nid(const u_char *data)
|
||||
static const char *
|
||||
format_256(const u_char *data)
|
||||
{
|
||||
static char buf[4][64+5];
|
||||
static char buf[4][sizeof("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")];
|
||||
#ifdef __rtems__
|
||||
__section(".rtemsrwset.bsd_prog_tcpdump.content")
|
||||
#endif /* __rtems__ */
|
||||
static int i = 0;
|
||||
i = (i + 1) % 4;
|
||||
snprintf(buf[i], 28, "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
|
||||
snprintf(buf[i], sizeof(buf[i]), "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
|
||||
EXTRACT_64BITS(data),
|
||||
EXTRACT_64BITS(data + 8),
|
||||
EXTRACT_64BITS(data + 16),
|
||||
@ -244,6 +244,8 @@ print_prefix(netdissect_options *ndo, const u_char *prefix, u_int max_length)
|
||||
plenbytes += 1 + IPV4_MAPPED_HEADING_LEN;
|
||||
} else {
|
||||
plenbytes = decode_prefix6(ndo, prefix, max_length, buf, sizeof(buf));
|
||||
if (plenbytes < 0)
|
||||
return plenbytes;
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, "%s", buf));
|
||||
|
@ -406,7 +406,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
|
||||
|
||||
default:
|
||||
(void)snprintf(buf, sizeof(buf),
|
||||
"%s protocol %d port %d unreachable",
|
||||
"%s protocol %u port %u unreachable",
|
||||
ipaddr_string(ndo, &oip->ip_dst),
|
||||
oip->ip_p, dport);
|
||||
break;
|
||||
@ -512,7 +512,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
|
||||
break;
|
||||
|
||||
default:
|
||||
(void)snprintf(buf, sizeof(buf), "time exceeded-#%d",
|
||||
(void)snprintf(buf, sizeof(buf), "time exceeded-#%u",
|
||||
dp->icmp_code);
|
||||
break;
|
||||
}
|
||||
@ -521,11 +521,11 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
|
||||
case ICMP_PARAMPROB:
|
||||
if (dp->icmp_code)
|
||||
(void)snprintf(buf, sizeof(buf),
|
||||
"parameter problem - code %d", dp->icmp_code);
|
||||
"parameter problem - code %u", dp->icmp_code);
|
||||
else {
|
||||
ND_TCHECK(dp->icmp_pptr);
|
||||
(void)snprintf(buf, sizeof(buf),
|
||||
"parameter problem - octet %d", dp->icmp_pptr);
|
||||
"parameter problem - octet %u", dp->icmp_pptr);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -563,13 +563,15 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
|
||||
}
|
||||
ND_PRINT((ndo, "ICMP %s, length %u", str, plen));
|
||||
if (ndo->ndo_vflag && !fragmented) { /* don't attempt checksumming if this is a frag */
|
||||
uint16_t sum, icmp_sum;
|
||||
|
||||
if (ND_TTEST2(*bp, plen)) {
|
||||
uint16_t sum;
|
||||
|
||||
vec[0].ptr = (const uint8_t *)(const void *)dp;
|
||||
vec[0].len = plen;
|
||||
sum = in_cksum(vec, 1);
|
||||
if (sum != 0) {
|
||||
uint16_t icmp_sum;
|
||||
ND_TCHECK_16BITS(&dp->icmp_cksum);
|
||||
icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum);
|
||||
ND_PRINT((ndo, " (wrong icmp cksum %x (->%x)!)",
|
||||
icmp_sum,
|
||||
|
@ -47,6 +47,10 @@
|
||||
#include "udp.h"
|
||||
#include "ah.h"
|
||||
|
||||
static const char icmp6_tstr[] = " [|icmp6]";
|
||||
static const char rpl_tstr[] = " [|rpl]";
|
||||
static const char mldv2_tstr[] = " [|mldv2]";
|
||||
|
||||
/* NetBSD: icmp6.h,v 1.13 2000/08/03 16:30:37 itojun Exp */
|
||||
/* $KAME: icmp6.h,v 1.22 2000/08/03 15:25:16 jinmei Exp $ */
|
||||
|
||||
@ -689,10 +693,11 @@ rpl_dio_printopt(netdissect_options *ndo,
|
||||
}
|
||||
opt = (const struct rpl_dio_genoption *)(((const char *)opt) + optlen);
|
||||
length -= optlen;
|
||||
ND_TCHECK(opt->rpl_dio_len);
|
||||
}
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo," [|truncated]"));
|
||||
ND_PRINT((ndo, "%s", rpl_tstr));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -721,7 +726,7 @@ rpl_dio_print(netdissect_options *ndo,
|
||||
}
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo," [|truncated]"));
|
||||
ND_PRINT((ndo, "%s", rpl_tstr));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -762,7 +767,7 @@ rpl_dao_print(netdissect_options *ndo,
|
||||
return;
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo," [|truncated]"));
|
||||
ND_PRINT((ndo, "%s", rpl_tstr));
|
||||
return;
|
||||
|
||||
tooshort:
|
||||
@ -806,7 +811,7 @@ rpl_daoack_print(netdissect_options *ndo,
|
||||
return;
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo," [|dao-truncated]"));
|
||||
ND_PRINT((ndo, "%s", rpl_tstr));
|
||||
return;
|
||||
|
||||
tooshort:
|
||||
@ -865,7 +870,7 @@ rpl_print(netdissect_options *ndo,
|
||||
|
||||
#if 0
|
||||
trunc:
|
||||
ND_PRINT((ndo," [|truncated]"));
|
||||
ND_PRINT((ndo, "%s", rpl_tstr));
|
||||
return;
|
||||
#endif
|
||||
|
||||
@ -1040,7 +1045,7 @@ icmp6_print(netdissect_options *ndo,
|
||||
p = (const struct nd_router_advert *)dp;
|
||||
ND_TCHECK(p->nd_ra_retransmit);
|
||||
ND_PRINT((ndo,"\n\thop limit %u, Flags [%s]" \
|
||||
", pref %s, router lifetime %us, reachable time %us, retrans time %us",
|
||||
", pref %s, router lifetime %us, reachable time %ums, retrans timer %ums",
|
||||
(u_int)p->nd_ra_curhoplimit,
|
||||
bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)),
|
||||
get_rtpref(p->nd_ra_flags_reserved),
|
||||
@ -1163,7 +1168,7 @@ icmp6_print(netdissect_options *ndo,
|
||||
ND_PRINT((ndo,", length %u", length));
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[|icmp6]"));
|
||||
ND_PRINT((ndo, "%s", icmp6_tstr));
|
||||
}
|
||||
|
||||
static const struct udphdr *
|
||||
@ -1387,8 +1392,8 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid)
|
||||
}
|
||||
return;
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[ndp opt]"));
|
||||
trunc:
|
||||
ND_PRINT((ndo, "%s", icmp6_tstr));
|
||||
return;
|
||||
#undef ECHECK
|
||||
}
|
||||
@ -1463,7 +1468,7 @@ mldv2_report_print(netdissect_options *ndo, const u_char *bp, u_int len)
|
||||
}
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo,"[|icmp6]"));
|
||||
ND_PRINT((ndo, "%s", mldv2_tstr));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1529,7 +1534,7 @@ mldv2_query_print(netdissect_options *ndo, const u_char *bp, u_int len)
|
||||
ND_PRINT((ndo,"]"));
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo,"[|icmp6]"));
|
||||
ND_PRINT((ndo, "%s", mldv2_tstr));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1816,7 +1821,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp,
|
||||
return;
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo, "[|icmp6]"));
|
||||
ND_PRINT((ndo, "%s", icmp6_tstr));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1951,7 +1956,7 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep)
|
||||
return;
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo,"[|icmp6]"));
|
||||
ND_PRINT((ndo, "%s", icmp6_tstr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -13,16 +13,19 @@
|
||||
#include <netdissect-stdinc.h>
|
||||
|
||||
#include "netdissect.h"
|
||||
#include "extract.h"
|
||||
|
||||
static const char tstr[] = "[|ipnet]";
|
||||
|
||||
typedef struct ipnet_hdr {
|
||||
uint8_t iph_version;
|
||||
uint8_t iph_family;
|
||||
uint16_t iph_htype;
|
||||
uint32_t iph_pktlen;
|
||||
uint32_t iph_ifindex;
|
||||
uint32_t iph_grifindex;
|
||||
uint32_t iph_zsrc;
|
||||
uint32_t iph_zdst;
|
||||
nd_uint8_t iph_version;
|
||||
nd_uint8_t iph_family;
|
||||
nd_uint16_t iph_htype;
|
||||
nd_uint32_t iph_pktlen;
|
||||
nd_uint32_t iph_ifindex;
|
||||
nd_uint32_t iph_grifindex;
|
||||
nd_uint32_t iph_zsrc;
|
||||
nd_uint32_t iph_zdst;
|
||||
} ipnet_hdr_t;
|
||||
|
||||
#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */
|
||||
@ -42,21 +45,26 @@ ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length)
|
||||
const ipnet_hdr_t *hdr;
|
||||
hdr = (const ipnet_hdr_t *)bp;
|
||||
|
||||
ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst));
|
||||
ND_TCHECK(*hdr);
|
||||
ND_PRINT((ndo, "%d > %d", EXTRACT_32BITS(hdr->iph_zsrc),
|
||||
EXTRACT_32BITS(hdr->iph_zdst)));
|
||||
|
||||
if (!ndo->ndo_qflag) {
|
||||
ND_PRINT((ndo,", family %s (%d)",
|
||||
tok2str(ipnet_values, "Unknown",
|
||||
hdr->iph_family),
|
||||
hdr->iph_family));
|
||||
EXTRACT_8BITS(&hdr->iph_family)),
|
||||
EXTRACT_8BITS(&hdr->iph_family)));
|
||||
} else {
|
||||
ND_PRINT((ndo,", %s",
|
||||
tok2str(ipnet_values,
|
||||
"Unknown Ethertype (0x%04x)",
|
||||
hdr->iph_family)));
|
||||
EXTRACT_8BITS(&hdr->iph_family))));
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, ", length %u: ", length));
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo, " %s", tstr));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -64,10 +72,8 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
|
||||
{
|
||||
const ipnet_hdr_t *hdr;
|
||||
|
||||
if (caplen < sizeof(ipnet_hdr_t)) {
|
||||
ND_PRINT((ndo, "[|ipnet]"));
|
||||
return;
|
||||
}
|
||||
if (caplen < sizeof(ipnet_hdr_t))
|
||||
goto trunc;
|
||||
|
||||
if (ndo->ndo_eflag)
|
||||
ipnet_hdr_print(ndo, p, length);
|
||||
@ -77,7 +83,8 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
|
||||
hdr = (const ipnet_hdr_t *)p;
|
||||
p += sizeof(ipnet_hdr_t);
|
||||
|
||||
switch (hdr->iph_family) {
|
||||
ND_TCHECK2(hdr->iph_family, 1);
|
||||
switch (EXTRACT_8BITS(&hdr->iph_family)) {
|
||||
|
||||
case IPH_AF_INET:
|
||||
ip_print(ndo, p, length);
|
||||
@ -96,6 +103,9 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
|
||||
ND_DEFAULTPRINT(p, caplen);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo, " %s", tstr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1779,6 +1779,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
|
||||
}
|
||||
case IPSECDOI_NTYPE_REPLAY_STATUS:
|
||||
ND_PRINT((ndo," status=("));
|
||||
ND_TCHECK_32BITS(cp);
|
||||
ND_PRINT((ndo,"replay detection %sabled",
|
||||
EXTRACT_32BITS(cp) ? "en" : "dis"));
|
||||
ND_PRINT((ndo,")"));
|
||||
|
@ -1360,6 +1360,11 @@ juniper_parse_header(netdissect_options *ndo,
|
||||
lp->s,
|
||||
l2info->cookie_len));
|
||||
|
||||
if (l2info->cookie_len > 8) {
|
||||
ND_PRINT((ndo, " (invalid)"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (l2info->cookie_len > 0) {
|
||||
ND_TCHECK2(p[0], l2info->cookie_len);
|
||||
if (ndo->ndo_eflag)
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
/* \summary: Layer Two Tunneling Protocol (L2TP) printer */
|
||||
|
||||
/* specification: RFC 2661 */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
@ -149,7 +151,7 @@ static const struct tok l2tp_msgtype2str[] = {
|
||||
#define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */
|
||||
#define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */
|
||||
#define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */
|
||||
#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code */
|
||||
#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code - RFC 3145 */
|
||||
|
||||
static const struct tok l2tp_avp2str[] = {
|
||||
{ L2TP_AVP_MSGTYPE, "MSGTYPE" },
|
||||
@ -288,15 +290,15 @@ print_octets(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
}
|
||||
|
||||
static void
|
||||
print_16bits_val(netdissect_options *ndo, const uint16_t *dat)
|
||||
print_16bits_val(netdissect_options *ndo, const uint8_t *dat)
|
||||
{
|
||||
ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat)));
|
||||
}
|
||||
|
||||
static void
|
||||
print_32bits_val(netdissect_options *ndo, const uint32_t *dat)
|
||||
print_32bits_val(netdissect_options *ndo, const uint8_t *dat)
|
||||
{
|
||||
ND_PRINT((ndo, "%lu", (u_long)EXTRACT_32BITS(dat)));
|
||||
ND_PRINT((ndo, "%u", EXTRACT_32BITS(dat)));
|
||||
}
|
||||
|
||||
/***********************************/
|
||||
@ -305,28 +307,24 @@ print_32bits_val(netdissect_options *ndo, const uint32_t *dat)
|
||||
static void
|
||||
l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint16_t *ptr = (const uint16_t *)dat;
|
||||
|
||||
if (length < 2) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
|
||||
EXTRACT_16BITS(ptr))));
|
||||
EXTRACT_16BITS(dat))));
|
||||
}
|
||||
|
||||
static void
|
||||
l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint16_t *ptr = (const uint16_t *)dat;
|
||||
|
||||
/* Result Code */
|
||||
if (length < 2) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr)));
|
||||
ptr++;
|
||||
ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat)));
|
||||
dat += 2;
|
||||
length -= 2;
|
||||
|
||||
/* Error Code (opt) */
|
||||
@ -336,19 +334,19 @@ l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
ND_PRINT((ndo, " AVP too short"));
|
||||
return;
|
||||
}
|
||||
ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr)));
|
||||
ptr++;
|
||||
ND_PRINT((ndo, "/%u", EXTRACT_16BITS(dat)));
|
||||
dat += 2;
|
||||
length -= 2;
|
||||
|
||||
/* Error Message (opt) */
|
||||
if (length == 0)
|
||||
return;
|
||||
ND_PRINT((ndo, " "));
|
||||
print_string(ndo, (const u_char *)ptr, length);
|
||||
print_string(ndo, dat, length);
|
||||
}
|
||||
|
||||
static void
|
||||
l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length)
|
||||
l2tp_proto_ver_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
if (length < 2) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
@ -361,16 +359,14 @@ l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length)
|
||||
static void
|
||||
l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint32_t *ptr = (const uint32_t *)dat;
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) {
|
||||
if (EXTRACT_32BITS(dat) & L2TP_FRAMING_CAP_ASYNC_MASK) {
|
||||
ND_PRINT((ndo, "A"));
|
||||
}
|
||||
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_SYNC_MASK) {
|
||||
if (EXTRACT_32BITS(dat) & L2TP_FRAMING_CAP_SYNC_MASK) {
|
||||
ND_PRINT((ndo, "S"));
|
||||
}
|
||||
}
|
||||
@ -378,16 +374,14 @@ l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
static void
|
||||
l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint32_t *ptr = (const uint32_t *)dat;
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) {
|
||||
if (EXTRACT_32BITS(dat) & L2TP_BEARER_CAP_ANALOG_MASK) {
|
||||
ND_PRINT((ndo, "A"));
|
||||
}
|
||||
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_DIGITAL_MASK) {
|
||||
if (EXTRACT_32BITS(dat) & L2TP_BEARER_CAP_DIGITAL_MASK) {
|
||||
ND_PRINT((ndo, "D"));
|
||||
}
|
||||
}
|
||||
@ -399,8 +393,8 @@ l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
print_16bits_val(ndo, (const uint16_t *)dat);
|
||||
ND_PRINT((ndo, ", %02x", dat[2]));
|
||||
print_16bits_val(ndo, dat);
|
||||
ND_PRINT((ndo, ", %02x", EXTRACT_8BITS(dat + 2)));
|
||||
dat += 3;
|
||||
length -= 3;
|
||||
if (length != 0) {
|
||||
@ -412,16 +406,14 @@ l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
static void
|
||||
l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint32_t *ptr = (const uint32_t *)dat;
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) {
|
||||
if (EXTRACT_32BITS(dat) & L2TP_BEARER_TYPE_ANALOG_MASK) {
|
||||
ND_PRINT((ndo, "A"));
|
||||
}
|
||||
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_DIGITAL_MASK) {
|
||||
if (EXTRACT_32BITS(dat) & L2TP_BEARER_TYPE_DIGITAL_MASK) {
|
||||
ND_PRINT((ndo, "D"));
|
||||
}
|
||||
}
|
||||
@ -429,16 +421,14 @@ l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
static void
|
||||
l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint32_t *ptr = (const uint32_t *)dat;
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
|
||||
if (EXTRACT_32BITS(dat) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
|
||||
ND_PRINT((ndo, "A"));
|
||||
}
|
||||
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_SYNC_MASK) {
|
||||
if (EXTRACT_32BITS(dat) & L2TP_FRAMING_TYPE_SYNC_MASK) {
|
||||
ND_PRINT((ndo, "S"));
|
||||
}
|
||||
}
|
||||
@ -452,125 +442,109 @@ l2tp_packet_proc_delay_print(netdissect_options *ndo)
|
||||
static void
|
||||
l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint16_t *ptr = (const uint16_t *)dat;
|
||||
|
||||
if (length < 2) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str,
|
||||
"AuthType-#%u", EXTRACT_16BITS(ptr))));
|
||||
"AuthType-#%u", EXTRACT_16BITS(dat))));
|
||||
}
|
||||
|
||||
static void
|
||||
l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint16_t *ptr = (const uint16_t *)dat;
|
||||
|
||||
if (length < 2) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK));
|
||||
ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat) & L2TP_PROXY_AUTH_ID_MASK));
|
||||
}
|
||||
|
||||
static void
|
||||
l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint16_t *ptr = (const uint16_t *)dat;
|
||||
uint16_t val_h, val_l;
|
||||
uint32_t val;
|
||||
|
||||
if (length < 2) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
ptr++; /* skip "Reserved" */
|
||||
dat += 2; /* skip "Reserved" */
|
||||
length -= 2;
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l));
|
||||
val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
|
||||
ND_PRINT((ndo, "CRCErr=%u ", val));
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l));
|
||||
val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
|
||||
ND_PRINT((ndo, "FrameErr=%u ", val));
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l));
|
||||
val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
|
||||
ND_PRINT((ndo, "HardOver=%u ", val));
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l));
|
||||
val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
|
||||
ND_PRINT((ndo, "BufOver=%u ", val));
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l));
|
||||
val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
|
||||
ND_PRINT((ndo, "Timeout=%u ", val));
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
val_h = EXTRACT_16BITS(ptr); ptr++;
|
||||
val_l = EXTRACT_16BITS(ptr); ptr++;
|
||||
ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l));
|
||||
val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
|
||||
ND_PRINT((ndo, "AlignErr=%u ", val));
|
||||
}
|
||||
|
||||
static void
|
||||
l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint16_t *ptr = (const uint16_t *)dat;
|
||||
uint16_t val_h, val_l;
|
||||
uint32_t val;
|
||||
|
||||
if (length < 2) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
ptr++; /* skip "Reserved" */
|
||||
dat += 2; /* skip "Reserved" */
|
||||
length -= 2;
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
|
||||
ND_PRINT((ndo, "send=%08x ", (val_h<<16) + val_l));
|
||||
val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
|
||||
ND_PRINT((ndo, "send=%08x ", val));
|
||||
|
||||
if (length < 4) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
}
|
||||
val_h = EXTRACT_16BITS(ptr); ptr++;
|
||||
val_l = EXTRACT_16BITS(ptr); ptr++;
|
||||
ND_PRINT((ndo, "recv=%08x ", (val_h<<16) + val_l));
|
||||
val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
|
||||
ND_PRINT((ndo, "recv=%08x ", val));
|
||||
}
|
||||
|
||||
static void
|
||||
l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
const uint16_t *ptr = (const uint16_t *)dat;
|
||||
|
||||
if (length < 5) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
return;
|
||||
@ -585,32 +559,27 @@ l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int lengt
|
||||
length -= 2;
|
||||
/* Direction */
|
||||
ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str,
|
||||
"Direction-#%u", EXTRACT_8BITS(ptr))));
|
||||
ptr++;
|
||||
"Direction-#%u", EXTRACT_8BITS(dat))));
|
||||
dat++;
|
||||
length--;
|
||||
|
||||
if (length != 0) {
|
||||
ND_PRINT((ndo, " "));
|
||||
print_string(ndo, (const u_char *)ptr, length);
|
||||
print_string(ndo, (const u_char *)dat, length);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
static u_int
|
||||
l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
{
|
||||
u_int len;
|
||||
const uint16_t *ptr = (const uint16_t *)dat;
|
||||
uint16_t attr_type;
|
||||
int hidden = FALSE;
|
||||
|
||||
if (length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, " "));
|
||||
|
||||
ND_TCHECK(*ptr); /* Flags & Length */
|
||||
len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK;
|
||||
ND_TCHECK_16BITS(dat); /* Flags & Length */
|
||||
len = EXTRACT_16BITS(dat) & L2TP_AVP_HDR_LEN_MASK;
|
||||
|
||||
/* If it is not long enough to contain the header, we'll give up. */
|
||||
if (len < 6)
|
||||
@ -623,7 +592,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
|
||||
/* If it goes past the end of the remaining length of the captured
|
||||
data, we'll give up. */
|
||||
ND_TCHECK2(*ptr, len);
|
||||
ND_TCHECK2(*dat, len);
|
||||
|
||||
/*
|
||||
* After this point, we don't need to check whether we go past
|
||||
@ -631,26 +600,26 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
* check whether we go past the end of the AVP.
|
||||
*/
|
||||
|
||||
if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
|
||||
if (EXTRACT_16BITS(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) {
|
||||
ND_PRINT((ndo, "*"));
|
||||
}
|
||||
if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
|
||||
if (EXTRACT_16BITS(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) {
|
||||
hidden = TRUE;
|
||||
ND_PRINT((ndo, "?"));
|
||||
}
|
||||
ptr++;
|
||||
dat += 2;
|
||||
|
||||
if (EXTRACT_16BITS(ptr)) {
|
||||
if (EXTRACT_16BITS(dat)) {
|
||||
/* Vendor Specific Attribute */
|
||||
ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(ptr))); ptr++;
|
||||
ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(ptr))); ptr++;
|
||||
ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(dat))); dat += 2;
|
||||
ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(dat))); dat += 2;
|
||||
ND_PRINT((ndo, "("));
|
||||
print_octets(ndo, (const u_char *)ptr, len-6);
|
||||
print_octets(ndo, dat, len-6);
|
||||
ND_PRINT((ndo, ")"));
|
||||
} else {
|
||||
/* IETF-defined Attributes */
|
||||
ptr++;
|
||||
attr_type = EXTRACT_16BITS(ptr); ptr++;
|
||||
dat += 2;
|
||||
attr_type = EXTRACT_16BITS(dat); dat += 2;
|
||||
ND_PRINT((ndo, "%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type)));
|
||||
ND_PRINT((ndo, "("));
|
||||
if (hidden) {
|
||||
@ -658,26 +627,26 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
} else {
|
||||
switch (attr_type) {
|
||||
case L2TP_AVP_MSGTYPE:
|
||||
l2tp_msgtype_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_msgtype_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_RESULT_CODE:
|
||||
l2tp_result_code_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_result_code_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_PROTO_VER:
|
||||
l2tp_proto_ver_print(ndo, ptr, len-6);
|
||||
l2tp_proto_ver_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_FRAMING_CAP:
|
||||
l2tp_framing_cap_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_framing_cap_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_BEARER_CAP:
|
||||
l2tp_bearer_cap_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_bearer_cap_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_TIE_BREAKER:
|
||||
if (len-6 < 8) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
break;
|
||||
}
|
||||
print_octets(ndo, (const u_char *)ptr, 8);
|
||||
print_octets(ndo, dat, 8);
|
||||
break;
|
||||
case L2TP_AVP_FIRM_VER:
|
||||
case L2TP_AVP_ASSND_TUN_ID:
|
||||
@ -687,7 +656,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
break;
|
||||
}
|
||||
print_16bits_val(ndo, ptr);
|
||||
print_16bits_val(ndo, dat);
|
||||
break;
|
||||
case L2TP_AVP_HOST_NAME:
|
||||
case L2TP_AVP_VENDOR_NAME:
|
||||
@ -696,7 +665,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
case L2TP_AVP_SUB_ADDRESS:
|
||||
case L2TP_AVP_PROXY_AUTH_NAME:
|
||||
case L2TP_AVP_PRIVATE_GRP_ID:
|
||||
print_string(ndo, (const u_char *)ptr, len-6);
|
||||
print_string(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_CHALLENGE:
|
||||
case L2TP_AVP_INI_RECV_LCP:
|
||||
@ -705,17 +674,17 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
case L2TP_AVP_PROXY_AUTH_CHAL:
|
||||
case L2TP_AVP_PROXY_AUTH_RESP:
|
||||
case L2TP_AVP_RANDOM_VECTOR:
|
||||
print_octets(ndo, (const u_char *)ptr, len-6);
|
||||
print_octets(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_Q931_CC:
|
||||
l2tp_q931_cc_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_q931_cc_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_CHALLENGE_RESP:
|
||||
if (len-6 < 16) {
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
break;
|
||||
}
|
||||
print_octets(ndo, (const u_char *)ptr, 16);
|
||||
print_octets(ndo, dat, 16);
|
||||
break;
|
||||
case L2TP_AVP_CALL_SER_NUM:
|
||||
case L2TP_AVP_MINIMUM_BPS:
|
||||
@ -727,33 +696,33 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
ND_PRINT((ndo, "AVP too short"));
|
||||
break;
|
||||
}
|
||||
print_32bits_val(ndo, (const uint32_t *)ptr);
|
||||
print_32bits_val(ndo, dat);
|
||||
break;
|
||||
case L2TP_AVP_BEARER_TYPE:
|
||||
l2tp_bearer_type_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_bearer_type_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_FRAMING_TYPE:
|
||||
l2tp_framing_type_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_framing_type_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_PACKET_PROC_DELAY:
|
||||
l2tp_packet_proc_delay_print(ndo);
|
||||
break;
|
||||
case L2TP_AVP_PROXY_AUTH_TYPE:
|
||||
l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_proxy_auth_type_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_PROXY_AUTH_ID:
|
||||
l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_proxy_auth_id_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_CALL_ERRORS:
|
||||
l2tp_call_errors_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_call_errors_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_ACCM:
|
||||
l2tp_accm_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_accm_print(ndo, dat, len-6);
|
||||
break;
|
||||
case L2TP_AVP_SEQ_REQUIRED:
|
||||
break; /* No Attribute Value */
|
||||
case L2TP_AVP_PPP_DISCON_CC:
|
||||
l2tp_ppp_discon_cc_print(ndo, (const u_char *)ptr, len-6);
|
||||
l2tp_ppp_discon_cc_print(ndo, dat, len-6);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -762,11 +731,11 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
|
||||
ND_PRINT((ndo, ")"));
|
||||
}
|
||||
|
||||
l2tp_avp_print(ndo, dat+len, length-len);
|
||||
return;
|
||||
return (len);
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo, "|..."));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@ -871,7 +840,22 @@ l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length)
|
||||
if (length - cnt == 0) {
|
||||
ND_PRINT((ndo, " ZLB"));
|
||||
} else {
|
||||
l2tp_avp_print(ndo, ptr, length - cnt);
|
||||
/*
|
||||
* Print AVPs.
|
||||
*/
|
||||
while (length - cnt != 0) {
|
||||
u_int avp_length;
|
||||
|
||||
avp_length = l2tp_avp_print(ndo, ptr, length - cnt);
|
||||
if (avp_length == 0) {
|
||||
/*
|
||||
* Truncated.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
cnt += avp_length;
|
||||
ptr += avp_length;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ND_PRINT((ndo, " {"));
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include "l2vpn.h"
|
||||
#include "af.h"
|
||||
|
||||
static const char tstr[] = " [|LDP]";
|
||||
|
||||
/*
|
||||
* ldp common header
|
||||
*
|
||||
@ -216,7 +218,7 @@ static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = {
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
static int ldp_pdu_print(netdissect_options *, register const u_char *);
|
||||
static u_int ldp_pdu_print(netdissect_options *, register const u_char *);
|
||||
|
||||
/*
|
||||
* ldp tlv header
|
||||
@ -441,19 +443,24 @@ ldp_tlv_print(netdissect_options *ndo,
|
||||
|
||||
switch(vc_info_tlv_type) {
|
||||
case LDP_FEC_MARTINI_IFPARM_MTU:
|
||||
ND_TCHECK_16BITS(tptr + 2);
|
||||
ND_PRINT((ndo, ": %u", EXTRACT_16BITS(tptr+2)));
|
||||
break;
|
||||
|
||||
case LDP_FEC_MARTINI_IFPARM_DESC:
|
||||
ND_PRINT((ndo, ": "));
|
||||
for (idx = 2; idx < vc_info_tlv_len; idx++)
|
||||
for (idx = 2; idx < vc_info_tlv_len; idx++) {
|
||||
ND_TCHECK_8BITS(tptr + idx);
|
||||
safeputchar(ndo, *(tptr + idx));
|
||||
}
|
||||
break;
|
||||
|
||||
case LDP_FEC_MARTINI_IFPARM_VCCV:
|
||||
ND_TCHECK_8BITS(tptr + 2);
|
||||
ND_PRINT((ndo, "\n\t\t Control Channels (0x%02x) = [%s]",
|
||||
*(tptr+2),
|
||||
bittok2str(ldp_fec_martini_ifparm_vccv_cc_values, "none", *(tptr+2))));
|
||||
ND_TCHECK_8BITS(tptr + 3);
|
||||
ND_PRINT((ndo, "\n\t\t CV Types (0x%02x) = [%s]",
|
||||
*(tptr+3),
|
||||
bittok2str(ldp_fec_martini_ifparm_vccv_cv_values, "none", *(tptr+3))));
|
||||
@ -492,7 +499,7 @@ ldp_tlv_print(netdissect_options *ndo,
|
||||
break;
|
||||
|
||||
case LDP_TLV_FT_SESSION:
|
||||
TLV_TCHECK(8);
|
||||
TLV_TCHECK(12);
|
||||
ft_flags = EXTRACT_16BITS(tptr);
|
||||
ND_PRINT((ndo, "\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
|
||||
ft_flags&0x8000 ? "" : "No ",
|
||||
@ -500,6 +507,7 @@ ldp_tlv_print(netdissect_options *ndo,
|
||||
ft_flags&0x4 ? "" : "No ",
|
||||
ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
|
||||
ft_flags&0x1 ? "" : "Don't "));
|
||||
/* 16 bits (FT Flags) + 16 bits (Reserved) */
|
||||
tptr+=4;
|
||||
ui = EXTRACT_32BITS(tptr);
|
||||
if (ui)
|
||||
@ -540,7 +548,7 @@ ldp_tlv_print(netdissect_options *ndo,
|
||||
return(tlv_len+4); /* Type & Length fields not included */
|
||||
|
||||
trunc:
|
||||
ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
return 0;
|
||||
|
||||
badtlv:
|
||||
@ -552,17 +560,23 @@ void
|
||||
ldp_print(netdissect_options *ndo,
|
||||
register const u_char *pptr, register u_int len)
|
||||
{
|
||||
int processed;
|
||||
u_int processed;
|
||||
while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) {
|
||||
processed = ldp_pdu_print(ndo, pptr);
|
||||
if (processed == 0)
|
||||
return;
|
||||
if (len < processed) {
|
||||
ND_PRINT((ndo, " [remaining length %u < %u]", len, processed));
|
||||
ND_PRINT((ndo, "%s", istr));
|
||||
break;
|
||||
|
||||
}
|
||||
len -= processed;
|
||||
pptr += processed;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
static u_int
|
||||
ldp_pdu_print(netdissect_options *ndo,
|
||||
register const u_char *pptr)
|
||||
{
|
||||
@ -692,7 +706,7 @@ ldp_pdu_print(netdissect_options *ndo,
|
||||
}
|
||||
return pdu_len+4;
|
||||
trunc:
|
||||
ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "addrtoname.h"
|
||||
#include "gmpls.h"
|
||||
|
||||
static const char tstr[] = " [|LMP]";
|
||||
|
||||
/*
|
||||
* LMP common header
|
||||
*
|
||||
@ -373,8 +375,9 @@ lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
|
||||
} bw;
|
||||
|
||||
while (total_subobj_len > 0 && hexdump == FALSE ) {
|
||||
subobj_type = EXTRACT_8BITS(obj_tptr+offset);
|
||||
subobj_len = EXTRACT_8BITS(obj_tptr+offset+1);
|
||||
ND_TCHECK_16BITS(obj_tptr + offset);
|
||||
subobj_type = EXTRACT_8BITS(obj_tptr + offset);
|
||||
subobj_len = EXTRACT_8BITS(obj_tptr + offset + 1);
|
||||
ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u",
|
||||
tok2str(lmp_data_link_subobj,
|
||||
"Unknown",
|
||||
@ -395,24 +398,29 @@ lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
|
||||
}
|
||||
switch(subobj_type) {
|
||||
case INT_SWITCHING_TYPE_SUBOBJ:
|
||||
ND_TCHECK_8BITS(obj_tptr + offset + 2);
|
||||
ND_PRINT((ndo, "\n\t Switching Type: %s (%u)",
|
||||
tok2str(gmpls_switch_cap_values,
|
||||
"Unknown",
|
||||
EXTRACT_8BITS(obj_tptr+offset+2)),
|
||||
EXTRACT_8BITS(obj_tptr+offset+2)));
|
||||
EXTRACT_8BITS(obj_tptr + offset + 2)),
|
||||
EXTRACT_8BITS(obj_tptr + offset + 2)));
|
||||
ND_TCHECK_8BITS(obj_tptr + offset + 3);
|
||||
ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)",
|
||||
tok2str(gmpls_encoding_values,
|
||||
"Unknown",
|
||||
EXTRACT_8BITS(obj_tptr+offset+3)),
|
||||
EXTRACT_8BITS(obj_tptr+offset+3)));
|
||||
EXTRACT_8BITS(obj_tptr + offset + 3)),
|
||||
EXTRACT_8BITS(obj_tptr + offset + 3)));
|
||||
ND_TCHECK_32BITS(obj_tptr + offset + 4);
|
||||
bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
|
||||
ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps",
|
||||
bw.f*8/1000000));
|
||||
ND_TCHECK_32BITS(obj_tptr + offset + 8);
|
||||
bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
|
||||
ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps",
|
||||
bw.f*8/1000000));
|
||||
break;
|
||||
case WAVELENGTH_SUBOBJ:
|
||||
ND_TCHECK_32BITS(obj_tptr + offset + 4);
|
||||
ND_PRINT((ndo, "\n\t Wavelength: %u",
|
||||
EXTRACT_32BITS(obj_tptr+offset+4)));
|
||||
break;
|
||||
@ -425,6 +433,8 @@ lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
|
||||
offset+=subobj_len;
|
||||
}
|
||||
return (hexdump);
|
||||
trunc:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
@ -435,7 +445,7 @@ lmp_print(netdissect_options *ndo,
|
||||
const struct lmp_object_header *lmp_obj_header;
|
||||
const u_char *tptr,*obj_tptr;
|
||||
u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
|
||||
int hexdump;
|
||||
int hexdump, ret;
|
||||
u_int offset;
|
||||
u_int link_type;
|
||||
|
||||
@ -737,7 +747,10 @@ lmp_print(netdissect_options *ndo,
|
||||
ipaddr_string(ndo, obj_tptr+8),
|
||||
EXTRACT_32BITS(obj_tptr+8)));
|
||||
|
||||
if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
|
||||
ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12);
|
||||
if (ret == -1)
|
||||
goto trunc;
|
||||
if (ret == TRUE)
|
||||
hexdump=TRUE;
|
||||
break;
|
||||
|
||||
@ -757,7 +770,10 @@ lmp_print(netdissect_options *ndo,
|
||||
ip6addr_string(ndo, obj_tptr+20),
|
||||
EXTRACT_32BITS(obj_tptr+20)));
|
||||
|
||||
if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36))
|
||||
ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36);
|
||||
if (ret == -1)
|
||||
goto trunc;
|
||||
if (ret == TRUE)
|
||||
hexdump=TRUE;
|
||||
break;
|
||||
|
||||
@ -777,7 +793,10 @@ lmp_print(netdissect_options *ndo,
|
||||
EXTRACT_32BITS(obj_tptr+8),
|
||||
EXTRACT_32BITS(obj_tptr+8)));
|
||||
|
||||
if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
|
||||
ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12);
|
||||
if (ret == -1)
|
||||
goto trunc;
|
||||
if (ret == TRUE)
|
||||
hexdump=TRUE;
|
||||
break;
|
||||
|
||||
@ -1018,7 +1037,7 @@ lmp_print(netdissect_options *ndo,
|
||||
EXTRACT_8BITS(obj_tptr))));
|
||||
|
||||
ND_PRINT((ndo, "\n\t UNI Version: %u",
|
||||
EXTRACT_8BITS(obj_tptr+1)));
|
||||
EXTRACT_8BITS(obj_tptr + 1)));
|
||||
|
||||
break;
|
||||
|
||||
@ -1040,28 +1059,28 @@ lmp_print(netdissect_options *ndo,
|
||||
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
|
||||
tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
|
||||
"Unknown",
|
||||
EXTRACT_8BITS(obj_tptr+1)),
|
||||
EXTRACT_8BITS(obj_tptr+1)));
|
||||
EXTRACT_8BITS(obj_tptr + 1)),
|
||||
EXTRACT_8BITS(obj_tptr + 1)));
|
||||
break;
|
||||
|
||||
case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET:
|
||||
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
|
||||
tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
|
||||
"Unknown",
|
||||
EXTRACT_8BITS(obj_tptr+1)),
|
||||
EXTRACT_8BITS(obj_tptr+1)));
|
||||
EXTRACT_8BITS(obj_tptr + 1)),
|
||||
EXTRACT_8BITS(obj_tptr + 1)));
|
||||
break;
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, "\n\t Transparency: %s",
|
||||
bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
|
||||
"none",
|
||||
EXTRACT_8BITS(obj_tptr+2))));
|
||||
EXTRACT_8BITS(obj_tptr + 2))));
|
||||
|
||||
ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s",
|
||||
bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
|
||||
"none",
|
||||
EXTRACT_8BITS(obj_tptr+3))));
|
||||
EXTRACT_8BITS(obj_tptr + 3))));
|
||||
|
||||
ND_PRINT((ndo, "\n\t Minimum NCC: %u",
|
||||
EXTRACT_16BITS(obj_tptr+4)));
|
||||
@ -1097,7 +1116,7 @@ lmp_print(netdissect_options *ndo,
|
||||
bittok2str(
|
||||
lmp_obj_service_config_nsa_tcm_flag_values,
|
||||
"none",
|
||||
EXTRACT_8BITS(obj_tptr+7))));
|
||||
EXTRACT_8BITS(obj_tptr + 7))));
|
||||
|
||||
break;
|
||||
|
||||
@ -1111,7 +1130,7 @@ lmp_print(netdissect_options *ndo,
|
||||
bittok2str(
|
||||
lmp_obj_service_config_nsa_network_diversity_flag_values,
|
||||
"none",
|
||||
EXTRACT_8BITS(obj_tptr+3))));
|
||||
EXTRACT_8BITS(obj_tptr + 3))));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1135,7 +1154,7 @@ lmp_print(netdissect_options *ndo,
|
||||
}
|
||||
return;
|
||||
trunc:
|
||||
ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
|
@ -1574,8 +1574,8 @@ interp_reply(netdissect_options *ndo,
|
||||
tok2str(nfsv3_writemodes,
|
||||
NULL, EXTRACT_32BITS(&dp[1]))));
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (parseattrstat(ndo, dp, ndo->ndo_vflag, v3) != 0)
|
||||
return;
|
||||
@ -1661,8 +1661,8 @@ interp_reply(netdissect_options *ndo,
|
||||
ND_PRINT((ndo, " dir:"));
|
||||
if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag)))
|
||||
break;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (parsestatus(ndo, dp, &er) != NULL)
|
||||
return;
|
||||
|
@ -138,13 +138,11 @@ trunc:
|
||||
/* Print a TCP segment worth of OpenFlow messages presuming the segment begins
|
||||
* on a message boundary. */
|
||||
void
|
||||
openflow_print(netdissect_options *ndo, const u_char *cp, const u_int len)
|
||||
openflow_print(netdissect_options *ndo, const u_char *cp, const u_int len _U_)
|
||||
{
|
||||
const u_char *ep = cp + len;
|
||||
|
||||
ND_PRINT((ndo, ": OpenFlow"));
|
||||
while (cp < ep)
|
||||
cp = of_header_body_print(ndo, cp, ep);
|
||||
while (cp < ndo->ndo_snapend)
|
||||
cp = of_header_body_print(ndo, cp, ndo->ndo_snapend);
|
||||
}
|
||||
#ifdef __rtems__
|
||||
#include "rtems-bsd-tcpdump-print-openflow-data.h"
|
||||
|
@ -712,7 +712,7 @@ ospf_print_lsa(netdissect_options *ndo,
|
||||
while ((const u_char *)lp < ls_end) {
|
||||
register uint32_t ul;
|
||||
|
||||
ND_TCHECK(*lp);
|
||||
ND_TCHECK_32BITS(lp);
|
||||
ul = EXTRACT_32BITS(lp);
|
||||
topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
|
||||
ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d",
|
||||
@ -729,7 +729,7 @@ ospf_print_lsa(netdissect_options *ndo,
|
||||
while ((const u_char *)lp < ls_end) {
|
||||
register uint32_t ul;
|
||||
|
||||
ND_TCHECK(*lp);
|
||||
ND_TCHECK_32BITS(lp);
|
||||
ul = EXTRACT_32BITS(lp);
|
||||
topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
|
||||
ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d",
|
||||
|
@ -395,8 +395,7 @@ ospf6_print_lshdr(netdissect_options *ndo,
|
||||
{
|
||||
if ((const u_char *)(lshp + 1) > dataend)
|
||||
goto trunc;
|
||||
ND_TCHECK(lshp->ls_type);
|
||||
ND_TCHECK(lshp->ls_seq);
|
||||
ND_TCHECK(lshp->ls_length); /* last field of struct lsa6_hdr */
|
||||
|
||||
ND_PRINT((ndo, "\n\t Advertising Router %s, seq 0x%08x, age %us, length %u",
|
||||
ipaddr_string(ndo, &lshp->ls_router),
|
||||
|
@ -103,8 +103,12 @@ pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
|
||||
else
|
||||
ND_PRINT((ndo, "rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr));
|
||||
|
||||
ND_PRINT((ndo, "%s: %s %s on %s: ",
|
||||
tok2str(pf_reasons, "unkn(%u)", hdr->reason),
|
||||
ND_PRINT((ndo, "%s", tok2str(pf_reasons, "unkn(%u)", hdr->reason)));
|
||||
|
||||
if (hdr->uid != UID_MAX)
|
||||
ND_PRINT((ndo, " [uid %u]", (unsigned)hdr->uid));
|
||||
|
||||
ND_PRINT((ndo, ": %s %s on %s: ",
|
||||
tok2str(pf_actions, "unkn(%u)", hdr->action),
|
||||
tok2str(pf_directions, "unkn(%u)", hdr->dir),
|
||||
hdr->ifname));
|
||||
|
@ -74,6 +74,7 @@ ppi_print(netdissect_options *ndo,
|
||||
}
|
||||
|
||||
hdr = (const ppi_header_t *)p;
|
||||
ND_TCHECK_16BITS(&hdr->ppi_len);
|
||||
len = EXTRACT_LE_16BITS(&hdr->ppi_len);
|
||||
if (caplen < len) {
|
||||
/*
|
||||
@ -87,6 +88,7 @@ ppi_print(netdissect_options *ndo,
|
||||
ND_PRINT((ndo, "[|ppi]"));
|
||||
return (len);
|
||||
}
|
||||
ND_TCHECK_32BITS(&hdr->ppi_dlt);
|
||||
dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt);
|
||||
|
||||
if (ndo->ndo_eflag)
|
||||
@ -110,6 +112,8 @@ ppi_print(netdissect_options *ndo,
|
||||
hdrlen = 0;
|
||||
}
|
||||
return (len + hdrlen);
|
||||
trunc:
|
||||
return (caplen);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -505,6 +505,7 @@ rsvp_intserv_print(netdissect_options *ndo,
|
||||
|
||||
if (obj_tlen < 4)
|
||||
return 0;
|
||||
ND_TCHECK_8BITS(tptr);
|
||||
parameter_id = *(tptr);
|
||||
ND_TCHECK2(*(tptr + 2), 2);
|
||||
parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */
|
||||
@ -1560,6 +1561,7 @@ rsvp_obj_print(netdissect_options *ndo,
|
||||
case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */
|
||||
switch(rsvp_obj_ctype) {
|
||||
case RSVP_CTYPE_1:
|
||||
ND_TCHECK_32BITS(obj_tptr);
|
||||
ND_PRINT((ndo, "%s CT: %u",
|
||||
ident,
|
||||
EXTRACT_32BITS(obj_tptr) & 0x7));
|
||||
|
@ -700,7 +700,7 @@ rx_cache_insert(netdissect_options *ndo,
|
||||
UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t));
|
||||
UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t));
|
||||
rxent->dport = dport;
|
||||
rxent->serviceId = EXTRACT_32BITS(&rxh->serviceId);
|
||||
rxent->serviceId = EXTRACT_16BITS(&rxh->serviceId);
|
||||
rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
|
||||
}
|
||||
|
||||
@ -731,7 +731,7 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,
|
||||
if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) &&
|
||||
rxent->client.s_addr == clip &&
|
||||
rxent->server.s_addr == sip &&
|
||||
rxent->serviceId == EXTRACT_32BITS(&rxh->serviceId) &&
|
||||
rxent->serviceId == EXTRACT_16BITS(&rxh->serviceId) &&
|
||||
rxent->dport == sport) {
|
||||
|
||||
/* We got a match! */
|
||||
@ -1025,6 +1025,7 @@ fs_print(netdissect_options *ndo,
|
||||
}
|
||||
if (j == 0)
|
||||
ND_PRINT((ndo, " <none!>"));
|
||||
break;
|
||||
}
|
||||
case 65537: /* Fetch data 64 */
|
||||
FIDOUT();
|
||||
@ -1285,6 +1286,7 @@ cb_print(netdissect_options *ndo,
|
||||
bp += sizeof(int32_t);
|
||||
tok2str(cb_types, "type %d", t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 214: {
|
||||
ND_PRINT((ndo, " afsuuid"));
|
||||
@ -1746,6 +1748,7 @@ vldb_reply_print(netdissect_options *ndo,
|
||||
INTOUT();
|
||||
ND_PRINT((ndo, " nextindex"));
|
||||
INTOUT();
|
||||
/*FALLTHROUGH*/
|
||||
case 503: /* Get entry by id */
|
||||
case 504: /* Get entry by name */
|
||||
{ unsigned long nservers, j;
|
||||
@ -1795,6 +1798,7 @@ vldb_reply_print(netdissect_options *ndo,
|
||||
INTOUT();
|
||||
ND_PRINT((ndo, " nextindex"));
|
||||
INTOUT();
|
||||
/*FALLTHROUGH*/
|
||||
case 518: /* Get entry by ID N */
|
||||
case 519: /* Get entry by name N */
|
||||
{ unsigned long nservers, j;
|
||||
|
@ -887,6 +887,14 @@ sflow_print(netdissect_options *ndo,
|
||||
tptr = pptr;
|
||||
tlen = len;
|
||||
sflow_datagram = (const struct sflow_datagram_t *)pptr;
|
||||
if (len < sizeof(struct sflow_datagram_t)) {
|
||||
ND_TCHECK(sflow_datagram->version);
|
||||
ND_PRINT((ndo, "sFlowv%u", EXTRACT_32BITS(sflow_datagram->version)));
|
||||
ND_PRINT((ndo, " [length %u < %zu]",
|
||||
len, sizeof(struct sflow_datagram_t)));
|
||||
ND_PRINT((ndo, " (invalid)"));
|
||||
return;
|
||||
}
|
||||
ND_TCHECK(*sflow_datagram);
|
||||
|
||||
/*
|
||||
@ -922,6 +930,8 @@ sflow_print(netdissect_options *ndo,
|
||||
|
||||
/* skip Common header */
|
||||
tptr += sizeof(const struct sflow_datagram_t);
|
||||
|
||||
if(tlen <= sizeof(const struct sflow_datagram_t)) goto trunc;
|
||||
tlen -= sizeof(const struct sflow_datagram_t);
|
||||
|
||||
while (nsamples > 0 && tlen > 0) {
|
||||
|
@ -58,8 +58,8 @@ static const char tstr[] = "[|slip]";
|
||||
static u_int lastlen[2][256];
|
||||
static u_int lastconn = 255;
|
||||
|
||||
static void sliplink_print(netdissect_options *, const u_char *, const struct ip *, u_int);
|
||||
static void compressed_sl_print(netdissect_options *, const u_char *, const struct ip *, u_int, int);
|
||||
static int sliplink_print(netdissect_options *, const u_char *, const struct ip *, u_int);
|
||||
static int compressed_sl_print(netdissect_options *, const u_char *, const struct ip *, u_int, int);
|
||||
|
||||
u_int
|
||||
sl_if_print(netdissect_options *ndo,
|
||||
@ -80,7 +80,10 @@ sl_if_print(netdissect_options *ndo,
|
||||
ip = (const struct ip *)(p + SLIP_HDRLEN);
|
||||
|
||||
if (ndo->ndo_eflag)
|
||||
sliplink_print(ndo, p, ip, length);
|
||||
if (sliplink_print(ndo, p, ip, length) == -1) {
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
return (caplen + SLIP_HDRLEN);
|
||||
}
|
||||
|
||||
if (caplen < 1 || length < 1) {
|
||||
ND_PRINT((ndo, "%s", tstr));
|
||||
@ -128,7 +131,7 @@ sl_bsdos_if_print(netdissect_options *ndo,
|
||||
return (SLIP_HDRLEN);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
sliplink_print(netdissect_options *ndo,
|
||||
register const u_char *p, register const struct ip *ip,
|
||||
register u_int length)
|
||||
@ -159,7 +162,7 @@ sliplink_print(netdissect_options *ndo,
|
||||
for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i)
|
||||
ND_PRINT((ndo, "%02x.", p[i]));
|
||||
ND_PRINT((ndo, "%02x: ", p[SLX_CHDR + CHDR_LEN - 1]));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
switch (p[SLX_CHDR] & 0xf0) {
|
||||
|
||||
@ -177,9 +180,11 @@ sliplink_print(netdissect_options *ndo,
|
||||
ND_PRINT((ndo, "utcp %d: ", lastconn));
|
||||
if (dir == -1) {
|
||||
/* Direction is bogus, don't use it */
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
ND_TCHECK(*ip);
|
||||
hlen = IP_HL(ip);
|
||||
ND_TCHECK(*((const struct tcphdr *)&((const int *)ip)[hlen]));
|
||||
hlen += TH_OFF((const struct tcphdr *)&((const int *)ip)[hlen]);
|
||||
lastlen[dir][lastconn] = length - (hlen << 2);
|
||||
break;
|
||||
@ -187,15 +192,19 @@ sliplink_print(netdissect_options *ndo,
|
||||
default:
|
||||
if (dir == -1) {
|
||||
/* Direction is bogus, don't use it */
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
|
||||
compressed_sl_print(ndo, &p[SLX_CHDR], ip,
|
||||
length, dir);
|
||||
if (compressed_sl_print(ndo, &p[SLX_CHDR], ip,
|
||||
length, dir) == -1)
|
||||
goto trunc;
|
||||
ND_PRINT((ndo, ": "));
|
||||
} else
|
||||
ND_PRINT((ndo, "slip-%d!: ", p[SLX_CHDR]));
|
||||
}
|
||||
return 0;
|
||||
trunc:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const u_char *
|
||||
@ -229,7 +238,7 @@ print_sl_winchange(netdissect_options *ndo,
|
||||
return (cp);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
compressed_sl_print(netdissect_options *ndo,
|
||||
const u_char *chdr, const struct ip *ip,
|
||||
u_int length, int dir)
|
||||
@ -275,10 +284,15 @@ compressed_sl_print(netdissect_options *ndo,
|
||||
* 'cp - chdr' is the length of the compressed header.
|
||||
* 'length - hlen' is the amount of data in the packet.
|
||||
*/
|
||||
ND_TCHECK(*ip);
|
||||
hlen = IP_HL(ip);
|
||||
ND_TCHECK(*((const struct tcphdr *)&((const int32_t *)ip)[hlen]));
|
||||
hlen += TH_OFF((const struct tcphdr *)&((const int32_t *)ip)[hlen]);
|
||||
lastlen[dir][lastconn] = length - (hlen << 2);
|
||||
ND_PRINT((ndo, " %d (%ld)", lastlen[dir][lastconn], (long)(cp - chdr)));
|
||||
return 0;
|
||||
trunc:
|
||||
return -1;
|
||||
}
|
||||
#ifdef __rtems__
|
||||
#include "rtems-bsd-tcpdump-print-sl-data.h"
|
||||
|
@ -204,6 +204,7 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
|
||||
u_int caplen = h->caplen;
|
||||
u_int length = h->len;
|
||||
register const struct sll_header *sllp;
|
||||
u_short hatype;
|
||||
u_short ether_type;
|
||||
int llc_hdrlen;
|
||||
u_int hdrlen;
|
||||
@ -231,6 +232,16 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
|
||||
p += SLL_HDR_LEN;
|
||||
hdrlen = SLL_HDR_LEN;
|
||||
|
||||
hatype = EXTRACT_16BITS(&sllp->sll_hatype);
|
||||
switch (hatype) {
|
||||
|
||||
case 803:
|
||||
/*
|
||||
* This is an packet with a radiotap header;
|
||||
* just dissect the payload as such.
|
||||
*/
|
||||
return (SLL_HDR_LEN + ieee802_11_radio_print(ndo, p, length, caplen));
|
||||
}
|
||||
ether_type = EXTRACT_16BITS(&sllp->sll_protocol);
|
||||
|
||||
recurse:
|
||||
|
@ -383,16 +383,21 @@ print_trans(netdissect_options *ndo,
|
||||
ND_PRINT((ndo, "smb_bcc=%u\n", bcc));
|
||||
if (bcc > 0) {
|
||||
smb_fdata(ndo, data1 + 2, f2, maxbuf - (paramlen + datalen), unicodestr);
|
||||
|
||||
if (strcmp((const char *)(data1 + 2), "\\MAILSLOT\\BROWSE") == 0) {
|
||||
#define MAILSLOT_BROWSE_STR "\\MAILSLOT\\BROWSE"
|
||||
ND_TCHECK2(*(data1 + 2), strlen(MAILSLOT_BROWSE_STR) + 1);
|
||||
if (strcmp((const char *)(data1 + 2), MAILSLOT_BROWSE_STR) == 0) {
|
||||
print_browse(ndo, param, paramlen, data, datalen);
|
||||
return;
|
||||
}
|
||||
#undef MAILSLOT_BROWSE_STR
|
||||
|
||||
if (strcmp((const char *)(data1 + 2), "\\PIPE\\LANMAN") == 0) {
|
||||
#define PIPE_LANMAN_STR "\\PIPE\\LANMAN"
|
||||
ND_TCHECK2(*(data1 + 2), strlen(PIPE_LANMAN_STR) + 1);
|
||||
if (strcmp((const char *)(data1 + 2), PIPE_LANMAN_STR) == 0) {
|
||||
print_ipc(ndo, param, paramlen, data, datalen);
|
||||
return;
|
||||
}
|
||||
#undef PIPE_LANMAN_STR
|
||||
|
||||
if (paramlen)
|
||||
smb_fdata(ndo, param, f3, min(param + paramlen, maxbuf), unicodestr);
|
||||
@ -952,7 +957,9 @@ nbt_tcp_print(netdissect_options *ndo,
|
||||
if (caplen < 4)
|
||||
goto trunc;
|
||||
maxbuf = data + caplen;
|
||||
ND_TCHECK_8BITS(data);
|
||||
type = data[0];
|
||||
ND_TCHECK_16BITS(data + 2);
|
||||
nbt_len = EXTRACT_16BITS(data + 2);
|
||||
length -= 4;
|
||||
caplen -= 4;
|
||||
|
@ -273,11 +273,11 @@ tcp_print(netdissect_options *ndo,
|
||||
if (rev) {
|
||||
UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst);
|
||||
UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src);
|
||||
tha.port = dport << 16 | sport;
|
||||
tha.port = ((u_int)dport) << 16 | sport;
|
||||
} else {
|
||||
UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst);
|
||||
UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src);
|
||||
tha.port = sport << 16 | dport;
|
||||
tha.port = ((u_int)sport) << 16 | dport;
|
||||
}
|
||||
|
||||
for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
|
||||
@ -324,11 +324,11 @@ tcp_print(netdissect_options *ndo,
|
||||
if (rev) {
|
||||
UNALIGNED_MEMCPY(&tha.src, &ip->ip_dst, sizeof ip->ip_dst);
|
||||
UNALIGNED_MEMCPY(&tha.dst, &ip->ip_src, sizeof ip->ip_src);
|
||||
tha.port = dport << 16 | sport;
|
||||
tha.port = ((u_int)dport) << 16 | sport;
|
||||
} else {
|
||||
UNALIGNED_MEMCPY(&tha.dst, &ip->ip_dst, sizeof ip->ip_dst);
|
||||
UNALIGNED_MEMCPY(&tha.src, &ip->ip_src, sizeof ip->ip_src);
|
||||
tha.port = sport << 16 | dport;
|
||||
tha.port = ((u_int)sport) << 16 | dport;
|
||||
}
|
||||
|
||||
for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
|
||||
@ -720,6 +720,12 @@ tcp_print(netdissect_options *ndo,
|
||||
rtsp_print(ndo, bp, length);
|
||||
} else if (length > 2 &&
|
||||
(IS_SRC_OR_DST_PORT(NAMESERVER_PORT))) {
|
||||
/* domain_print() assumes it does not have to prepend a space before its
|
||||
* own output to separate it from the output of the calling function. This
|
||||
* works well with udp_print(), but requires a small prop here.
|
||||
*/
|
||||
ND_PRINT((ndo, " "));
|
||||
|
||||
/*
|
||||
* TCP DNS query has 2byte length at the head.
|
||||
* XXX packet could be unaligned, it can go strange
|
||||
|
@ -427,7 +427,9 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length,
|
||||
|
||||
if (ndo->ndo_packettype) {
|
||||
register const struct sunrpc_msg *rp;
|
||||
#ifndef __rtems__
|
||||
enum sunrpc_msg_type direction;
|
||||
#endif /* __rtems__ */
|
||||
|
||||
switch (ndo->ndo_packettype) {
|
||||
|
||||
@ -443,8 +445,8 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length,
|
||||
|
||||
case PT_RPC:
|
||||
rp = (const struct sunrpc_msg *)(up + 1);
|
||||
direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
|
||||
#ifndef __rtems__
|
||||
direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
|
||||
if (direction == SUNRPC_CALL)
|
||||
sunrpcrequest_print(ndo, (const u_char *)rp, length,
|
||||
(const u_char *)ip);
|
||||
|
@ -148,17 +148,21 @@ vrrp_print(netdissect_options *ndo,
|
||||
|
||||
vec[0].ptr = bp;
|
||||
vec[0].len = len;
|
||||
if (in_cksum(vec, 1))
|
||||
if (in_cksum(vec, 1)) {
|
||||
ND_TCHECK_16BITS(&bp[6]);
|
||||
ND_PRINT((ndo, ", (bad vrrp cksum %x)",
|
||||
EXTRACT_16BITS(&bp[6])));
|
||||
}
|
||||
}
|
||||
|
||||
if (version == 3 && ND_TTEST2(bp[0], len)) {
|
||||
uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp,
|
||||
len, len, IPPROTO_VRRP);
|
||||
if (cksum)
|
||||
if (cksum) {
|
||||
ND_TCHECK_16BITS(&bp[6]);
|
||||
ND_PRINT((ndo, ", (bad vrrp cksum %x)",
|
||||
EXTRACT_16BITS(&bp[6])));
|
||||
}
|
||||
}
|
||||
|
||||
ND_PRINT((ndo, ", addrs"));
|
||||
|
@ -247,7 +247,7 @@ vtp_print (netdissect_options *ndo,
|
||||
*/
|
||||
|
||||
tptr += 4;
|
||||
while (tptr < (pptr+length)) {
|
||||
while ((unsigned)(tptr - pptr) < length) {
|
||||
|
||||
ND_TCHECK_8BITS(tptr);
|
||||
len = *tptr;
|
||||
|
@ -209,7 +209,7 @@ wb_id(netdissect_options *ndo,
|
||||
len -= sizeof(*io) * nid;
|
||||
io = (const struct id_off *)(id + 1);
|
||||
cp = (const char *)(io + nid);
|
||||
if (ND_TTEST2(cp, len)) {
|
||||
if (ND_TTEST2(*cp, len)) {
|
||||
ND_PRINT((ndo, "\""));
|
||||
fn_print(ndo, (const u_char *)cp, (const u_char *)cp + len);
|
||||
ND_PRINT((ndo, "\""));
|
||||
|
@ -65,6 +65,7 @@
|
||||
#define ieee802_11_if_print _bsd_tcpdump_ieee802_11_if_print
|
||||
#define ieee802_11_radio_avs_if_print _bsd_tcpdump_ieee802_11_radio_avs_if_print
|
||||
#define ieee802_11_radio_if_print _bsd_tcpdump_ieee802_11_radio_if_print
|
||||
#define ieee802_11_radio_print _bsd_tcpdump_ieee802_11_radio_print
|
||||
#define prism_if_print _bsd_tcpdump_prism_if_print
|
||||
/* print-802_15_4.c */
|
||||
#define ieee802_15_4_if_print _bsd_tcpdump_ieee802_15_4_if_print
|
||||
@ -138,7 +139,6 @@
|
||||
#define dccp_print _bsd_tcpdump_dccp_print
|
||||
/* print-decnet.c */
|
||||
#define decnet_print _bsd_tcpdump_decnet_print
|
||||
#define dnname_string _bsd_tcpdump_dnname_string
|
||||
#define dnnum_string _bsd_tcpdump_dnnum_string
|
||||
/* print-dhcp6.c */
|
||||
#define dhcp6_print _bsd_tcpdump_dhcp6_print
|
||||
|
@ -2,4 +2,3 @@
|
||||
#include <rtems/linkersets.h>
|
||||
#include "rtems-bsd-tcpdump-data.h"
|
||||
/* print-dvmrp.c */
|
||||
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static uint32_t target_level);
|
||||
|
@ -2,4 +2,3 @@
|
||||
#include <rtems/linkersets.h>
|
||||
#include "rtems-bsd-tcpdump-data.h"
|
||||
/* print-pim.c */
|
||||
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int pimv2_addr_len);
|
||||
|
@ -136,7 +136,7 @@ signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen,
|
||||
/*
|
||||
* Do we have all the packet data to be checked?
|
||||
*/
|
||||
if (!ND_TTEST2(pptr, plen)) {
|
||||
if (!ND_TTEST2(*pptr, plen)) {
|
||||
/* No. */
|
||||
return (CANT_CHECK_SIGNATURE);
|
||||
}
|
||||
@ -144,7 +144,7 @@ signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen,
|
||||
/*
|
||||
* Do we have the entire signature to check?
|
||||
*/
|
||||
if (!ND_TTEST2(sig_ptr, sizeof(sig))) {
|
||||
if (!ND_TTEST2(*sig_ptr, sizeof(sig))) {
|
||||
/* No. */
|
||||
return (CANT_CHECK_SIGNATURE);
|
||||
}
|
||||
|
@ -484,12 +484,13 @@ smb_fdata1(netdissect_options *ndo,
|
||||
|
||||
case 'P':
|
||||
{
|
||||
int l = atoi(fmt + 1);
|
||||
int l = atoi(fmt + 1);
|
||||
if(l <= 0) goto trunc; /* actually error in fmt string */
|
||||
ND_TCHECK2(buf[0], l);
|
||||
buf += l;
|
||||
fmt++;
|
||||
while (isdigit((unsigned char)*fmt))
|
||||
fmt++;
|
||||
fmt++;
|
||||
break;
|
||||
}
|
||||
case 'r':
|
||||
@ -803,17 +804,33 @@ smb_fdata(netdissect_options *ndo,
|
||||
int unicodestr)
|
||||
{
|
||||
static int depth = 0;
|
||||
const u_char *buf_start = buf;
|
||||
char s[128];
|
||||
char *p;
|
||||
|
||||
while (*fmt) {
|
||||
switch (*fmt) {
|
||||
case '*':
|
||||
/*
|
||||
* List of multiple instances of something described by the
|
||||
* remainder of the string (which may itself include a list
|
||||
* of multiple instances of something, so we recurse).
|
||||
*/
|
||||
fmt++;
|
||||
while (buf < maxbuf) {
|
||||
const u_char *buf2;
|
||||
depth++;
|
||||
buf2 = smb_fdata(ndo, buf, fmt, maxbuf, unicodestr);
|
||||
/*
|
||||
* In order to avoid stack exhaustion recurse at most 10
|
||||
* levels; that "should not happen", as no SMB structure
|
||||
* should be nested *that* deeply, and we thus shouldn't
|
||||
* have format strings with that level of nesting.
|
||||
*/
|
||||
if (depth == 10) {
|
||||
ND_PRINT((ndo, "(too many nested levels, not recursing)"));
|
||||
buf2 = buf;
|
||||
} else
|
||||
buf2 = smb_fdata(ndo, buf, fmt, maxbuf, unicodestr);
|
||||
depth--;
|
||||
if (buf2 == NULL)
|
||||
return(NULL);
|
||||
@ -824,22 +841,35 @@ smb_fdata(netdissect_options *ndo,
|
||||
return(buf);
|
||||
|
||||
case '|':
|
||||
/*
|
||||
* Just do a bounds check.
|
||||
*/
|
||||
fmt++;
|
||||
if (buf >= maxbuf)
|
||||
return(buf);
|
||||
break;
|
||||
|
||||
case '%':
|
||||
/*
|
||||
* XXX - unused?
|
||||
*/
|
||||
fmt++;
|
||||
buf = maxbuf;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
/*
|
||||
* Done?
|
||||
*/
|
||||
fmt++;
|
||||
return(buf);
|
||||
break;
|
||||
|
||||
case '[':
|
||||
/*
|
||||
* Format of an item, enclosed in square brackets; dissect
|
||||
* the item with smb_fdata1().
|
||||
*/
|
||||
fmt++;
|
||||
if (buf >= maxbuf)
|
||||
return(buf);
|
||||
@ -853,11 +883,15 @@ smb_fdata(netdissect_options *ndo,
|
||||
s[p - fmt] = '\0';
|
||||
fmt = p + 1;
|
||||
buf = smb_fdata1(ndo, buf, s, maxbuf, unicodestr);
|
||||
if (buf == NULL)
|
||||
if(buf < buf_start || buf == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* Not a formatting character, so just print it.
|
||||
*/
|
||||
ND_PRINT((ndo, "%c", *fmt));
|
||||
fmt++;
|
||||
break;
|
||||
|
@ -125,10 +125,6 @@ The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* HAVE_CAP_NG_H */
|
||||
#endif /* HAVE_LIBCAP_NG */
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/sysctl.h>
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#include "netdissect.h"
|
||||
#include "interface.h"
|
||||
#include "addrtoname.h"
|
||||
@ -652,11 +648,10 @@ droproot(const char *username, const char *chroot_dir)
|
||||
#ifdef HAVE_LIBCAP_NG
|
||||
{
|
||||
int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error : ret %d\n", ret);
|
||||
} else {
|
||||
if (ret < 0)
|
||||
error("capng_change_id(): return %d\n", ret);
|
||||
else
|
||||
fprintf(stderr, "dropped privs to %s\n", username);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifndef __rtems__
|
||||
@ -747,13 +742,15 @@ static char *
|
||||
get_next_file(FILE *VFile, char *ptr)
|
||||
{
|
||||
char *ret;
|
||||
size_t len;
|
||||
|
||||
ret = fgets(ptr, PATH_MAX, VFile);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (ptr[strlen(ptr) - 1] == '\n')
|
||||
ptr[strlen(ptr) - 1] = '\0';
|
||||
len = strlen (ptr);
|
||||
if (len > 0 && ptr[len - 1] == '\n')
|
||||
ptr[len - 1] = '\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1099,6 +1096,10 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf)
|
||||
if (status < 0)
|
||||
error("%s: Can't set time stamp type: %s",
|
||||
device, pcap_statustostr(status));
|
||||
else if (status > 0)
|
||||
warning("When trying to set timestamp type '%s' on %s: %s",
|
||||
pcap_tstamp_type_val_to_name(jflag), device,
|
||||
pcap_statustostr(status));
|
||||
}
|
||||
#endif
|
||||
status = pcap_activate(pc);
|
||||
@ -1120,30 +1121,6 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf)
|
||||
} else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0')
|
||||
error("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), cp);
|
||||
#ifdef __FreeBSD__
|
||||
else if (status == PCAP_ERROR_RFMON_NOTSUP &&
|
||||
strncmp(device, "wlan", 4) == 0) {
|
||||
char parent[8], newdev[8];
|
||||
char sysctl[32];
|
||||
size_t s = sizeof(parent);
|
||||
|
||||
snprintf(sysctl, sizeof(sysctl),
|
||||
"net.wlan.%d.%%parent", atoi(device + 4));
|
||||
sysctlbyname(sysctl, parent, &s, NULL, 0);
|
||||
strlcpy(newdev, device, sizeof(newdev));
|
||||
/* Suggest a new wlan device. */
|
||||
/* FIXME: incrementing the index this way is not going to work well
|
||||
* when the index is 9 or greater but the only consequence in this
|
||||
* specific case would be an error message that looks a bit odd.
|
||||
*/
|
||||
newdev[strlen(newdev)-1]++;
|
||||
error("%s is not a monitor mode VAP\n"
|
||||
"To create a new monitor mode VAP use:\n"
|
||||
" ifconfig %s create wlandev %s wlanmode monitor\n"
|
||||
"and use %s as the tcpdump interface",
|
||||
device, newdev, parent, newdev);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
error("%s: %s", device,
|
||||
pcap_statustostr(status));
|
||||
|
@ -126,10 +126,21 @@ fn_print(netdissect_options *ndo,
|
||||
|
||||
/*
|
||||
* Print out a null-terminated filename (or other ascii string) from
|
||||
* a fixed-length buffer.
|
||||
* If ep is NULL, assume no truncation check is needed.
|
||||
* a fixed-length field in the packet buffer, or from what remains of
|
||||
* the packet.
|
||||
*
|
||||
* n is the length of the fixed-length field, or the number of bytes
|
||||
* remaining in the packet based on its on-the-network length.
|
||||
*
|
||||
* If ep is non-null, it should point just past the last captured byte
|
||||
* of the packet, e.g. ndo->ndo_snapend. If ep is NULL, we assume no
|
||||
* truncation check, other than the checks of the field length/remaining
|
||||
* packet data length, is needed.
|
||||
*
|
||||
* Return the number of bytes of string processed, including the
|
||||
* terminating null, if not truncated. Return 0 if truncated.
|
||||
* terminating null, if not truncated; as the terminating null is
|
||||
* included in the count, and as there must be a terminating null,
|
||||
* this will always be non-zero. Return 0 if truncated.
|
||||
*/
|
||||
u_int
|
||||
fn_printztn(netdissect_options *ndo,
|
||||
@ -143,7 +154,8 @@ fn_printztn(netdissect_options *ndo,
|
||||
if (n == 0 || (ep != NULL && s >= ep)) {
|
||||
/*
|
||||
* Truncated. This includes "no null before we
|
||||
* got to the end of the fixed-length buffer".
|
||||
* got to the end of the fixed-length buffer or
|
||||
* the end of the packet".
|
||||
*
|
||||
* XXX - BOOTP says "null-terminated", which
|
||||
* means the maximum length of the string, in
|
||||
|
@ -765,7 +765,7 @@ YY_DECL
|
||||
char *yy_cp, *yy_bp;
|
||||
int yy_act;
|
||||
|
||||
#line 61 "nslexer.l"
|
||||
#line 62 "nslexer.l"
|
||||
|
||||
|
||||
#line 772 "nslexer.c"
|
||||
@ -827,16 +827,12 @@ yy_match:
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
++yy_cp;
|
||||
}
|
||||
while ( yy_base[yy_current_state] != 69 );
|
||||
while ( yy_current_state != 58 );
|
||||
yy_cp = (yy_last_accepting_cpos);
|
||||
yy_current_state = (yy_last_accepting_state);
|
||||
|
||||
yy_find_action:
|
||||
yy_act = yy_accept[yy_current_state];
|
||||
if ( yy_act == 0 )
|
||||
{ /* have to back up */
|
||||
yy_cp = (yy_last_accepting_cpos);
|
||||
yy_current_state = (yy_last_accepting_state);
|
||||
yy_act = yy_accept[yy_current_state];
|
||||
}
|
||||
|
||||
YY_DO_BEFORE_ACTION;
|
||||
|
||||
@ -863,59 +859,59 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
|
||||
case 1:
|
||||
YY_RULE_SETUP
|
||||
#line 63 "nslexer.l"
|
||||
#line 64 "nslexer.l"
|
||||
; /* skip whitespace */
|
||||
YY_BREAK
|
||||
case 2:
|
||||
YY_RULE_SETUP
|
||||
#line 65 "nslexer.l"
|
||||
#line 66 "nslexer.l"
|
||||
; /* skip comments */
|
||||
YY_BREAK
|
||||
case 3:
|
||||
/* rule 3 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 67 "nslexer.l"
|
||||
#line 68 "nslexer.l"
|
||||
; /* allow continuation */
|
||||
YY_BREAK
|
||||
case 4:
|
||||
/* rule 4 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 69 "nslexer.l"
|
||||
#line 70 "nslexer.l"
|
||||
return NL;
|
||||
YY_BREAK
|
||||
case 5:
|
||||
YY_RULE_SETUP
|
||||
#line 71 "nslexer.l"
|
||||
#line 72 "nslexer.l"
|
||||
return SUCCESS;
|
||||
YY_BREAK
|
||||
case 6:
|
||||
YY_RULE_SETUP
|
||||
#line 72 "nslexer.l"
|
||||
#line 73 "nslexer.l"
|
||||
return UNAVAIL;
|
||||
YY_BREAK
|
||||
case 7:
|
||||
YY_RULE_SETUP
|
||||
#line 73 "nslexer.l"
|
||||
#line 74 "nslexer.l"
|
||||
return NOTFOUND;
|
||||
YY_BREAK
|
||||
case 8:
|
||||
YY_RULE_SETUP
|
||||
#line 74 "nslexer.l"
|
||||
#line 75 "nslexer.l"
|
||||
return TRYAGAIN;
|
||||
YY_BREAK
|
||||
case 9:
|
||||
YY_RULE_SETUP
|
||||
#line 76 "nslexer.l"
|
||||
#line 77 "nslexer.l"
|
||||
return RETURN;
|
||||
YY_BREAK
|
||||
case 10:
|
||||
YY_RULE_SETUP
|
||||
#line 77 "nslexer.l"
|
||||
#line 78 "nslexer.l"
|
||||
return CONTINUE;
|
||||
YY_BREAK
|
||||
case 11:
|
||||
YY_RULE_SETUP
|
||||
#line 79 "nslexer.l"
|
||||
#line 80 "nslexer.l"
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
@ -935,15 +931,15 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 12:
|
||||
YY_RULE_SETUP
|
||||
#line 96 "nslexer.l"
|
||||
#line 97 "nslexer.l"
|
||||
return _nsyytext[0];
|
||||
YY_BREAK
|
||||
case 13:
|
||||
YY_RULE_SETUP
|
||||
#line 98 "nslexer.l"
|
||||
#line 99 "nslexer.l"
|
||||
ECHO;
|
||||
YY_BREAK
|
||||
#line 947 "nslexer.c"
|
||||
#line 943 "nslexer.c"
|
||||
case YY_STATE_EOF(INITIAL):
|
||||
yyterminate();
|
||||
|
||||
@ -1010,7 +1006,8 @@ case YY_STATE_EOF(INITIAL):
|
||||
|
||||
else
|
||||
{
|
||||
yy_cp = (yy_c_buf_p);
|
||||
yy_cp = (yy_last_accepting_cpos);
|
||||
yy_current_state = (yy_last_accepting_state);
|
||||
goto yy_find_action;
|
||||
}
|
||||
}
|
||||
@ -1484,7 +1481,7 @@ static void _nsyy_load_buffer_state (void)
|
||||
b->yy_bs_column = 0;
|
||||
}
|
||||
|
||||
b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
|
||||
b->yy_is_interactive = 0;
|
||||
|
||||
errno = oerrno;
|
||||
}
|
||||
@ -1908,7 +1905,7 @@ void _nsyyfree (void * ptr )
|
||||
|
||||
#define YYTABLES_NAME "yytables"
|
||||
|
||||
#line 98 "nslexer.l"
|
||||
#line 99 "nslexer.l"
|
||||
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define YYBYACC 1
|
||||
#define YYMAJOR 1
|
||||
#define YYMINOR 9
|
||||
#define YYPATCH 20170201
|
||||
#define YYPATCH 20170430
|
||||
|
||||
#define YYEMPTY (-1)
|
||||
#define yyclearin (yychar = YYEMPTY)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user