Update to FreeBSD stable/12 2020-02-10

Git mirror commit 0d1c391321b34b3025cf0e72f2231d836ff76da8.
This commit is contained in:
Sebastian Huber 2020-02-10 15:34:55 +01:00
parent 18cc38e73e
commit 46b3858b27
272 changed files with 18816 additions and 15956 deletions

@ -1 +1 @@
Subproject commit 7e8d1444023128d34fb9aa4e4515928a4f794d1b
Subproject commit 0d1c391321b34b3025cf0e72f2231d836ff76da8

View File

@ -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

View File

@ -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,

View File

@ -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
}

View File

@ -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;

View File

@ -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,

View File

@ -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
}

View File

@ -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,

View File

@ -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,
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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 */

View File

@ -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)
/*

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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;
}
}
/*

View File

@ -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);

View File

@ -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 *);

View File

@ -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;

View File

@ -160,4 +160,4 @@
(__HP_aCC >= ((major)*10000 + (minor)*100))
#endif
#endif /* lib_pcap_funcattrs_h */
#endif /* lib_pcap_compiler_tests_h */

View File

@ -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

View File

@ -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 {

View File

@ -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 */

View File

@ -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);

View File

@ -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

View 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 */

View File

@ -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 */

View File

@ -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

View File

@ -376,7 +376,7 @@ extern int pcap_lex \
#undef YY_DECL
#endif
#line 490 "scanner.l"
#line 479 "scanner.l"
#line 383 "scanner.h"

View File

@ -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; }
%%
/*

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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",

View File

@ -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;

View File

@ -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));
}
/*

View File

@ -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));

View File

@ -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) {

View File

@ -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__ */

View File

@ -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 */

View File

@ -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);

View File

@ -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: ",

View File

@ -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

View File

@ -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;

View File

@ -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));

View File

@ -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,

View File

@ -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));
}
/*

View File

@ -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));
}
/*

View File

@ -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,")"));

View File

@ -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)

View File

@ -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, " {"));

View File

@ -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;
}

View File

@ -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:

View File

@ -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;

View File

@ -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"

View File

@ -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",

View File

@ -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),

View File

@ -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));

View File

@ -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);
}
/*

View File

@ -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));

View File

@ -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;

View File

@ -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) {

View File

@ -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"

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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"));

View File

@ -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;

View File

@ -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, "\""));

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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));

View File

@ -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

View File

@ -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"

View File

@ -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