Merge ^/head r313644 through r313895.
This commit is contained in:
commit
a3906ca572
7
UPDATING
7
UPDATING
@ -56,6 +56,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
|
||||
Please see the 20141231 entry below for information about prerequisites
|
||||
and upgrading, if you are not already using clang 3.5.0 or higher.
|
||||
|
||||
20170216:
|
||||
EISA bus support has been removed. The WITH_EISA option is no longer
|
||||
valid.
|
||||
|
||||
20170215:
|
||||
MCA bus support has been removed.
|
||||
|
||||
20170127:
|
||||
The WITH_LLD_AS_LD / WITHOUT_LLD_AS_LD build knobs have been renamed
|
||||
WITH_LLD_IS_LD / WITHOUT_LLD_IS_LD, for consistency with CLANG_IS_CC.
|
||||
|
@ -259,12 +259,12 @@ printlong(const DISPLAY *dp)
|
||||
np = p->fts_pointer;
|
||||
xo_attr("value", "%03o", (int) sp->st_mode & ALLPERMS);
|
||||
if (f_numericonly) {
|
||||
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} {td:user/%-*s}{e:user/%ju} {td:group/%-*s}{e:group/%ju} ",
|
||||
buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, sp->st_nlink,
|
||||
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*ju} {td:user/%-*s}{e:user/%ju} {td:group/%-*s}{e:group/%ju} ",
|
||||
buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, (uintmax_t)sp->st_nlink,
|
||||
dp->s_user, np->user, (uintmax_t)sp->st_uid, dp->s_group, np->group, (uintmax_t)sp->st_gid);
|
||||
} else {
|
||||
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} {t:user/%-*s} {t:group/%-*s} ",
|
||||
buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, sp->st_nlink,
|
||||
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*ju} {t:user/%-*s} {t:group/%-*s} ",
|
||||
buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, (uintmax_t)sp->st_nlink,
|
||||
dp->s_user, np->user, dp->s_group, np->group);
|
||||
}
|
||||
if (S_ISBLK(sp->st_mode))
|
||||
|
@ -87,7 +87,7 @@ utility conforms to
|
||||
.St -p1003.1-2001 .
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
.Nm
|
||||
command appeared in
|
||||
.At v5 .
|
||||
.Sh BUGS
|
||||
|
@ -1033,7 +1033,7 @@ The syntax of the
|
||||
command is:
|
||||
.Bd -unfilled -offset indent -compact
|
||||
.Ic case Ar word Ic in
|
||||
.Ar pattern Ns Li ) Ar list Li ;;
|
||||
.Ar pattern Ns ) Ar list Li ;;
|
||||
.Ar ...
|
||||
.Ic esac
|
||||
.Ed
|
||||
|
@ -83,6 +83,50 @@ static void append_entry(char **p, const char *prefix, int type,
|
||||
int tag, int flags, const char *name, int perm, int id);
|
||||
static void append_id(char **p, int id);
|
||||
|
||||
static const struct {
|
||||
const int perm;
|
||||
const char c;
|
||||
const wchar_t wc;
|
||||
} nfsv4_acl_perm_map[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 'r',
|
||||
L'r' },
|
||||
{ ARCHIVE_ENTRY_ACL_WRITE_DATA | ARCHIVE_ENTRY_ACL_ADD_FILE, 'w',
|
||||
L'w' },
|
||||
{ ARCHIVE_ENTRY_ACL_EXECUTE, 'x', L'x' },
|
||||
{ ARCHIVE_ENTRY_ACL_APPEND_DATA | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
|
||||
'p', L'p' },
|
||||
{ ARCHIVE_ENTRY_ACL_DELETE, 'd', L'd' },
|
||||
{ ARCHIVE_ENTRY_ACL_DELETE_CHILD, 'D', L'D' },
|
||||
{ ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 'a', L'a' },
|
||||
{ ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 'A', L'A' },
|
||||
{ ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 'R', L'R' },
|
||||
{ ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 'W', L'W' },
|
||||
{ ARCHIVE_ENTRY_ACL_READ_ACL, 'c', L'c' },
|
||||
{ ARCHIVE_ENTRY_ACL_WRITE_ACL, 'C', L'C' },
|
||||
{ ARCHIVE_ENTRY_ACL_WRITE_OWNER, 'o', L'o' },
|
||||
{ ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 's', L's' }
|
||||
};
|
||||
|
||||
static const int nfsv4_acl_perm_map_size = (int)(sizeof(nfsv4_acl_perm_map) /
|
||||
sizeof(nfsv4_acl_perm_map[0]));
|
||||
|
||||
static const struct {
|
||||
const int perm;
|
||||
const char c;
|
||||
const wchar_t wc;
|
||||
} nfsv4_acl_flag_map[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 'f', L'f' },
|
||||
{ ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, 'd', L'd' },
|
||||
{ ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, 'i', L'i' },
|
||||
{ ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, 'n', L'n' },
|
||||
{ ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, 'S', L'S' },
|
||||
{ ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, 'F', L'F' },
|
||||
{ ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, 'I', L'I' }
|
||||
};
|
||||
|
||||
static const int nfsv4_acl_flag_map_size = (int)(sizeof(nfsv4_acl_flag_map) /
|
||||
sizeof(nfsv4_acl_flag_map[0]));
|
||||
|
||||
void
|
||||
archive_acl_clear(struct archive_acl *acl)
|
||||
{
|
||||
@ -741,6 +785,8 @@ static void
|
||||
append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
|
||||
int tag, int flags, const wchar_t *wname, int perm, int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prefix != NULL) {
|
||||
wcscpy(*wp, prefix);
|
||||
*wp += wcslen(*wp);
|
||||
@ -810,46 +856,20 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
|
||||
*(*wp)++ = (perm & 0222) ? L'w' : L'-';
|
||||
*(*wp)++ = (perm & 0111) ? L'x' : L'-';
|
||||
} else {
|
||||
/* NFS4 ACL perms */
|
||||
*(*wp)++ = (perm & (ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_LIST_DIRECTORY)) ? L'r' : L'-';
|
||||
*(*wp)++ = (perm & (ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_ADD_FILE)) ? L'w' : L'-';
|
||||
*(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_EXECUTE) ? L'x' : L'-';
|
||||
*(*wp)++ = (perm & (ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY)) ? L'p' : L'-';
|
||||
*(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_DELETE) ? L'd' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_DELETE_CHILD) ? L'D' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES) ? L'a' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES) ? L'A' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS) ? L'R' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS) ? L'W' : L'-';
|
||||
*(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_READ_ACL) ? L'c' : L'-';
|
||||
*(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_WRITE_ACL) ? L'C' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER) ? L'o' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE) ? L's' : L'-';
|
||||
/* NFSv4 ACL perms */
|
||||
for (i = 0; i < nfsv4_acl_perm_map_size; i++) {
|
||||
if (perm & nfsv4_acl_perm_map[i].perm)
|
||||
*(*wp)++ = nfsv4_acl_perm_map[i].wc;
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
|
||||
*(*wp)++ = L'-';
|
||||
}
|
||||
*(*wp)++ = L':';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT) ? L'f' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT) ? L'd' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY) ? L'i' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT) ? L'n' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS) ? L'S' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS) ? L'F' : L'-';
|
||||
*(*wp)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERITED) ? L'I' : L'-';
|
||||
for (i = 0; i < nfsv4_acl_flag_map_size; i++) {
|
||||
if (perm & nfsv4_acl_flag_map[i].perm)
|
||||
*(*wp)++ = nfsv4_acl_flag_map[i].wc;
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
|
||||
*(*wp)++ = L'-';
|
||||
}
|
||||
*(*wp)++ = L':';
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
@ -998,6 +1018,8 @@ static void
|
||||
append_entry(char **p, const char *prefix, int type,
|
||||
int tag, int flags, const char *name, int perm, int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prefix != NULL) {
|
||||
strcpy(*p, prefix);
|
||||
*p += strlen(*p);
|
||||
@ -1067,47 +1089,20 @@ append_entry(char **p, const char *prefix, int type,
|
||||
*(*p)++ = (perm & 0222) ? 'w' : '-';
|
||||
*(*p)++ = (perm & 0111) ? 'x' : '-';
|
||||
} else {
|
||||
/* NFS4 ACL perms */
|
||||
*(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_LIST_DIRECTORY)) ? 'r' : '-';
|
||||
*(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_ADD_FILE)) ? 'w' : '-';
|
||||
*(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_EXECUTE)) ? 'x' : '-';
|
||||
*(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY)) ? 'p' : '-';
|
||||
*(*p)++ = (perm & ARCHIVE_ENTRY_ACL_DELETE) ? 'd' : '-';
|
||||
*(*p)++ = (perm & ARCHIVE_ENTRY_ACL_DELETE_CHILD) ? 'D' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES) ? 'a' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES) ? 'A' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS) ? 'R' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS) ? 'W' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL) ? 'c' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL) ? 'C' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER) ? 'o' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE) ? 's' : '-';
|
||||
/* NFSv4 ACL perms */
|
||||
for (i = 0; i < nfsv4_acl_perm_map_size; i++) {
|
||||
if (perm & nfsv4_acl_perm_map[i].perm)
|
||||
*(*p)++ = nfsv4_acl_perm_map[i].c;
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
|
||||
*(*p)++ = '-';
|
||||
}
|
||||
*(*p)++ = ':';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT) ? 'f' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT) ? 'd' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY) ? 'i' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT) ? 'n' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS) ? 'S' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS) ? 'F' : '-';
|
||||
*(*p)++ = (perm &
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERITED) ? 'I' : '-';
|
||||
for (i = 0; i < nfsv4_acl_flag_map_size; i++) {
|
||||
if (perm & nfsv4_acl_flag_map[i].perm)
|
||||
*(*p)++ = nfsv4_acl_flag_map[i].c;
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
|
||||
*(*p)++ = '-';
|
||||
}
|
||||
*(*p)++ = ':';
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
@ -1467,11 +1462,8 @@ ismode_w(const wchar_t *start, const wchar_t *end, int *permset)
|
||||
static int
|
||||
is_nfs4_perms_w(const wchar_t *start, const wchar_t *end, int *permset)
|
||||
{
|
||||
const wchar_t *p;
|
||||
const wchar_t *p = start;
|
||||
|
||||
if (start >= end)
|
||||
return (0);
|
||||
p = start;
|
||||
while (p < end) {
|
||||
switch (*p++) {
|
||||
case L'r':
|
||||
@ -1533,11 +1525,8 @@ is_nfs4_perms_w(const wchar_t *start, const wchar_t *end, int *permset)
|
||||
static int
|
||||
is_nfs4_flags_w(const wchar_t *start, const wchar_t *end, int *permset)
|
||||
{
|
||||
const wchar_t *p;
|
||||
const wchar_t *p = start;
|
||||
|
||||
if (start >= end)
|
||||
return (0);
|
||||
p = start;
|
||||
while (p < end) {
|
||||
switch(*p++) {
|
||||
case L'f':
|
||||
@ -1945,11 +1934,8 @@ ismode(const char *start, const char *end, int *permset)
|
||||
static int
|
||||
is_nfs4_perms(const char *start, const char *end, int *permset)
|
||||
{
|
||||
const char *p;
|
||||
const char *p = start;
|
||||
|
||||
if (start >= end)
|
||||
return (0);
|
||||
p = start;
|
||||
while (p < end) {
|
||||
switch (*p++) {
|
||||
case 'r':
|
||||
@ -2011,11 +1997,8 @@ is_nfs4_perms(const char *start, const char *end, int *permset)
|
||||
static int
|
||||
is_nfs4_flags(const char *start, const char *end, int *permset)
|
||||
{
|
||||
const char *p;
|
||||
const char *p = start;
|
||||
|
||||
if (start >= end)
|
||||
return (0);
|
||||
p = start;
|
||||
while (p < end) {
|
||||
switch(*p++) {
|
||||
case 'f':
|
||||
|
@ -509,6 +509,10 @@ __LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_SOLARIS - Output only one colon after "other" and
|
||||
* "mask" entries.
|
||||
*
|
||||
* Flags only for archive entries with NFSv4 ACL:
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_COMPACT - Do not output the minus character for
|
||||
* unset permissions and flags in NFSv4 ACL permission and flag fields
|
||||
*
|
||||
* Flags for for archive entries with POSIX.1e ACL or NFSv4 ACL:
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
|
||||
* each ACL entry.
|
||||
@ -519,6 +523,7 @@ __LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 0x00000002
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_SOLARIS 0x00000004
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 0x00000008
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_COMPACT 0x00000010
|
||||
|
||||
__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *,
|
||||
ssize_t * /* len */, int /* flags */);
|
||||
|
@ -23,7 +23,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd December 27, 2016
|
||||
.Dd February 15, 2017
|
||||
.Dt ARCHIVE_ENTRY_ACL 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -390,6 +390,13 @@ Prefix each default ACL entry with the word
|
||||
The mask and other ACLs don not contain a double colon.
|
||||
.El
|
||||
.Pp
|
||||
The following flags are effecive only on NFSv4 ACL:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_COMPACT
|
||||
Do not output minus characters for unset permissions and flags in NFSv4 ACL
|
||||
permission and flag fields.
|
||||
.El
|
||||
.Pp
|
||||
The following flags are effective on both POSIX.1e and NFSv4 ACL:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
|
||||
|
@ -618,9 +618,9 @@ setup_acls(struct archive_read_disk *a,
|
||||
/*
|
||||
* Translate system ACL permissions into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
static const struct {
|
||||
const int archive_perm;
|
||||
const int platform_perm;
|
||||
} acl_perm_map[] = {
|
||||
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
|
||||
@ -687,9 +687,9 @@ static struct {
|
||||
/*
|
||||
* Translate system NFSv4 inheritance flags into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
static const struct {
|
||||
const int archive_inherit;
|
||||
const int platform_inherit;
|
||||
} acl_inherit_map[] = {
|
||||
#if HAVE_SUN_ACL /* Solaris ACL inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
|
||||
@ -882,7 +882,7 @@ sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
|
||||
/*
|
||||
* POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
|
||||
* FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
|
||||
* incuding mask.
|
||||
* including mask.
|
||||
*/
|
||||
if (acl->acl_type == ACLENT_T) {
|
||||
if (acl->acl_cnt == 4)
|
||||
|
@ -452,26 +452,38 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
/* Zip64 extended information extra field. */
|
||||
zip_entry->flags |= LA_USED_ZIP64;
|
||||
if (zip_entry->uncompressed_size == 0xffffffff) {
|
||||
if (datasize < 8)
|
||||
break;
|
||||
zip_entry->uncompressed_size =
|
||||
archive_le64dec(p + offset);
|
||||
uint64_t t = 0;
|
||||
if (datasize < 8
|
||||
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit uncompressed size");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
zip_entry->uncompressed_size = t;
|
||||
offset += 8;
|
||||
datasize -= 8;
|
||||
}
|
||||
if (zip_entry->compressed_size == 0xffffffff) {
|
||||
if (datasize < 8)
|
||||
break;
|
||||
zip_entry->compressed_size =
|
||||
archive_le64dec(p + offset);
|
||||
uint64_t t = 0;
|
||||
if (datasize < 8
|
||||
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit compressed size");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
zip_entry->compressed_size = t;
|
||||
offset += 8;
|
||||
datasize -= 8;
|
||||
}
|
||||
if (zip_entry->local_header_offset == 0xffffffff) {
|
||||
if (datasize < 8)
|
||||
break;
|
||||
zip_entry->local_header_offset =
|
||||
archive_le64dec(p + offset);
|
||||
uint64_t t = 0;
|
||||
if (datasize < 8
|
||||
|| (t = archive_le64dec(p + offset)) > INT64_MAX) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Malformed 64-bit local header offset");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
zip_entry->local_header_offset = t;
|
||||
offset += 8;
|
||||
datasize -= 8;
|
||||
}
|
||||
@ -1156,11 +1168,18 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
|
||||
|| (zip->hctx_valid
|
||||
&& zip->entry->aes_extra.vendor == AES_VENDOR_AE_2))) {
|
||||
if (zip->entry->flags & LA_USED_ZIP64) {
|
||||
uint64_t compressed, uncompressed;
|
||||
zip->entry->crc32 = archive_le32dec(p + 4);
|
||||
zip->entry->compressed_size =
|
||||
archive_le64dec(p + 8);
|
||||
zip->entry->uncompressed_size =
|
||||
archive_le64dec(p + 16);
|
||||
compressed = archive_le64dec(p + 8);
|
||||
uncompressed = archive_le64dec(p + 16);
|
||||
if (compressed > INT64_MAX || uncompressed > INT64_MAX) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Overflow of 64-bit file sizes");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
zip->entry->compressed_size = compressed;
|
||||
zip->entry->uncompressed_size = uncompressed;
|
||||
zip->unconsumed = 24;
|
||||
} else {
|
||||
zip->entry->crc32 = archive_le32dec(p + 4);
|
||||
@ -1437,9 +1456,18 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
|
||||
zip->unconsumed = 4;
|
||||
}
|
||||
if (zip->entry->flags & LA_USED_ZIP64) {
|
||||
uint64_t compressed, uncompressed;
|
||||
zip->entry->crc32 = archive_le32dec(p);
|
||||
zip->entry->compressed_size = archive_le64dec(p + 4);
|
||||
zip->entry->uncompressed_size = archive_le64dec(p + 12);
|
||||
compressed = archive_le64dec(p + 4);
|
||||
uncompressed = archive_le64dec(p + 12);
|
||||
if (compressed > INT64_MAX || uncompressed > INT64_MAX) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Overflow of 64-bit file sizes");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
zip->entry->compressed_size = compressed;
|
||||
zip->entry->uncompressed_size = uncompressed;
|
||||
zip->unconsumed += 20;
|
||||
} else {
|
||||
zip->entry->crc32 = archive_le32dec(p);
|
||||
|
@ -101,7 +101,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
|
||||
"default");
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
/* Simultaeous POSIX.1e and NFSv4 is not supported */
|
||||
/* Simultaneous POSIX.1e and NFSv4 is not supported */
|
||||
return (ret);
|
||||
}
|
||||
#endif /* !HAVE_DARWIN_ACL */
|
||||
@ -119,9 +119,9 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
/*
|
||||
* Translate system ACL permissions into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
static const struct {
|
||||
const int archive_perm;
|
||||
const int platform_perm;
|
||||
} acl_perm_map[] = {
|
||||
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
|
||||
@ -188,9 +188,9 @@ static struct {
|
||||
/*
|
||||
* Translate system NFSv4 inheritance flags into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
static const struct {
|
||||
const int archive_inherit;
|
||||
const int platform_inherit;
|
||||
} acl_inherit_map[] = {
|
||||
#if HAVE_SUN_ACL /* Solaris NFSv4 inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
|
||||
|
@ -1166,7 +1166,8 @@ archive_write_pax_header(struct archive_write *a,
|
||||
if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = add_pax_acl(a, entry_original, pax,
|
||||
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
|
||||
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_COMPACT);
|
||||
if (ret == ARCHIVE_FATAL)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
begin 644 test_acl_pax_nfs4.tar
|
||||
M4&%X2&5A9&5R+V9I;&4`````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````#`P,#<W-R``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,C`R
|
||||
M(#`P,#`P,#`P,#`P(#`Q,C`P,0`@>```````````````````````````````
|
||||
M`````````````#`P,#<W-R``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,3,R
|
||||
M(#`P,#`P,#`P,#`P(#`Q,C`P,P`@>```````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````!U<W1A<@`P,```````
|
||||
M````````````````````````````````````````````````````````````
|
||||
@ -10,10 +10,10 @@ M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````Q,S`@4T-(24Q9+F%C;"YA8V4];W=N97)`.G)W
|
||||
M>'`M+6%!4E=C0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7!`.G)W+7`M+6$M4BUC
|
||||
M+2US.BTM+2TM+2TZ86QL;W<L979E<GEO;F5`.G(M+2TM+6$M4BUC+2US.BTM
|
||||
M+2TM+2TZ86QL;W<*````````````````````````````````````````````
|
||||
M```````````````````````Y,"!30TA)3%DN86-L+F%C93UO=VYE<D`Z<G=X
|
||||
M<&%!4E=C0V]S.CIA;&QO=RQG<F]U<$`Z<G=P85)C<SHZ86QL;W<L979E<GEO
|
||||
M;F5`.G)A4F-S.CIA;&QO=PH`````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
@ -36,7 +36,7 @@ M````````````````````````````````````````````````````````````
|
||||
M````````4&%X2&5A9&5R+V9I;&4`````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````#`P,#<W-R``,#`P,#`P(``P,#`P,#`@`#`P,#`P
|
||||
M,#`P-#`V(#`P,#`P,#`P,#`P(#`Q,C`P-P`@>```````````````````````
|
||||
M,#`P,C4V(#`P,#`P,#`P,#`P(#`Q,C`Q,@`@>```````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````````````!U<W1A<@`P
|
||||
M,```````````````````````````````````````````````````````````
|
||||
@ -44,13 +44,13 @@ M```````````````````````````P,#`P,#`@`#`P,#`P,"``````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````````````R-C(@4T-(24Q9+F%C;"YA8V4];W=N
|
||||
M97)`.G)W+7`M+6%!4E=C0V]S.BTM+2TM+2TZ86QL;W<L=7-E<CIU<V5R-S<Z
|
||||
M<BTM+2TM82U2+6,M+7,Z+2TM+2TM23IA;&QO=SHW-RQU<V5R.G5S97(W.#IR
|
||||
M=W@M+2TM+2TM+2TM+3HM+2TM+2TM.F1E;GDZ-S@L9W)O=7!`.G)W+7`M+6$M
|
||||
M4BUC+2US.BTM+2TM+2TZ86QL;W<L9W)O=7`Z9W)O=7`W.#HM=RUP+2TM02U7
|
||||
M+4-O+3HM+2TM+2TM.F1E;GDZ-S@L979E<GEO;F5`.G(M+2TM+6$M4BUC+2US
|
||||
M.BTM+2TM+2TZ86QL;W<*````````````````````````````````````````
|
||||
M```````````````````````````````Q-S0@4T-(24Q9+F%C;"YA8V4];W=N
|
||||
M97)`.G)W<&%!4E=C0V]S.CIA;&QO=RQU<V5R.G5S97(W-SIR85)C<SI).F%L
|
||||
M;&]W.C<W+'5S97(Z=7-E<C<X.G)W>#HZ9&5N>3HW."QG<F]U<$`Z<G=P85)C
|
||||
M<SHZ86QL;W<L9W)O=7`Z9W)O=7`W.#IW<$%70V\Z.F1E;GDZ-S@L979E<GEO
|
||||
M;F5`.G)A4F-S.CIA;&QO=PH`````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
@ -70,7 +70,7 @@ M````````````````````````````````````````````````````````````
|
||||
M````````````````4&%X2&5A9&5R+V9I;&4`````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````````````#`P,#<W-R``,#`P,#`P(``P,#`P,#`@
|
||||
M`#`P,#`P,#`P-#$P(#`P,#`P,#`P,#`P(#`Q,C`P,@`@>```````````````
|
||||
M`#`P,#`P,#`P,C8R(#`P,#`P,#`P,#`P(#`Q,C`P-P`@>```````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````````````````````!U
|
||||
M<W1A<@`P,```````````````````````````````````````````````````
|
||||
@ -78,13 +78,13 @@ M```````````````````````````````````P,#`P,#`@`#`P,#`P,"``````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````````````````````R-C0@4T-(24Q9+F%C;"YA
|
||||
M8V4];W=N97)`.G)W>'`M+6%!4E=C0V]S.BTM+2TM+2TZ86QL;W<L=7-E<CIU
|
||||
M<V5R-S<Z<G<M<"TM82U2+6,M;W,Z+2TM+2TM+3IA;&QO=SHW-RQU<V5R.G5S
|
||||
M97(W-SHM=RUP+2TM+2TM+2TM+3HM+2TM4RTM.F%U9&ET.C<W+&=R;W5P0#IR
|
||||
M=RUP+2UA+5(M8RTM<SHM+2TM+2TM.F%L;&]W+&=R;W5P.F=R;W5P-S@Z<BTM
|
||||
M+2TM82U2+6,M+2TZ+2TM+2U&+3IA;&%R;3HW."QE=F5R>6]N94`Z<BTM+2TM
|
||||
M82U2+6,M+7,Z+2TM+2TM+3IA;&QO=PH`````````````````````````````
|
||||
M```````````````````````````````````````Q-S@@4T-(24Q9+F%C;"YA
|
||||
M8V4];W=N97)`.G)W>'!A05)78T-O<SHZ86QL;W<L=7-E<CIU<V5R-S<Z<G=P
|
||||
M85)C;W,Z.F%L;&]W.C<W+'5S97(Z=7-E<C<W.G=P.E,Z875D:70Z-S<L9W)O
|
||||
M=7!`.G)W<&%28W,Z.F%L;&]W+&=R;W5P.F=R;W5P-S@Z<F%28SI&.F%L87)M
|
||||
M.C<X+&5V97)Y;VYE0#IR85)C<SHZ86QL;W<*````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
|
@ -472,7 +472,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
return;
|
||||
}
|
||||
#if HAVE_SUN_ACL
|
||||
/* Check if Solars filesystem supports POSIX.1e ACLs */
|
||||
/* Check if Solaris filesystem supports POSIX.1e ACLs */
|
||||
n = facl_get(fd, 0, &acl);
|
||||
if (n != 0)
|
||||
close(fd);
|
||||
|
@ -221,7 +221,14 @@ const char* acltext[] = {
|
||||
"group:group78:r-----a-R-c---:------I:allow:78\n"
|
||||
"owner@:rwxp--aARWcCo-:-------:allow\n"
|
||||
"group@:rw-p--a-R-c---:-------:allow\n"
|
||||
"everyone@:r-----a-R-c--s:-------:allow"
|
||||
"everyone@:r-----a-R-c--s:-------:allow",
|
||||
|
||||
"user:user77:rwpaRco::allow:77\n"
|
||||
"user:user101:wpdD:fdin:deny:101\n"
|
||||
"group:group78:raRc:I:allow:78\n"
|
||||
"owner@:rwxpaARWcCo::allow\n"
|
||||
"group@:rwpaRc::allow\n"
|
||||
"everyone@:raRcs::allow"
|
||||
};
|
||||
|
||||
static wchar_t *
|
||||
@ -458,5 +465,9 @@ DEFINE_TEST(test_acl_to_text)
|
||||
/* NFSv4 ACLs like "getfacl -i" on FreeBSD */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[10]);
|
||||
|
||||
/* NFSv4 ACLs like "getfacl -i" on FreeBSD with stripped minus chars */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_COMPACT, acltext[11]);
|
||||
|
||||
archive_entry_free(ae);
|
||||
}
|
||||
|
@ -1,5 +1,80 @@
|
||||
Tuesday, Oct. 25, 2016 mcr@sandelman.ca
|
||||
Summary for 1.8.1 libpcap release
|
||||
Add a target in Makefile.in for Exuberant Ctags use: 'extags'.
|
||||
Rename configure.in to configure.ac: autoconf 2.59
|
||||
Clean up the name-to-DLT mapping table.
|
||||
Add some newer DLT_ values: IPMI_HPM_2,ZWAVE_R1_R2,ZWAVE_R3,WATTSTOPPER_DLM,ISO_14443,RDS
|
||||
Clarify what the return values are for both success and failure.
|
||||
Many changes to build on windows
|
||||
Check for the "break the loop" condition in the inner loop for TPACKET_V3.
|
||||
Fix handling of packet count in the TPACKET_V3 inner loop: GitHub issue #493.
|
||||
Filter out duplicate looped back CAN frames.
|
||||
Fix the handling of loopback filters for IPv6 packets.
|
||||
Add a link-layer header type for RDS (IEC 62106) groups.
|
||||
Use different intermediate folders for x86 and x64 builds on Windows.
|
||||
On Linux, handle all CAN captures with pcap-linux.c, in cooked mode.
|
||||
Removes the need for the "host-endian" link-layer header type.
|
||||
Compile with '-Wused-but-marked-unused' in devel mode if supported
|
||||
Have separate DLTs for big-endian and host-endian SocketCAN headers.
|
||||
Reflect version.h being renamed to pcap_version.h.
|
||||
Require that version.h be generated: all build procedures we support generate version.h (autoconf, CMake, MSVC)!
|
||||
Properly check for sock_recv() errors.
|
||||
Re-impose some of Winsock's limitations on sock_recv().
|
||||
Replace sprintf() with pcap_snprintf().
|
||||
Fix signature of pcap_stats_ex_remote().
|
||||
Initial cmake support for remote packet capture.
|
||||
Have rpcap_remoteact_getsock() return a SOCKET and supply an "is active" flag.
|
||||
Clean up {DAG, Septel, Myricom SNF}-only builds.
|
||||
Do UTF-16-to-ASCII conversion into the right place.
|
||||
pcap_create_interface() needs the interface name on Linux.
|
||||
Clean up hardware time stamp support: the "any" device does not support any time stamp types.
|
||||
Add support for capturing on FreeBSD usbusN interfaces.
|
||||
Add a LINKTYPE/DLT_ value for FreeBSD USB.
|
||||
Go back to using PCAP_API on Windows.
|
||||
CMake support
|
||||
Add TurboCap support from WinPcap.
|
||||
Recognize 802.1ad nested VLAN tag in vlan filter.
|
||||
|
||||
Thursday Sep. 3, 2015 guy@alum.mit.edu
|
||||
Summary for 1.7.5 libpcap release
|
||||
Man page cleanups.
|
||||
Add some allocation failure checks.
|
||||
Fix a number of Linux/ucLinux configure/build issues.
|
||||
Fix some memory leaks.
|
||||
Recognize 802.1ad nested VLAN tag in vlan filter.
|
||||
Fix building Bluetooth Linux Monitor support with BlueZ 5.1+
|
||||
|
||||
Saturday Jun. 27, 2015 mcr@sandelman.ca
|
||||
Summary for 1.7.4 libpcap release
|
||||
Include fix for GitHub issue #424 -- out of tree builds.
|
||||
|
||||
Friday Apr. 10, 2015 guy@alum.mit.edu
|
||||
Summary for 1.7.3 libpcap release
|
||||
Work around a Linux bonding driver bug.
|
||||
|
||||
Thursday Feb. 12, 2015 guy@alum.mit.edu/mcr@sandelman.ca
|
||||
Summary for 1.7.2 libpcap release
|
||||
Support for filtering Geneve encapsulated packets.
|
||||
Generalize encapsulation handling, fixing some bugs.
|
||||
Don't add null addresses to address lists.
|
||||
Add pcap_dump_open_append() to open for appending.
|
||||
Fix the swapping of isochronous descriptors in Linux USB.
|
||||
Attempt to handle TPACKET_V1 with 32-bit userland and 64-bit kernel.
|
||||
|
||||
Wednesday Nov. 12, 2014 guy@alum.mit.edu/mcr@sandelman.ca
|
||||
Summary for 1.7.0 libpcap release
|
||||
Fix handling of zones for BPF on Solaris
|
||||
new DLT for ZWAVE
|
||||
clarifications for read timeouts.
|
||||
Use BPF extensions in compiled filters, fixing VLAN filters
|
||||
some fixes to compilation without stdint.h
|
||||
EBUSY can now be returned by SNFv3 code.
|
||||
Fix the range checks in BPF loads
|
||||
Various DAG fixes.
|
||||
Various Linux fixes.
|
||||
|
||||
Monday Aug. 12, 2014 guy@alum.mit.edu
|
||||
Summary for 1.6.2 tcpdump release
|
||||
Summary for 1.6.2 libpcap release
|
||||
Don't crash on filters testing a non-existent link-layer type
|
||||
field.
|
||||
Fix sending in non-blocking mode on Linux with memory-mapped
|
||||
@ -8,12 +83,12 @@ Monday Aug. 12, 2014 guy@alum.mit.edu
|
||||
machines.
|
||||
|
||||
Saturday Jul. 19, 2014 mcr@sandelman.ca
|
||||
Summary for 1.6.1 tcpdump release
|
||||
Summary for 1.6.1 libpcap release
|
||||
some fixes for the any device
|
||||
changes for how --enable-XXX works
|
||||
changes for how --enable-XXX (--enable-sniffing, --enable-can) works
|
||||
|
||||
Wednesday Jul. 2, 2014 mcr@sandelman.ca
|
||||
Summary for 1.6.0 tcpdump release
|
||||
Summary for 1.6.0 libpcap release
|
||||
Don't support D-Bus sniffing on OS X
|
||||
fixes for byte order issues with NFLOG captures
|
||||
Handle using cooked mode for DLT_NETLINK in activate_new().
|
||||
|
@ -2,11 +2,12 @@ This file lists people who have contributed to libpcap:
|
||||
|
||||
The current maintainers:
|
||||
Bill Fenner <fenner at research dot att dot com>
|
||||
Denis Ovsienko <infrastation at yandex dot ru>
|
||||
Denis Ovsienko <denis at ovsienko dot info>
|
||||
Fulvio Risso <risso at polito dot it>
|
||||
Guy Harris <guy at alum dot mit dot edu>
|
||||
Hannes Gredler <hannes at juniper dot net>
|
||||
Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
|
||||
Francois-Xavier Le Bail <fx dot lebail at yahoo dot com>
|
||||
|
||||
Additional people who have contributed patches:
|
||||
|
||||
@ -45,7 +46,7 @@ Additional people who have contributed patches:
|
||||
David Young <dyoung at ojctech dot com>
|
||||
Dean Gaudet <dean at arctic dot org>
|
||||
dhruv <rsrivat at sourceforge dot net>
|
||||
Don Ebright <Don dot Ebright at compuware dot com>
|
||||
Don Ebright <Don dot Ebright at compuware dot com>
|
||||
Dug Song <dugsong at monkey dot org>
|
||||
Dustin Spicuzza <dustin at virtualroadside dot com>
|
||||
dzejarczech <dzejarczech at sourceforge dot net>
|
||||
@ -83,6 +84,7 @@ Additional people who have contributed patches:
|
||||
Jefferson Ogata <jogata at nodc dot noaa dot gov>
|
||||
Jesper Dangaard Brouer <hawk at comx dot dk>
|
||||
Jesper Peterson <jesper at endace dot com>
|
||||
Jesse Gross <jesse at nicira dot com>
|
||||
Jiri Slaby <jirislaby at gmail dot com>
|
||||
Joerg Mayer <jmayer at loplof dot de>
|
||||
John Bankier <jbankier at rainfinity dot com>
|
||||
@ -105,6 +107,7 @@ Additional people who have contributed patches:
|
||||
Mansour Behabadi <mansour at oxplot dot com>
|
||||
Marcus Felipe Pereira <marcus at task dot com dot br>
|
||||
Mark C. Brown <mbrown at hp dot com>
|
||||
Mark Johnston <markjdb at gmail dot com>
|
||||
Mark Pizzolato <List-tcpdump-workers at subscriptions dot pizzolato dot net>
|
||||
Markus Mayer <markus_mayer at sourceforge dot net>
|
||||
Martin Husemann <martin at netbsd dot org>
|
||||
|
@ -16,7 +16,7 @@ does support packet capture but libpcap does not support that
|
||||
particular type. (If you have HP-UX, see below.) If your system uses a
|
||||
packet capture not supported by libpcap, please send us patches; don't
|
||||
forget to include an autoconf fragment suitable for use in
|
||||
configure.in.
|
||||
configure.ac.
|
||||
|
||||
It is possible to override the default packet capture type, although
|
||||
the circumstance where this works are limited. For example if you have
|
||||
@ -31,40 +31,22 @@ You will need an ANSI C compiler to build libpcap. The configure script
|
||||
will abort if your compiler is not ANSI compliant. If this happens, use
|
||||
the generally available GNU C compiler (GCC).
|
||||
|
||||
If you use flex, you must use version 2.4.6 or higher. The configure
|
||||
script automatically detects the version of flex and will not use it
|
||||
unless it is new enough. You can use "flex -V" to see what version you
|
||||
have (unless it's really old). The current version of flex is available
|
||||
at flex.sourceforge.net and often comes packaged by means of the OS.
|
||||
As of this writing, the current version is 2.5.37.
|
||||
You will need either Flex 2.5.31 or later, or a version of Lex
|
||||
compatible with it (if any exist), to build libpcap. The configure
|
||||
script will abort if there isn't any such program. If you have an older
|
||||
version of Flex, or don't have a compatible version of Lex, the current
|
||||
version of flex is available at flex.sourceforge.net.
|
||||
|
||||
If you use bison, you must use flex (and visa versa). The configure
|
||||
script automatically falls back to lex and yacc if both flex and bison
|
||||
are not found.
|
||||
You will need either Bison, Berkeley YACC, or a version of YACC
|
||||
compatible with them (if any exist), to build libpcap. The configure
|
||||
script will abort if there isn't any such program. If you don't have
|
||||
any such program, the current version of Bison can be found at
|
||||
http://ftp.gnu.org/gnu/bison/ and the current version of Berkeley YACC
|
||||
can be found at http://invisible-island.net/byacc/.
|
||||
|
||||
Sometimes the stock C compiler does not interact well with flex and
|
||||
bison. The list of problems includes undefined references for alloca.
|
||||
You can get around this by installing gcc or manually disabling flex
|
||||
and bison with:
|
||||
|
||||
./configure --without-flex --without-bison
|
||||
|
||||
If your system only has AT&T lex, this is okay unless your libpcap
|
||||
program uses other lex/yacc generated code. (Although it's possible to
|
||||
map the yy* identifiers with a script, we use flex and bison so we
|
||||
don't feel this is necessary.)
|
||||
|
||||
Some systems support the Berkeley Packet Filter natively; for example
|
||||
out of the box OSF and BSD/OS have bpf. If your system does not support
|
||||
bpf, you will need to pick up:
|
||||
|
||||
ftp://ftp.ee.lbl.gov/bpf-*.tar.Z
|
||||
|
||||
Note well: you MUST have kernel source for your operating system in
|
||||
order to install bpf. An exception is SunOS 4; the bpf distribution
|
||||
includes replacement kernel objects for some of the standard SunOS 4
|
||||
network device drivers. See the bpf INSTALL document for more
|
||||
information.
|
||||
Sometimes the stock C compiler does not interact well with Flex and
|
||||
Bison. The list of problems includes undefined references for alloca.
|
||||
You can get around this by installing GCC.
|
||||
|
||||
If you use Solaris, there is a bug with bufmod(7) that is fixed in
|
||||
Solaris 2.3.2 (aka SunOS 5.3.2). Setting a snapshot length with the
|
||||
@ -178,14 +160,14 @@ packet timestamps aren't very good. This appears to be due to haphazard
|
||||
handling of the timestamp in the kernel.
|
||||
|
||||
Note well: there is rumoured to be a version of tcpdump floating around
|
||||
called 3.0.3 that includes libpcap and is supposed to support Linux.
|
||||
called 3.0.3 that includes libpcap and is supposed to support Linux.
|
||||
You should be advised that neither the Network Research Group at LBNL
|
||||
nor the Tcpdump Group ever generated a release with this version number.
|
||||
nor the Tcpdump Group ever generated a release with this version number.
|
||||
The LBNL Network Research Group notes with interest that a standard
|
||||
cracker trick to get people to install trojans is to distribute bogus
|
||||
packages that have a version number higher than the current release.
|
||||
packages that have a version number higher than the current release.
|
||||
They also noted with annoyance that 90% of the Linux related bug reports
|
||||
they got are due to changes made to unofficial versions of their page.
|
||||
they got are due to changes made to unofficial versions of their page.
|
||||
If you are having trouble but aren't using a version that came from
|
||||
tcpdump.org, please try that before submitting a bug report!
|
||||
|
||||
@ -239,11 +221,11 @@ the libpcap 0.6.2 source release, so this release of libpcap might also
|
||||
build without changes on UnixWare 7.
|
||||
|
||||
If linking tcpdump fails with "Undefined: _alloca" when using bison on
|
||||
a Sun4, your version of bison is broken. In any case version 1.16 or
|
||||
a Sun4, your version of Bison is broken. In any case version 1.16 or
|
||||
higher is recommended (1.14 is known to cause problems 1.16 is known to
|
||||
work). Either pick up a current version from:
|
||||
|
||||
ftp://ftp.gnu.org/pub/gnu/bison
|
||||
http://ftp.gnu.org/gnu/bison/
|
||||
|
||||
or hack around it by inserting the lines:
|
||||
|
||||
@ -289,6 +271,7 @@ FILES
|
||||
CHANGES - description of differences between releases
|
||||
ChmodBPF/* - Mac OS X startup item to set ownership and permissions
|
||||
on /dev/bpf*
|
||||
CMakeLists.txt - CMake file
|
||||
CREDITS - people that have helped libpcap along
|
||||
INSTALL.txt - this file
|
||||
LICENSE - the license under which tcpdump is distributed
|
||||
@ -317,7 +300,7 @@ config.guess - autoconf support
|
||||
config.h.in - autoconf input
|
||||
config.sub - autoconf support
|
||||
configure - configure script (run this first)
|
||||
configure.in - configure script source
|
||||
configure.ac - configure script source
|
||||
dlpisubs.c - DLPI-related functions for pcap-dlpi.c and pcap-libdlpi.c
|
||||
dlpisubs.h - DLPI-related function declarations
|
||||
etherent.c - /etc/ethers support routines
|
||||
@ -325,9 +308,6 @@ ethertype.h - Ethernet protocol types and names definitions
|
||||
fad-getad.c - pcap_findalldevs() for systems with getifaddrs()
|
||||
fad-gifc.c - pcap_findalldevs() for systems with only SIOCGIFLIST
|
||||
fad-glifc.c - pcap_findalldevs() for systems with SIOCGLIFCONF
|
||||
fad-null.c - pcap_findalldevs() for systems without capture support
|
||||
fad-sita.c - pcap_findalldevs() for systems with SITA support
|
||||
fad-win32.c - pcap_findalldevs() for WinPcap
|
||||
filtertest.c - test program for BPF compiler
|
||||
findalldevstest.c - test program for pcap_findalldevs()
|
||||
gencode.c - BPF code generation routines
|
||||
@ -345,7 +325,6 @@ nametoaddr.c - hostname to address routines
|
||||
nlpid.h - OSI network layer protocol identifier definitions
|
||||
net - symlink to bpf/net
|
||||
optimize.c - BPF optimization routines
|
||||
packaging - packaging information for building libpcap RPMs
|
||||
pcap/bluetooth.h - public definition of DLT_BLUETOOTH_HCI_H4_WITH_PHDR header
|
||||
pcap/bpf.h - BPF definitions
|
||||
pcap/namedb.h - public libpcap name database definitions
|
||||
@ -389,7 +368,6 @@ pcap_*.3pcap - manual entries for library functions
|
||||
pcap-filter.4 - manual entry for filter syntax
|
||||
pcap-linktype.4 - manual entry for link-layer header types
|
||||
ppp.h - Point to Point Protocol definitions
|
||||
runlex.sh - wrapper for Lex/Flex
|
||||
savefile.c - offline support
|
||||
scanner.l - filter string scanner
|
||||
sunatmpos.h - definitions for SunATM capturing
|
||||
|
@ -1,9 +1,9 @@
|
||||
License: BSD
|
||||
|
||||
|
||||
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
|
||||
@ -13,7 +13,7 @@ are met:
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
@ -2,12 +2,12 @@
|
||||
# Auto-regenerate configure script or Makefile when things change.
|
||||
# From autoconf.info . Works best with GNU Make.
|
||||
#
|
||||
${srcdir}/configure: configure.in aclocal.m4
|
||||
${srcdir}/configure: configure.ac aclocal.m4
|
||||
cd ${srcdir} && autoconf
|
||||
|
||||
# autoheader might not change config.h.in, so touch a stamp file.
|
||||
${srcdir}/config.h.in: ${srcdir}/stamp-h.in
|
||||
${srcdir}/stamp-h.in: configure.in aclocal.m4
|
||||
${srcdir}/stamp-h.in: configure.ac aclocal.m4
|
||||
cd ${srcdir} && autoheader
|
||||
echo timestamp > ${srcdir}/stamp-h.in
|
||||
|
||||
|
@ -49,12 +49,13 @@ LN_S = @LN_S@
|
||||
MKDEP = @MKDEP@
|
||||
CCOPT = @V_CCOPT@
|
||||
INCLS = -I. @V_INCLS@
|
||||
DEFS = @DEFS@ @V_DEFS@
|
||||
DEFS = -DBUILDING_PCAP @DEFS@ @V_DEFS@
|
||||
ADDLOBJS = @ADDLOBJS@
|
||||
ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
|
||||
LIBS = @LIBS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
CROSSFLAGS=
|
||||
CFLAGS = @CFLAGS@ ${CROSSFLAGS}
|
||||
LDFLAGS = @LDFLAGS@ ${CROSSFLAGS}
|
||||
DYEXT = @DYEXT@
|
||||
V_RPATH_OPT = @V_RPATH_OPT@
|
||||
DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
|
||||
@ -68,13 +69,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
RANLIB = @RANLIB@
|
||||
|
||||
#
|
||||
# Flex and bison allow you to specify the prefixes of the global symbols
|
||||
# used by the generated parser. This allows programs to use lex/yacc
|
||||
# and link against libpcap. If you don't have flex or bison, get them.
|
||||
#
|
||||
LEX = @V_LEX@
|
||||
YACC = @V_YACC@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
|
||||
# Also, gcc does not remove the .o before forking 'as', which can be a
|
||||
@ -83,11 +79,11 @@ YACC = @V_YACC@
|
||||
@rm -f $@
|
||||
$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
|
||||
|
||||
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @CAN_SRC@ @NETFILTER_SRC@ @CANUSB_SRC@ @DBUS_SRC@
|
||||
FSRC = fad-@V_FINDALLDEVS@.c
|
||||
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@
|
||||
FSRC = @V_FINDALLDEVS@
|
||||
SSRC = @SSRC@
|
||||
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c \
|
||||
savefile.c sf-pcap.c sf-pcap-ng.c pcap-common.c \
|
||||
CSRC = pcap.c inet.c fad-helpers.c gencode.c optimize.c nametoaddr.c \
|
||||
etherent.c savefile.c sf-pcap.c sf-pcap-ng.c pcap-common.c \
|
||||
bpf_image.c bpf_dump.c
|
||||
GENSRC = scanner.c grammar.c bpf_filter.c version.c
|
||||
LIBOBJS = @LIBOBJS@
|
||||
@ -103,6 +99,9 @@ PUBHDR = \
|
||||
pcap-namedb.h \
|
||||
pcap/bpf.h \
|
||||
pcap/bluetooth.h \
|
||||
pcap/can_socketcan.h \
|
||||
pcap/dlt.h \
|
||||
pcap/export-defs.h \
|
||||
pcap/ipnet.h \
|
||||
pcap/namedb.h \
|
||||
pcap/nflog.h \
|
||||
@ -115,37 +114,43 @@ HDR = $(PUBHDR) \
|
||||
arcnet.h \
|
||||
atmuni31.h \
|
||||
ethertype.h \
|
||||
extract.h \
|
||||
gencode.h \
|
||||
ieee80211.h \
|
||||
llc.h \
|
||||
nametoaddr.h \
|
||||
nlpid.h \
|
||||
pcap-common.h \
|
||||
pcap-int.h \
|
||||
pcap-stdinc.h \
|
||||
portability.h \
|
||||
ppp.h \
|
||||
sf-pcap.h \
|
||||
sf-pcap-ng.h \
|
||||
sunatmpos.h
|
||||
|
||||
TESTS = \
|
||||
@VALGRINDTEST@ \
|
||||
capturetest \
|
||||
can_set_rfmon_test \
|
||||
filtertest \
|
||||
findalldevstest \
|
||||
opentest \
|
||||
selpolltest \
|
||||
valgrindtest
|
||||
reactivatetest \
|
||||
selpolltest
|
||||
|
||||
TESTS_SRC = \
|
||||
tests/valgrindtest.c \
|
||||
tests/capturetest.c \
|
||||
tests/can_set_rfmon_test.c \
|
||||
tests/filtertest.c \
|
||||
tests/findalldevstest.c \
|
||||
tests/opentest.c \
|
||||
tests/reactivatetest.c \
|
||||
tests/selpolltest.c \
|
||||
tests/valgrindtest.c
|
||||
tests/selpolltest.c
|
||||
|
||||
GENHDR = \
|
||||
scanner.h tokdefs.h version.h
|
||||
scanner.h grammar.h pcap_version.h
|
||||
|
||||
TAGFILES = \
|
||||
$(SRC) $(HDR)
|
||||
@ -231,6 +236,8 @@ EXTRA_DIST = \
|
||||
ChmodBPF/ChmodBPF \
|
||||
ChmodBPF/StartupParameters.plist \
|
||||
CREDITS \
|
||||
CMakeLists.txt \
|
||||
GenVersion.bat \
|
||||
INSTALL.txt \
|
||||
LICENSE \
|
||||
Makefile.in \
|
||||
@ -253,29 +260,37 @@ EXTRA_DIST = \
|
||||
aclocal.m4 \
|
||||
bpf/net/bpf_filter.c \
|
||||
chmod_bpf \
|
||||
cmakeconfig.h.in \
|
||||
cmake/preconfigure.cmake \
|
||||
config/have_siocglifconf.c \
|
||||
config.guess \
|
||||
config.h.in \
|
||||
config.sub \
|
||||
configure \
|
||||
configure.in \
|
||||
configure.ac \
|
||||
dlpisubs.c \
|
||||
dlpisubs.h \
|
||||
fad-getad.c \
|
||||
fad-gifc.c \
|
||||
fad-glifc.c \
|
||||
fad-null.c \
|
||||
fad-sita.c \
|
||||
fad-win32.c \
|
||||
fad-helpers.c \
|
||||
gen_version_c.sh \
|
||||
gen_version_header.sh \
|
||||
grammar.y \
|
||||
install-sh \
|
||||
lbl/os-aix4.h \
|
||||
lbl/os-aix7.h \
|
||||
lbl/os-hpux11.h \
|
||||
lbl/os-osf4.h \
|
||||
lbl/os-osf5.h \
|
||||
lbl/os-solaris2.h \
|
||||
lbl/os-sunos4.h \
|
||||
lbl/os-ultrix4.h \
|
||||
missing/getopt.c \
|
||||
missing/getopt.h \
|
||||
missing/snprintf.c \
|
||||
missing/strtok_r.c \
|
||||
missing/win_snprintf.c \
|
||||
mkdep \
|
||||
msdos/bin2c.c \
|
||||
msdos/common.dj \
|
||||
@ -291,16 +306,11 @@ EXTRA_DIST = \
|
||||
msdos/pktdrvr.h \
|
||||
msdos/readme.dos \
|
||||
org.tcpdump.chmod_bpf.plist \
|
||||
packaging/pcap.spec.in \
|
||||
pcap-bpf.c \
|
||||
pcap-bt-linux.c \
|
||||
pcap-bt-linux.h \
|
||||
pcap-bt-monitor-linux.c \
|
||||
pcap-bt-monitor-linux.h \
|
||||
pcap-can-linux.c \
|
||||
pcap-can-linux.h \
|
||||
pcap-canusb-linux.c \
|
||||
pcap-canusb-linux.h \
|
||||
pcap-config.in \
|
||||
pcap-dag.c \
|
||||
pcap-dag.h \
|
||||
@ -314,11 +324,14 @@ EXTRA_DIST = \
|
||||
pcap-libdlpi.c \
|
||||
pcap-linux.c \
|
||||
pcap-namedb.h \
|
||||
pcap-new.c \
|
||||
pcap-netfilter-linux.c \
|
||||
pcap-netfilter-linux.h \
|
||||
pcap-nit.c \
|
||||
pcap-null.c \
|
||||
pcap-pf.c \
|
||||
pcap-rpcap.c \
|
||||
pcap-rpcap.h \
|
||||
pcap-septel.c \
|
||||
pcap-septel.h \
|
||||
pcap-sita.h \
|
||||
@ -328,34 +341,22 @@ EXTRA_DIST = \
|
||||
pcap-snf.h \
|
||||
pcap-snit.c \
|
||||
pcap-snoop.c \
|
||||
pcap-tc.c \
|
||||
pcap-tc.h \
|
||||
pcap-usb-linux.c \
|
||||
pcap-usb-linux.h \
|
||||
pcap-win32.c \
|
||||
runlex.sh \
|
||||
remote-ext.h \
|
||||
sockutils.c \
|
||||
sockutils.h \
|
||||
scanner.l \
|
||||
tests/CMakeLists.txt \
|
||||
pcap_version.h.in \
|
||||
Win32/Include/Gnuc.h \
|
||||
Win32/Include/addrinfo.h \
|
||||
Win32/Include/bittypes.h \
|
||||
Win32/Include/cdecl_ext.h \
|
||||
Win32/Include/inetprivate.h \
|
||||
Win32/Include/ip6_misc.h \
|
||||
Win32/Include/sockstorage.h \
|
||||
Win32/Include/arpa/nameser.h \
|
||||
Win32/Include/net/if.h \
|
||||
Win32/Include/net/netdb.h \
|
||||
Win32/Include/net/paths.h \
|
||||
Win32/Prj/libpcap.dsp \
|
||||
Win32/Prj/libpcap.dsw \
|
||||
Win32/Src/ffs.c \
|
||||
Win32/Src/gai_strerror.c \
|
||||
Win32/Src/getaddrinfo.c \
|
||||
Win32/Src/getnetbynm.c \
|
||||
Win32/Src/getnetent.c \
|
||||
Win32/Src/getopt.c \
|
||||
Win32/Src/getservent.c \
|
||||
Win32/Src/inet_aton.c \
|
||||
Win32/Src/inet_net.c \
|
||||
Win32/Src/inet_pton.c
|
||||
Win32/Prj/wpcap.sln \
|
||||
Win32/Prj/wpcap.vcxproj \
|
||||
Win32/Prj/wpcap.vcxproj.filters
|
||||
|
||||
all: libpcap.a shared pcap-config
|
||||
|
||||
@ -443,24 +444,33 @@ libpcap.shareda: $(OBJ)
|
||||
libpcap.none:
|
||||
|
||||
scanner.c: $(srcdir)/scanner.l
|
||||
@rm -f $@
|
||||
$(srcdir)/runlex.sh $(LEX) -o$@ $<
|
||||
$(LEX) -P pcap_ --header-file=scanner.h --nounput -o scanner.c $<
|
||||
scanner.h: scanner.c
|
||||
## Recover from the removal of $@
|
||||
@if test -f $@; then :; else \
|
||||
rm -f scanner.c; \
|
||||
$(MAKE) $(MAKEFLAGS) scanner.c; \
|
||||
fi
|
||||
|
||||
scanner.o: scanner.c tokdefs.h
|
||||
scanner.o: scanner.c grammar.h
|
||||
$(CC) $(FULL_CFLAGS) -c scanner.c
|
||||
|
||||
pcap.o: version.h
|
||||
pcap.o: pcap_version.h
|
||||
|
||||
tokdefs.h: grammar.c
|
||||
grammar.c: $(srcdir)/grammar.y
|
||||
@rm -f grammar.c tokdefs.h
|
||||
$(YACC) -d $<
|
||||
mv y.tab.c grammar.c
|
||||
mv y.tab.h tokdefs.h
|
||||
$(YACC) -p pcap_ -o grammar.c -d $<
|
||||
grammar.h: grammar.c
|
||||
## Recover from the removal of $@
|
||||
@if test -f $@; then :; else \
|
||||
rm -f grammar.c; \
|
||||
$(MAKE) $(MAKEFLAGS) grammar.c; \
|
||||
fi
|
||||
|
||||
grammar.o: grammar.c
|
||||
@rm -f $@
|
||||
$(CC) $(FULL_CFLAGS) -Dyylval=pcap_lval -c grammar.c
|
||||
$(CC) $(FULL_CFLAGS) -c grammar.c
|
||||
|
||||
gencode.o: $(srcdir)/gencode.c grammar.h scanner.h
|
||||
$(CC) $(FULL_CFLAGS) -c $(srcdir)/gencode.c
|
||||
|
||||
version.o: version.c
|
||||
$(CC) $(FULL_CFLAGS) -c version.c
|
||||
@ -468,32 +478,21 @@ version.o: version.c
|
||||
snprintf.o: $(srcdir)/missing/snprintf.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
|
||||
|
||||
version.c: $(srcdir)/VERSION
|
||||
@rm -f $@
|
||||
if grep GIT ${srcdir}/VERSION >/dev/null; then \
|
||||
read ver <${srcdir}/VERSION; \
|
||||
echo $$ver | tr -d '\012'; \
|
||||
date +_%Y_%m_%d; \
|
||||
else \
|
||||
cat ${srcdir}/VERSION; \
|
||||
fi | sed -e 's/.*/char pcap_version[] = "&";/' > $@
|
||||
strtok_r.o: $(srcdir)/missing/strtok_r.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strtok_r.c
|
||||
|
||||
#
|
||||
# NOTE: this really is supposed to be static; importing a string
|
||||
# from a shared library does not work very well on many
|
||||
# versions of UNIX (Solaris, Linux, and the BSDs, for example),
|
||||
# so we make the version string static and return it from
|
||||
# a function, which does work.
|
||||
#
|
||||
version.h: $(srcdir)/VERSION
|
||||
version.c: $(srcdir)/VERSION $(srcdir)/gen_version_c.sh
|
||||
#
|
||||
# Older programs import this if they want to show the
|
||||
# libpcap version number, rather than calling
|
||||
# pcap_lib_version(), so we need to export it.
|
||||
#
|
||||
@rm -f $@
|
||||
if grep GIT ${srcdir}/VERSION >/dev/null; then \
|
||||
read ver <${srcdir}/VERSION; \
|
||||
echo $$ver | tr -d '\012'; \
|
||||
date +_%Y_%m_%d; \
|
||||
else \
|
||||
cat ${srcdir}/VERSION; \
|
||||
fi | sed -e 's/.*/static const char pcap_version_string[] = "libpcap version &";/' > $@
|
||||
$(srcdir)/gen_version_c.sh $(srcdir)/VERSION $@
|
||||
|
||||
pcap_version.h: $(srcdir)/VERSION $(srcdir)/pcap_version.h.in $(srcdir)/gen_version_header.sh
|
||||
@rm -f $@
|
||||
$(srcdir)/gen_version_header.sh $(srcdir)/VERSION $(srcdir)/pcap_version.h.in $@
|
||||
|
||||
bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
|
||||
rm -f bpf_filter.c
|
||||
@ -530,6 +529,9 @@ tests: $(TESTS)
|
||||
capturetest: tests/capturetest.c libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/tests/capturetest.c libpcap.a $(LIBS)
|
||||
|
||||
can_set_rfmon_test: tests/can_set_rfmon_test.c libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o can_set_rfmon_test $(srcdir)/tests/can_set_rfmon_test.c libpcap.a $(LIBS)
|
||||
|
||||
filtertest: tests/filtertest.c libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o filtertest $(srcdir)/tests/filtertest.c libpcap.a $(LIBS)
|
||||
|
||||
@ -539,6 +541,9 @@ findalldevstest: tests/findalldevstest.c libpcap.a
|
||||
opentest: tests/opentest.c libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/tests/opentest.c libpcap.a $(LIBS)
|
||||
|
||||
reactivatetest: tests/reactivatetest.c libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o reactivatetest $(srcdir)/tests/reactivatetest.c libpcap.a $(LIBS)
|
||||
|
||||
selpolltest: tests/selpolltest.c libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o selpolltest $(srcdir)/tests/selpolltest.c libpcap.a $(LIBS)
|
||||
|
||||
@ -728,13 +733,12 @@ distclean: clean
|
||||
rm -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=)
|
||||
rm -rf autom4te.cache
|
||||
|
||||
extags: $(TAGFILES)
|
||||
ctags $(TAGFILES)
|
||||
|
||||
tags: $(TAGFILES)
|
||||
ctags -wtd $(TAGFILES)
|
||||
|
||||
packaging/pcap.spec: packaging/pcap.spec.in VERSION
|
||||
RPMVERSION=`cat VERSION | sed s/-.*//g`; \
|
||||
sed -e s/@VERSION@/$$RPMVERSION/ -e s/@NAME@/libpcap-`cat VERSION`/ $< > $@
|
||||
|
||||
releasetar:
|
||||
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
|
||||
mkdir $$name; \
|
||||
|
@ -76,15 +76,15 @@ information on configuring that option.
|
||||
|
||||
Note to Linux distributions and *BSD systems that include libpcap:
|
||||
|
||||
There's now a rule to make a shared library, which should work on Linux
|
||||
There's now a rule to make a shared library, which should work on Linux
|
||||
and *BSD, among other platforms.
|
||||
|
||||
It sets the soname of the library to "libpcap.so.1"; this is what it
|
||||
should be, *NOT* libpcap.so.1.x or libpcap.so.1.x.y or something such as
|
||||
It sets the soname of the library to "libpcap.so.1"; this is what it
|
||||
should be, *NOT* libpcap.so.1.x or libpcap.so.1.x.y or something such as
|
||||
that.
|
||||
|
||||
We've been maintaining binary compatibility between libpcap releases for
|
||||
quite a while; there's no reason to tie a binary linked with libpcap to
|
||||
We've been maintaining binary compatibility between libpcap releases for
|
||||
quite a while; there's no reason to tie a binary linked with libpcap to
|
||||
a particular release of libpcap.
|
||||
|
||||
Problems, bugs, questions, desirable enhancements, etc. should be sent
|
||||
|
@ -6,11 +6,11 @@ Important stuff (to be done before the next release)
|
||||
|
||||
General
|
||||
|
||||
- configure should not be in Git. Most open source projects have an
|
||||
autogen.sh script to run autoconf etc. after checkout. I think we
|
||||
should stick to the standard.
|
||||
- configure should not be in Git. Most open source projects have an
|
||||
autogen.sh script to run autoconf etc. after checkout. I think we
|
||||
should stick to the standard.
|
||||
|
||||
- The source files should be better documented. There is no official
|
||||
- The source files should be better documented. There is no official
|
||||
design guideline for what is done where. There should be a common coding
|
||||
style (okay, you can guess that by looking at the code) and a guide for
|
||||
what needs to be documented.
|
||||
@ -18,7 +18,7 @@ General
|
||||
Less urgent items
|
||||
-----------------
|
||||
|
||||
- Better documentation and cleanup of the interface. I am seeing a few
|
||||
- Better documentation and cleanup of the interface. I am seeing a few
|
||||
problems at the first glance which needs fixing:
|
||||
+ pcap_lookupnet makes little to no sense with protocols != IPv4
|
||||
+ not very well suited for interactive programs (think ethereal). There
|
||||
|
@ -1 +1 @@
|
||||
1.6.2
|
||||
1.8.1
|
||||
|
@ -42,11 +42,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <pcap-stdinc.h>
|
||||
|
||||
#else /* WIN32 */
|
||||
#else /* _WIN32 */
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
@ -73,7 +73,7 @@
|
||||
# define MLEN(m) ((m)->m_len)
|
||||
#endif /* defined(__hpux) || SOLARIS */
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <pcap/bpf.h>
|
||||
|
||||
@ -99,7 +99,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef LBL_ALIGN
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
@ -195,23 +195,41 @@ m_xhalf(m, k, err)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/filter.h>
|
||||
#endif
|
||||
|
||||
enum {
|
||||
BPF_S_ANC_NONE,
|
||||
BPF_S_ANC_VLAN_TAG,
|
||||
BPF_S_ANC_VLAN_TAG_PRESENT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Execute the filter program starting at pc on the packet p
|
||||
* wirelen is the length of the original packet
|
||||
* buflen is the amount of data present
|
||||
* aux_data is auxiliary data, currently used only when interpreting
|
||||
* filters intended for the Linux kernel in cases where the kernel
|
||||
* rejects the filter; it contains VLAN tag information
|
||||
* For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
|
||||
* in all other cases, p is a pointer to a buffer and buflen is its size.
|
||||
*
|
||||
* Thanks to Ani Sinha <ani@arista.com> for providing initial implementation
|
||||
*/
|
||||
u_int
|
||||
bpf_filter(pc, p, wirelen, buflen)
|
||||
bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
|
||||
register const struct bpf_insn *pc;
|
||||
register const u_char *p;
|
||||
u_int wirelen;
|
||||
register u_int buflen;
|
||||
register const struct bpf_aux_data *aux_data;
|
||||
{
|
||||
register u_int32 A, X;
|
||||
register int k;
|
||||
int32 mem[BPF_MEMWORDS];
|
||||
register bpf_u_int32 k;
|
||||
u_int32 mem[BPF_MEMWORDS];
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
struct mbuf *m, *n;
|
||||
int merr, len;
|
||||
@ -250,7 +268,7 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
|
||||
case BPF_LD|BPF_W|BPF_ABS:
|
||||
k = pc->k;
|
||||
if (k + sizeof(int32) > buflen) {
|
||||
if (k > buflen || sizeof(int32_t) > buflen - k) {
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
@ -267,7 +285,7 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
|
||||
case BPF_LD|BPF_H|BPF_ABS:
|
||||
k = pc->k;
|
||||
if (k + sizeof(short) > buflen) {
|
||||
if (k > buflen || sizeof(int16_t) > buflen - k) {
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
@ -283,22 +301,50 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
continue;
|
||||
|
||||
case BPF_LD|BPF_B|BPF_ABS:
|
||||
k = pc->k;
|
||||
if (k >= buflen) {
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
n = m;
|
||||
MINDEX(len, n, k);
|
||||
A = mtod(n, u_char *)[k];
|
||||
continue;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
A = p[k];
|
||||
continue;
|
||||
{
|
||||
#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
|
||||
int code = BPF_S_ANC_NONE;
|
||||
#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \
|
||||
code = BPF_S_ANC_##CODE; \
|
||||
if (!aux_data) \
|
||||
return 0; \
|
||||
break;
|
||||
|
||||
switch (pc->k) {
|
||||
ANCILLARY(VLAN_TAG);
|
||||
ANCILLARY(VLAN_TAG_PRESENT);
|
||||
default :
|
||||
#endif
|
||||
k = pc->k;
|
||||
if (k >= buflen) {
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
n = m;
|
||||
MINDEX(len, n, k);
|
||||
A = mtod(n, u_char *)[k];
|
||||
continue;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
A = p[k];
|
||||
#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
|
||||
}
|
||||
switch (code) {
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
if (aux_data)
|
||||
A = aux_data->vlan_tag;
|
||||
break;
|
||||
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
if (aux_data)
|
||||
A = aux_data->vlan_tag_present;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
case BPF_LD|BPF_W|BPF_LEN:
|
||||
A = wirelen;
|
||||
continue;
|
||||
@ -309,7 +355,8 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
|
||||
case BPF_LD|BPF_W|BPF_IND:
|
||||
k = X + pc->k;
|
||||
if (k + sizeof(int32) > buflen) {
|
||||
if (pc->k > buflen || X > buflen - pc->k ||
|
||||
sizeof(int32_t) > buflen - k) {
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
@ -326,7 +373,8 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
|
||||
case BPF_LD|BPF_H|BPF_IND:
|
||||
k = X + pc->k;
|
||||
if (k + sizeof(short) > buflen) {
|
||||
if (X > buflen || pc->k > buflen - X ||
|
||||
sizeof(int16_t) > buflen - k) {
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
@ -343,7 +391,7 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
|
||||
case BPF_LD|BPF_B|BPF_IND:
|
||||
k = X + pc->k;
|
||||
if (k >= buflen) {
|
||||
if (pc->k >= buflen || X >= buflen - pc->k) {
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
@ -531,7 +579,12 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_NEG:
|
||||
A = -A;
|
||||
/*
|
||||
* Most BPF arithmetic is unsigned, but negation
|
||||
* can't be unsigned; throw some casts to
|
||||
* specify what we're trying to do.
|
||||
*/
|
||||
A = (u_int32)(-(int32)A);
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TAX:
|
||||
@ -545,6 +598,17 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
}
|
||||
}
|
||||
|
||||
u_int
|
||||
bpf_filter(pc, p, wirelen, buflen)
|
||||
register const struct bpf_insn *pc;
|
||||
register const u_char *p;
|
||||
u_int wirelen;
|
||||
register u_int buflen;
|
||||
{
|
||||
return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the 'fcode' is a valid filter program.
|
||||
* The constraints are that each jump be forward and to a valid
|
||||
@ -574,7 +638,7 @@ bpf_validate(f, len)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
for (i = 0; i < (u_int)len; ++i) {
|
||||
p = &f[i];
|
||||
switch (BPF_CLASS(p->code)) {
|
||||
/*
|
||||
@ -675,7 +739,7 @@ bpf_validate(f, len)
|
||||
#if defined(KERNEL) || defined(_KERNEL)
|
||||
if (from + p->k < from || from + p->k >= len)
|
||||
#else
|
||||
if (from + p->k >= len)
|
||||
if (from + p->k >= (u_int)len)
|
||||
#endif
|
||||
return 0;
|
||||
break;
|
||||
@ -683,7 +747,7 @@ bpf_validate(f, len)
|
||||
case BPF_JGT:
|
||||
case BPF_JGE:
|
||||
case BPF_JSET:
|
||||
if (from + p->jt >= len || from + p->jf >= len)
|
||||
if (from + p->jt >= (u_int)len || from + p->jf >= (u_int)len)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -51,7 +51,10 @@ bpf_dump(const struct bpf_program *p, int option)
|
||||
for (i = 0; i < n; ++insn, ++i) {
|
||||
#ifdef BDEBUG
|
||||
extern int bids[];
|
||||
printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
|
||||
if (bids[i] > 0)
|
||||
printf("[%02d]", bids[i] - 1);
|
||||
else
|
||||
printf(" -- ");
|
||||
#endif
|
||||
puts(bpf_image(insn, i));
|
||||
}
|
||||
|
@ -23,9 +23,9 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#else /* _WIN32 */
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif HAVE_STDINT_H
|
||||
@ -35,7 +35,7 @@
|
||||
#include <sys/bitypes.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -306,13 +306,13 @@ bpf_image(p, n)
|
||||
fmt = "";
|
||||
break;
|
||||
}
|
||||
(void)snprintf(operand, sizeof operand, fmt, v);
|
||||
(void)pcap_snprintf(operand, sizeof operand, fmt, v);
|
||||
if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
|
||||
(void)snprintf(image, sizeof image,
|
||||
(void)pcap_snprintf(image, sizeof image,
|
||||
"(%03d) %-8s %-16s jt %d\tjf %d",
|
||||
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
|
||||
} else {
|
||||
(void)snprintf(image, sizeof image,
|
||||
(void)pcap_snprintf(image, sizeof image,
|
||||
"(%03d) %-8s %s",
|
||||
n, op, operand);
|
||||
}
|
||||
|
373
contrib/libpcap/config.guess
vendored
373
contrib/libpcap/config.guess
vendored
@ -1,14 +1,12 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2012-02-10'
|
||||
timestamp='2015-02-23'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
@ -22,19 +20,17 @@ timestamp='2012-02-10'
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Originally written by Per Bothner. Please send patches (context
|
||||
# diff format) to <config-patches@gnu.org> and include a ChangeLog
|
||||
# entry.
|
||||
# the same distribution terms that you use for the rest of that
|
||||
# program. This Exception is an additional permission under section 7
|
||||
# of the GNU General Public License, version 3 ("GPLv3").
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
# exits with 0. Otherwise, it exits with 1.
|
||||
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
|
||||
#
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
#
|
||||
# Please send patches to <config-patches@gnu.org>.
|
||||
|
||||
|
||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||
|
||||
@ -54,9 +50,7 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||
Free Software Foundation, Inc.
|
||||
Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@ -138,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
|
||||
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
case "${UNAME_SYSTEM}" in
|
||||
Linux|GNU|GNU/*)
|
||||
# If the system lacks a compiler, then just pick glibc.
|
||||
# We could probably try harder.
|
||||
LIBC=gnu
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat <<-EOF > $dummy.c
|
||||
#include <features.h>
|
||||
#if defined(__UCLIBC__)
|
||||
LIBC=uclibc
|
||||
#elif defined(__dietlibc__)
|
||||
LIBC=dietlibc
|
||||
#else
|
||||
LIBC=gnu
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
|
||||
;;
|
||||
esac
|
||||
|
||||
# Note: order is significant - the case branches are not exclusive.
|
||||
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
@ -153,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# Note: NetBSD doesn't particularly care about the vendor
|
||||
# portion of the name. We always set it to "unknown".
|
||||
sysctl="sysctl -n hw.machine_arch"
|
||||
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
|
||||
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
|
||||
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
|
||||
/sbin/$sysctl 2>/dev/null || \
|
||||
/usr/sbin/$sysctl 2>/dev/null || \
|
||||
echo unknown)`
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
armeb) machine=armeb-unknown ;;
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
sh5el) machine=sh5le-unknown ;;
|
||||
earmv*)
|
||||
arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
|
||||
endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
|
||||
machine=${arch}${endian}-unknown
|
||||
;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
# to ELF recently, or will in the future.
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ELF__
|
||||
@ -182,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
os=netbsd
|
||||
;;
|
||||
esac
|
||||
# Determine ABI tags.
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
earm*)
|
||||
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
|
||||
abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
# Debian GNU/NetBSD machines have a different userland, and
|
||||
# thus, need a distinct triplet. However, they do not need
|
||||
@ -198,7 +227,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
||||
# contains redundant information, the shorter form:
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
echo "${machine}-${os}${release}${abi}"
|
||||
exit ;;
|
||||
*:Bitrig:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:OpenBSD:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
||||
@ -302,7 +335,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
arm:riscos:*:*|arm:RISCOS:*:*)
|
||||
arm*:riscos:*:*|arm*:RISCOS:*:*)
|
||||
echo arm-unknown-riscos
|
||||
exit ;;
|
||||
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
|
||||
@ -560,8 +593,9 @@ EOF
|
||||
else
|
||||
IBM_ARCH=powerpc
|
||||
fi
|
||||
if [ -x /usr/bin/oslevel ] ; then
|
||||
IBM_REV=`/usr/bin/oslevel`
|
||||
if [ -x /usr/bin/lslpp ] ; then
|
||||
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
|
||||
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
|
||||
else
|
||||
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
|
||||
fi
|
||||
@ -801,10 +835,13 @@ EOF
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
exit ;;
|
||||
*:MINGW64*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw64
|
||||
exit ;;
|
||||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:MSYS*:*)
|
||||
*:MSYS*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msys
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
@ -852,21 +889,21 @@ EOF
|
||||
exit ;;
|
||||
*:GNU:*:*)
|
||||
# the GNU system
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
exit ;;
|
||||
*:GNU/*:*:*)
|
||||
# other systems with GNU libc and userland
|
||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
||||
exit ;;
|
||||
i*86:Minix:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
exit ;;
|
||||
aarch64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
aarch64_be:Linux:*:*)
|
||||
UNAME_MACHINE=aarch64_be
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
alpha:Linux:*:*)
|
||||
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
||||
@ -879,59 +916,54 @@ EOF
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
arc:Linux:*:* | arceb:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
else
|
||||
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_PCS_VFP
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
|
||||
fi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-gnu
|
||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-gnu
|
||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
hexagon:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
LIBC=gnu
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#ifdef __dietlibc__
|
||||
LIBC=dietlibc
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
||||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
mips:Linux:*:* | mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
@ -950,54 +982,63 @@ EOF
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
|
||||
;;
|
||||
or32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
openrisc*:Linux:*:*)
|
||||
echo or1k-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
or32:Linux:*:* | or1k*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
padre:Linux:*:*)
|
||||
echo sparc-unknown-linux-gnu
|
||||
echo sparc-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-gnu
|
||||
echo hppa64-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
parisc:Linux:*:* | hppa:Linux:*:*)
|
||||
# Look for CPU level
|
||||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||||
PA7*) echo hppa1.1-unknown-linux-gnu ;;
|
||||
PA8*) echo hppa2.0-unknown-linux-gnu ;;
|
||||
*) echo hppa-unknown-linux-gnu ;;
|
||||
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
|
||||
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
|
||||
*) echo hppa-unknown-linux-${LIBC} ;;
|
||||
esac
|
||||
exit ;;
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
echo powerpc64-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
echo powerpc-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
ppc64le:Linux:*:*)
|
||||
echo powerpc64le-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
ppcle:Linux:*:*)
|
||||
echo powerpcle-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
s390:Linux:*:* | s390x:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-linux
|
||||
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
|
||||
exit ;;
|
||||
sh64*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
sh*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
tile*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
vax:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-dec-linux-gnu
|
||||
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
||||
exit ;;
|
||||
x86_64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
i*86:DYNIX/ptx:4*:*)
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
||||
@ -1201,6 +1242,9 @@ EOF
|
||||
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
||||
echo i586-pc-haiku
|
||||
exit ;;
|
||||
x86_64:Haiku:*:*)
|
||||
echo x86_64-unknown-haiku
|
||||
exit ;;
|
||||
SX-4:SUPER-UX:*:*)
|
||||
echo sx4-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@ -1227,19 +1271,31 @@ EOF
|
||||
exit ;;
|
||||
*:Darwin:*:*)
|
||||
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
||||
case $UNAME_PROCESSOR in
|
||||
i386)
|
||||
eval $set_cc_for_build
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
UNAME_PROCESSOR="x86_64"
|
||||
fi
|
||||
fi ;;
|
||||
unknown) UNAME_PROCESSOR=powerpc ;;
|
||||
esac
|
||||
eval $set_cc_for_build
|
||||
if test "$UNAME_PROCESSOR" = unknown ; then
|
||||
UNAME_PROCESSOR=powerpc
|
||||
fi
|
||||
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
case $UNAME_PROCESSOR in
|
||||
i386) UNAME_PROCESSOR=x86_64 ;;
|
||||
powerpc) UNAME_PROCESSOR=powerpc64 ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
elif test "$UNAME_PROCESSOR" = i386 ; then
|
||||
# Avoid executing cc on OS X 10.9, as it ships with a stub
|
||||
# that puts up a graphical alert prompting to install
|
||||
# developer tools. Any system running Mac OS X 10.7 or
|
||||
# later (Darwin 11 and later) is required to have a 64-bit
|
||||
# processor. This is not true of the ARM version of Darwin
|
||||
# that Apple uses in portable devices.
|
||||
UNAME_PROCESSOR=x86_64
|
||||
fi
|
||||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||
@ -1256,7 +1312,7 @@ EOF
|
||||
NEO-?:NONSTOP_KERNEL:*:*)
|
||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSE-?:NONSTOP_KERNEL:*:*)
|
||||
NSE-*:NONSTOP_KERNEL:*:*)
|
||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSR-?:NONSTOP_KERNEL:*:*)
|
||||
@ -1330,157 +1386,6 @@ EOF
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat >$dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
# include <sys/types.h>
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
main ()
|
||||
{
|
||||
#if defined (sony)
|
||||
#if defined (MIPSEB)
|
||||
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
|
||||
I don't know.... */
|
||||
printf ("mips-sony-bsd\n"); exit (0);
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
printf ("m68k-sony-newsos%s\n",
|
||||
#ifdef NEWSOS4
|
||||
"4"
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__arm) && defined (__acorn) && defined (__unix)
|
||||
printf ("arm-acorn-riscix\n"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (hp300) && !defined (hpux)
|
||||
printf ("m68k-hp-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (NeXT)
|
||||
#if !defined (__ARCHITECTURE__)
|
||||
#define __ARCHITECTURE__ "m68k"
|
||||
#endif
|
||||
int version;
|
||||
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
|
||||
if (version < 4)
|
||||
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
|
||||
else
|
||||
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
|
||||
exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (MULTIMAX) || defined (n16)
|
||||
#if defined (UMAXV)
|
||||
printf ("ns32k-encore-sysv\n"); exit (0);
|
||||
#else
|
||||
#if defined (CMU)
|
||||
printf ("ns32k-encore-mach\n"); exit (0);
|
||||
#else
|
||||
printf ("ns32k-encore-bsd\n"); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__386BSD__)
|
||||
printf ("i386-pc-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (sequent)
|
||||
#if defined (i386)
|
||||
printf ("i386-sequent-dynix\n"); exit (0);
|
||||
#endif
|
||||
#if defined (ns32000)
|
||||
printf ("ns32k-sequent-dynix\n"); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (_SEQUENT_)
|
||||
struct utsname un;
|
||||
|
||||
uname(&un);
|
||||
|
||||
if (strncmp(un.version, "V2", 2) == 0) {
|
||||
printf ("i386-sequent-ptx2\n"); exit (0);
|
||||
}
|
||||
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
|
||||
printf ("i386-sequent-ptx1\n"); exit (0);
|
||||
}
|
||||
printf ("i386-sequent-ptx\n"); exit (0);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (vax)
|
||||
# if !defined (ultrix)
|
||||
# include <sys/param.h>
|
||||
# if defined (BSD)
|
||||
# if BSD == 43
|
||||
printf ("vax-dec-bsd4.3\n"); exit (0);
|
||||
# else
|
||||
# if BSD == 199006
|
||||
printf ("vax-dec-bsd4.3reno\n"); exit (0);
|
||||
# else
|
||||
printf ("vax-dec-bsd\n"); exit (0);
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
printf ("vax-dec-bsd\n"); exit (0);
|
||||
# endif
|
||||
# else
|
||||
printf ("vax-dec-ultrix\n"); exit (0);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (alliant) && defined (i860)
|
||||
printf ("i860-alliant-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
exit (1);
|
||||
}
|
||||
EOF
|
||||
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
|
||||
{ echo "$SYSTEM_NAME"; exit; }
|
||||
|
||||
# Apollos put the system type in the environment.
|
||||
|
||||
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
|
||||
|
||||
# Convex versions that predate uname can use getsysinfo(1)
|
||||
|
||||
if [ -x /usr/convex/getsysinfo ]
|
||||
then
|
||||
case `getsysinfo -f cpu_type` in
|
||||
c1*)
|
||||
echo c1-convex-bsd
|
||||
exit ;;
|
||||
c2*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit ;;
|
||||
c34*)
|
||||
echo c34-convex-bsd
|
||||
exit ;;
|
||||
c38*)
|
||||
echo c38-convex-bsd
|
||||
exit ;;
|
||||
c4*)
|
||||
echo c4-convex-bsd
|
||||
exit ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
cat >&2 <<EOF
|
||||
$0: unable to guess system type
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Enable optimizer debugging */
|
||||
#undef BDEBUG
|
||||
@ -76,12 +76,18 @@
|
||||
/* Define to 1 if you have the <linux/ethtool.h> header file. */
|
||||
#undef HAVE_LINUX_ETHTOOL_H
|
||||
|
||||
/* Define to 1 if you have the <linux/if_bonding.h> header file. */
|
||||
#undef HAVE_LINUX_IF_BONDING_H
|
||||
|
||||
/* Define to 1 if you have the <linux/if_packet.h> header file. */
|
||||
#undef HAVE_LINUX_IF_PACKET_H
|
||||
|
||||
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
|
||||
#undef HAVE_LINUX_NET_TSTAMP_H
|
||||
|
||||
/* Define to 1 if you have the <linux/sockios.h> header file. */
|
||||
#undef HAVE_LINUX_SOCKIOS_H
|
||||
|
||||
/* if tp_vlan_tci exists */
|
||||
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
|
||||
|
||||
@ -118,16 +124,13 @@
|
||||
/* if there's an os_proto.h for this platform, to use additional prototypes */
|
||||
#undef HAVE_OS_PROTO_H
|
||||
|
||||
/* Define to 1 if you have the <paths.h> header file. */
|
||||
#undef HAVE_PATHS_H
|
||||
|
||||
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
|
||||
#undef HAVE_PF_NAT_THROUGH_PF_NORDR
|
||||
|
||||
/* define if you have a Septel API */
|
||||
/* define if you have the Septel API */
|
||||
#undef HAVE_SEPTEL_API
|
||||
|
||||
/* define if you have Myricom SNF API */
|
||||
/* define if you have the Myricom SNF API */
|
||||
#undef HAVE_SNF_API
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
@ -163,6 +166,9 @@
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#undef HAVE_STRTOK_R
|
||||
|
||||
/* Define to 1 if the system has the type `struct BPF_TIMEVAL'. */
|
||||
#undef HAVE_STRUCT_BPF_TIMEVAL
|
||||
|
||||
@ -181,6 +187,9 @@
|
||||
/* Define to 1 if you have the <sys/ioccom.h> header file. */
|
||||
#undef HAVE_SYS_IOCCOM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
#undef HAVE_SYS_SOCKIO_H
|
||||
|
||||
@ -190,6 +199,9 @@
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* define if you have the TurboCap API */
|
||||
#undef HAVE_TC_API
|
||||
|
||||
/* if if_packet.h has tpacket_stats defined */
|
||||
#undef HAVE_TPACKET_STATS
|
||||
|
||||
@ -199,9 +211,6 @@
|
||||
/* if struct usbdevfs_ctrltransfer has bRequestType */
|
||||
#undef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
|
||||
|
||||
/* define if version.h is generated in the build procedure */
|
||||
#undef HAVE_VERSION_H
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
@ -220,9 +229,6 @@
|
||||
/* path for device for USB sniffing */
|
||||
#undef LINUX_USB_MON_DEV
|
||||
|
||||
/* if we need a pcap_parse wrapper around yyparse */
|
||||
#undef NEED_YYPARSE_WRAPPER
|
||||
|
||||
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
|
||||
#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
|
||||
|
||||
@ -259,18 +265,15 @@
|
||||
/* target host supports Bluetooth Monitor */
|
||||
#undef PCAP_SUPPORT_BT_MONITOR
|
||||
|
||||
/* target host supports CAN sniffing */
|
||||
#undef PCAP_SUPPORT_CAN
|
||||
|
||||
/* target host supports canusb */
|
||||
#undef PCAP_SUPPORT_CANUSB
|
||||
|
||||
/* support D-Bus sniffing */
|
||||
#undef PCAP_SUPPORT_DBUS
|
||||
|
||||
/* target host supports netfilter sniffing */
|
||||
#undef PCAP_SUPPORT_NETFILTER
|
||||
|
||||
/* use Linux packet ring capture if available */
|
||||
#undef PCAP_SUPPORT_PACKET_RING
|
||||
|
||||
/* target host supports USB sniffing */
|
||||
#undef PCAP_SUPPORT_USB
|
||||
|
||||
@ -286,6 +289,10 @@
|
||||
/* Enable parser debugging */
|
||||
#undef YYDEBUG
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
|
128
contrib/libpcap/config.sub
vendored
128
contrib/libpcap/config.sub
vendored
@ -1,24 +1,18 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2012-04-18'
|
||||
timestamp='2015-02-22'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
# can handle that machine. It does not imply ALL GNU software can.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
@ -26,11 +20,12 @@ timestamp='2012-04-18'
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
# the same distribution terms that you use for the rest of that
|
||||
# program. This Exception is an additional permission under section 7
|
||||
# of the GNU General Public License, version 3 ("GPLv3").
|
||||
|
||||
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted GNU ChangeLog entry.
|
||||
# Please send patches to <config-patches@gnu.org>.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
@ -73,9 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||
Free Software Foundation, Inc.
|
||||
Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@ -123,8 +116,8 @@ esac
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
||||
kopensolaris*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
@ -156,7 +149,7 @@ case $os in
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple | -axis | -knuth | -cray | -microblaze)
|
||||
-apple | -axis | -knuth | -cray | -microblaze*)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
@ -259,21 +252,24 @@ case $basic_machine in
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||
| be32 | be64 \
|
||||
| arc | arceb \
|
||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||||
| avr | avr32 \
|
||||
| be32 | be64 \
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| c4x | c8051 | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| epiphany \
|
||||
| fido | fr30 | frv \
|
||||
| fido | fr30 | frv | ft32 \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| k1om \
|
||||
| le32 | le64 \
|
||||
| lm32 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore | mep | metag \
|
||||
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@ -287,23 +283,26 @@ case $basic_machine in
|
||||
| mips64vr5900 | mips64vr5900el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa32r6 | mipsisa32r6el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64r2 | mipsisa64r2el \
|
||||
| mipsisa64r6 | mipsisa64r6el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipsr5900 | mipsr5900el \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| moxie \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nds32 | nds32le | nds32be \
|
||||
| nios | nios2 \
|
||||
| nios | nios2 | nios2eb | nios2el \
|
||||
| ns16k | ns32k \
|
||||
| open8 \
|
||||
| or32 \
|
||||
| open8 | or1k | or1knd | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||
| pyramid \
|
||||
| riscv32 | riscv64 \
|
||||
| rl78 | rx \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
@ -314,6 +313,7 @@ case $basic_machine in
|
||||
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
||||
| ubicom32 \
|
||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||
| visium \
|
||||
| we32k \
|
||||
| x86 | xc16x | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
@ -328,7 +328,10 @@ case $basic_machine in
|
||||
c6x)
|
||||
basic_machine=tic6x-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
|
||||
leon|leon[3-9])
|
||||
basic_machine=sparc-$basic_machine
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
@ -370,13 +373,13 @@ case $basic_machine in
|
||||
| aarch64-* | aarch64_be-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* | avr32-* \
|
||||
| be32-* | be64-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
@ -385,11 +388,13 @@ case $basic_machine in
|
||||
| hexagon-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| k1om-* \
|
||||
| le32-* | le64-* \
|
||||
| lm32-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
||||
| microblaze-* | microblazeel-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
@ -403,18 +408,22 @@ case $basic_machine in
|
||||
| mips64vr5900-* | mips64vr5900el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa32r6-* | mipsisa32r6el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||
| mipsisa64r6-* | mipsisa64r6el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipsr5900-* | mipsr5900el-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| nds32-* | nds32le-* | nds32be-* \
|
||||
| nios-* | nios2-* \
|
||||
| nios-* | nios2-* | nios2eb-* | nios2el-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| open8-* \
|
||||
| or1k*-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||
@ -432,6 +441,7 @@ case $basic_machine in
|
||||
| ubicom32-* \
|
||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||
| vax-* \
|
||||
| visium-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
@ -769,6 +779,9 @@ case $basic_machine in
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
leon-*|leon[3-9]-*)
|
||||
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
@ -788,11 +801,15 @@ case $basic_machine in
|
||||
basic_machine=ns32k-utek
|
||||
os=-sysv
|
||||
;;
|
||||
microblaze)
|
||||
microblaze*)
|
||||
basic_machine=microblaze-xilinx
|
||||
;;
|
||||
mingw64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-mingw64
|
||||
;;
|
||||
mingw32)
|
||||
basic_machine=i386-pc
|
||||
basic_machine=i686-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
@ -820,6 +837,10 @@ case $basic_machine in
|
||||
basic_machine=powerpc-unknown
|
||||
os=-morphos
|
||||
;;
|
||||
moxiebox)
|
||||
basic_machine=moxie-unknown
|
||||
os=-moxiebox
|
||||
;;
|
||||
msdos)
|
||||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
@ -828,7 +849,7 @@ case $basic_machine in
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
msys)
|
||||
basic_machine=i386-pc
|
||||
basic_machine=i686-pc
|
||||
os=-msys
|
||||
;;
|
||||
mvs)
|
||||
@ -1019,7 +1040,11 @@ case $basic_machine in
|
||||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rdos)
|
||||
rdos | rdos64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-rdos
|
||||
;;
|
||||
rdos32)
|
||||
basic_machine=i386-pc
|
||||
os=-rdos
|
||||
;;
|
||||
@ -1346,29 +1371,29 @@ case $os in
|
||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||
| -sym* | -kopensolaris* \
|
||||
| -sym* | -kopensolaris* | -plan9* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* | -aros* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -openbsd* | -solidbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@ -1492,9 +1517,6 @@ case $os in
|
||||
-aros*)
|
||||
os=-aros
|
||||
;;
|
||||
-kaos*)
|
||||
os=-kaos
|
||||
;;
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
@ -1543,6 +1565,12 @@ case $basic_machine in
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
c8051-*)
|
||||
os=-elf
|
||||
;;
|
||||
hexagon-*)
|
||||
os=-elf
|
||||
;;
|
||||
tic54x-*)
|
||||
os=-coff
|
||||
;;
|
||||
|
6
contrib/libpcap/config/have_siocglifconf.c
Normal file
6
contrib/libpcap/config/have_siocglifconf.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
int main() {
|
||||
ioctl(0, SIOCGLIFCONF, (char *)0);
|
||||
}
|
1614
contrib/libpcap/configure
vendored
1614
contrib/libpcap/configure
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -186,8 +186,8 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
|
||||
pkthdr.len = origlen;
|
||||
pkthdr.caplen = caplen;
|
||||
/* Insure caplen does not exceed snapshot */
|
||||
if (pkthdr.caplen > p->snapshot)
|
||||
pkthdr.caplen = p->snapshot;
|
||||
if (pkthdr.caplen > (bpf_u_int32)p->snapshot)
|
||||
pkthdr.caplen = (bpf_u_int32)p->snapshot;
|
||||
(*callback)(user, &pkthdr, pk);
|
||||
if (++n >= count && !PACKET_COUNT_IS_UNLIMITED(count)) {
|
||||
p->cc = ep - bufp;
|
||||
@ -255,8 +255,29 @@ pcap_process_mactype(pcap_t *p, u_int mactype)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef DL_IPV4
|
||||
case DL_IPV4:
|
||||
p->linktype = DLT_IPV4;
|
||||
p->offset = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef DL_IPV6
|
||||
case DL_IPV6:
|
||||
p->linktype = DLT_IPV6;
|
||||
p->offset = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef DL_IPNET
|
||||
case DL_IPNET:
|
||||
p->linktype = DLT_IPNET;
|
||||
p->offset = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype 0x%x",
|
||||
mactype);
|
||||
retv = -1;
|
||||
}
|
||||
@ -326,7 +347,7 @@ int
|
||||
pcap_alloc_databuf(pcap_t *p)
|
||||
{
|
||||
p->bufsize = PKTBUFSIZE;
|
||||
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
|
||||
p->buffer = malloc(p->bufsize + p->offset);
|
||||
if (p->buffer == NULL) {
|
||||
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
@ -362,6 +383,6 @@ strioctl(int fd, int cmd, int len, char *dp)
|
||||
static void
|
||||
pcap_stream_err(const char *func, int err, char *errbuf)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err));
|
||||
}
|
||||
#endif
|
||||
|
@ -23,9 +23,9 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#else /* _WIN32 */
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif HAVE_STDINT_H
|
||||
@ -35,7 +35,7 @@
|
||||
#include <sys/bitypes.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <memory.h>
|
||||
|
@ -112,6 +112,9 @@
|
||||
#ifndef ETHERTYPE_PPPOES
|
||||
#define ETHERTYPE_PPPOES 0x8864
|
||||
#endif
|
||||
#ifndef ETHERTYPE_8021AD
|
||||
#define ETHERTYPE_8021AD 0x88a8
|
||||
#endif
|
||||
#ifndef ETHERTYPE_LOOPBACK
|
||||
#define ETHERTYPE_LOOPBACK 0x9000
|
||||
#endif
|
||||
|
221
contrib/libpcap/extract.h
Normal file
221
contrib/libpcap/extract.h
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1994, 1995, 1996
|
||||
* 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: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros to extract possibly-unaligned big-endian integral values.
|
||||
*/
|
||||
#ifdef LBL_ALIGN
|
||||
/*
|
||||
* The processor doesn't natively handle unaligned loads.
|
||||
*/
|
||||
#if defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \
|
||||
(defined(__alpha) || defined(__alpha__) || \
|
||||
defined(__mips) || defined(__mips__))
|
||||
|
||||
/*
|
||||
* This is a GCC-compatible compiler and we have __attribute__, which
|
||||
* we assume that mean we have __attribute__((packed)), and this is
|
||||
* MIPS or Alpha, which has instructions that can help when doing
|
||||
* unaligned loads.
|
||||
*
|
||||
* Declare packed structures containing a uint16_t and a uint32_t,
|
||||
* cast the pointer to point to one of those, and fetch through it;
|
||||
* the GCC manual doesn't appear to explicitly say that
|
||||
* __attribute__((packed)) causes the compiler to generate unaligned-safe
|
||||
* code, but it apppears to do so.
|
||||
*
|
||||
* We do this in case the compiler can generate code using those
|
||||
* instructions to do an unaligned load and pass stuff to "ntohs()" or
|
||||
* "ntohl()", which might be better than than the code to fetch the
|
||||
* bytes one at a time and assemble them. (That might not be the
|
||||
* case on a little-endian platform, such as DEC's MIPS machines and
|
||||
* Alpha machines, where "ntohs()" and "ntohl()" might not be done
|
||||
* inline.)
|
||||
*
|
||||
* We do this only for specific architectures because, for example,
|
||||
* at least some versions of GCC, when compiling for 64-bit SPARC,
|
||||
* generate code that assumes alignment if we do this.
|
||||
*
|
||||
* XXX - add other architectures and compilers as possible and
|
||||
* appropriate.
|
||||
*
|
||||
* HP's C compiler, indicated by __HP_cc being defined, supports
|
||||
* "#pragma unaligned N" in version A.05.50 and later, where "N"
|
||||
* specifies a number of bytes at which the typedef on the next
|
||||
* line is aligned, e.g.
|
||||
*
|
||||
* #pragma unalign 1
|
||||
* typedef uint16_t unaligned_uint16_t;
|
||||
*
|
||||
* to define unaligned_uint16_t as a 16-bit unaligned data type.
|
||||
* This could be presumably used, in sufficiently recent versions of
|
||||
* the compiler, with macros similar to those below. This would be
|
||||
* useful only if that compiler could generate better code for PA-RISC
|
||||
* or Itanium than would be generated by a bunch of shifts-and-ORs.
|
||||
*
|
||||
* DEC C, indicated by __DECC being defined, has, at least on Alpha,
|
||||
* an __unaligned qualifier that can be applied to pointers to get the
|
||||
* compiler to generate code that does unaligned loads and stores when
|
||||
* dereferencing the pointer in question.
|
||||
*
|
||||
* XXX - what if the native C compiler doesn't support
|
||||
* __attribute__((packed))? How can we get it to generate unaligned
|
||||
* accesses for *specific* items?
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t val;
|
||||
} __attribute__((packed)) unaligned_uint16_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t val;
|
||||
} __attribute__((packed)) unaligned_uint32_t;
|
||||
|
||||
static inline uint16_t
|
||||
EXTRACT_16BITS(const void *p)
|
||||
{
|
||||
return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val));
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
EXTRACT_32BITS(const void *p)
|
||||
{
|
||||
return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
EXTRACT_64BITS(const void *p)
|
||||
{
|
||||
return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | \
|
||||
((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0));
|
||||
}
|
||||
|
||||
#else /* have to do it a byte at a time */
|
||||
/*
|
||||
* This isn't a GCC-compatible compiler, we don't have __attribute__,
|
||||
* or we do but we don't know of any better way with this instruction
|
||||
* set to do unaligned loads, so do unaligned loads of big-endian
|
||||
* quantities the hard way - fetch the bytes one at a time and
|
||||
* assemble them.
|
||||
*/
|
||||
#define EXTRACT_16BITS(p) \
|
||||
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \
|
||||
((uint16_t)(*((const uint8_t *)(p) + 1)) << 0)))
|
||||
#define EXTRACT_32BITS(p) \
|
||||
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
|
||||
#define EXTRACT_64BITS(p) \
|
||||
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 7)) << 0)))
|
||||
#endif /* must special-case unaligned accesses */
|
||||
#else /* LBL_ALIGN */
|
||||
/*
|
||||
* The processor natively handles unaligned loads, so we can just
|
||||
* cast the pointer and fetch through it.
|
||||
*/
|
||||
static inline uint16_t
|
||||
EXTRACT_16BITS(const void *p)
|
||||
{
|
||||
return ((uint16_t)ntohs(*(const uint16_t *)(p)));
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
EXTRACT_32BITS(const void *p)
|
||||
{
|
||||
return ((uint32_t)ntohl(*(const uint32_t *)(p)));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
EXTRACT_64BITS(const void *p)
|
||||
{
|
||||
return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | \
|
||||
((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0));
|
||||
|
||||
}
|
||||
|
||||
#endif /* LBL_ALIGN */
|
||||
|
||||
#define EXTRACT_24BITS(p) \
|
||||
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 2)) << 0)))
|
||||
|
||||
#define EXTRACT_40BITS(p) \
|
||||
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 4)) << 0)))
|
||||
|
||||
#define EXTRACT_48BITS(p) \
|
||||
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 5)) << 0)))
|
||||
|
||||
#define EXTRACT_56BITS(p) \
|
||||
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 6)) << 0)))
|
||||
|
||||
/*
|
||||
* Macros to extract possibly-unaligned little-endian integral values.
|
||||
* XXX - do loads on little-endian machines that support unaligned loads?
|
||||
*/
|
||||
#define EXTRACT_LE_8BITS(p) (*(p))
|
||||
#define EXTRACT_LE_16BITS(p) \
|
||||
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
|
||||
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
|
||||
#define EXTRACT_LE_32BITS(p) \
|
||||
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
|
||||
#define EXTRACT_LE_24BITS(p) \
|
||||
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
|
||||
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
|
||||
#define EXTRACT_LE_64BITS(p) \
|
||||
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \
|
||||
((uint64_t)(*((const uint8_t *)(p) + 0)) << 0)))
|
@ -144,7 +144,8 @@ get_sa_len(struct sockaddr *addr)
|
||||
* could be opened.
|
||||
*/
|
||||
int
|
||||
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
|
||||
int (*check_usable)(const char *))
|
||||
{
|
||||
pcap_if_t *devlist = NULL;
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
@ -168,11 +169,50 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
* those.
|
||||
*/
|
||||
if (getifaddrs(&ifap) != 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"getifaddrs: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
/*
|
||||
* If this entry has a colon followed by a number at
|
||||
* the end, we assume it's a logical interface. Those
|
||||
* are just the way you assign multiple IP addresses to
|
||||
* a real interface on Linux, so an entry for a logical
|
||||
* interface should be treated like the entry for the
|
||||
* real interface; we do that by stripping off the ":"
|
||||
* and the number.
|
||||
*
|
||||
* XXX - should we do this only on Linux?
|
||||
*/
|
||||
p = strchr(ifa->ifa_name, ':');
|
||||
if (p != NULL) {
|
||||
/*
|
||||
* We have a ":"; is it followed by a number?
|
||||
*/
|
||||
q = p + 1;
|
||||
while (isdigit((unsigned char)*q))
|
||||
q++;
|
||||
if (*q == '\0') {
|
||||
/*
|
||||
* All digits after the ":" until the end.
|
||||
* Strip off the ":" and everything after
|
||||
* it.
|
||||
*/
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Can we capture on this device?
|
||||
*/
|
||||
if (!(*check_usable)(ifa->ifa_name)) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* "ifa_addr" was apparently null on at least one
|
||||
* interface on some system. Therefore, we supply
|
||||
@ -222,40 +262,12 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
dstaddr_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this entry has a colon followed by a number at
|
||||
* the end, we assume it's a logical interface. Those
|
||||
* are just the way you assign multiple IP addresses to
|
||||
* a real interface on Linux, so an entry for a logical
|
||||
* interface should be treated like the entry for the
|
||||
* real interface; we do that by stripping off the ":"
|
||||
* and the number.
|
||||
*
|
||||
* XXX - should we do this only on Linux?
|
||||
*/
|
||||
p = strchr(ifa->ifa_name, ':');
|
||||
if (p != NULL) {
|
||||
/*
|
||||
* We have a ":"; is it followed by a number?
|
||||
*/
|
||||
q = p + 1;
|
||||
while (isdigit((unsigned char)*q))
|
||||
q++;
|
||||
if (*q == '\0') {
|
||||
/*
|
||||
* All digits after the ":" until the end.
|
||||
* Strip off the ":" and everything after
|
||||
* it.
|
||||
*/
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add information for this address to the list.
|
||||
*/
|
||||
if (add_addr_to_iflist(&devlist, ifa->ifa_name,
|
||||
ifa->ifa_flags, addr, addr_size, netmask, addr_size,
|
||||
if_flags_to_pcap_flags(ifa->ifa_name, ifa->ifa_flags),
|
||||
addr, addr_size, netmask, addr_size,
|
||||
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
|
||||
errbuf) < 0) {
|
||||
ret = -1;
|
||||
|
@ -132,12 +132,13 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
* we already have that.
|
||||
*/
|
||||
int
|
||||
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
|
||||
int (*check_usable)(const char *))
|
||||
{
|
||||
pcap_if_t *devlist = NULL;
|
||||
register int fd;
|
||||
register struct ifreq *ifrp, *ifend, *ifnext;
|
||||
int n;
|
||||
size_t n;
|
||||
struct ifconf ifc;
|
||||
char *buf = NULL;
|
||||
unsigned buf_size;
|
||||
@ -154,7 +155,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
*/
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"socket: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -170,7 +171,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
for (;;) {
|
||||
buf = malloc(buf_size);
|
||||
if (buf == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
(void)close(fd);
|
||||
return (-1);
|
||||
@ -181,7 +182,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
memset(buf, 0, buf_size);
|
||||
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
|
||||
&& errno != EINVAL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGIFCONF: %s", pcap_strerror(errno));
|
||||
(void)close(fd);
|
||||
free(buf);
|
||||
@ -217,12 +218,12 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
/*
|
||||
* XXX - The 32-bit compatibility layer for Linux on IA-64
|
||||
* is slightly broken. It correctly converts the structures
|
||||
* to and from kernel land from 64 bit to 32 bit but
|
||||
* doesn't update ifc.ifc_len, leaving it larger than the
|
||||
* amount really used. This means we read off the end
|
||||
* of the buffer and encounter an interface with an
|
||||
* "empty" name. Since this is highly unlikely to ever
|
||||
* occur in a valid case we can just finish looking for
|
||||
* to and from kernel land from 64 bit to 32 bit but
|
||||
* doesn't update ifc.ifc_len, leaving it larger than the
|
||||
* amount really used. This means we read off the end
|
||||
* of the buffer and encounter an interface with an
|
||||
* "empty" name. Since this is highly unlikely to ever
|
||||
* occur in a valid case we can just finish looking for
|
||||
* interfaces if we see an empty name.
|
||||
*/
|
||||
if (!(*ifrp->ifr_name))
|
||||
@ -236,6 +237,16 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
if (strncmp(ifrp->ifr_name, "dummy", 5) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Can we capture on this device?
|
||||
*/
|
||||
if (!(*check_usable)(ifrp->ifr_name)) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the flags for this interface.
|
||||
*/
|
||||
@ -244,7 +255,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
|
||||
if (errno == ENXIO)
|
||||
continue;
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGIFFLAGS: %.*s: %s",
|
||||
(int)sizeof(ifrflags.ifr_name),
|
||||
ifrflags.ifr_name,
|
||||
@ -268,7 +279,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
netmask = NULL;
|
||||
netmask_size = 0;
|
||||
} else {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGIFNETMASK: %.*s: %s",
|
||||
(int)sizeof(ifrnetmask.ifr_name),
|
||||
ifrnetmask.ifr_name,
|
||||
@ -299,7 +310,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
broadaddr = NULL;
|
||||
broadaddr_size = 0;
|
||||
} else {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGIFBRDADDR: %.*s: %s",
|
||||
(int)sizeof(ifrbroadaddr.ifr_name),
|
||||
ifrbroadaddr.ifr_name,
|
||||
@ -338,7 +349,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
dstaddr = NULL;
|
||||
dstaddr_size = 0;
|
||||
} else {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGIFDSTADDR: %.*s: %s",
|
||||
(int)sizeof(ifrdstaddr.ifr_name),
|
||||
ifrdstaddr.ifr_name,
|
||||
@ -391,10 +402,10 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
* Add information for this address to the list.
|
||||
*/
|
||||
if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
|
||||
ifrflags.ifr_flags, &ifrp->ifr_addr,
|
||||
SA_LEN(&ifrp->ifr_addr), netmask, netmask_size,
|
||||
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
|
||||
errbuf) < 0) {
|
||||
if_flags_to_pcap_flags(ifrp->ifr_name, ifrflags.ifr_flags),
|
||||
&ifrp->ifr_addr, SA_LEN(&ifrp->ifr_addr),
|
||||
netmask, netmask_size, broadaddr, broadaddr_size,
|
||||
dstaddr, dstaddr_size, errbuf) < 0) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -75,7 +75,8 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
* SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
|
||||
*/
|
||||
int
|
||||
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
|
||||
int (*check_usable)(const char *))
|
||||
{
|
||||
pcap_if_t *devlist = NULL;
|
||||
register int fd4, fd6, fd;
|
||||
@ -97,7 +98,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
*/
|
||||
fd4 = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd4 < 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"socket: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -107,7 +108,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
*/
|
||||
fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (fd6 < 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"socket: %s", pcap_strerror(errno));
|
||||
(void)close(fd4);
|
||||
return (-1);
|
||||
@ -120,7 +121,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
ifn.lifn_flags = 0;
|
||||
ifn.lifn_count = 0;
|
||||
if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGLIFNUM: %s", pcap_strerror(errno));
|
||||
(void)close(fd6);
|
||||
(void)close(fd4);
|
||||
@ -133,7 +134,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
buf_size = ifn.lifn_count * sizeof (struct lifreq);
|
||||
buf = malloc(buf_size);
|
||||
if (buf == NULL) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
(void)close(fd6);
|
||||
(void)close(fd4);
|
||||
@ -149,7 +150,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
ifc.lifc_flags = 0;
|
||||
memset(buf, 0, buf_size);
|
||||
if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGLIFCONF: %s", pcap_strerror(errno));
|
||||
(void)close(fd6);
|
||||
(void)close(fd4);
|
||||
@ -164,14 +165,6 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
ifend = (struct lifreq *)(buf + ifc.lifc_len);
|
||||
|
||||
for (; ifrp < ifend; ifrp++) {
|
||||
/*
|
||||
* IPv6 or not?
|
||||
*/
|
||||
if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6)
|
||||
fd = fd6;
|
||||
else
|
||||
fd = fd4;
|
||||
|
||||
/*
|
||||
* Skip entries that begin with "dummy".
|
||||
* XXX - what are these? Is this Linux-specific?
|
||||
@ -180,27 +173,23 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
if (strncmp(ifrp->lifr_name, "dummy", 5) == 0)
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_SOLARIS
|
||||
/*
|
||||
* Skip entries that have a ":" followed by a number
|
||||
* at the end - those are Solaris virtual interfaces
|
||||
* on which you can't capture.
|
||||
* Can we capture on this device?
|
||||
*/
|
||||
p = strchr(ifrp->lifr_name, ':');
|
||||
if (p != NULL) {
|
||||
if (!(*check_usable)(ifrp->lifr_name)) {
|
||||
/*
|
||||
* We have a ":"; is it followed by a number?
|
||||
* No.
|
||||
*/
|
||||
while (isdigit((unsigned char)*p))
|
||||
p++;
|
||||
if (*p == '\0') {
|
||||
/*
|
||||
* All digits after the ":" until the end.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IPv6 or not?
|
||||
*/
|
||||
if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6)
|
||||
fd = fd6;
|
||||
else
|
||||
fd = fd4;
|
||||
|
||||
/*
|
||||
* Get the flags for this interface.
|
||||
@ -210,7 +199,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
|
||||
if (errno == ENXIO)
|
||||
continue;
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGLIFFLAGS: %.*s: %s",
|
||||
(int)sizeof(ifrflags.lifr_name),
|
||||
ifrflags.lifr_name,
|
||||
@ -233,7 +222,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
*/
|
||||
netmask = NULL;
|
||||
} else {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGLIFNETMASK: %.*s: %s",
|
||||
(int)sizeof(ifrnetmask.lifr_name),
|
||||
ifrnetmask.lifr_name,
|
||||
@ -261,7 +250,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
*/
|
||||
broadaddr = NULL;
|
||||
} else {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGLIFBRDADDR: %.*s: %s",
|
||||
(int)sizeof(ifrbroadaddr.lifr_name),
|
||||
ifrbroadaddr.lifr_name,
|
||||
@ -296,7 +285,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
*/
|
||||
dstaddr = NULL;
|
||||
} else {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SIOCGLIFDSTADDR: %.*s: %s",
|
||||
(int)sizeof(ifrdstaddr.lifr_name),
|
||||
ifrdstaddr.lifr_name,
|
||||
@ -341,7 +330,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||
* Add information for this address to the list.
|
||||
*/
|
||||
if (add_addr_to_iflist(&devlist, ifrp->lifr_name,
|
||||
ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr,
|
||||
if_flags_to_pcap_flags(ifrp->lifr_name, ifrflags.lifr_flags),
|
||||
(struct sockaddr *)&ifrp->lifr_addr,
|
||||
sizeof (struct sockaddr_storage),
|
||||
netmask, sizeof (struct sockaddr_storage),
|
||||
broadaddr, sizeof (struct sockaddr_storage),
|
||||
|
884
contrib/libpcap/fad-helpers.c
Normal file
884
contrib/libpcap/fad-helpers.c
Normal file
@ -0,0 +1,884 @@
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996, 1997, 1998
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifndef MSDOS
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_SOCKIO_H
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
struct mbuf; /* Squelch compiler warnings on some platforms for */
|
||||
struct rtentry; /* declarations in <net/if.h> */
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if !defined(_WIN32) && !defined(__BORLANDC__)
|
||||
#include <unistd.h>
|
||||
#endif /* !_WIN32 && !__BORLANDC__ */
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#else
|
||||
#define INT_MAX 2147483647
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Not all systems have IFF_LOOPBACK */
|
||||
#ifdef IFF_LOOPBACK
|
||||
#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
|
||||
#else
|
||||
#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
|
||||
(isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
|
||||
#endif
|
||||
|
||||
#ifdef IFF_UP
|
||||
#define ISUP(flags) ((flags) & IFF_UP)
|
||||
#else
|
||||
#define ISUP(flags) 0
|
||||
#endif
|
||||
|
||||
#ifdef IFF_RUNNING
|
||||
#define ISRUNNING(flags) ((flags) & IFF_RUNNING)
|
||||
#else
|
||||
#define ISRUNNING(flags) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Map UN*X-style interface flags to libpcap flags.
|
||||
*/
|
||||
bpf_u_int32
|
||||
if_flags_to_pcap_flags(const char *name _U_, u_int if_flags)
|
||||
{
|
||||
bpf_u_int32 pcap_flags;
|
||||
|
||||
pcap_flags = 0;
|
||||
if (ISLOOPBACK(name, if_flags))
|
||||
pcap_flags |= PCAP_IF_LOOPBACK;
|
||||
if (ISUP(if_flags))
|
||||
pcap_flags |= PCAP_IF_UP;
|
||||
if (ISRUNNING(if_flags))
|
||||
pcap_flags |= PCAP_IF_RUNNING;
|
||||
return (pcap_flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct sockaddr *
|
||||
dup_sockaddr(struct sockaddr *sa, size_t sa_length)
|
||||
{
|
||||
struct sockaddr *newsa;
|
||||
|
||||
if ((newsa = malloc(sa_length)) == NULL)
|
||||
return (NULL);
|
||||
return (memcpy(newsa, sa, sa_length));
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a "figure of merit" for an interface, for use when sorting
|
||||
* the list of interfaces, in which interfaces that are up are superior
|
||||
* to interfaces that aren't up, interfaces that are up and running are
|
||||
* superior to interfaces that are up but not running, and non-loopback
|
||||
* interfaces that are up and running are superior to loopback interfaces,
|
||||
* and interfaces with the same flags have a figure of merit that's higher
|
||||
* the lower the instance number.
|
||||
*
|
||||
* The goal is to try to put the interfaces most likely to be useful for
|
||||
* capture at the beginning of the list.
|
||||
*
|
||||
* The figure of merit, which is lower the "better" the interface is,
|
||||
* has the uppermost bit set if the interface isn't running, the bit
|
||||
* below that set if the interface isn't up, the bit below that set
|
||||
* if the interface is a loopback interface, and the interface index
|
||||
* in the 29 bits below that. (Yes, we assume u_int is 32 bits.)
|
||||
*/
|
||||
static u_int
|
||||
get_figure_of_merit(pcap_if_t *dev)
|
||||
{
|
||||
const char *cp;
|
||||
u_int n;
|
||||
|
||||
if (strcmp(dev->name, "any") == 0) {
|
||||
/*
|
||||
* Give the "any" device an artificially high instance
|
||||
* number, so it shows up after all other non-loopback
|
||||
* interfaces.
|
||||
*/
|
||||
n = 0x1FFFFFFF; /* 29 all-1 bits */
|
||||
} else {
|
||||
/*
|
||||
* A number at the end of the device name string is
|
||||
* assumed to be a unit number.
|
||||
*/
|
||||
cp = dev->name + strlen(dev->name) - 1;
|
||||
while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9')
|
||||
cp--;
|
||||
if (*cp >= '0' && *cp <= '9')
|
||||
n = atoi(cp);
|
||||
else
|
||||
n = 0;
|
||||
}
|
||||
if (!(dev->flags & PCAP_IF_RUNNING))
|
||||
n |= 0x80000000;
|
||||
if (!(dev->flags & PCAP_IF_UP))
|
||||
n |= 0x40000000;
|
||||
if (dev->flags & PCAP_IF_LOOPBACK)
|
||||
n |= 0x20000000;
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to get a description for a given device.
|
||||
* Returns a mallocated description if it could and NULL if it couldn't.
|
||||
*
|
||||
* XXX - on FreeBSDs that support it, should it get the sysctl named
|
||||
* "dev.{adapter family name}.{adapter unit}.%desc" to get a description
|
||||
* of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
|
||||
* with my Cisco 350 card, so the name isn't entirely descriptive. The
|
||||
* "dev.an.0.%pnpinfo" has a better description, although one might argue
|
||||
* that the problem is really a driver bug - if it can find out that it's
|
||||
* a Cisco 340 or 350, rather than an old Aironet card, it should use
|
||||
* that in the description.
|
||||
*
|
||||
* Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD
|
||||
* and OpenBSD let you get a description, but it's not generated by the OS,
|
||||
* it's set with another ioctl that ifconfig supports; we use that to get
|
||||
* a description in FreeBSD and OpenBSD, but if there is no such
|
||||
* description available, it still might be nice to get some description
|
||||
* string based on the device type or something such as that.
|
||||
*
|
||||
* In OS X, the System Configuration framework can apparently return
|
||||
* names in 10.4 and later.
|
||||
*
|
||||
* It also appears that freedesktop.org's HAL offers an "info.product"
|
||||
* string, but the HAL specification says it "should not be used in any
|
||||
* UI" and "subsystem/capability specific properties" should be used
|
||||
* instead and, in any case, I think HAL is being deprecated in
|
||||
* favor of other stuff such as DeviceKit. DeviceKit doesn't appear
|
||||
* to have any obvious product information for devices, but maybe
|
||||
* I haven't looked hard enough.
|
||||
*
|
||||
* Using the System Configuration framework, or HAL, or DeviceKit, or
|
||||
* whatever, would require that libpcap applications be linked with
|
||||
* the frameworks/libraries in question. That shouldn't be a problem
|
||||
* for programs linking with the shared version of libpcap (unless
|
||||
* you're running on AIX - which I think is the only UN*X that doesn't
|
||||
* support linking a shared library with other libraries on which it
|
||||
* depends, and having an executable linked only with the first shared
|
||||
* library automatically pick up the other libraries when started -
|
||||
* and using HAL or whatever). Programs linked with the static
|
||||
* version of libpcap would have to use pcap-config with the --static
|
||||
* flag in order to get the right linker flags in order to pick up
|
||||
* the additional libraries/frameworks; those programs need that anyway
|
||||
* for libpcap 1.1 and beyond on Linux, as, by default, it requires
|
||||
* -lnl.
|
||||
*
|
||||
* Do any other UN*Xes, or desktop environments support getting a
|
||||
* description?
|
||||
*/
|
||||
static char *
|
||||
get_if_description(const char *name)
|
||||
{
|
||||
#ifdef SIOCGIFDESCR
|
||||
char *description = NULL;
|
||||
int s;
|
||||
struct ifreq ifrdesc;
|
||||
#ifndef IFDESCRSIZE
|
||||
size_t descrlen = 64;
|
||||
#else
|
||||
size_t descrlen = IFDESCRSIZE;
|
||||
#endif /* IFDESCRSIZE */
|
||||
|
||||
/*
|
||||
* Get the description for the interface.
|
||||
*/
|
||||
memset(&ifrdesc, 0, sizeof ifrdesc);
|
||||
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
#ifdef __FreeBSD__
|
||||
/*
|
||||
* On FreeBSD, if the buffer isn't big enough for the
|
||||
* description, the ioctl succeeds, but the description
|
||||
* isn't copied, ifr_buffer.length is set to the description
|
||||
* length, and ifr_buffer.buffer is set to NULL.
|
||||
*/
|
||||
for (;;) {
|
||||
free(description);
|
||||
if ((description = malloc(descrlen)) != NULL) {
|
||||
ifrdesc.ifr_buffer.buffer = description;
|
||||
ifrdesc.ifr_buffer.length = descrlen;
|
||||
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
|
||||
if (ifrdesc.ifr_buffer.buffer ==
|
||||
description)
|
||||
break;
|
||||
else
|
||||
descrlen = ifrdesc.ifr_buffer.length;
|
||||
} else {
|
||||
/*
|
||||
* Failed to get interface description.
|
||||
*/
|
||||
free(description);
|
||||
description = NULL;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
#else /* __FreeBSD__ */
|
||||
/*
|
||||
* The only other OS that currently supports
|
||||
* SIOCGIFDESCR is OpenBSD, and it has no way
|
||||
* to get the description length - it's clamped
|
||||
* to a maximum of IFDESCRSIZE.
|
||||
*/
|
||||
if ((description = malloc(descrlen)) != NULL) {
|
||||
ifrdesc.ifr_data = (caddr_t)description;
|
||||
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
|
||||
/*
|
||||
* Failed to get interface description.
|
||||
*/
|
||||
free(description);
|
||||
description = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
close(s);
|
||||
if (description != NULL && strlen(description) == 0) {
|
||||
/*
|
||||
* Description is empty, so discard it.
|
||||
*/
|
||||
free(description);
|
||||
description = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/*
|
||||
* For FreeBSD, if we didn't get a description, and this is
|
||||
* a device with a name of the form usbusN, label it as a USB
|
||||
* bus.
|
||||
*/
|
||||
if (description == NULL) {
|
||||
if (strncmp(name, "usbus", 5) == 0) {
|
||||
/*
|
||||
* OK, it begins with "usbus".
|
||||
*/
|
||||
long busnum;
|
||||
char *p;
|
||||
|
||||
errno = 0;
|
||||
busnum = strtol(name + 5, &p, 10);
|
||||
if (errno == 0 && p != name + 5 && *p == '\0' &&
|
||||
busnum >= 0 && busnum <= INT_MAX) {
|
||||
/*
|
||||
* OK, it's a valid number that's not
|
||||
* bigger than INT_MAX. Construct
|
||||
* a description from it.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return (description);
|
||||
#else /* SIOCGIFDESCR */
|
||||
return (NULL);
|
||||
#endif /* SIOCGIFDESCR */
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for a given device in the specified list of devices.
|
||||
*
|
||||
* If we find it, return 0 and set *curdev_ret to point to it.
|
||||
*
|
||||
* If we don't find it, check whether we can open it:
|
||||
*
|
||||
* If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
|
||||
* PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
|
||||
* it, as that probably means it exists but doesn't support
|
||||
* packet capture.
|
||||
*
|
||||
* Otherwise, attempt to add an entry for it, with the specified
|
||||
* ifnet flags and description, and, if that succeeds, return 0
|
||||
* and set *curdev_ret to point to the new entry, otherwise
|
||||
* return PCAP_ERROR and set errbuf to an error message. If we
|
||||
* weren't given a description, try to get one.
|
||||
*/
|
||||
int
|
||||
add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
|
||||
bpf_u_int32 flags, const char *description, char *errbuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
pcap_if_t *curdev, *prevdev, *nextdev;
|
||||
u_int this_figure_of_merit, nextdev_figure_of_merit;
|
||||
char open_errbuf[PCAP_ERRBUF_SIZE];
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Is there already an entry in the list for this interface?
|
||||
*/
|
||||
for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
|
||||
if (strcmp(name, curdev->name) == 0)
|
||||
break; /* yes, we found it */
|
||||
}
|
||||
|
||||
if (curdev == NULL) {
|
||||
/*
|
||||
* No, we didn't find it.
|
||||
*
|
||||
* Can we open this interface for live capture?
|
||||
*
|
||||
* We do this check so that interfaces that are
|
||||
* supplied by the interface enumeration mechanism
|
||||
* we're using but that don't support packet capture
|
||||
* aren't included in the list. Loopback interfaces
|
||||
* on Solaris are an example of this; we don't just
|
||||
* omit loopback interfaces on all platforms because
|
||||
* you *can* capture on loopback interfaces on some
|
||||
* OSes.
|
||||
*
|
||||
* On OS X, we don't do this check if the device
|
||||
* name begins with "wlt"; at least some versions
|
||||
* of OS X offer monitor mode capturing by having
|
||||
* a separate "monitor mode" device for each wireless
|
||||
* adapter, rather than by implementing the ioctls
|
||||
* that {Free,Net,Open,DragonFly}BSD provide.
|
||||
* Opening that device puts the adapter into monitor
|
||||
* mode, which, at least for some adapters, causes
|
||||
* them to deassociate from the network with which
|
||||
* they're associated.
|
||||
*
|
||||
* Instead, we try to open the corresponding "en"
|
||||
* device (so that we don't end up with, for users
|
||||
* without sufficient privilege to open capture
|
||||
* devices, a list of adapters that only includes
|
||||
* the wlt devices).
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
if (strncmp(name, "wlt", 3) == 0) {
|
||||
char *en_name;
|
||||
size_t en_name_len;
|
||||
|
||||
/*
|
||||
* Try to allocate a buffer for the "en"
|
||||
* device's name.
|
||||
*/
|
||||
en_name_len = strlen(name) - 1;
|
||||
en_name = malloc(en_name_len + 1);
|
||||
if (en_name == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
strcpy(en_name, "en");
|
||||
strcat(en_name, name + 3);
|
||||
p = pcap_create(en_name, open_errbuf);
|
||||
free(en_name);
|
||||
} else
|
||||
#endif /* __APPLE */
|
||||
p = pcap_create(name, open_errbuf);
|
||||
if (p == NULL) {
|
||||
/*
|
||||
* The attempt to create the pcap_t failed;
|
||||
* that's probably an indication that we're
|
||||
* out of memory.
|
||||
*
|
||||
* Don't bother including this interface,
|
||||
* but don't treat it as an error.
|
||||
*/
|
||||
*curdev_ret = NULL;
|
||||
return (0);
|
||||
}
|
||||
/* Small snaplen, so we don't try to allocate much memory. */
|
||||
pcap_set_snaplen(p, 68);
|
||||
ret = pcap_activate(p);
|
||||
pcap_close(p);
|
||||
switch (ret) {
|
||||
|
||||
case PCAP_ERROR_NO_SUCH_DEVICE:
|
||||
case PCAP_ERROR_IFACE_NOT_UP:
|
||||
/*
|
||||
* We expect these two errors - they're the
|
||||
* reason we try to open the device.
|
||||
*
|
||||
* PCAP_ERROR_NO_SUCH_DEVICE typically means
|
||||
* "there's no such device *known to the
|
||||
* OS's capture mechanism*", so, even though
|
||||
* it might be a valid network interface, you
|
||||
* can't capture on it (e.g., the loopback
|
||||
* device in Solaris up to Solaris 10, or
|
||||
* the vmnet devices in OS X with VMware
|
||||
* Fusion). We don't include those devices
|
||||
* in our list of devices, as there's no
|
||||
* point in doing so - they're not available
|
||||
* for capture.
|
||||
*
|
||||
* PCAP_ERROR_IFACE_NOT_UP means that the
|
||||
* OS's capture mechanism doesn't work on
|
||||
* interfaces not marked as up; some capture
|
||||
* mechanisms *do* support that, so we no
|
||||
* longer reject those interfaces out of hand,
|
||||
* but we *do* want to reject them if they
|
||||
* can't be opened for capture.
|
||||
*/
|
||||
*curdev_ret = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Yes, we can open it, or we can't, for some other
|
||||
* reason.
|
||||
*
|
||||
* If we can open it, we want to offer it for
|
||||
* capture, as you can capture on it. If we can't,
|
||||
* we want to offer it for capture, so that, if
|
||||
* the user tries to capture on it, they'll get
|
||||
* an error and they'll know why they can't
|
||||
* capture on it (e.g., insufficient permissions)
|
||||
* or they'll report it as a problem (and then
|
||||
* have the error message to provide as information).
|
||||
*
|
||||
* Allocate a new entry.
|
||||
*/
|
||||
curdev = malloc(sizeof(pcap_if_t));
|
||||
if (curdev == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the entry.
|
||||
*/
|
||||
curdev->next = NULL;
|
||||
curdev->name = strdup(name);
|
||||
if (curdev->name == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
free(curdev);
|
||||
return (-1);
|
||||
}
|
||||
if (description == NULL) {
|
||||
/*
|
||||
* We weren't handed a description for the
|
||||
* interface, so see if we can generate one
|
||||
* ourselves.
|
||||
*/
|
||||
curdev->description = get_if_description(name);
|
||||
} else {
|
||||
/*
|
||||
* We were handed a description; make a copy.
|
||||
*/
|
||||
curdev->description = strdup(description);
|
||||
if (curdev->description == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
free(curdev->name);
|
||||
free(curdev);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
curdev->addresses = NULL; /* list starts out as empty */
|
||||
curdev->flags = flags;
|
||||
|
||||
/*
|
||||
* Add it to the list, in the appropriate location.
|
||||
* First, get the "figure of merit" for this
|
||||
* interface.
|
||||
*/
|
||||
this_figure_of_merit = get_figure_of_merit(curdev);
|
||||
|
||||
/*
|
||||
* Now look for the last interface with an figure of merit
|
||||
* less than or equal to the new interface's figure of
|
||||
* merit.
|
||||
*
|
||||
* We start with "prevdev" being NULL, meaning we're before
|
||||
* the first element in the list.
|
||||
*/
|
||||
prevdev = NULL;
|
||||
for (;;) {
|
||||
/*
|
||||
* Get the interface after this one.
|
||||
*/
|
||||
if (prevdev == NULL) {
|
||||
/*
|
||||
* The next element is the first element.
|
||||
*/
|
||||
nextdev = *alldevs;
|
||||
} else
|
||||
nextdev = prevdev->next;
|
||||
|
||||
/*
|
||||
* Are we at the end of the list?
|
||||
*/
|
||||
if (nextdev == NULL) {
|
||||
/*
|
||||
* Yes - we have to put the new entry
|
||||
* after "prevdev".
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the new interface's figure of merit less
|
||||
* than the next interface's figure of merit,
|
||||
* meaning that the new interface is better
|
||||
* than the next interface?
|
||||
*/
|
||||
nextdev_figure_of_merit = get_figure_of_merit(nextdev);
|
||||
if (this_figure_of_merit < nextdev_figure_of_merit) {
|
||||
/*
|
||||
* Yes - we should put the new entry
|
||||
* before "nextdev", i.e. after "prevdev".
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
prevdev = nextdev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert before "nextdev".
|
||||
*/
|
||||
curdev->next = nextdev;
|
||||
|
||||
/*
|
||||
* Insert after "prevdev" - unless "prevdev" is null,
|
||||
* in which case this is the first interface.
|
||||
*/
|
||||
if (prevdev == NULL) {
|
||||
/*
|
||||
* This is the first interface. Pass back a
|
||||
* pointer to it, and put "curdev" before
|
||||
* "nextdev".
|
||||
*/
|
||||
*alldevs = curdev;
|
||||
} else
|
||||
prevdev->next = curdev;
|
||||
}
|
||||
|
||||
*curdev_ret = curdev;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to get a description for a given device, and then look for that
|
||||
* device in the specified list of devices.
|
||||
*
|
||||
* If we find it, then, if the specified address isn't null, add it to
|
||||
* the list of addresses for the device and return 0.
|
||||
*
|
||||
* If we don't find it, check whether we can open it:
|
||||
*
|
||||
* If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
|
||||
* PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
|
||||
* it, as that probably means it exists but doesn't support
|
||||
* packet capture.
|
||||
*
|
||||
* Otherwise, attempt to add an entry for it, with the specified
|
||||
* ifnet flags, and, if that succeeds, add the specified address
|
||||
* to its list of addresses if that address is non-null, set
|
||||
* *curdev_ret to point to the new entry, and return 0, otherwise
|
||||
* return PCAP_ERROR and set errbuf to an error message.
|
||||
*
|
||||
* (We can get called with a null address because we might get a list
|
||||
* of interface name/address combinations from the underlying OS, with
|
||||
* the address being absent in some cases, rather than a list of
|
||||
* interfaces with each interface having a list of addresses, so this
|
||||
* call may be the only call made to add to the list, and we want to
|
||||
* add interfaces even if they have no addresses.)
|
||||
*/
|
||||
int
|
||||
add_addr_to_iflist(pcap_if_t **alldevs, const char *name, bpf_u_int32 flags,
|
||||
struct sockaddr *addr, size_t addr_size,
|
||||
struct sockaddr *netmask, size_t netmask_size,
|
||||
struct sockaddr *broadaddr, size_t broadaddr_size,
|
||||
struct sockaddr *dstaddr, size_t dstaddr_size,
|
||||
char *errbuf)
|
||||
{
|
||||
pcap_if_t *curdev;
|
||||
|
||||
if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
|
||||
/*
|
||||
* Error - give up.
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
if (curdev == NULL) {
|
||||
/*
|
||||
* Device wasn't added because it can't be opened.
|
||||
* Not a fatal error.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (addr == NULL) {
|
||||
/*
|
||||
* There's no address to add; this entry just meant
|
||||
* "here's a new interface".
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* "curdev" is an entry for this interface, and we have an
|
||||
* address for it; add an entry for that address to the
|
||||
* interface's list of addresses.
|
||||
*
|
||||
* Allocate the new entry and fill it in.
|
||||
*/
|
||||
return (add_addr_to_dev(curdev, addr, addr_size, netmask,
|
||||
netmask_size, broadaddr, broadaddr_size, dstaddr,
|
||||
dstaddr_size, errbuf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an entry to the list of addresses for an interface.
|
||||
* "curdev" is the entry for that interface.
|
||||
* If this is the first IP address added to the interface, move it
|
||||
* in the list as appropriate.
|
||||
*/
|
||||
int
|
||||
add_addr_to_dev(pcap_if_t *curdev,
|
||||
struct sockaddr *addr, size_t addr_size,
|
||||
struct sockaddr *netmask, size_t netmask_size,
|
||||
struct sockaddr *broadaddr, size_t broadaddr_size,
|
||||
struct sockaddr *dstaddr, size_t dstaddr_size,
|
||||
char *errbuf)
|
||||
{
|
||||
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
|
||||
|
||||
curaddr = malloc(sizeof(pcap_addr_t));
|
||||
if (curaddr == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
curaddr->next = NULL;
|
||||
if (addr != NULL) {
|
||||
curaddr->addr = dup_sockaddr(addr, addr_size);
|
||||
if (curaddr->addr == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
free(curaddr);
|
||||
return (-1);
|
||||
}
|
||||
} else
|
||||
curaddr->addr = NULL;
|
||||
|
||||
if (netmask != NULL) {
|
||||
curaddr->netmask = dup_sockaddr(netmask, netmask_size);
|
||||
if (curaddr->netmask == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
if (curaddr->addr != NULL)
|
||||
free(curaddr->addr);
|
||||
free(curaddr);
|
||||
return (-1);
|
||||
}
|
||||
} else
|
||||
curaddr->netmask = NULL;
|
||||
|
||||
if (broadaddr != NULL) {
|
||||
curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
|
||||
if (curaddr->broadaddr == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
if (curaddr->netmask != NULL)
|
||||
free(curaddr->netmask);
|
||||
if (curaddr->addr != NULL)
|
||||
free(curaddr->addr);
|
||||
free(curaddr);
|
||||
return (-1);
|
||||
}
|
||||
} else
|
||||
curaddr->broadaddr = NULL;
|
||||
|
||||
if (dstaddr != NULL) {
|
||||
curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
|
||||
if (curaddr->dstaddr == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
if (curaddr->broadaddr != NULL)
|
||||
free(curaddr->broadaddr);
|
||||
if (curaddr->netmask != NULL)
|
||||
free(curaddr->netmask);
|
||||
if (curaddr->addr != NULL)
|
||||
free(curaddr->addr);
|
||||
free(curaddr);
|
||||
return (-1);
|
||||
}
|
||||
} else
|
||||
curaddr->dstaddr = NULL;
|
||||
|
||||
/*
|
||||
* Find the end of the list of addresses.
|
||||
*/
|
||||
for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
|
||||
nextaddr = prevaddr->next;
|
||||
if (nextaddr == NULL) {
|
||||
/*
|
||||
* This is the end of the list.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (prevaddr == NULL) {
|
||||
/*
|
||||
* The list was empty; this is the first member.
|
||||
*/
|
||||
curdev->addresses = curaddr;
|
||||
} else {
|
||||
/*
|
||||
* "prevaddr" is the last member of the list; append
|
||||
* this member to it.
|
||||
*/
|
||||
prevaddr->next = curaddr;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for a given device in the specified list of devices.
|
||||
*
|
||||
* If we find it, return 0.
|
||||
*
|
||||
* If we don't find it, check whether we can open it:
|
||||
*
|
||||
* If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
|
||||
* PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
|
||||
* it, as that probably means it exists but doesn't support
|
||||
* packet capture.
|
||||
*
|
||||
* Otherwise, attempt to add an entry for it, with the specified
|
||||
* ifnet flags and description, and, if that succeeds, return 0
|
||||
* and set *curdev_ret to point to the new entry, otherwise
|
||||
* return PCAP_ERROR and set errbuf to an error message.
|
||||
*/
|
||||
int
|
||||
pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
|
||||
const char *description, char *errbuf)
|
||||
{
|
||||
pcap_if_t *curdev;
|
||||
|
||||
return (add_or_find_if(&curdev, devlist, name, flags, description,
|
||||
errbuf));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free a list of interfaces.
|
||||
*/
|
||||
void
|
||||
pcap_freealldevs(pcap_if_t *alldevs)
|
||||
{
|
||||
pcap_if_t *curdev, *nextdev;
|
||||
pcap_addr_t *curaddr, *nextaddr;
|
||||
|
||||
for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
|
||||
nextdev = curdev->next;
|
||||
|
||||
/*
|
||||
* Free all addresses.
|
||||
*/
|
||||
for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
|
||||
nextaddr = curaddr->next;
|
||||
if (curaddr->addr)
|
||||
free(curaddr->addr);
|
||||
if (curaddr->netmask)
|
||||
free(curaddr->netmask);
|
||||
if (curaddr->broadaddr)
|
||||
free(curaddr->broadaddr);
|
||||
if (curaddr->dstaddr)
|
||||
free(curaddr->dstaddr);
|
||||
free(curaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the name string.
|
||||
*/
|
||||
free(curdev->name);
|
||||
|
||||
/*
|
||||
* Free the description string, if any.
|
||||
*/
|
||||
if (curdev->description != NULL)
|
||||
free(curdev->description);
|
||||
|
||||
/*
|
||||
* Free the interface.
|
||||
*/
|
||||
free(curdev);
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* fad-sita.c: Packet capture interface additions for SITA ACN devices
|
||||
*
|
||||
* Copyright (c) 2007 Fulko Hew, SITA INC Canada, Inc <fulko.hew@sita.aero>
|
||||
*
|
||||
* License: BSD
|
||||
*
|
||||
* 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. The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "pcap-sita.h"
|
||||
|
||||
extern pcap_if_t *acn_if_list; /* pcap's list of available interfaces */
|
||||
|
||||
int pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) {
|
||||
|
||||
//printf("pcap_findalldevs()\n"); // fulko
|
||||
|
||||
*alldevsp = 0; /* initialize the returned variables before we do anything */
|
||||
strcpy(errbuf, "");
|
||||
if (acn_parse_hosts_file(errbuf)) /* scan the hosts file for potential IOPs */
|
||||
{
|
||||
//printf("pcap_findalldevs() returning BAD after parsehosts\n"); // fulko
|
||||
return -1;
|
||||
}
|
||||
//printf("pcap_findalldevs() got hostlist now finding devs\n"); // fulko
|
||||
if (acn_findalldevs(errbuf)) /* then ask the IOPs for their monitorable devices */
|
||||
{
|
||||
//printf("pcap_findalldevs() returning BAD after findalldevs\n"); // fulko
|
||||
return -1;
|
||||
}
|
||||
*alldevsp = acn_if_list;
|
||||
acn_if_list = 0; /* then forget our list head, because someone will call pcap_freealldevs() to empty the malloc'ed stuff */
|
||||
//printf("pcap_findalldevs() returning ZERO OK\n"); // fulko
|
||||
return 0;
|
||||
}
|
11
contrib/libpcap/gen_version_c.sh
Executable file
11
contrib/libpcap/gen_version_c.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#! /bin/sh
|
||||
echo '#include <pcap/export-defs.h>' > "$2"
|
||||
echo 'PCAP_API_DEF' >> "$2"
|
||||
if grep GIT "$1" >/dev/null; then
|
||||
read ver <"$1"
|
||||
echo $ver | tr -d '\012'
|
||||
date +_%Y_%m_%d
|
||||
else
|
||||
cat "$1"
|
||||
fi | sed -e 's/.*/char pcap_version[] = "&";/' >> "$2"
|
||||
|
19
contrib/libpcap/gen_version_header.sh
Executable file
19
contrib/libpcap/gen_version_header.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#! /bin/sh
|
||||
print_version_string()
|
||||
{
|
||||
if grep GIT "$1" >/dev/null
|
||||
then
|
||||
read ver <"$1"
|
||||
echo $ver | tr -d '\012'
|
||||
date +_%Y_%m_%d
|
||||
else
|
||||
cat "$1"
|
||||
fi
|
||||
}
|
||||
if test $# != 3
|
||||
then
|
||||
echo "Usage: gen_version_header.sh <version file> <template> <output file>" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
version_string=`print_version_string "$1"`
|
||||
sed "s/%%LIBPCAP_VERSION%%/$version_string/" "$2" >"$3"
|
File diff suppressed because it is too large
Load Diff
@ -161,7 +161,7 @@
|
||||
#define A_CONNECTACK 44 /* Connect Ack message */
|
||||
#define A_RELEASE 45 /* Release message */
|
||||
#define A_RELEASE_DONE 46 /* Release message */
|
||||
|
||||
|
||||
/* ATM field types */
|
||||
#define A_VPI 51
|
||||
#define A_VCI 52
|
||||
@ -281,83 +281,115 @@ struct qual {
|
||||
unsigned char pad;
|
||||
};
|
||||
|
||||
struct arth *gen_loadi(int);
|
||||
struct arth *gen_load(int, struct arth *, int);
|
||||
struct arth *gen_loadlen(void);
|
||||
struct arth *gen_neg(struct arth *);
|
||||
struct arth *gen_arth(int, struct arth *, struct arth *);
|
||||
struct _compiler_state;
|
||||
|
||||
typedef struct _compiler_state compiler_state_t;
|
||||
|
||||
struct arth *gen_loadi(compiler_state_t *, int);
|
||||
struct arth *gen_load(compiler_state_t *, int, struct arth *, int);
|
||||
struct arth *gen_loadlen(compiler_state_t *);
|
||||
struct arth *gen_neg(compiler_state_t *, struct arth *);
|
||||
struct arth *gen_arth(compiler_state_t *, int, struct arth *, struct arth *);
|
||||
|
||||
void gen_and(struct block *, struct block *);
|
||||
void gen_or(struct block *, struct block *);
|
||||
void gen_not(struct block *);
|
||||
|
||||
struct block *gen_scode(const char *, struct qual);
|
||||
struct block *gen_ecode(const u_char *, struct qual);
|
||||
struct block *gen_acode(const u_char *, struct qual);
|
||||
struct block *gen_mcode(const char *, const char *, int, struct qual);
|
||||
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_mcode(compiler_state_t *, const char *, const char *,
|
||||
unsigned int, struct qual);
|
||||
#ifdef INET6
|
||||
struct block *gen_mcode6(const char *, const char *, int, struct qual);
|
||||
struct block *gen_mcode6(compiler_state_t *, const char *, const char *,
|
||||
unsigned int, struct qual);
|
||||
#endif
|
||||
struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
|
||||
struct block *gen_proto_abbrev(int);
|
||||
struct block *gen_relation(int, struct arth *, struct arth *, int);
|
||||
struct block *gen_less(int);
|
||||
struct block *gen_greater(int);
|
||||
struct block *gen_byteop(int, int, int);
|
||||
struct block *gen_broadcast(int);
|
||||
struct block *gen_multicast(int);
|
||||
struct block *gen_inbound(int);
|
||||
struct block *gen_ncode(compiler_state_t *, const char *, bpf_u_int32,
|
||||
struct qual);
|
||||
struct block *gen_proto_abbrev(compiler_state_t *, int);
|
||||
struct block *gen_relation(compiler_state_t *, int, struct arth *,
|
||||
struct arth *, int);
|
||||
struct block *gen_less(compiler_state_t *, int);
|
||||
struct block *gen_greater(compiler_state_t *, int);
|
||||
struct block *gen_byteop(compiler_state_t *, int, int, int);
|
||||
struct block *gen_broadcast(compiler_state_t *, int);
|
||||
struct block *gen_multicast(compiler_state_t *, int);
|
||||
struct block *gen_inbound(compiler_state_t *, int);
|
||||
|
||||
struct block *gen_llc(void);
|
||||
struct block *gen_llc_i(void);
|
||||
struct block *gen_llc_s(void);
|
||||
struct block *gen_llc_u(void);
|
||||
struct block *gen_llc_s_subtype(bpf_u_int32);
|
||||
struct block *gen_llc_u_subtype(bpf_u_int32);
|
||||
struct block *gen_llc(compiler_state_t *);
|
||||
struct block *gen_llc_i(compiler_state_t *);
|
||||
struct block *gen_llc_s(compiler_state_t *);
|
||||
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(int);
|
||||
struct block *gen_mpls(int);
|
||||
struct block *gen_vlan(compiler_state_t *, int);
|
||||
struct block *gen_mpls(compiler_state_t *, int);
|
||||
|
||||
struct block *gen_pppoed(void);
|
||||
struct block *gen_pppoes(int);
|
||||
struct block *gen_pppoed(compiler_state_t *);
|
||||
struct block *gen_pppoes(compiler_state_t *, int);
|
||||
|
||||
struct block *gen_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 jtype, int reverse);
|
||||
struct block *gen_atmtype_abbrev(int type);
|
||||
struct block *gen_atmmulti_abbrev(int type);
|
||||
struct block *gen_geneve(compiler_state_t *, int);
|
||||
|
||||
struct block *gen_mtp2type_abbrev(int type);
|
||||
struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
|
||||
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
|
||||
bpf_u_int32, int);
|
||||
struct block *gen_atmtype_abbrev(compiler_state_t *, int type);
|
||||
struct block *gen_atmmulti_abbrev(compiler_state_t *, int type);
|
||||
|
||||
struct block *gen_pf_ifname(const char *);
|
||||
struct block *gen_pf_rnr(int);
|
||||
struct block *gen_pf_srnr(int);
|
||||
struct block *gen_pf_ruleset(char *);
|
||||
struct block *gen_pf_reason(int);
|
||||
struct block *gen_pf_action(int);
|
||||
struct block *gen_pf_dir(int);
|
||||
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);
|
||||
|
||||
struct block *gen_p80211_type(int, int);
|
||||
struct block *gen_p80211_fcdir(int);
|
||||
struct block *gen_pf_ifname(compiler_state_t *, const char *);
|
||||
struct block *gen_pf_rnr(compiler_state_t *, int);
|
||||
struct block *gen_pf_srnr(compiler_state_t *, int);
|
||||
struct block *gen_pf_ruleset(compiler_state_t *, char *);
|
||||
struct block *gen_pf_reason(compiler_state_t *, int);
|
||||
struct block *gen_pf_action(compiler_state_t *, int);
|
||||
|
||||
void bpf_optimize(struct block **);
|
||||
void bpf_error(const char *, ...)
|
||||
struct block *gen_p80211_type(compiler_state_t *, int, int);
|
||||
struct block *gen_p80211_fcdir(compiler_state_t *, int);
|
||||
|
||||
/*
|
||||
* Representation of a program as a tree of blocks, plus current mark.
|
||||
* A block is marked if only if its mark equals the current mark.
|
||||
* Rather than traverse the code array, marking each item, 'cur_mark'
|
||||
* is incremented. This automatically makes each element unmarked.
|
||||
*/
|
||||
#define isMarked(icp, p) ((p)->mark == (icp)->cur_mark)
|
||||
#define unMarkAll(icp) (icp)->cur_mark += 1
|
||||
#define Mark(icp, p) ((p)->mark = (icp)->cur_mark)
|
||||
|
||||
struct icode {
|
||||
struct block *root;
|
||||
int cur_mark;
|
||||
};
|
||||
|
||||
void bpf_optimize(compiler_state_t *, struct icode *ic);
|
||||
void bpf_syntax_error(compiler_state_t *, const char *);
|
||||
void bpf_error(compiler_state_t *, const char *, ...)
|
||||
__attribute__((noreturn))
|
||||
#ifdef __ATTRIBUTE___FORMAT_OK
|
||||
__attribute__((format (printf, 1, 2)))
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
#endif /* __ATTRIBUTE___FORMAT_OK */
|
||||
;
|
||||
|
||||
void finish_parse(struct block *);
|
||||
char *sdup(const char *);
|
||||
void finish_parse(compiler_state_t *, struct block *);
|
||||
char *sdup(compiler_state_t *, const char *);
|
||||
|
||||
struct bpf_insn *icode_to_fcode(struct block *, u_int *);
|
||||
int pcap_parse(void);
|
||||
void lex_init(const char *);
|
||||
void lex_cleanup(void);
|
||||
struct _opt_state;
|
||||
typedef struct _opt_state opt_state_t;
|
||||
|
||||
struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
|
||||
struct block *, u_int *);
|
||||
void sappend(struct slist *, struct slist *);
|
||||
|
||||
/*
|
||||
* Older versions of Bison don't put this declaration in
|
||||
* grammar.h.
|
||||
*/
|
||||
int pcap_parse(void *, compiler_state_t *);
|
||||
|
||||
/* XXX */
|
||||
#define JT(b) ((b)->et.succ)
|
||||
#define JF(b) ((b)->ef.succ)
|
||||
|
||||
extern int no_optimize;
|
||||
|
@ -1,3 +1,28 @@
|
||||
/*
|
||||
* We want a reentrant parser.
|
||||
*/
|
||||
%pure-parser
|
||||
|
||||
/*
|
||||
* We also want a reentrant scanner, so we have to pass the
|
||||
* handle for the reentrant scanner to the parser, and the
|
||||
* parser has to pass it to the lexical analyzer.
|
||||
*
|
||||
* We use void * rather than yyscan_t because, at least with some
|
||||
* versions of Flex and Bison, if you use yyscan_t in %parse-param and
|
||||
* %lex-param, you have to include scanner.h before grammar.h to get
|
||||
* yyscan_t declared, and you have to include grammar.h before scanner.h
|
||||
* to get YYSTYPE declared. Using void * breaks the cycle; the Flex
|
||||
* documentation says yyscan_t is just a void *.
|
||||
*/
|
||||
%parse-param {void *yyscanner}
|
||||
%lex-param {void *yyscanner}
|
||||
|
||||
/*
|
||||
* And we need to pass the compiler state to the scanner.
|
||||
*/
|
||||
%parse-param {compiler_state_t *cstate}
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
|
||||
@ -26,16 +51,16 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#else /* _WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#if __STDC__
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
@ -43,13 +68,16 @@ struct rtentry;
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "gencode.h"
|
||||
#include "grammar.h"
|
||||
#include "scanner.h"
|
||||
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
#include <net/if.h>
|
||||
#include <netpfil/pf/pf.h>
|
||||
@ -170,31 +198,18 @@ str2tok(const char *str, const struct tok *toks)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int n_errors = 0;
|
||||
|
||||
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
|
||||
static void
|
||||
yyerror(const char *msg)
|
||||
yyerror(void *yyscanner, compiler_state_t *cstate, const char *msg)
|
||||
{
|
||||
++n_errors;
|
||||
bpf_error("%s", msg);
|
||||
bpf_syntax_error(cstate, msg);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#ifdef NEED_YYPARSE_WRAPPER
|
||||
int yyparse(void);
|
||||
|
||||
int
|
||||
pcap_parse()
|
||||
{
|
||||
return (yyparse());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
static int
|
||||
pfreason_to_num(const char *reason)
|
||||
pfreason_to_num(compiler_state_t *cstate, const char *reason)
|
||||
{
|
||||
const char *reasons[] = PFRES_NAMES;
|
||||
int i;
|
||||
@ -203,12 +218,12 @@ pfreason_to_num(const char *reason)
|
||||
if (pcap_strcasecmp(reason, reasons[i]) == 0)
|
||||
return (i);
|
||||
}
|
||||
bpf_error("unknown PF reason");
|
||||
bpf_error(cstate, "unknown PF reason");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
static int
|
||||
pfaction_to_num(const char *action)
|
||||
pfaction_to_num(compiler_state_t *cstate, const char *action)
|
||||
{
|
||||
if (pcap_strcasecmp(action, "pass") == 0 ||
|
||||
pcap_strcasecmp(action, "accept") == 0)
|
||||
@ -227,15 +242,15 @@ pfaction_to_num(const char *action)
|
||||
return (PF_NORDR);
|
||||
#endif
|
||||
else {
|
||||
bpf_error("unknown PF action");
|
||||
bpf_error(cstate, "unknown PF action");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
#else /* !HAVE_NET_PFVAR_H */
|
||||
static int
|
||||
pfreason_to_num(const char *reason)
|
||||
pfreason_to_num(compiler_state_t *cstate, const char *reason)
|
||||
{
|
||||
bpf_error("libpcap was compiled on a machine without pf support");
|
||||
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
/*NOTREACHED*/
|
||||
|
||||
/* this is to make the VC compiler happy */
|
||||
@ -243,9 +258,9 @@ pfreason_to_num(const char *reason)
|
||||
}
|
||||
|
||||
static int
|
||||
pfaction_to_num(const char *action)
|
||||
pfaction_to_num(compiler_state_t *cstate, const char *action)
|
||||
{
|
||||
bpf_error("libpcap was compiled on a machine without pf support");
|
||||
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
/*NOTREACHED*/
|
||||
|
||||
/* this is to make the VC compiler happy */
|
||||
@ -300,8 +315,8 @@ pfaction_to_num(const char *action)
|
||||
%token LEN
|
||||
%token IPV6 ICMPV6 AH ESP
|
||||
%token VLAN MPLS
|
||||
%token PPPOED PPPOES
|
||||
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
|
||||
%token PPPOED PPPOES GENEVE
|
||||
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
|
||||
%token STP
|
||||
%token IPX
|
||||
%token NETBEUI
|
||||
@ -311,7 +326,7 @@ pfaction_to_num(const char *action)
|
||||
%token RADIO
|
||||
%token FISU LSSU MSU HFISU HLSSU HMSU
|
||||
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
|
||||
|
||||
|
||||
|
||||
%type <s> ID
|
||||
%type <e> EID
|
||||
@ -330,7 +345,7 @@ pfaction_to_num(const char *action)
|
||||
%%
|
||||
prog: null expr
|
||||
{
|
||||
finish_parse($2.b);
|
||||
finish_parse(cstate, $2.b);
|
||||
}
|
||||
| null
|
||||
;
|
||||
@ -347,48 +362,48 @@ and: AND { $$ = $<blk>0; }
|
||||
or: OR { $$ = $<blk>0; }
|
||||
;
|
||||
id: nid
|
||||
| pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
|
||||
| pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q); }
|
||||
| paren pid ')' { $$ = $2; }
|
||||
;
|
||||
nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
|
||||
| HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
|
||||
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($1, $3, 0,
|
||||
| HID NETMASK HID { $$.b = gen_mcode(cstate, $1, $3, 0,
|
||||
$$.q = $<blk>0.q); }
|
||||
| HID {
|
||||
/* Decide how to parse HID based on proto */
|
||||
$$.q = $<blk>0.q;
|
||||
if ($$.q.addr == Q_PORT)
|
||||
bpf_error("'port' modifier applied to ip host");
|
||||
bpf_error(cstate, "'port' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PORTRANGE)
|
||||
bpf_error("'portrange' modifier applied to ip host");
|
||||
bpf_error(cstate, "'portrange' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PROTO)
|
||||
bpf_error("'proto' modifier applied to ip host");
|
||||
bpf_error(cstate, "'proto' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PROTOCHAIN)
|
||||
bpf_error("'protochain' modifier applied to ip host");
|
||||
$$.b = gen_ncode($1, 0, $$.q);
|
||||
bpf_error(cstate, "'protochain' modifier applied to ip host");
|
||||
$$.b = gen_ncode(cstate, $1, 0, $$.q);
|
||||
}
|
||||
| HID6 '/' NUM {
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6($1, NULL, $3,
|
||||
$$.b = gen_mcode6(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q);
|
||||
#else
|
||||
bpf_error("'ip6addr/prefixlen' not supported "
|
||||
bpf_error(cstate, "'ip6addr/prefixlen' not supported "
|
||||
"in this configuration");
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| HID6 {
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6($1, 0, 128,
|
||||
$$.b = gen_mcode6(cstate, $1, 0, 128,
|
||||
$$.q = $<blk>0.q);
|
||||
#else
|
||||
bpf_error("'ip6addr' not supported "
|
||||
bpf_error(cstate, "'ip6addr' not supported "
|
||||
"in this configuration");
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| EID {
|
||||
$$.b = gen_ecode($1, $$.q = $<blk>0.q);
|
||||
| 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
|
||||
@ -397,7 +412,7 @@ nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
|
||||
free($1);
|
||||
}
|
||||
| AID {
|
||||
$$.b = gen_acode($1, $$.q = $<blk>0.q);
|
||||
$$.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
|
||||
@ -415,7 +430,7 @@ 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(NULL, (bpf_u_int32)$1,
|
||||
qid: pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q); }
|
||||
| pid
|
||||
;
|
||||
@ -431,16 +446,16 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
|
||||
;
|
||||
rterm: head id { $$ = $2; }
|
||||
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
|
||||
| pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
|
||||
| arth relop arth { $$.b = gen_relation($2, $1, $3, 0);
|
||||
| pname { $$.b = gen_proto_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| arth relop arth { $$.b = gen_relation(cstate, $2, $1, $3, 0);
|
||||
$$.q = qerr; }
|
||||
| arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
|
||||
| arth irelop arth { $$.b = gen_relation(cstate, $2, $1, $3, 1);
|
||||
$$.q = qerr; }
|
||||
| other { $$.b = $1; $$.q = qerr; }
|
||||
| atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
|
||||
| atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
|
||||
| atmtype { $$.b = gen_atmtype_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| atmmultitype { $$.b = gen_atmmulti_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
|
||||
| mtp2type { $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; }
|
||||
| mtp2type { $$.b = gen_mtp2type_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
/* protocol level qualifiers */
|
||||
@ -510,52 +525,54 @@ pname: LINK { $$ = Q_LINK; }
|
||||
| NETBEUI { $$ = Q_NETBEUI; }
|
||||
| RADIO { $$ = Q_RADIO; }
|
||||
;
|
||||
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
|
||||
| pqual TK_MULTICAST { $$ = gen_multicast($1); }
|
||||
| LESS NUM { $$ = gen_less($2); }
|
||||
| GREATER NUM { $$ = gen_greater($2); }
|
||||
| CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
|
||||
| INBOUND { $$ = gen_inbound(0); }
|
||||
| OUTBOUND { $$ = gen_inbound(1); }
|
||||
| VLAN pnum { $$ = gen_vlan($2); }
|
||||
| VLAN { $$ = gen_vlan(-1); }
|
||||
| MPLS pnum { $$ = gen_mpls($2); }
|
||||
| MPLS { $$ = gen_mpls(-1); }
|
||||
| PPPOED { $$ = gen_pppoed(); }
|
||||
| PPPOES pnum { $$ = gen_pppoes($2); }
|
||||
| PPPOES { $$ = gen_pppoes(-1); }
|
||||
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); }
|
||||
| pfvar { $$ = $1; }
|
||||
| pqual p80211 { $$ = $2; }
|
||||
| pllc { $$ = $1; }
|
||||
;
|
||||
|
||||
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
|
||||
| PF_RSET ID { $$ = gen_pf_ruleset($2); }
|
||||
| PF_RNR NUM { $$ = gen_pf_rnr($2); }
|
||||
| PF_SRNR NUM { $$ = gen_pf_srnr($2); }
|
||||
| PF_REASON reason { $$ = gen_pf_reason($2); }
|
||||
| PF_ACTION action { $$ = gen_pf_action($2); }
|
||||
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); }
|
||||
;
|
||||
|
||||
p80211: TYPE type SUBTYPE subtype
|
||||
{ $$ = gen_p80211_type($2 | $4,
|
||||
{ $$ = gen_p80211_type(cstate, $2 | $4,
|
||||
IEEE80211_FC0_TYPE_MASK |
|
||||
IEEE80211_FC0_SUBTYPE_MASK);
|
||||
}
|
||||
| TYPE type { $$ = gen_p80211_type($2,
|
||||
| TYPE type { $$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK);
|
||||
}
|
||||
| SUBTYPE type_subtype { $$ = gen_p80211_type($2,
|
||||
| SUBTYPE type_subtype { $$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK |
|
||||
IEEE80211_FC0_SUBTYPE_MASK);
|
||||
}
|
||||
| DIR dir { $$ = gen_p80211_fcdir($2); }
|
||||
| DIR dir { $$ = gen_p80211_fcdir(cstate, $2); }
|
||||
;
|
||||
|
||||
type: NUM
|
||||
| ID { $$ = str2tok($1, ieee80211_types);
|
||||
if ($$ == -1)
|
||||
bpf_error("unknown 802.11 type name");
|
||||
bpf_error(cstate, "unknown 802.11 type name");
|
||||
}
|
||||
;
|
||||
|
||||
@ -565,7 +582,7 @@ subtype: NUM
|
||||
for (i = 0;; i++) {
|
||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||
/* Ran out of types */
|
||||
bpf_error("unknown 802.11 type");
|
||||
bpf_error(cstate, "unknown 802.11 type");
|
||||
break;
|
||||
}
|
||||
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
|
||||
@ -576,7 +593,7 @@ subtype: NUM
|
||||
|
||||
$$ = str2tok($1, types);
|
||||
if ($$ == -1)
|
||||
bpf_error("unknown 802.11 subtype name");
|
||||
bpf_error(cstate, "unknown 802.11 subtype name");
|
||||
}
|
||||
;
|
||||
|
||||
@ -584,7 +601,7 @@ type_subtype: ID { int i;
|
||||
for (i = 0;; i++) {
|
||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||
/* Ran out of types */
|
||||
bpf_error("unknown 802.11 type name");
|
||||
bpf_error(cstate, "unknown 802.11 type name");
|
||||
break;
|
||||
}
|
||||
$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
|
||||
@ -596,29 +613,29 @@ type_subtype: ID { int i;
|
||||
}
|
||||
;
|
||||
|
||||
pllc: LLC { $$ = gen_llc(); }
|
||||
pllc: LLC { $$ = gen_llc(cstate); }
|
||||
| LLC ID { if (pcap_strcasecmp($2, "i") == 0)
|
||||
$$ = gen_llc_i();
|
||||
$$ = gen_llc_i(cstate);
|
||||
else if (pcap_strcasecmp($2, "s") == 0)
|
||||
$$ = gen_llc_s();
|
||||
$$ = gen_llc_s(cstate);
|
||||
else if (pcap_strcasecmp($2, "u") == 0)
|
||||
$$ = gen_llc_u();
|
||||
$$ = gen_llc_u(cstate);
|
||||
else {
|
||||
u_int subtype;
|
||||
int subtype;
|
||||
|
||||
subtype = str2tok($2, llc_s_subtypes);
|
||||
if (subtype != -1)
|
||||
$$ = gen_llc_s_subtype(subtype);
|
||||
$$ = gen_llc_s_subtype(cstate, subtype);
|
||||
else {
|
||||
subtype = str2tok($2, llc_u_subtypes);
|
||||
if (subtype == -1)
|
||||
bpf_error("unknown LLC type name \"%s\"", $2);
|
||||
$$ = gen_llc_u_subtype(subtype);
|
||||
bpf_error(cstate, "unknown LLC type name \"%s\"", $2);
|
||||
$$ = gen_llc_u_subtype(cstate, subtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* sigh, "rnr" is already a keyword for PF */
|
||||
| LLC PF_RNR { $$ = gen_llc_s_subtype(LLC_RNR); }
|
||||
| LLC PF_RNR { $$ = gen_llc_s_subtype(cstate, LLC_RNR); }
|
||||
;
|
||||
|
||||
dir: NUM
|
||||
@ -631,15 +648,15 @@ dir: NUM
|
||||
else if (pcap_strcasecmp($1, "dstods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_DSTODS;
|
||||
else
|
||||
bpf_error("unknown 802.11 direction");
|
||||
bpf_error(cstate, "unknown 802.11 direction");
|
||||
}
|
||||
;
|
||||
|
||||
reason: NUM { $$ = $1; }
|
||||
| ID { $$ = pfreason_to_num($1); }
|
||||
| ID { $$ = pfreason_to_num(cstate, $1); }
|
||||
;
|
||||
|
||||
action: ID { $$ = pfaction_to_num($1); }
|
||||
action: ID { $$ = pfaction_to_num(cstate, $1); }
|
||||
;
|
||||
|
||||
relop: '>' { $$ = BPF_JGT; }
|
||||
@ -650,24 +667,24 @@ irelop: LEQ { $$ = BPF_JGT; }
|
||||
| '<' { $$ = BPF_JGE; }
|
||||
| NEQ { $$ = BPF_JEQ; }
|
||||
;
|
||||
arth: pnum { $$ = gen_loadi($1); }
|
||||
arth: pnum { $$ = gen_loadi(cstate, $1); }
|
||||
| narth
|
||||
;
|
||||
narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); }
|
||||
| pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); }
|
||||
| arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); }
|
||||
| arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); }
|
||||
| arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); }
|
||||
| arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); }
|
||||
| arth '%' arth { $$ = gen_arth(BPF_MOD, $1, $3); }
|
||||
| arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); }
|
||||
| arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); }
|
||||
| arth '^' arth { $$ = gen_arth(BPF_XOR, $1, $3); }
|
||||
| arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); }
|
||||
| arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); }
|
||||
| '-' arth %prec UMINUS { $$ = gen_neg($2); }
|
||||
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); }
|
||||
| paren narth ')' { $$ = $2; }
|
||||
| LEN { $$ = gen_loadlen(); }
|
||||
| LEN { $$ = gen_loadlen(cstate); }
|
||||
;
|
||||
byteop: '&' { $$ = '&'; }
|
||||
| '|' { $$ = '|'; }
|
||||
@ -696,15 +713,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
|
||||
| VCI { $$.atmfieldtype = A_VCI; }
|
||||
;
|
||||
atmvalue: atmfieldvalue
|
||||
| relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
|
||||
| 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); }
|
||||
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
atmfieldvalue: NUM {
|
||||
$$.atmfieldtype = $<blk>0.atmfieldtype;
|
||||
if ($$.atmfieldtype == A_VPI ||
|
||||
$$.atmfieldtype == A_VCI)
|
||||
$$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
|
||||
$$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
|
||||
}
|
||||
;
|
||||
atmlistvalue: atmfieldvalue
|
||||
@ -729,8 +746,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
|
||||
| HSLS { $$.mtp3fieldtype = MH_SLS; }
|
||||
;
|
||||
mtp3value: mtp3fieldvalue
|
||||
| relop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
|
||||
| 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); }
|
||||
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
mtp3fieldvalue: NUM {
|
||||
@ -743,7 +760,7 @@ mtp3fieldvalue: NUM {
|
||||
$$.mtp3fieldtype == MH_OPC ||
|
||||
$$.mtp3fieldtype == MH_DPC ||
|
||||
$$.mtp3fieldtype == MH_SLS)
|
||||
$$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
$$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
}
|
||||
;
|
||||
mtp3listvalue: mtp3fieldvalue
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -115,7 +115,7 @@ fi
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
@ -124,7 +124,7 @@ if [ x"$dir_arg" != x ]; then
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
@ -134,7 +134,7 @@ else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
@ -201,17 +201,17 @@ else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
@ -242,7 +242,7 @@ else
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
23
contrib/libpcap/lbl/os-aix7.h
Normal file
23
contrib/libpcap/lbl/os-aix7.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/* Prototypes missing in AIX 7.x */
|
||||
int ffs(int i);
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/* Prototypes missing in Digital UNIX 4.x */
|
||||
int snprintf(char *, size_t, const char *, ...);
|
||||
int vsnprintf(char *, size_t, const char *, va_list);
|
||||
int pcap_snprintf(char *, size_t, const char *, ...);
|
||||
int pcap_vsnprintf(char *, size_t, const char *, va_list);
|
||||
int pfopen(char *, int);
|
||||
|
||||
|
||||
|
@ -21,10 +21,10 @@
|
||||
|
||||
/*
|
||||
* Prototypes missing in Tru64 UNIX 5.x
|
||||
* XXX - "snprintf()" and "vsnprintf()" aren't missing, but you have to
|
||||
* XXX - "pcap_snprintf()" and "pcap_vsnprintf()" aren't missing, but you have to
|
||||
* #define the right value to get them defined by <stdio.h>.
|
||||
*/
|
||||
int snprintf(char *, size_t, const char *, ...);
|
||||
int vsnprintf(char *, size_t, const char *, va_list);
|
||||
int pcap_snprintf(char *, size_t, const char *, ...);
|
||||
int pcap_vsnprintf(char *, size_t, const char *, va_list);
|
||||
int pfopen(char *, int);
|
||||
|
||||
|
||||
|
@ -21,4 +21,4 @@
|
||||
|
||||
/* Prototypes missing in SunOS 5 */
|
||||
char *strerror(int);
|
||||
int snprintf(char *, size_t, const char *, ...);
|
||||
int pcap_snprintf(char *, size_t, const char *, ...);
|
||||
|
@ -65,7 +65,6 @@ int fchmod(int, int);
|
||||
int fchown(int, int, int);
|
||||
void endgrent(void);
|
||||
void endpwent(void);
|
||||
void endservent(void);
|
||||
#ifdef __STDC__
|
||||
struct ether_addr;
|
||||
#endif
|
||||
@ -146,7 +145,6 @@ int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
|
||||
int setpgrp(int, int);
|
||||
void setpwent(void);
|
||||
int setrlimit(int, struct rlimit *);
|
||||
void setservent(int);
|
||||
int setsockopt(int, int, int, char *, int);
|
||||
int shutdown(int, int);
|
||||
int sigblock(int);
|
||||
@ -157,7 +155,7 @@ int sigsetmask(int);
|
||||
struct sigvec;
|
||||
#endif
|
||||
int sigvec(int, struct sigvec *, struct sigvec*);
|
||||
int snprintf(char *, size_t, const char *, ...);
|
||||
int pcap_snprintf(char *, size_t, const char *, ...);
|
||||
int socket(int, int, int);
|
||||
int socketpair(int, int, int, int *);
|
||||
int symlink(const char *, const char *);
|
||||
|
@ -23,7 +23,6 @@
|
||||
int bcmp(const char *, const char *, u_int);
|
||||
void bcopy(const void *, void *, u_int);
|
||||
void bzero(void *, u_int);
|
||||
void endservent(void);
|
||||
int getopt(int, char * const *, const char *);
|
||||
#ifdef __STDC__
|
||||
struct timeval;
|
||||
|
126
contrib/libpcap/missing/getopt.c
Normal file
126
contrib/libpcap/missing/getopt.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* 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 University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
int opterr = 1, /* if error message should be printed */
|
||||
optind = 1, /* index into parent argv vector */
|
||||
optopt, /* character checked for validity */
|
||||
optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt(nargc, nargv, ostr)
|
||||
int nargc;
|
||||
char * const *nargv;
|
||||
const char *ostr;
|
||||
{
|
||||
char *cp;
|
||||
static char *__progname;
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
|
||||
if (__progname == NULL) {
|
||||
if ((cp = strrchr(nargv[0], '/')) != NULL)
|
||||
__progname = cp + 1;
|
||||
else
|
||||
__progname = nargv[0];
|
||||
}
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
if (optind >= nargc || *(place = nargv[optind]) != '-') {
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (place[1] && *++place == '-') { /* found "--" */
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
} /* option letter okay? */
|
||||
if ((optopt = (int)*place++) == (int)':' ||
|
||||
!(oli = strchr(ostr, optopt))) {
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means -1.
|
||||
*/
|
||||
if (optopt == (int)'-')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %c\n", __progname, optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
}
|
||||
else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (nargc <= ++optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (opterr)
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
__progname, optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* dump back option letter */
|
||||
}
|
7
contrib/libpcap/missing/getopt.h
Normal file
7
contrib/libpcap/missing/getopt.h
Normal file
@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Header for the getopt() we supply if the platform doesn't supply it.
|
||||
*/
|
||||
extern char *optarg; /* getopt(3) external variables */
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
extern int getopt(int nargc, char * const *nargv, const char *ostr);
|
@ -456,13 +456,13 @@ xyzprintf (struct state *state, const char *char_format, va_list ap)
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
int
|
||||
snprintf (char *str, size_t sz, const char *format, ...)
|
||||
pcap_snprintf (char *str, size_t sz, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = vsnprintf (str, sz, format, args);
|
||||
ret = pcap_vsnprintf (str, sz, format, args);
|
||||
|
||||
#ifdef PARANOIA
|
||||
{
|
||||
@ -473,7 +473,7 @@ snprintf (char *str, size_t sz, const char *format, ...)
|
||||
if (tmp == NULL)
|
||||
abort ();
|
||||
|
||||
ret2 = vsprintf (tmp, format, args);
|
||||
ret2 = pcap_vsprintf (tmp, format, args);
|
||||
if (ret != ret2 || strcmp(str, tmp))
|
||||
abort ();
|
||||
free (tmp);
|
||||
@ -518,13 +518,13 @@ asprintf (char **ret, const char *format, ...)
|
||||
|
||||
#ifndef HAVE_ASNPRINTF
|
||||
int
|
||||
asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||
pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int val;
|
||||
|
||||
va_start(args, format);
|
||||
val = vasnprintf (ret, max_sz, format, args);
|
||||
val = pcap_vasnprintf (ret, max_sz, format, args);
|
||||
|
||||
#ifdef PARANOIA
|
||||
{
|
||||
@ -534,7 +534,7 @@ asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||
if (tmp == NULL)
|
||||
abort ();
|
||||
|
||||
ret2 = vsprintf (tmp, format, args);
|
||||
ret2 = pcap_vsprintf (tmp, format, args);
|
||||
if (val != ret2 || strcmp(*ret, tmp))
|
||||
abort ();
|
||||
free (tmp);
|
||||
@ -548,16 +548,16 @@ asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||
|
||||
#ifndef HAVE_VASPRINTF
|
||||
int
|
||||
vasprintf (char **ret, const char *format, va_list args)
|
||||
pcap_vasprintf (char **ret, const char *format, va_list args)
|
||||
{
|
||||
return vasnprintf (ret, 0, format, args);
|
||||
return pcap_vasnprintf (ret, 0, format, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_VASNPRINTF
|
||||
int
|
||||
vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
|
||||
pcap_vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
|
||||
{
|
||||
int st;
|
||||
size_t len;
|
||||
@ -600,7 +600,7 @@ vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
|
||||
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
int
|
||||
vsnprintf (char *str, size_t sz, const char *format, va_list args)
|
||||
pcap_vsnprintf (char *str, size_t sz, const char *format, va_list args)
|
||||
{
|
||||
struct state state;
|
||||
int ret;
|
||||
|
87
contrib/libpcap/missing/strtok_r.c
Normal file
87
contrib/libpcap/missing/strtok_r.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Softweyr LLC. All rights reserved.
|
||||
*
|
||||
* strtok_r, from Berkeley strtok
|
||||
* Oct 13, 1998 by Wes Peters <wes@softweyr.com>
|
||||
*
|
||||
* Copyright (c) 1988, 1993
|
||||
* 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
|
||||
* notices, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notices, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, 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 SOFTWEYR LLC, 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.
|
||||
*
|
||||
* From: @(#)strtok.c 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
char *
|
||||
pcap_strtok_r(char *s, const char *delim, char **last)
|
||||
{
|
||||
char *spanp, *tok;
|
||||
int c, sc;
|
||||
|
||||
if (s == NULL && (s = *last) == NULL)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
|
||||
*/
|
||||
cont:
|
||||
c = *s++;
|
||||
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
|
||||
if (c == sc)
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (c == 0) { /* no non-delimiter characters */
|
||||
*last = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
tok = s - 1;
|
||||
|
||||
/*
|
||||
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
|
||||
* Note that delim must have one NUL; we stop if we see that, too.
|
||||
*/
|
||||
for (;;) {
|
||||
c = *s++;
|
||||
spanp = (char *)delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = '\0';
|
||||
*last = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
31
contrib/libpcap/missing/win_snprintf.c
Normal file
31
contrib/libpcap/missing/win_snprintf.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
pcap_vsnprintf(char *str, size_t str_size, const char *format, va_list args)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _vsnprintf_s(str, str_size, _TRUNCATE, format, args);
|
||||
|
||||
/*
|
||||
* XXX - _vsnprintf() and _snprintf() do *not* guarantee
|
||||
* that str is null-terminated, but C99's vsnprintf()
|
||||
* and snprintf() do, and we want to offer C99 behavior,
|
||||
* so forcibly null-terminate the string.
|
||||
*/
|
||||
str[str_size - 1] = '\0';
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_snprintf(char *str, size_t str_size, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = pcap_vsnprintf(str, str_size, format, args);
|
||||
va_end(args);
|
||||
return (ret);
|
||||
}
|
@ -13,9 +13,6 @@
|
||||
# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88
|
||||
#
|
||||
|
||||
PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin:/usr/sfw/bin
|
||||
export PATH
|
||||
|
||||
MAKE=Makefile # default makefile name is "Makefile"
|
||||
CC=cc # default C compiler is "cc"
|
||||
DEPENDENCY_CFLAG=-M # default dependency-generation flag is -M
|
||||
|
@ -33,10 +33,36 @@
|
||||
#include <netdnet/dnetdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
|
||||
#else /* WIN32 */
|
||||
#ifdef INET6
|
||||
/*
|
||||
* To quote the MSDN page for getaddrinfo() at
|
||||
*
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
|
||||
*
|
||||
* "Support for getaddrinfo on Windows 2000 and older versions
|
||||
* The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
|
||||
* later. To execute an application that uses this function on earlier
|
||||
* versions of Windows, then you need to include the Ws2tcpip.h and
|
||||
* Wspiapi.h files. When the Wspiapi.h include file is added, the
|
||||
* getaddrinfo function is defined to the WspiapiGetAddrInfo inline
|
||||
* function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
|
||||
* function is implemented in such a way that if the Ws2_32.dll or the
|
||||
* Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
|
||||
* Preview for Windows 2000) does not include getaddrinfo, then a
|
||||
* version of getaddrinfo is implemented inline based on code in the
|
||||
* Wspiapi.h header file. This inline code will be used on older Windows
|
||||
* platforms that do not natively support the getaddrinfo function."
|
||||
*
|
||||
* We use getaddrinfo(), so we include Wspiapi.h here. pcap-stdinc.h
|
||||
* includes Ws2tcpip.h, so we don't need to include it ourselves.
|
||||
*/
|
||||
#include <Wspiapi.h>
|
||||
#endif
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h> /* concession to AIX */
|
||||
@ -44,9 +70,9 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#ifdef HAVE_ETHER_HOSTTON
|
||||
/*
|
||||
* XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
|
||||
@ -64,7 +90,7 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
#endif /* HAVE_ETHER_HOSTTON */
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -76,6 +102,7 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
|
||||
#include "gencode.h"
|
||||
#include <pcap/namedb.h>
|
||||
#include "nametoaddr.h"
|
||||
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
@ -142,7 +169,7 @@ pcap_nametoaddrinfo(const char *name)
|
||||
bpf_u_int32
|
||||
pcap_nametonetaddr(const char *name)
|
||||
{
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
struct netent *np;
|
||||
|
||||
if ((np = getnetbyname(name)) != NULL)
|
||||
@ -152,6 +179,15 @@ pcap_nametonetaddr(const char *name)
|
||||
#else
|
||||
/*
|
||||
* There's no "getnetbyname()" on Windows.
|
||||
*
|
||||
* XXX - I guess we could use the BSD code to read
|
||||
* C:\Windows\System32\drivers\etc/networks, assuming
|
||||
* that's its home on all the versions of Windows
|
||||
* we use, but that file probably just has the loopback
|
||||
* network on 127/24 on 99 44/100% of Windows machines.
|
||||
*
|
||||
* (Heck, these days it probably just has that on 99 44/100%
|
||||
* of *UN*X* machines.)
|
||||
*/
|
||||
return 0;
|
||||
#endif
|
||||
@ -276,8 +312,14 @@ struct eproto {
|
||||
u_short p;
|
||||
};
|
||||
|
||||
/* Static data base of ether protocol types. */
|
||||
struct eproto eproto_db[] = {
|
||||
/*
|
||||
* Static data base of ether protocol types.
|
||||
* tcpdump used to import this, and it's declared as an export on
|
||||
* Debian, at least, so make it a public symbol, even though we
|
||||
* don't officially export it by declaring it in a header file.
|
||||
* (Programs *should* do this themselves, as tcpdump now does.)
|
||||
*/
|
||||
PCAP_API_DEF struct eproto eproto_db[] = {
|
||||
#if 0
|
||||
/* The FreeBSD elf linker generates a request to copy this array
|
||||
* (including its size) when you link with -lpcap. In order to
|
||||
@ -394,7 +436,7 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr)
|
||||
u_int node, area;
|
||||
|
||||
if (sscanf(s, "%d.%d", &area, &node) != 2)
|
||||
bpf_error("malformed decnet address '%s'", s);
|
||||
return(0);
|
||||
|
||||
*addr = (area << AREASHIFT) & AREAMASK;
|
||||
*addr |= (node & NODEMASK);
|
||||
@ -498,23 +540,20 @@ pcap_ether_hostton(const char *name)
|
||||
}
|
||||
#endif
|
||||
|
||||
u_short
|
||||
__pcap_nametodnaddr(const char *name)
|
||||
int
|
||||
__pcap_nametodnaddr(const char *name, u_short *res)
|
||||
{
|
||||
#ifdef DECNETLIB
|
||||
struct nodeent *getnodebyname();
|
||||
struct nodeent *nep;
|
||||
unsigned short res;
|
||||
|
||||
nep = getnodebyname(name);
|
||||
if (nep == ((struct nodeent *)0))
|
||||
bpf_error("unknown decnet host name '%s'\n", name);
|
||||
return(0);
|
||||
|
||||
memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
|
||||
return(res);
|
||||
memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
|
||||
return(1);
|
||||
#else
|
||||
bpf_error("decnet name support not included, '%s' cannot be translated\n",
|
||||
name);
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
48
contrib/libpcap/nametoaddr.h
Normal file
48
contrib/libpcap/nametoaddr.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 1996
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Routines used for name-or-address-string-to-address resolution
|
||||
* that are *not* exported to code using libpcap.
|
||||
*/
|
||||
int __pcap_atodn(const char *, bpf_u_int32 *);
|
||||
int __pcap_atoin(const char *, bpf_u_int32 *);
|
||||
int __pcap_nametodnaddr(const char *, u_short *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@
|
||||
*
|
||||
* This code is derived from the Stanford/CMU enet packet filter,
|
||||
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
|
||||
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
|
||||
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
|
||||
* Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -11,8 +11,8 @@
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
@ -31,7 +31,7 @@
|
||||
* By Paolo Abeni <paolo.abeni@email.it>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
@ -73,7 +73,7 @@ struct pcap_bt {
|
||||
int dev_id; /* device ID of device we're bound to */
|
||||
};
|
||||
|
||||
int
|
||||
int
|
||||
bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||
{
|
||||
struct hci_dev_list_req *dev_list;
|
||||
@ -84,18 +84,18 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||
if (sock < 0)
|
||||
{
|
||||
/* if bluetooth is not supported this this is not fatal*/
|
||||
/* if bluetooth is not supported this this is not fatal*/
|
||||
if (errno == EAFNOSUPPORT)
|
||||
return 0;
|
||||
snprintf(err_str, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
|
||||
"Can't open raw Bluetooth socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev_list = malloc(HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
|
||||
if (!dev_list)
|
||||
if (!dev_list)
|
||||
{
|
||||
snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't allocate %zu bytes for Bluetooth device list",
|
||||
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't allocate %zu bytes for Bluetooth device list",
|
||||
HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
|
||||
ret = -1;
|
||||
goto done;
|
||||
@ -103,9 +103,9 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||
|
||||
dev_list->dev_num = HCI_MAX_DEV;
|
||||
|
||||
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
|
||||
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
|
||||
{
|
||||
snprintf(err_str, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
|
||||
"Can't get Bluetooth device list via ioctl: %s",
|
||||
strerror(errno));
|
||||
ret = -1;
|
||||
@ -115,11 +115,11 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||
dev_req = dev_list->dev_req;
|
||||
for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
|
||||
char dev_name[20], dev_descr[30];
|
||||
|
||||
snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
|
||||
snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
|
||||
|
||||
if (pcap_add_if(alldevsp, dev_name, 0,
|
||||
|
||||
pcap_snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
|
||||
pcap_snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
|
||||
|
||||
if (pcap_add_if(alldevsp, dev_name, 0,
|
||||
dev_descr, err_str) < 0)
|
||||
{
|
||||
ret = -1;
|
||||
@ -171,7 +171,7 @@ bt_create(const char *device, char *ebuf, int *is_ours)
|
||||
/* OK, it's probably ours. */
|
||||
*is_ours = 1;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_bt));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_bt));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -190,17 +190,16 @@ bt_activate(pcap_t* handle)
|
||||
int err = PCAP_ERROR;
|
||||
|
||||
/* get bt interface id */
|
||||
if (sscanf(handle->opt.source, BT_IFACE"%d", &dev_id) != 1)
|
||||
if (sscanf(handle->opt.device, BT_IFACE"%d", &dev_id) != 1)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't get Bluetooth device index from %s",
|
||||
handle->opt.source);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't get Bluetooth device index from %s",
|
||||
handle->opt.device);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/* Initialize some components of the pcap structure. */
|
||||
handle->bufsize = handle->snapshot+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
|
||||
handle->offset = BT_CTRL_SIZE;
|
||||
handle->bufsize = BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header)+handle->snapshot;
|
||||
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
|
||||
|
||||
handle->read_op = bt_read_linux;
|
||||
@ -212,43 +211,43 @@ bt_activate(pcap_t* handle)
|
||||
handle->setnonblock_op = pcap_setnonblock_fd;
|
||||
handle->stats_op = bt_stats_linux;
|
||||
handlep->dev_id = dev_id;
|
||||
|
||||
|
||||
/* Create HCI socket */
|
||||
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||
if (handle->fd < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't create raw socket: %s", strerror(errno));
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
handle->buffer = malloc(handle->bufsize);
|
||||
if (!handle->buffer) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
|
||||
pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
opt = 1;
|
||||
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't enable data direction info: %s", strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
opt = 1;
|
||||
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't enable time stamp: %s", strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
/* Setup filter, do not call hci function to avoid dependence on
|
||||
/* Setup filter, do not call hci function to avoid dependence on
|
||||
* external libs */
|
||||
memset(&flt, 0, sizeof(flt));
|
||||
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
|
||||
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
|
||||
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
|
||||
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't set filter: %s", strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
@ -261,7 +260,7 @@ bt_activate(pcap_t* handle)
|
||||
addr.hci_channel = HCI_CHANNEL_RAW;
|
||||
#endif
|
||||
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't attach to device %d: %s", handlep->dev_id,
|
||||
strerror(errno));
|
||||
goto close_fail;
|
||||
@ -282,7 +281,7 @@ bt_activate(pcap_t* handle)
|
||||
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF,
|
||||
&handle->opt.buffer_size,
|
||||
sizeof(handle->opt.buffer_size)) == -1) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"SO_RCVBUF: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
@ -305,16 +304,19 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
|
||||
ssize_t ret;
|
||||
struct pcap_pkthdr pkth;
|
||||
pcap_bluetooth_h4_header* bthdr;
|
||||
u_char *pktd;
|
||||
int in = 0;
|
||||
|
||||
bthdr = (pcap_bluetooth_h4_header*) &handle->buffer[handle->offset];
|
||||
iv.iov_base = &handle->buffer[handle->offset+sizeof(pcap_bluetooth_h4_header)];
|
||||
pktd = (u_char *)handle->buffer + BT_CTRL_SIZE;
|
||||
bthdr = (pcap_bluetooth_h4_header*)(void *)pktd;
|
||||
iv.iov_base = pktd + sizeof(pcap_bluetooth_h4_header);
|
||||
iv.iov_len = handle->snapshot;
|
||||
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = &iv;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = handle->buffer;
|
||||
msg.msg_controllen = handle->offset;
|
||||
msg.msg_controllen = BT_CTRL_SIZE;
|
||||
|
||||
/* ignore interrupt system call error */
|
||||
do {
|
||||
@ -327,16 +329,15 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
|
||||
} while ((ret == -1) && (errno == EINTR));
|
||||
|
||||
if (ret < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't receive packet: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pkth.caplen = ret;
|
||||
|
||||
/* get direction and timestamp*/
|
||||
/* get direction and timestamp*/
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
int in=0;
|
||||
while (cmsg) {
|
||||
switch (cmsg->cmsg_type) {
|
||||
case HCI_CMSG_DIR:
|
||||
@ -349,7 +350,7 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
|
||||
}
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
||||
}
|
||||
if ((in && (handle->direction == PCAP_D_OUT)) ||
|
||||
if ((in && (handle->direction == PCAP_D_OUT)) ||
|
||||
((!in) && (handle->direction == PCAP_D_IN)))
|
||||
return 0;
|
||||
|
||||
@ -357,9 +358,8 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
|
||||
pkth.caplen+=sizeof(pcap_bluetooth_h4_header);
|
||||
pkth.len = pkth.caplen;
|
||||
if (handle->fcode.bf_insns == NULL ||
|
||||
bpf_filter(handle->fcode.bf_insns, &handle->buffer[handle->offset],
|
||||
pkth.len, pkth.caplen)) {
|
||||
callback(user, &pkth, &handle->buffer[handle->offset]);
|
||||
bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
|
||||
callback(user, &pkth, pktd);
|
||||
return 1;
|
||||
}
|
||||
return 0; /* didn't pass filter */
|
||||
@ -368,13 +368,13 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
|
||||
static int
|
||||
bt_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
|
||||
"bluetooth devices");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static int
|
||||
bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
{
|
||||
struct pcap_bt *handlep = handle->priv;
|
||||
@ -382,28 +382,28 @@ bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
struct hci_dev_info dev_info;
|
||||
struct hci_dev_stats * s = &dev_info.stat;
|
||||
dev_info.dev_id = handlep->dev_id;
|
||||
|
||||
|
||||
/* ignore eintr */
|
||||
do {
|
||||
ret = ioctl(handle->fd, HCIGETDEVINFO, (void *)&dev_info);
|
||||
} while ((ret == -1) && (errno == EINTR));
|
||||
|
||||
|
||||
if (ret < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't get stats via ioctl: %s", strerror(errno));
|
||||
return (-1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* we receive both rx and tx frames, so comulate all stats */
|
||||
stats->ps_recv = s->evt_rx + s->acl_rx + s->sco_rx + s->cmd_tx +
|
||||
/* we receive both rx and tx frames, so comulate all stats */
|
||||
stats->ps_recv = s->evt_rx + s->acl_rx + s->sco_rx + s->cmd_tx +
|
||||
s->acl_tx +s->sco_tx;
|
||||
stats->ps_drop = s->err_rx + s->err_tx;
|
||||
stats->ps_ifdrop = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
bt_setdirection_linux(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
p->direction = d;
|
||||
|
@ -11,8 +11,8 @@
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
|
@ -34,19 +34,31 @@
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/mgmt.h>
|
||||
|
||||
#include "pcap/bluetooth.h"
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "pcap-bt-monitor-linux.h"
|
||||
|
||||
#define BT_CONTROL_SIZE 32
|
||||
#define INTERFACE_NAME "bluetooth-monitor"
|
||||
|
||||
/*
|
||||
* Fields and alignment must match the declaration in the Linux kernel 3.4+.
|
||||
* See struct hci_mon_hdr in include/net/bluetooth/hci_mon.h.
|
||||
*/
|
||||
struct hci_mon_hdr {
|
||||
uint16_t opcode;
|
||||
uint16_t index;
|
||||
uint16_t len;
|
||||
} __attribute__((packed));
|
||||
|
||||
int
|
||||
bt_monitor_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||
{
|
||||
@ -70,14 +82,15 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
|
||||
ssize_t ret;
|
||||
struct pcap_pkthdr pkth;
|
||||
pcap_bluetooth_linux_monitor_header *bthdr;
|
||||
struct mgmt_hdr hdr;
|
||||
int in = 0;
|
||||
u_char *pktd;
|
||||
struct hci_mon_hdr hdr;
|
||||
|
||||
bthdr = (pcap_bluetooth_linux_monitor_header*) &handle->buffer[handle->offset];
|
||||
pktd = (u_char *)handle->buffer + BT_CONTROL_SIZE;
|
||||
bthdr = (pcap_bluetooth_linux_monitor_header*)(void *)pktd;
|
||||
|
||||
iv[0].iov_base = &hdr;
|
||||
iv[0].iov_len = MGMT_HDR_SIZE;
|
||||
iv[1].iov_base = &handle->buffer[handle->offset + sizeof(pcap_bluetooth_linux_monitor_header)];
|
||||
iv[0].iov_len = sizeof(hdr);
|
||||
iv[1].iov_base = pktd + sizeof(pcap_bluetooth_linux_monitor_header);
|
||||
iv[1].iov_len = handle->snapshot;
|
||||
|
||||
memset(&pkth.ts, 0, sizeof(pkth.ts));
|
||||
@ -85,7 +98,7 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
|
||||
msg.msg_iov = iv;
|
||||
msg.msg_iovlen = 2;
|
||||
msg.msg_control = handle->buffer;
|
||||
msg.msg_controllen = handle->offset;
|
||||
msg.msg_controllen = BT_CONTROL_SIZE;
|
||||
|
||||
do {
|
||||
ret = recvmsg(handle->fd, &msg, 0);
|
||||
@ -97,12 +110,12 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
|
||||
} while ((ret == -1) && (errno == EINTR));
|
||||
|
||||
if (ret < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't receive packet: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pkth.caplen = ret - MGMT_HDR_SIZE + sizeof(pcap_bluetooth_linux_monitor_header);
|
||||
pkth.caplen = ret - sizeof(hdr) + sizeof(pcap_bluetooth_linux_monitor_header);
|
||||
pkth.len = pkth.caplen;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
@ -117,9 +130,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
|
||||
bthdr->opcode = htons(hdr.opcode);
|
||||
|
||||
if (handle->fcode.bf_insns == NULL ||
|
||||
bpf_filter(handle->fcode.bf_insns, &handle->buffer[handle->offset],
|
||||
pkth.len, pkth.caplen)) {
|
||||
callback(user, &pkth, &handle->buffer[handle->offset]);
|
||||
bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
|
||||
callback(user, &pkth, pktd);
|
||||
return 1;
|
||||
}
|
||||
return 0; /* didn't pass filter */
|
||||
@ -128,7 +140,7 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
|
||||
static int
|
||||
bt_monitor_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported yet");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported yet");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -161,8 +173,7 @@ bt_monitor_activate(pcap_t* handle)
|
||||
return PCAP_ERROR_RFMON_NOTSUP;
|
||||
}
|
||||
|
||||
handle->bufsize = handle->snapshot + BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header);
|
||||
handle->offset = BT_CONTROL_SIZE;
|
||||
handle->bufsize = BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header) + handle->snapshot;
|
||||
handle->linktype = DLT_BLUETOOTH_LINUX_MONITOR;
|
||||
|
||||
handle->read_op = bt_monitor_read;
|
||||
@ -176,14 +187,14 @@ bt_monitor_activate(pcap_t* handle)
|
||||
|
||||
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||
if (handle->fd < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't create raw socket: %s", strerror(errno));
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
handle->buffer = malloc(handle->bufsize);
|
||||
if (!handle->buffer) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
|
||||
pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
@ -194,14 +205,14 @@ bt_monitor_activate(pcap_t* handle)
|
||||
addr.hci_channel = HCI_CHANNEL_MONITOR;
|
||||
|
||||
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't attach to interface: %s", strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
opt = 1;
|
||||
if (setsockopt(handle->fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't enable time stamp: %s", strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
@ -231,7 +242,7 @@ bt_monitor_create(const char *device, char *ebuf, int *is_ours)
|
||||
}
|
||||
|
||||
*is_ours = 1;
|
||||
p = pcap_create_common(device, ebuf, 0);
|
||||
p = pcap_create_common(ebuf, 0);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -1,319 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Felix Obenhuber
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* SocketCan sniffing API implementation for Linux platform
|
||||
* By Felix Obenhuber <felix@obenhuber.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
#include "pcap-can-linux.h"
|
||||
|
||||
#ifdef NEED_STRERROR_H
|
||||
#include "strerror.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/raw.h>
|
||||
|
||||
/* not yet defined anywhere */
|
||||
#ifndef PF_CAN
|
||||
#define PF_CAN 29
|
||||
#endif
|
||||
#ifndef AF_CAN
|
||||
#define AF_CAN PF_CAN
|
||||
#endif
|
||||
|
||||
/* forward declaration */
|
||||
static int can_activate(pcap_t *);
|
||||
static int can_read_linux(pcap_t *, int , pcap_handler , u_char *);
|
||||
static int can_inject_linux(pcap_t *, const void *, size_t);
|
||||
static int can_setfilter_linux(pcap_t *, struct bpf_program *);
|
||||
static int can_setdirection_linux(pcap_t *, pcap_direction_t);
|
||||
static int can_stats_linux(pcap_t *, struct pcap_stat *);
|
||||
|
||||
/*
|
||||
* Private data for capturing on Linux CANbus devices.
|
||||
*/
|
||||
struct pcap_can {
|
||||
int ifindex; /* interface index of device we're bound to */
|
||||
};
|
||||
|
||||
int
|
||||
can_findalldevs(pcap_if_t **devlistp, char *errbuf)
|
||||
{
|
||||
/*
|
||||
* There are no platform-specific devices since each device
|
||||
* exists as a regular network interface.
|
||||
*
|
||||
* XXX - true?
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
can_create(const char *device, char *ebuf, int *is_ours)
|
||||
{
|
||||
const char *cp;
|
||||
char *cpend;
|
||||
long devnum;
|
||||
pcap_t* p;
|
||||
|
||||
/* Does this look like a CANbus device? */
|
||||
cp = strrchr(device, '/');
|
||||
if (cp == NULL)
|
||||
cp = device;
|
||||
/* Does it begin with "can" or "vcan"? */
|
||||
if (strncmp(cp, "can", 3) == 0) {
|
||||
/* Begins with "can" */
|
||||
cp += 3; /* skip past "can" */
|
||||
} else if (strncmp(cp, "vcan", 4) == 0) {
|
||||
/* Begins with "vcan" */
|
||||
cp += 4;
|
||||
} else {
|
||||
/* Nope, doesn't begin with "can" or "vcan" */
|
||||
*is_ours = 0;
|
||||
return NULL;
|
||||
}
|
||||
/* Yes - is "can" or "vcan" followed by a number from 0? */
|
||||
devnum = strtol(cp, &cpend, 10);
|
||||
if (cpend == cp || *cpend != '\0') {
|
||||
/* Not followed by a number. */
|
||||
*is_ours = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (devnum < 0) {
|
||||
/* Followed by a non-valid number. */
|
||||
*is_ours = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* OK, it's probably ours. */
|
||||
*is_ours = 1;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_can));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
p->activate_op = can_activate;
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
can_activate(pcap_t* handle)
|
||||
{
|
||||
struct pcap_can *handlep = handle->priv;
|
||||
struct sockaddr_can addr;
|
||||
struct ifreq ifr;
|
||||
|
||||
/* Initialize some components of the pcap structure. */
|
||||
handle->bufsize = 24;
|
||||
handle->offset = 8;
|
||||
handle->linktype = DLT_CAN_SOCKETCAN;
|
||||
handle->read_op = can_read_linux;
|
||||
handle->inject_op = can_inject_linux;
|
||||
handle->setfilter_op = can_setfilter_linux;
|
||||
handle->setdirection_op = can_setdirection_linux;
|
||||
handle->set_datalink_op = NULL;
|
||||
handle->getnonblock_op = pcap_getnonblock_fd;
|
||||
handle->setnonblock_op = pcap_setnonblock_fd;
|
||||
handle->stats_op = can_stats_linux;
|
||||
|
||||
/* Create socket */
|
||||
handle->fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
|
||||
if (handle->fd < 0)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
|
||||
errno, strerror(errno));
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/* get interface index */
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
|
||||
if (ioctl(handle->fd, SIOCGIFINDEX, &ifr) < 0)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Unable to get interface index: %s",
|
||||
pcap_strerror(errno));
|
||||
pcap_cleanup_live_common(handle);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
handlep->ifindex = ifr.ifr_ifindex;
|
||||
|
||||
/* allocate butter */
|
||||
handle->buffer = malloc(handle->bufsize);
|
||||
if (!handle->buffer)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
|
||||
pcap_strerror(errno));
|
||||
pcap_cleanup_live_common(handle);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/* Bind to the socket */
|
||||
addr.can_family = AF_CAN;
|
||||
addr.can_ifindex = handlep->ifindex;
|
||||
if( bind( handle->fd, (struct sockaddr*)&addr, sizeof(addr) ) < 0 )
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
|
||||
handlep->ifindex, errno, strerror(errno));
|
||||
pcap_cleanup_live_common(handle);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
if (handle->opt.rfmon)
|
||||
{
|
||||
/* Monitor mode doesn't apply to CAN devices. */
|
||||
pcap_cleanup_live_common(handle);
|
||||
return PCAP_ERROR_RFMON_NOTSUP;
|
||||
}
|
||||
|
||||
handle->selectable_fd = handle->fd;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
can_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct pcap_pkthdr pkth;
|
||||
struct iovec iv;
|
||||
struct can_frame* cf;
|
||||
|
||||
iv.iov_base = &handle->buffer[handle->offset];
|
||||
iv.iov_len = handle->snapshot;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = &iv;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = handle->buffer;
|
||||
msg.msg_controllen = handle->offset;
|
||||
|
||||
do
|
||||
{
|
||||
pkth.caplen = recvmsg(handle->fd, &msg, 0);
|
||||
if (handle->break_loop)
|
||||
{
|
||||
handle->break_loop = 0;
|
||||
return -2;
|
||||
}
|
||||
} while ((pkth.caplen == -1) && (errno == EINTR));
|
||||
|
||||
if (pkth.caplen == -1)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* adjust capture len according to frame len */
|
||||
cf = (struct can_frame*)&handle->buffer[8];
|
||||
pkth.caplen -= 8 - cf->can_dlc;
|
||||
pkth.len = pkth.caplen;
|
||||
|
||||
cf->can_id = htonl( cf->can_id );
|
||||
|
||||
if( -1 == gettimeofday(&pkth.ts, NULL) )
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get time of day %d:%s",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
callback(user, &pkth, &handle->buffer[8]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
can_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
||||
{
|
||||
/* not yet implemented */
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
|
||||
"can devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
can_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
{
|
||||
/* not yet implemented */
|
||||
stats->ps_recv = 0; /* number of packets received */
|
||||
stats->ps_drop = 0; /* number of packets dropped */
|
||||
stats->ps_ifdrop = 0; /* drops by interface -- only supported on some platforms */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
can_setfilter_linux(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
/* not yet implemented */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
can_setdirection_linux(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
/* no support for PCAP_D_OUT */
|
||||
if (d == PCAP_D_OUT)
|
||||
{
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"Setting direction to PCAP_D_OUT is not supported on can");
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->direction = d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* eof */
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Felix Obenhuber
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Prototypes for SocketCAN related functions
|
||||
*/
|
||||
pcap_t* can_create(const char *device, char *ebuf, int *is_ours);
|
||||
int can_findalldevs(pcap_if_t **devlistp, char *errbuf);
|
@ -1,472 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Felix Obenhuber
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* Sockettrace sniffing API implementation for Linux platform
|
||||
* By Felix Obenhuber <felix@obenhuber.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
#include "pcap-canusb-linux.h"
|
||||
|
||||
#define CANUSB_IFACE "canusb"
|
||||
|
||||
#define CANUSB_VID 0x0403
|
||||
#define CANUSB_PID 0x8990
|
||||
|
||||
#define USE_THREAD 1
|
||||
|
||||
#if USE_THREAD == 0
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* forward declaration */
|
||||
static int canusb_activate(pcap_t *);
|
||||
static int canusb_read_linux(pcap_t *, int , pcap_handler , u_char *);
|
||||
static int canusb_inject_linux(pcap_t *, const void *, size_t);
|
||||
static int canusb_setfilter_linux(pcap_t *, struct bpf_program *);
|
||||
static int canusb_setdirection_linux(pcap_t *, pcap_direction_t);
|
||||
static int canusb_stats_linux(pcap_t *, struct pcap_stat *);
|
||||
|
||||
struct CAN_Msg
|
||||
{
|
||||
uint32_t timestamp;
|
||||
uint32_t id;
|
||||
uint32_t length;
|
||||
uint8_t data[8];
|
||||
};
|
||||
|
||||
/*
|
||||
* Private data for capturing on Linux CANbus USB devices.
|
||||
*/
|
||||
struct pcap_canusb {
|
||||
libusb_context *ctx;
|
||||
libusb_device_handle *dev;
|
||||
pthread_t worker;
|
||||
int rdpipe, wrpipe;
|
||||
volatile int loop;
|
||||
};
|
||||
|
||||
int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||
{
|
||||
libusb_context *fdctx;
|
||||
libusb_device** devs;
|
||||
unsigned char sernum[65];
|
||||
int cnt, i;
|
||||
|
||||
if (libusb_init(&fdctx) != 0) {
|
||||
/*
|
||||
* XXX - if this doesn't just mean "no USB file system mounted",
|
||||
* perhaps we should report a real error rather than just
|
||||
* saying "no CANUSB devices".
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnt = libusb_get_device_list(fdctx,&devs);
|
||||
|
||||
for(i=0;i<cnt;i++)
|
||||
{
|
||||
int ret;
|
||||
// Check if this device is interesting.
|
||||
struct libusb_device_descriptor desc;
|
||||
libusb_get_device_descriptor(devs[i],&desc);
|
||||
|
||||
if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
|
||||
continue; //It is not, check next device
|
||||
|
||||
//It is!
|
||||
libusb_device_handle *dh = NULL;
|
||||
|
||||
if ((ret = libusb_open(devs[i],&dh)) == 0)
|
||||
{
|
||||
char dev_name[30];
|
||||
char dev_descr[50];
|
||||
int n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,sernum,64);
|
||||
sernum[n] = 0;
|
||||
|
||||
snprintf(dev_name, 30, CANUSB_IFACE"%s", sernum);
|
||||
snprintf(dev_descr, 50, "CanUSB [%s]", sernum);
|
||||
|
||||
libusb_close(dh);
|
||||
|
||||
if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0)
|
||||
{
|
||||
libusb_free_device_list(devs,1);
|
||||
libusb_exit(fdctx);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_device_list(devs,1);
|
||||
libusb_exit(fdctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static libusb_device_handle* canusb_opendevice(struct libusb_context *ctx, char* devserial)
|
||||
{
|
||||
libusb_device** devs;
|
||||
unsigned char serial[65];
|
||||
int cnt,i,n;
|
||||
|
||||
cnt = libusb_get_device_list(ctx,&devs);
|
||||
|
||||
for(i=0;i<cnt;i++)
|
||||
{
|
||||
// Check if this device is interesting.
|
||||
struct libusb_device_descriptor desc;
|
||||
libusb_get_device_descriptor(devs[i],&desc);
|
||||
|
||||
if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
|
||||
continue;
|
||||
|
||||
//Found one!
|
||||
libusb_device_handle *dh = NULL;
|
||||
|
||||
if (libusb_open(devs[i],&dh) != 0) continue;
|
||||
|
||||
n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,serial,64);
|
||||
serial[n] = 0;
|
||||
|
||||
if ((devserial) && (strcmp((char *)serial,devserial) != 0))
|
||||
{
|
||||
libusb_close(dh);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((libusb_kernel_driver_active(dh,0)) && (libusb_detach_kernel_driver(dh,0) != 0))
|
||||
{
|
||||
libusb_close(dh);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (libusb_set_configuration(dh,1) != 0)
|
||||
{
|
||||
libusb_close(dh);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (libusb_claim_interface(dh,0) != 0)
|
||||
{
|
||||
libusb_close(dh);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Fount it!
|
||||
libusb_free_device_list(devs,1);
|
||||
return dh;
|
||||
}
|
||||
|
||||
libusb_free_device_list(devs,1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
pcap_t *
|
||||
canusb_create(const char *device, char *ebuf, int *is_ours)
|
||||
{
|
||||
const char *cp;
|
||||
char *cpend;
|
||||
long devnum;
|
||||
pcap_t* p;
|
||||
struct pcap_canusb *canusb;
|
||||
|
||||
/* Does this look like a DAG device? */
|
||||
cp = strrchr(device, '/');
|
||||
if (cp == NULL)
|
||||
cp = device;
|
||||
/* Does it begin with "canusb"? */
|
||||
if (strncmp(cp, "canusb", 6) != 0) {
|
||||
/* Nope, doesn't begin with "canusb" */
|
||||
*is_ours = 0;
|
||||
return NULL;
|
||||
}
|
||||
/* Yes - is "canusb" followed by a number? */
|
||||
cp += 6;
|
||||
devnum = strtol(cp, &cpend, 10);
|
||||
if (cpend == cp || *cpend != '\0') {
|
||||
/* Not followed by a number. */
|
||||
*is_ours = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (devnum < 0) {
|
||||
/* Followed by a non-valid number. */
|
||||
*is_ours = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* OK, it's probably ours. */
|
||||
*is_ours = 1;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_canusb));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
canusb = p->priv;
|
||||
canusb->ctx = NULL;
|
||||
canusb->dev = NULL;
|
||||
canusb->rdpipe = -1;
|
||||
canusb->wrpipe = -1;
|
||||
|
||||
p->activate_op = canusb_activate;
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
static void* canusb_capture_thread(void *arg)
|
||||
{
|
||||
struct pcap_canusb *canusb = arg;
|
||||
int i;
|
||||
struct
|
||||
{
|
||||
uint8_t rxsz, txsz;
|
||||
} status;
|
||||
|
||||
fcntl(canusb->wrpipe, F_SETFL, O_NONBLOCK);
|
||||
|
||||
while(canusb->loop)
|
||||
{
|
||||
int sz;
|
||||
struct CAN_Msg msg;
|
||||
|
||||
libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
|
||||
//HACK!!!!! -> drop buffered data, read new one by reading twice.
|
||||
libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
|
||||
|
||||
for(i = 0; i<status.rxsz; i++)
|
||||
{
|
||||
libusb_bulk_transfer(canusb->dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);
|
||||
write(canusb->wrpipe, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int canusb_startcapture(struct pcap_canusb* this)
|
||||
{
|
||||
int pipefd[2];
|
||||
|
||||
if (pipe(pipefd) == -1)
|
||||
return -1;
|
||||
|
||||
this->rdpipe = pipefd[0];
|
||||
this->wrpipe = pipefd[1];
|
||||
|
||||
this->loop = 1;
|
||||
pthread_create(&this->worker, NULL, canusb_capture_thread, this);
|
||||
|
||||
return this->rdpipe;
|
||||
}
|
||||
|
||||
static void canusb_clearbufs(struct pcap_canusb* this)
|
||||
{
|
||||
unsigned char cmd[16];
|
||||
int al;
|
||||
|
||||
cmd[0] = 1; //Empty incoming buffer
|
||||
cmd[1] = 1; //Empty outgoing buffer
|
||||
cmd[3] = 0; //Not a write to serial number
|
||||
memset(&cmd[4],0,16-4);
|
||||
|
||||
libusb_interrupt_transfer(this->dev, 0x1,cmd,16,&al,100);
|
||||
}
|
||||
|
||||
|
||||
static void canusb_close(pcap_t* handle)
|
||||
{
|
||||
struct pcap_canusb *canusb = handle->priv;
|
||||
|
||||
canusb->loop = 0;
|
||||
pthread_join(canusb->worker, NULL);
|
||||
|
||||
if (canusb->dev)
|
||||
{
|
||||
libusb_close(canusb->dev);
|
||||
canusb->dev = NULL;
|
||||
}
|
||||
if (canusb->ctx)
|
||||
{
|
||||
libusb_exit(canusb->ctx);
|
||||
canusb->ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int canusb_activate(pcap_t* handle)
|
||||
{
|
||||
struct pcap_canusb *canusb = handle->priv;
|
||||
char *serial;
|
||||
|
||||
if (libusb_init(&canusb->ctx) != 0) {
|
||||
/*
|
||||
* XXX - what causes this to fail?
|
||||
*/
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "libusb_init() failed");
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
handle->read_op = canusb_read_linux;
|
||||
|
||||
handle->inject_op = canusb_inject_linux;
|
||||
handle->setfilter_op = canusb_setfilter_linux;
|
||||
handle->setdirection_op = canusb_setdirection_linux;
|
||||
handle->getnonblock_op = pcap_getnonblock_fd;
|
||||
handle->setnonblock_op = pcap_setnonblock_fd;
|
||||
handle->stats_op = canusb_stats_linux;
|
||||
handle->cleanup_op = canusb_close;
|
||||
|
||||
/* Initialize some components of the pcap structure. */
|
||||
handle->bufsize = 32;
|
||||
handle->offset = 8;
|
||||
handle->linktype = DLT_CAN_SOCKETCAN;
|
||||
handle->set_datalink_op = NULL;
|
||||
|
||||
serial = handle->opt.source + strlen(CANUSB_IFACE);
|
||||
|
||||
canusb->dev = canusb_opendevice(canusb->ctx, serial);
|
||||
if (!canusb->dev)
|
||||
{
|
||||
libusb_exit(canusb->ctx);
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't open USB Device");
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
canusb_clearbufs(canusb);
|
||||
|
||||
handle->fd = canusb_startcapture(canusb);
|
||||
handle->selectable_fd = handle->fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
canusb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
|
||||
{
|
||||
static struct timeval firstpacket = { -1, -1};
|
||||
int i = 0;
|
||||
struct CAN_Msg msg;
|
||||
struct pcap_pkthdr pkth;
|
||||
|
||||
while(i < max_packets)
|
||||
{
|
||||
int n;
|
||||
usleep(10 * 1000);
|
||||
n = read(handle->fd, &msg, sizeof(msg));
|
||||
if (n <= 0)
|
||||
break;
|
||||
pkth.caplen = pkth.len = n;
|
||||
pkth.caplen -= 4;
|
||||
pkth.caplen -= 8 - msg.length;
|
||||
|
||||
if ((firstpacket.tv_sec == -1) && (firstpacket.tv_usec == -1))
|
||||
gettimeofday(&firstpacket, NULL);
|
||||
|
||||
pkth.ts.tv_usec = firstpacket.tv_usec + (msg.timestamp % 100) * 10000;
|
||||
pkth.ts.tv_sec = firstpacket.tv_usec + (msg.timestamp / 100);
|
||||
if (pkth.ts.tv_usec > 1000000)
|
||||
{
|
||||
pkth.ts.tv_usec -= 1000000;
|
||||
pkth.ts.tv_sec++;
|
||||
}
|
||||
|
||||
callback(user, &pkth, (void*)&msg.id);
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
canusb_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
||||
{
|
||||
/* not yet implemented */
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on canusb devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
canusb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
{
|
||||
/* not yet implemented */
|
||||
stats->ps_recv = 0; /* number of packets received */
|
||||
stats->ps_drop = 0; /* number of packets dropped */
|
||||
stats->ps_ifdrop = 0; /* drops by interface -- only supported on some platforms */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
canusb_setfilter_linux(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
/* not yet implemented */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
canusb_setdirection_linux(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
/* no support for PCAP_D_OUT */
|
||||
if (d == PCAP_D_OUT)
|
||||
{
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"Setting direction to PCAP_D_OUT is not supported on this interface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->direction = d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* eof */
|
@ -25,9 +25,9 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#else /* _WIN32 */
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif HAVE_STDINT_H
|
||||
@ -37,11 +37,14 @@
|
||||
#include <sys/bitypes.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "pcap-int.h"
|
||||
#include "extract.h"
|
||||
#include "pcap/sll.h"
|
||||
#include "pcap/usb.h"
|
||||
#include "pcap/nflog.h"
|
||||
#include "pcap/can_socketcan.h"
|
||||
|
||||
#include "pcap-common.h"
|
||||
|
||||
@ -351,7 +354,7 @@
|
||||
|
||||
#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */
|
||||
#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
|
||||
#define LINKTYPE_GPF_F 171 /* GPF-T (ITU-T G.7041/Y.1303) */
|
||||
#define LINKTYPE_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */
|
||||
|
||||
/*
|
||||
* Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
|
||||
@ -386,7 +389,7 @@
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* The Link Types are used for prepending meta-information
|
||||
* like interface index, interface name
|
||||
* before standard Ethernet, PPP, Frelay & C-HDLC Frames
|
||||
@ -403,7 +406,7 @@
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* The DLT_ is used for internal communication with a
|
||||
* voice Adapter Card (PIC)
|
||||
*/
|
||||
@ -426,10 +429,17 @@
|
||||
#define LINKTYPE_A653_ICM 185
|
||||
|
||||
/*
|
||||
* USB packets, beginning with a USB setup header; requested by
|
||||
* Paolo Abeni <paolo.abeni@email.it>.
|
||||
* This used to be "USB packets, beginning with a USB setup header;
|
||||
* requested by Paolo Abeni <paolo.abeni@email.it>."
|
||||
*
|
||||
* However, that header didn't work all that well - it left out some
|
||||
* useful information - and was abandoned in favor of the DLT_USB_LINUX
|
||||
* header.
|
||||
*
|
||||
* This is now used by FreeBSD for its BPF taps for USB; that has its
|
||||
* own headers. So it is written, so it is done.
|
||||
*/
|
||||
#define LINKTYPE_USB 186
|
||||
#define LINKTYPE_USB_FREEBSD 186
|
||||
|
||||
/*
|
||||
* Bluetooth HCI UART transport layer (part H:4); requested by
|
||||
@ -478,7 +488,7 @@
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* The DLT_ is used for internal communication with a
|
||||
* integrated service module (ISM).
|
||||
*/
|
||||
@ -519,7 +529,7 @@
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* The DLT_ is used for capturing data on a secure tunnel interface.
|
||||
*/
|
||||
#define LINKTYPE_JUNIPER_ST 200
|
||||
@ -611,11 +621,11 @@
|
||||
*/
|
||||
#define LINKTYPE_IEEE802_15_4_NONASK_PHY 215
|
||||
|
||||
/*
|
||||
/*
|
||||
* David Gibson <david@gibson.dropbear.id.au> requested this for
|
||||
* captures from the Linux kernel /dev/input/eventN devices. This
|
||||
* is used to communicate keystrokes and mouse movements from the
|
||||
* Linux kernel to display systems, such as Xorg.
|
||||
* Linux kernel to display systems, such as Xorg.
|
||||
*/
|
||||
#define LINKTYPE_LINUX_EVDEV 216
|
||||
|
||||
@ -736,8 +746,10 @@
|
||||
|
||||
/*
|
||||
* CAN (Controller Area Network) frames, with a pseudo-header as supplied
|
||||
* by Linux SocketCAN. See Documentation/networking/can.txt in the Linux
|
||||
* source.
|
||||
* by Linux SocketCAN, and with multi-byte numerical fields in that header
|
||||
* in big-endian byte order.
|
||||
*
|
||||
* See Documentation/networking/can.txt in the Linux source.
|
||||
*
|
||||
* Requested by Felix Obenhuber <felix@obenhuber.de>.
|
||||
*/
|
||||
@ -777,7 +789,7 @@
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
*/
|
||||
#define LINKTYPE_JUNIPER_VS 232
|
||||
#define LINKTYPE_JUNIPER_SRX_E2E 233
|
||||
@ -809,12 +821,12 @@
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
* Hannes Gredler <hannes@juniper.net>.
|
||||
*/
|
||||
#define LINKTYPE_JUNIPER_ATM_CEMIC 238
|
||||
|
||||
/*
|
||||
* NetFilter LOG messages
|
||||
* NetFilter LOG messages
|
||||
* (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets)
|
||||
*
|
||||
* Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl>
|
||||
@ -922,7 +934,7 @@
|
||||
|
||||
/*
|
||||
* Link-layer header type for upper-protocol layer PDU saves from wireshark.
|
||||
*
|
||||
*
|
||||
* the actual contents are determined by two TAGs stored with each
|
||||
* packet:
|
||||
* EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the
|
||||
@ -959,7 +971,6 @@
|
||||
*/
|
||||
#define LINKTYPE_PROFIBUS_DL 257
|
||||
|
||||
|
||||
/*
|
||||
* Apple's DLT_PKTAP headers.
|
||||
*
|
||||
@ -994,7 +1005,30 @@
|
||||
*/
|
||||
#define LINKTYPE_IPMI_HPM_2 260
|
||||
|
||||
#define LINKTYPE_MATCHING_MAX 260 /* highest value in the "matching" range */
|
||||
/*
|
||||
* per Joshua Wright <jwright@hasborg.com>, formats for Zwave captures.
|
||||
*/
|
||||
#define LINKTYPE_ZWAVE_R1_R2 261
|
||||
#define LINKTYPE_ZWAVE_R3 262
|
||||
|
||||
/*
|
||||
* per Steve Karg <skarg@users.sourceforge.net>, formats for Wattstopper
|
||||
* Digital Lighting Management room bus serial protocol captures.
|
||||
*/
|
||||
#define LINKTYPE_WATTSTOPPER_DLM 263
|
||||
|
||||
/*
|
||||
* ISO 14443 contactless smart card messages.
|
||||
*/
|
||||
#define LINKTYPE_ISO_14443 264
|
||||
|
||||
/*
|
||||
* Radio data system (RDS) groups. IEC 62106.
|
||||
* Per Jonathan Brucker <jonathan.brucke@gmail.com>.
|
||||
*/
|
||||
#define LINKTYPE_RDS 265
|
||||
|
||||
#define LINKTYPE_MATCHING_MAX 265 /* highest value in the "matching" range */
|
||||
|
||||
static struct linktype_map {
|
||||
int dlt;
|
||||
@ -1141,6 +1175,48 @@ linktype_to_dlt(int linktype)
|
||||
return linktype;
|
||||
}
|
||||
|
||||
#define EXTRACT_
|
||||
|
||||
/*
|
||||
* DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
|
||||
* LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
|
||||
* with the CAN ID being in host byte order.
|
||||
*
|
||||
* When reading a DLT_LINUX_SLL capture file, we need to check for those
|
||||
* packets and convert the CAN ID from the byte order of the host that
|
||||
* wrote the file to this host's byte order.
|
||||
*/
|
||||
static void
|
||||
swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
|
||||
{
|
||||
u_int caplen = hdr->caplen;
|
||||
u_int length = hdr->len;
|
||||
struct sll_header *shdr = (struct sll_header *)buf;
|
||||
u_int16_t protocol;
|
||||
pcap_can_socketcan_hdr *chdr;
|
||||
|
||||
if (caplen < (u_int) sizeof(struct sll_header) ||
|
||||
length < (u_int) sizeof(struct sll_header)) {
|
||||
/* Not enough data to have the protocol field */
|
||||
return;
|
||||
}
|
||||
|
||||
protocol = EXTRACT_16BITS(&shdr->sll_protocol);
|
||||
if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
|
||||
return;
|
||||
|
||||
/*
|
||||
* SocketCAN packet; fix up the packet's header.
|
||||
*/
|
||||
chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll_header));
|
||||
if (caplen < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id) ||
|
||||
length < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id)) {
|
||||
/* Not enough data to have the CAN ID */
|
||||
return;
|
||||
}
|
||||
chdr->can_id = SWAPLONG(chdr->can_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
|
||||
* byte order when capturing (it's supplied directly from a
|
||||
@ -1156,8 +1232,6 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
|
||||
{
|
||||
pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
|
||||
bpf_u_int32 offset = 0;
|
||||
usb_isodesc *pisodesc;
|
||||
int32_t numdesc, i;
|
||||
|
||||
/*
|
||||
* "offset" is the offset *past* the field we're swapping;
|
||||
@ -1166,7 +1240,7 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
|
||||
*/
|
||||
|
||||
/*
|
||||
* The URB id is a totally opaque value; do we really need to
|
||||
* The URB id is a totally opaque value; do we really need to
|
||||
* convert it to the reading host's byte order???
|
||||
*/
|
||||
offset += 8; /* skip past id */
|
||||
@ -1221,6 +1295,17 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
|
||||
} else
|
||||
offset += 8; /* skip USB setup header */
|
||||
|
||||
/*
|
||||
* With the old header, there are no isochronous descriptors
|
||||
* after the header.
|
||||
*
|
||||
* With the new header, the actual number of descriptors in
|
||||
* the header is not s.iso.numdesc, it's ndesc - only the
|
||||
* first N descriptors, for some value of N, are put into
|
||||
* the header, and ndesc is set to the actual number copied.
|
||||
* In addition, if s.iso.numdesc is negative, no descriptors
|
||||
* are captured, and ndesc is set to 0.
|
||||
*/
|
||||
if (header_len_64_bytes) {
|
||||
/*
|
||||
* This is either the "version 1" header, with
|
||||
@ -1249,31 +1334,33 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
|
||||
if (hdr->caplen < offset)
|
||||
return;
|
||||
uhdr->ndesc = SWAPLONG(uhdr->ndesc);
|
||||
}
|
||||
|
||||
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
|
||||
/* swap the values in struct linux_usb_isodesc */
|
||||
pisodesc = (usb_isodesc *)(void *)(buf+offset);
|
||||
numdesc = uhdr->s.iso.numdesc;
|
||||
for (i = 0; i < numdesc; i++) {
|
||||
offset += 4; /* skip past status */
|
||||
if (hdr->caplen < offset)
|
||||
return;
|
||||
pisodesc->status = SWAPLONG(pisodesc->status);
|
||||
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
|
||||
/* swap the values in struct linux_usb_isodesc */
|
||||
usb_isodesc *pisodesc;
|
||||
u_int32_t i;
|
||||
|
||||
offset += 4; /* skip past offset */
|
||||
if (hdr->caplen < offset)
|
||||
return;
|
||||
pisodesc->offset = SWAPLONG(pisodesc->offset);
|
||||
pisodesc = (usb_isodesc *)(void *)(buf+offset);
|
||||
for (i = 0; i < uhdr->ndesc; i++) {
|
||||
offset += 4; /* skip past status */
|
||||
if (hdr->caplen < offset)
|
||||
return;
|
||||
pisodesc->status = SWAPLONG(pisodesc->status);
|
||||
|
||||
offset += 4; /* skip past len */
|
||||
if (hdr->caplen < offset)
|
||||
return;
|
||||
pisodesc->len = SWAPLONG(pisodesc->len);
|
||||
offset += 4; /* skip past offset */
|
||||
if (hdr->caplen < offset)
|
||||
return;
|
||||
pisodesc->offset = SWAPLONG(pisodesc->offset);
|
||||
|
||||
offset += 4; /* skip past padding */
|
||||
offset += 4; /* skip past len */
|
||||
if (hdr->caplen < offset)
|
||||
return;
|
||||
pisodesc->len = SWAPLONG(pisodesc->len);
|
||||
|
||||
pisodesc++;
|
||||
offset += 4; /* skip past padding */
|
||||
|
||||
pisodesc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1299,12 +1386,13 @@ swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
|
||||
u_int length = hdr->len;
|
||||
u_int16_t size;
|
||||
|
||||
if (caplen < (int) sizeof(nflog_hdr_t) || length < (int) sizeof(nflog_hdr_t)) {
|
||||
if (caplen < (u_int) sizeof(nflog_hdr_t) ||
|
||||
length < (u_int) sizeof(nflog_hdr_t)) {
|
||||
/* Not enough data to have any TLVs. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(nfhdr->nflog_version) == 0) {
|
||||
if (nfhdr->nflog_version != 0) {
|
||||
/* Unknown NFLOG version */
|
||||
return;
|
||||
}
|
||||
@ -1354,6 +1442,10 @@ swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
|
||||
*/
|
||||
switch (linktype) {
|
||||
|
||||
case DLT_LINUX_SLL:
|
||||
swap_linux_sll_header(hdr, data);
|
||||
break;
|
||||
|
||||
case DLT_USB_LINUX:
|
||||
swap_linux_usb_header(hdr, data, 0);
|
||||
break;
|
||||
|
@ -18,7 +18,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP-CONFIG 1 "22 May 2009"
|
||||
.TH PCAP-CONFIG 1 "15 February 2015"
|
||||
.SH NAME
|
||||
pcap-config \- write libpcap compiler and linker flags to standard output
|
||||
.SH SYNOPSIS
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* pcap-dag.c: Packet capture interface for Endace DAG card.
|
||||
* pcap-dag.c: Packet capture interface for Emulex EndaceDAG cards.
|
||||
*
|
||||
* The functionality of this code attempts to mimic that of pcap-linux as much
|
||||
* as possible. This code is compiled in several different ways depending on
|
||||
@ -10,9 +10,9 @@
|
||||
* called as required from their pcap-linux/bpf equivalents.
|
||||
*
|
||||
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
|
||||
* Modifications: Jesper Peterson <support@endace.com>
|
||||
* Koryn Grant <support@endace.com>
|
||||
* Stephen Donnelly <support@endace.com>
|
||||
* Modifications: Jesper Peterson
|
||||
* Koryn Grant
|
||||
* Stephen Donnelly <stephen.donnelly@emulex.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -40,6 +40,7 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
|
||||
#include "dagnew.h"
|
||||
#include "dagapi.h"
|
||||
#include "dagpci.h"
|
||||
|
||||
#include "pcap-dag.h"
|
||||
|
||||
@ -52,6 +53,99 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
#define DAG_MAX_BOARDS 32
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef TYPE_AAL5
|
||||
#define TYPE_AAL5 4
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_HDLC
|
||||
#define TYPE_MC_HDLC 5
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_RAW
|
||||
#define TYPE_MC_RAW 6
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_ATM
|
||||
#define TYPE_MC_ATM 7
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_RAW_CHANNEL
|
||||
#define TYPE_MC_RAW_CHANNEL 8
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_AAL5
|
||||
#define TYPE_MC_AAL5 9
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_HDLC_POS
|
||||
#define TYPE_COLOR_HDLC_POS 10
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_ETH
|
||||
#define TYPE_COLOR_ETH 11
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_AAL2
|
||||
#define TYPE_MC_AAL2 12
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_IP_COUNTER
|
||||
#define TYPE_IP_COUNTER 13
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_TCP_FLOW_COUNTER
|
||||
#define TYPE_TCP_FLOW_COUNTER 14
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_DSM_COLOR_HDLC_POS
|
||||
#define TYPE_DSM_COLOR_HDLC_POS 15
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_DSM_COLOR_ETH
|
||||
#define TYPE_DSM_COLOR_ETH 16
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_MC_HDLC_POS
|
||||
#define TYPE_COLOR_MC_HDLC_POS 17
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_AAL2
|
||||
#define TYPE_AAL2 18
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_HASH_POS
|
||||
#define TYPE_COLOR_HASH_POS 19
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_HASH_ETH
|
||||
#define TYPE_COLOR_HASH_ETH 20
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_INFINIBAND
|
||||
#define TYPE_INFINIBAND 21
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_IPV4
|
||||
#define TYPE_IPV4 22
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_IPV6
|
||||
#define TYPE_IPV6 23
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_RAW_LINK
|
||||
#define TYPE_RAW_LINK 24
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_INFINIBAND_LINK
|
||||
#define TYPE_INFINIBAND_LINK 25
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_PAD
|
||||
#define TYPE_PAD 48
|
||||
#endif
|
||||
|
||||
#define ATM_CELL_SIZE 52
|
||||
#define ATM_HDR_SIZE 4
|
||||
|
||||
@ -143,28 +237,25 @@ delete_pcap_dag(pcap_t *p)
|
||||
static void
|
||||
dag_platform_cleanup(pcap_t *p)
|
||||
{
|
||||
struct pcap_dag *pd;
|
||||
struct pcap_dag *pd = p->pr;
|
||||
|
||||
if (p != NULL) {
|
||||
pd = p->priv;
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
|
||||
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
||||
|
||||
if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
|
||||
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
||||
if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
|
||||
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
||||
|
||||
if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
|
||||
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
||||
#else
|
||||
if(dag_stop(p->fd) < 0)
|
||||
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
||||
if(dag_stop(p->fd) < 0)
|
||||
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
if(p->fd != -1) {
|
||||
if(dag_close(p->fd) < 0)
|
||||
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
||||
p->fd = -1;
|
||||
}
|
||||
delete_pcap_dag(p);
|
||||
pcap_cleanup_live_common(p);
|
||||
if(p->fd != -1) {
|
||||
if(dag_close(p->fd) < 0)
|
||||
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
||||
p->fd = -1;
|
||||
}
|
||||
delete_pcap_dag(p);
|
||||
pcap_cleanup_live_common(p);
|
||||
/* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */
|
||||
}
|
||||
|
||||
@ -173,7 +264,8 @@ atexit_handler(void)
|
||||
{
|
||||
while (pcap_dags != NULL) {
|
||||
if (pcap_dags->pid == getpid()) {
|
||||
dag_platform_cleanup(pcap_dags->p);
|
||||
if (pcap_dags->p != NULL)
|
||||
dag_platform_cleanup(pcap_dags->p);
|
||||
} else {
|
||||
delete_pcap_dag(pcap_dags->p);
|
||||
}
|
||||
@ -221,7 +313,7 @@ dag_erf_ext_header_count(uint8_t * erf, size_t len)
|
||||
|
||||
/* loop over the extension headers */
|
||||
do {
|
||||
|
||||
|
||||
/* sanity check we have enough bytes */
|
||||
if ( len < (24 + (hdr_num * 8)) )
|
||||
return hdr_num;
|
||||
@ -248,10 +340,11 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
int flags = pd->dag_offset_flags;
|
||||
unsigned int nonblocking = flags & DAGF_NONBLOCK;
|
||||
unsigned int num_ext_hdr = 0;
|
||||
unsigned int ticks_per_second;
|
||||
|
||||
/* Get the next bufferful of packets (if necessary). */
|
||||
while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
|
||||
|
||||
|
||||
/*
|
||||
* Has "pcap_breakloop()" been called?
|
||||
*/
|
||||
@ -290,7 +383,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
/* Pcap is configured to process only available packets, and there aren't any, return immediately. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(!nonblocking &&
|
||||
pd->dag_timeout &&
|
||||
(pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
|
||||
@ -300,14 +393,14 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Process the packets. */
|
||||
while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
|
||||
|
||||
|
||||
unsigned short packet_len = 0;
|
||||
int caplen = 0;
|
||||
struct pcap_pkthdr pcap_header;
|
||||
|
||||
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
|
||||
#else
|
||||
@ -316,7 +409,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
|
||||
u_char *dp = ((u_char *)header); /* + dag_record_size; */
|
||||
unsigned short rlen;
|
||||
|
||||
|
||||
/*
|
||||
* Has "pcap_breakloop()" been called?
|
||||
*/
|
||||
@ -329,7 +422,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
p->break_loop = 0;
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
rlen = ntohs(header->rlen);
|
||||
if (rlen < dag_record_size)
|
||||
{
|
||||
@ -359,7 +452,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((header->type & 0x7f) == TYPE_PAD) {
|
||||
continue;
|
||||
}
|
||||
@ -367,13 +460,13 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
|
||||
|
||||
/* ERF encapsulation */
|
||||
/* The Extensible Record Format is not dropped for this kind of encapsulation,
|
||||
/* The Extensible Record Format is not dropped for this kind of encapsulation,
|
||||
* and will be handled as a pseudo header by the decoding application.
|
||||
* The information carried in the ERF header and in the optional subheader (if present)
|
||||
* could be merged with the libpcap information, to offer a better decoding.
|
||||
* The packet length is
|
||||
* o the length of the packet on the link (header->wlen),
|
||||
* o plus the length of the ERF header (dag_record_size), as the length of the
|
||||
* o plus the length of the ERF header (dag_record_size), as the length of the
|
||||
* pseudo header will be adjusted during the decoding,
|
||||
* o plus the length of the optional subheader (if present).
|
||||
*
|
||||
@ -415,7 +508,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
dp += dag_record_size;
|
||||
/* Skip over extension headers */
|
||||
dp += 8 * num_ext_hdr;
|
||||
|
||||
|
||||
switch((header->type & 0x7f)) {
|
||||
case TYPE_ATM:
|
||||
case TYPE_AAL5:
|
||||
@ -434,19 +527,22 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
caplen = rlen - dag_record_size - 4;
|
||||
dp+=4;
|
||||
}
|
||||
/* Skip over extension headers */
|
||||
caplen -= (8 * num_ext_hdr);
|
||||
|
||||
if (header->type == TYPE_ATM) {
|
||||
caplen = packet_len = ATM_CELL_SIZE;
|
||||
}
|
||||
if (p->linktype == DLT_SUNATM) {
|
||||
struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
|
||||
unsigned long rawatm;
|
||||
|
||||
|
||||
rawatm = ntohl(*((unsigned long *)dp));
|
||||
sunatm->vci = htons((rawatm >> 4) & 0xffff);
|
||||
sunatm->vpi = (rawatm >> 20) & 0x00ff;
|
||||
sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
|
||||
sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
|
||||
((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
|
||||
((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
|
||||
((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
|
||||
((dp[ATM_HDR_SIZE] == 0xaa &&
|
||||
dp[ATM_HDR_SIZE+1] == 0xaa &&
|
||||
dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
|
||||
@ -465,6 +561,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
packet_len = ntohs(header->wlen);
|
||||
packet_len -= (pd->dag_fcs_bits >> 3);
|
||||
caplen = rlen - dag_record_size - 2;
|
||||
/* Skip over extension headers */
|
||||
caplen -= (8 * num_ext_hdr);
|
||||
if (caplen > packet_len) {
|
||||
caplen = packet_len;
|
||||
}
|
||||
@ -478,6 +576,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
packet_len = ntohs(header->wlen);
|
||||
packet_len -= (pd->dag_fcs_bits >> 3);
|
||||
caplen = rlen - dag_record_size;
|
||||
/* Skip over extension headers */
|
||||
caplen -= (8 * num_ext_hdr);
|
||||
if (caplen > packet_len) {
|
||||
caplen = packet_len;
|
||||
}
|
||||
@ -488,6 +588,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
packet_len = ntohs(header->wlen);
|
||||
packet_len -= (pd->dag_fcs_bits >> 3);
|
||||
caplen = rlen - dag_record_size - 4;
|
||||
/* Skip over extension headers */
|
||||
caplen -= (8 * num_ext_hdr);
|
||||
if (caplen > packet_len) {
|
||||
caplen = packet_len;
|
||||
}
|
||||
@ -498,7 +600,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
/* Add the MTP2 Pseudo Header */
|
||||
caplen += MTP2_HDR_LEN;
|
||||
packet_len += MTP2_HDR_LEN;
|
||||
|
||||
|
||||
TempPkt[MTP2_SENT_OFFSET] = 0;
|
||||
TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
|
||||
*(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
|
||||
@ -513,6 +615,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
case TYPE_IPV6:
|
||||
packet_len = ntohs(header->wlen);
|
||||
caplen = rlen - dag_record_size;
|
||||
/* Skip over extension headers */
|
||||
caplen -= (8 * num_ext_hdr);
|
||||
if (caplen > packet_len) {
|
||||
caplen = packet_len;
|
||||
}
|
||||
@ -533,45 +637,52 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
continue;
|
||||
} /* switch type */
|
||||
|
||||
/* Skip over extension headers */
|
||||
caplen -= (8 * num_ext_hdr);
|
||||
|
||||
} /* ERF encapsulation */
|
||||
|
||||
|
||||
if (caplen > p->snapshot)
|
||||
caplen = p->snapshot;
|
||||
|
||||
/* Run the packet filter if there is one. */
|
||||
if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
|
||||
|
||||
|
||||
/* convert between timestamp formats */
|
||||
register unsigned long long ts;
|
||||
|
||||
|
||||
if (IS_BIGENDIAN()) {
|
||||
ts = SWAPLL(header->ts);
|
||||
} else {
|
||||
ts = header->ts;
|
||||
}
|
||||
|
||||
switch (p->opt.tstamp_precision) {
|
||||
case PCAP_TSTAMP_PRECISION_NANO:
|
||||
ticks_per_second = 1000000000;
|
||||
break;
|
||||
case PCAP_TSTAMP_PRECISION_MICRO:
|
||||
default:
|
||||
ticks_per_second = 1000000;
|
||||
break;
|
||||
|
||||
}
|
||||
pcap_header.ts.tv_sec = ts >> 32;
|
||||
ts = (ts & 0xffffffffULL) * 1000000;
|
||||
ts = (ts & 0xffffffffULL) * ticks_per_second;
|
||||
ts += 0x80000000; /* rounding */
|
||||
pcap_header.ts.tv_usec = ts >> 32;
|
||||
if (pcap_header.ts.tv_usec >= 1000000) {
|
||||
pcap_header.ts.tv_usec -= 1000000;
|
||||
pcap_header.ts.tv_usec = ts >> 32;
|
||||
if (pcap_header.ts.tv_usec >= ticks_per_second) {
|
||||
pcap_header.ts.tv_usec -= ticks_per_second;
|
||||
pcap_header.ts.tv_sec++;
|
||||
}
|
||||
|
||||
/* Fill in our own header data */
|
||||
pcap_header.caplen = caplen;
|
||||
pcap_header.len = packet_len;
|
||||
|
||||
|
||||
/* Count the packet. */
|
||||
pd->stat.ps_recv++;
|
||||
|
||||
|
||||
/* Call the user supplied callback function */
|
||||
callback(user, &pcap_header, dp);
|
||||
|
||||
|
||||
/* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
|
||||
processed++;
|
||||
if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
|
||||
@ -598,7 +709,7 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
* device will result in a failure. The promisc flag is ignored because DAG
|
||||
* cards are always promiscuous. The to_ms parameter is used in setting the
|
||||
* API polling parameters.
|
||||
*
|
||||
*
|
||||
* snaplen is now also ignored, until we get per-stream slen support. Set
|
||||
* slen with approprite DAG tool BEFORE pcap_activate().
|
||||
*
|
||||
@ -614,7 +725,7 @@ static int dag_activate(pcap_t* handle)
|
||||
int n;
|
||||
daginf_t* daginf;
|
||||
char * newDev = NULL;
|
||||
char * device = handle->opt.source;
|
||||
char * device = handle->opt.device;
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
uint32_t mindata;
|
||||
struct timeval maxwait;
|
||||
@ -622,7 +733,7 @@ static int dag_activate(pcap_t* handle)
|
||||
#endif
|
||||
|
||||
if (device == NULL) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -631,26 +742,26 @@ static int dag_activate(pcap_t* handle)
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
newDev = (char *)malloc(strlen(device) + 16);
|
||||
if (newDev == NULL) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s", pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
/* Parse input name to get dag device and stream number if provided */
|
||||
if (dag_parse_name(device, newDev, strlen(device) + 16, &handlep->dag_stream) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s", pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
device = newDev;
|
||||
|
||||
if (handlep->dag_stream%2) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
if (strncmp(device, "/dev/", 5) != 0) {
|
||||
newDev = (char *)malloc(strlen(device) + 5);
|
||||
if (newDev == NULL) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s", pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
strcpy(newDev, "/dev/");
|
||||
@ -661,14 +772,14 @@ static int dag_activate(pcap_t* handle)
|
||||
|
||||
/* setup device parameters */
|
||||
if((handle->fd = dag_open((char *)device)) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
/* Open requested stream. Can fail if already locked or on error */
|
||||
if (dag_attach_stream(handle->fd, handlep->dag_stream, 0, 0) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s", pcap_strerror(errno));
|
||||
goto failclose;
|
||||
}
|
||||
|
||||
@ -677,10 +788,10 @@ static int dag_activate(pcap_t* handle)
|
||||
*/
|
||||
if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
|
||||
&mindata, &maxwait, &poll) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
|
||||
goto faildetach;
|
||||
}
|
||||
|
||||
|
||||
if (handle->opt.immediate) {
|
||||
/* Call callback immediately.
|
||||
* XXX - is this the right way to handle this?
|
||||
@ -702,13 +813,13 @@ static int dag_activate(pcap_t* handle)
|
||||
|
||||
if (dag_set_stream_poll(handle->fd, handlep->dag_stream,
|
||||
mindata, &maxwait, &poll) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
|
||||
goto faildetach;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
if((handlep->dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s", device, pcap_strerror(errno));
|
||||
goto failclose;
|
||||
}
|
||||
|
||||
@ -728,22 +839,22 @@ static int dag_activate(pcap_t* handle)
|
||||
handle->snapshot = MIN_DAG_SNAPLEN;
|
||||
}
|
||||
/* snap len has to be a multiple of 4 */
|
||||
snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
|
||||
pcap_snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
|
||||
|
||||
if(dag_configure(handle->fd, conf) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s", device, pcap_strerror(errno));
|
||||
goto faildetach;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
if(dag_start_stream(handle->fd, handlep->dag_stream) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s", device, pcap_strerror(errno));
|
||||
goto faildetach;
|
||||
}
|
||||
#else
|
||||
if(dag_start(handle->fd) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s", device, pcap_strerror(errno));
|
||||
goto failclose;
|
||||
}
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
@ -778,8 +889,8 @@ static int dag_activate(pcap_t* handle)
|
||||
if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
|
||||
handlep->dag_fcs_bits = n;
|
||||
} else {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
|
||||
goto failstop;
|
||||
}
|
||||
}
|
||||
@ -802,11 +913,11 @@ static int dag_activate(pcap_t* handle)
|
||||
handle->linktype = -1;
|
||||
if (dag_get_datalink(handle) < 0)
|
||||
goto failstop;
|
||||
|
||||
|
||||
handle->bufsize = 0;
|
||||
|
||||
if (new_pcap_dag(handle) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s", device, pcap_strerror(errno));
|
||||
goto failstop;
|
||||
}
|
||||
|
||||
@ -833,12 +944,12 @@ static int dag_activate(pcap_t* handle)
|
||||
handlep->stat.ps_ifdrop = 0;
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
failstop:
|
||||
if (dag_stop_stream(handle->fd, handlep->dag_stream) < 0) {
|
||||
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
faildetach:
|
||||
if (dag_detach_stream(handle->fd, handlep->dag_stream) < 0)
|
||||
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
||||
@ -847,7 +958,7 @@ failstop:
|
||||
if (dag_stop(handle->fd) < 0)
|
||||
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
|
||||
|
||||
failclose:
|
||||
if (dag_close(handle->fd) < 0)
|
||||
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
||||
@ -912,11 +1023,29 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
|
||||
/* OK, it's probably ours. */
|
||||
*is_ours = 1;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dag));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_dag));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
p->activate_op = dag_activate;
|
||||
|
||||
/*
|
||||
* We claim that we support microsecond and nanosecond time
|
||||
* stamps.
|
||||
*
|
||||
* XXX Our native precision is 2^-32s, but libpcap doesn't support
|
||||
* power of two precisions yet. We can convert to either MICRO or NANO.
|
||||
*/
|
||||
p->tstamp_precision_count = 2;
|
||||
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
|
||||
if (p->tstamp_precision_list == NULL) {
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
pcap_strerror(errno));
|
||||
pcap_close(p);
|
||||
return NULL;
|
||||
}
|
||||
p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
|
||||
p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -929,9 +1058,9 @@ dag_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||
*/
|
||||
/*pd->stat.ps_recv = 0;*/
|
||||
/*pd->stat.ps_drop = 0;*/
|
||||
|
||||
|
||||
*ps = pd->stat;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -953,16 +1082,21 @@ dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
|
||||
char dagname[DAGNAME_BUFSIZE];
|
||||
int dagstream;
|
||||
int dagfd;
|
||||
dag_card_inf_t *inf;
|
||||
char *description;
|
||||
|
||||
/* Try all the DAGs 0-DAG_MAX_BOARDS */
|
||||
for (c = 0; c < DAG_MAX_BOARDS; c++) {
|
||||
snprintf(name, 12, "dag%d", c);
|
||||
pcap_snprintf(name, 12, "dag%d", c);
|
||||
if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
description = NULL;
|
||||
if ( (dagfd = dag_open(dagname)) >= 0 ) {
|
||||
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
|
||||
if ((inf = dag_pciinfo(dagfd)))
|
||||
description = dag_device_name(inf->device_code, 1);
|
||||
if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
|
||||
/*
|
||||
* Failure.
|
||||
*/
|
||||
@ -976,20 +1110,20 @@ dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
|
||||
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
|
||||
dag_detach_stream(dagfd, stream);
|
||||
|
||||
snprintf(name, 10, "dag%d:%d", c, stream);
|
||||
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
|
||||
pcap_snprintf(name, 10, "dag%d:%d", c, stream);
|
||||
if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
|
||||
/*
|
||||
* Failure.
|
||||
*/
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
|
||||
rxstreams--;
|
||||
if(rxstreams <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
dag_close(dagfd);
|
||||
@ -1049,13 +1183,13 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
uint32_t mindata;
|
||||
struct timeval maxwait;
|
||||
struct timeval poll;
|
||||
|
||||
|
||||
if (dag_get_stream_poll(p->fd, pd->dag_stream,
|
||||
&mindata, &maxwait, &poll) < 0) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Amount of data to collect in Bytes before calling callbacks.
|
||||
* Important for efficiency, but can introduce latency
|
||||
* at low packet rates if to_ms not set!
|
||||
@ -1064,10 +1198,10 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
mindata = 0;
|
||||
else
|
||||
mindata = 65536;
|
||||
|
||||
|
||||
if (dag_set_stream_poll(p->fd, pd->dag_stream,
|
||||
mindata, &maxwait, &poll) < 0) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1079,7 +1213,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dag_get_datalink(pcap_t *p)
|
||||
{
|
||||
@ -1090,7 +1224,7 @@ dag_get_datalink(pcap_t *p)
|
||||
memset(types, 0, 255);
|
||||
|
||||
if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
|
||||
(void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
|
||||
(void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -1099,19 +1233,19 @@ dag_get_datalink(pcap_t *p)
|
||||
#ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
|
||||
/* Get list of possible ERF types for this card */
|
||||
if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
|
||||
snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
while (types[index]) {
|
||||
|
||||
#elif defined HAVE_DAG_GET_ERF_TYPES
|
||||
/* Get list of possible ERF types for this card */
|
||||
if (dag_get_erf_types(p->fd, types, 255) < 0) {
|
||||
snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
while (types[index]) {
|
||||
#else
|
||||
/* Check the type through a dagapi call. */
|
||||
@ -1157,7 +1291,7 @@ dag_get_datalink(pcap_t *p)
|
||||
p->linktype = DLT_EN10MB;
|
||||
break;
|
||||
|
||||
case TYPE_ATM:
|
||||
case TYPE_ATM:
|
||||
case TYPE_AAL5:
|
||||
case TYPE_MC_ATM:
|
||||
case TYPE_MC_AAL5:
|
||||
@ -1215,3 +1349,31 @@ dag_get_datalink(pcap_t *p)
|
||||
|
||||
return p->linktype;
|
||||
}
|
||||
|
||||
#ifdef DAG_ONLY
|
||||
/*
|
||||
* This libpcap build supports only DAG cards, not regular network
|
||||
* interfaces.
|
||||
*/
|
||||
|
||||
/*
|
||||
* There are no regular interfaces, just DAG interfaces.
|
||||
*/
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
*alldevsp = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempts to open a regular interface fail.
|
||||
*/
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *errbuf)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"This version of libpcap only supports DAG cards");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
@ -10,97 +10,3 @@
|
||||
|
||||
pcap_t *dag_create(const char *, char *, int *);
|
||||
int dag_findalldevs(pcap_if_t **devlistp, char *errbuf);
|
||||
|
||||
#ifndef TYPE_AAL5
|
||||
#define TYPE_AAL5 4
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_HDLC
|
||||
#define TYPE_MC_HDLC 5
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_RAW
|
||||
#define TYPE_MC_RAW 6
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_ATM
|
||||
#define TYPE_MC_ATM 7
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_RAW_CHANNEL
|
||||
#define TYPE_MC_RAW_CHANNEL 8
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_AAL5
|
||||
#define TYPE_MC_AAL5 9
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_HDLC_POS
|
||||
#define TYPE_COLOR_HDLC_POS 10
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_ETH
|
||||
#define TYPE_COLOR_ETH 11
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_MC_AAL2
|
||||
#define TYPE_MC_AAL2 12
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_IP_COUNTER
|
||||
#define TYPE_IP_COUNTER 13
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_TCP_FLOW_COUNTER
|
||||
#define TYPE_TCP_FLOW_COUNTER 14
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_DSM_COLOR_HDLC_POS
|
||||
#define TYPE_DSM_COLOR_HDLC_POS 15
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_DSM_COLOR_ETH
|
||||
#define TYPE_DSM_COLOR_ETH 16
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_MC_HDLC_POS
|
||||
#define TYPE_COLOR_MC_HDLC_POS 17
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_AAL2
|
||||
#define TYPE_AAL2 18
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_HASH_POS
|
||||
#define TYPE_COLOR_HASH_POS 19
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_COLOR_HASH_ETH
|
||||
#define TYPE_COLOR_HASH_ETH 20
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_INFINIBAND
|
||||
#define TYPE_INFINIBAND 21
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_IPV4
|
||||
#define TYPE_IPV4 22
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_IPV6
|
||||
#define TYPE_IPV6 23
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_RAW_LINK
|
||||
#define TYPE_RAW_LINK 24
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_INFINIBAND_LINK
|
||||
#define TYPE_INFINIBAND_LINK 25
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef TYPE_PAD
|
||||
#define TYPE_PAD 48
|
||||
#endif
|
||||
|
@ -11,8 +11,8 @@
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
@ -66,9 +66,9 @@ dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
|
||||
message = dbus_connection_pop_message(handlep->conn);
|
||||
|
||||
while (!message) {
|
||||
// XXX handle->opt.timeout = timeout_ms;
|
||||
/* XXX handle->opt.timeout = timeout_ms; */
|
||||
if (!dbus_connection_read_write(handlep->conn, 100)) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
|
||||
}
|
||||
|
||||
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ dbus_write(pcap_t *handle, const void *buf, size_t size)
|
||||
DBusMessage *msg;
|
||||
|
||||
if (!(msg = dbus_message_demarshal(buf, size, &error))) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dbus_message_demarshal() failed: %s", error.message);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dbus_message_demarshal() failed: %s", error.message);
|
||||
dbus_error_free(&error);
|
||||
return -1;
|
||||
}
|
||||
@ -122,7 +122,7 @@ dbus_write(pcap_t *handle, const void *buf, size_t size)
|
||||
|
||||
dbus_message_unref(msg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dbus_stats(pcap_t *handle, struct pcap_stat *stats)
|
||||
@ -160,21 +160,21 @@ dbus_activate(pcap_t *handle)
|
||||
#define N_RULES sizeof(rules)/sizeof(rules[0])
|
||||
|
||||
struct pcap_dbus *handlep = handle->priv;
|
||||
const char *dev = handle->opt.source;
|
||||
const char *dev = handle->opt.device;
|
||||
|
||||
DBusError error = DBUS_ERROR_INIT;
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
if (strcmp(dev, "dbus-system") == 0) {
|
||||
if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get system bus: %s", error.message);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get system bus: %s", error.message);
|
||||
dbus_error_free(&error);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
} else if (strcmp(dev, "dbus-session") == 0) {
|
||||
if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SESSION, &error))) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get session bus: %s", error.message);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get session bus: %s", error.message);
|
||||
dbus_error_free(&error);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
@ -183,19 +183,19 @@ dbus_activate(pcap_t *handle)
|
||||
const char *addr = dev + 7;
|
||||
|
||||
if (!(handlep->conn = dbus_connection_open(addr, &error))) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to open connection to: %s: %s", addr, error.message);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to open connection to: %s: %s", addr, error.message);
|
||||
dbus_error_free(&error);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
if (!dbus_bus_register(handlep->conn, &error)) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register bus %s: %s\n", addr, error.message);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register bus %s: %s\n", addr, error.message);
|
||||
dbus_error_free(&error);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get bus address from %s", handle->opt.source);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get bus address from %s", handle->opt.device);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
@ -234,7 +234,7 @@ dbus_activate(pcap_t *handle)
|
||||
/* try without eavesdrop */
|
||||
dbus_bus_add_match(handlep->conn, rules[i] + strlen(EAVESDROPPING_RULE), &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to add bus match: %s\n", error.message);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to add bus match: %s\n", error.message);
|
||||
dbus_error_free(&error);
|
||||
dbus_cleanup(handle);
|
||||
return PCAP_ERROR;
|
||||
@ -250,8 +250,8 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
if (strcmp(device, "dbus-system") &&
|
||||
strcmp(device, "dbus-session") &&
|
||||
if (strcmp(device, "dbus-system") &&
|
||||
strcmp(device, "dbus-session") &&
|
||||
strncmp(device, "dbus://", 7))
|
||||
{
|
||||
*is_ours = 0;
|
||||
@ -259,7 +259,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
|
||||
}
|
||||
|
||||
*is_ours = 1;
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dbus));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_dbus));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -267,7 +267,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
|
||||
return (p);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
dbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||
{
|
||||
if (pcap_add_if(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) < 0)
|
||||
|
@ -153,10 +153,12 @@ static void dlpassive(int, char *);
|
||||
static int dlrawdatareq(int, const u_char *, int);
|
||||
#endif
|
||||
static int recv_ack(int, int, const char *, char *, char *, int *);
|
||||
static char *dlstrerror(bpf_u_int32);
|
||||
static char *dlprim(bpf_u_int32);
|
||||
static char *dlstrerror(char *, size_t, bpf_u_int32);
|
||||
static char *dlprim(char *, size_t, bpf_u_int32);
|
||||
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
|
||||
static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *);
|
||||
#define GET_RELEASE_BUFSIZE 32
|
||||
static void get_release(char *, size_t, bpf_u_int32 *, bpf_u_int32 *,
|
||||
bpf_u_int32 *);
|
||||
#endif
|
||||
static int send_request(int, char *, int, char *, char *);
|
||||
#ifdef HAVE_HPUX9
|
||||
@ -166,14 +168,6 @@ static int dlpi_kread(int, off_t, void *, u_int, char *);
|
||||
static int get_dlpi_ppa(int, const char *, int, char *);
|
||||
#endif
|
||||
|
||||
/* XXX Needed by HP-UX (at least) */
|
||||
static bpf_u_int32 ctlbuf[MAXDLBUF];
|
||||
static struct strbuf ctl = {
|
||||
MAXDLBUF,
|
||||
0,
|
||||
(char *)ctlbuf
|
||||
};
|
||||
|
||||
/*
|
||||
* Cast a buffer to "union DL_primitives" without provoking warnings
|
||||
* from the compiler.
|
||||
@ -186,6 +180,12 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
int cc;
|
||||
u_char *bp;
|
||||
int flags;
|
||||
bpf_u_int32 ctlbuf[MAXDLBUF];
|
||||
struct strbuf ctl = {
|
||||
MAXDLBUF,
|
||||
0,
|
||||
(char *)ctlbuf
|
||||
};
|
||||
struct strbuf data;
|
||||
|
||||
flags = 0;
|
||||
@ -213,6 +213,9 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
* would be DL_HP_RAWDATA_IND on HP-UX
|
||||
* if we're in raw mode?
|
||||
*/
|
||||
ctl.buf = (char *)ctlbuf;
|
||||
ctl.maxlen = MAXDLBUF;
|
||||
ctl.len = 0;
|
||||
if (getmsg(p->fd, &ctl, &data, &flags) < 0) {
|
||||
/* Don't choke when we get ptraced */
|
||||
switch (errno) {
|
||||
@ -230,7 +233,7 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
}
|
||||
cc = data.len;
|
||||
} while (cc == 0);
|
||||
bp = p->buffer + p->offset;
|
||||
bp = (u_char *)p->buffer + p->offset;
|
||||
} else
|
||||
bp = p->bp;
|
||||
|
||||
@ -248,19 +251,19 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
|
||||
#if defined(DLIOCRAW)
|
||||
ret = write(p->fd, buf, size);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
#elif defined(DL_HP_RAWDLS)
|
||||
if (pd->send_fd < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"send: Output FD couldn't be opened");
|
||||
return (-1);
|
||||
}
|
||||
ret = dlrawdatareq(pd->send_fd, buf, size);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -298,7 +301,7 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
|
||||
ret = -1;
|
||||
#endif /* raw mode */
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DL_IPATM
|
||||
#define DL_IPATM 0x12 /* ATM Classical IP interface */
|
||||
@ -331,28 +334,12 @@ pcap_cleanup_dlpi(pcap_t *p)
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_activate_dlpi(pcap_t *p)
|
||||
open_dlpi_device(const char *name, int *ppa, char *errbuf)
|
||||
{
|
||||
#ifdef DL_HP_RAWDLS
|
||||
struct pcap_dlpi *pd = p->priv;
|
||||
#endif
|
||||
int status = 0;
|
||||
int retv;
|
||||
register char *cp;
|
||||
int ppa;
|
||||
#ifdef HAVE_SOLARIS
|
||||
int isatm = 0;
|
||||
#endif
|
||||
register dl_info_ack_t *infop;
|
||||
#ifdef HAVE_SYS_BUFMOD_H
|
||||
bpf_u_int32 ss;
|
||||
#ifdef HAVE_SOLARIS
|
||||
register char *release;
|
||||
bpf_u_int32 osmajor, osminor, osmicro;
|
||||
#endif
|
||||
#endif
|
||||
bpf_u_int32 buf[MAXDLBUF];
|
||||
int status;
|
||||
char dname[100];
|
||||
char *cp;
|
||||
int fd;
|
||||
#ifndef HAVE_DEV_DLPI
|
||||
char dname2[100];
|
||||
#endif
|
||||
@ -361,9 +348,9 @@ pcap_activate_dlpi(pcap_t *p)
|
||||
/*
|
||||
** Remove any "/dev/" on the front of the device.
|
||||
*/
|
||||
cp = strrchr(p->opt.source, '/');
|
||||
cp = strrchr(name, '/');
|
||||
if (cp == NULL)
|
||||
strlcpy(dname, p->opt.source, sizeof(dname));
|
||||
strlcpy(dname, name, sizeof(dname));
|
||||
else
|
||||
strlcpy(dname, cp + 1, sizeof(dname));
|
||||
|
||||
@ -371,11 +358,9 @@ pcap_activate_dlpi(pcap_t *p)
|
||||
* Split the device name into a device type name and a unit number;
|
||||
* chop off the unit number, so "dname" is just a device type name.
|
||||
*/
|
||||
cp = split_dname(dname, &ppa, p->errbuf);
|
||||
if (cp == NULL) {
|
||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
goto bad;
|
||||
}
|
||||
cp = split_dname(dname, ppa, errbuf);
|
||||
if (cp == NULL)
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
*cp = '\0';
|
||||
|
||||
/*
|
||||
@ -390,13 +375,137 @@ pcap_activate_dlpi(pcap_t *p)
|
||||
* device number, rather than hardwiring "/dev/dlpi".
|
||||
*/
|
||||
cp = "/dev/dlpi";
|
||||
if ((p->fd = open(cp, O_RDWR)) < 0) {
|
||||
if ((fd = open(cp, O_RDWR)) < 0) {
|
||||
if (errno == EPERM || errno == EACCES)
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
status = PCAP_ERROR;
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: %s", cp, pcap_strerror(errno));
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a table of all PPAs for that device, and search that
|
||||
* table for the specified device type name and unit number.
|
||||
*/
|
||||
*ppa = get_dlpi_ppa(fd, dname, *ppa, errbuf);
|
||||
if (*ppa < 0) {
|
||||
close(fd);
|
||||
return (*ppa);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* If the device name begins with "/", assume it begins with
|
||||
* the pathname of the directory containing the device to open;
|
||||
* otherwise, concatenate the device directory name and the
|
||||
* device name.
|
||||
*/
|
||||
if (*name == '/')
|
||||
strlcpy(dname, name, sizeof(dname));
|
||||
else
|
||||
pcap_snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
|
||||
name);
|
||||
|
||||
/*
|
||||
* Get the unit number, and a pointer to the end of the device
|
||||
* type name.
|
||||
*/
|
||||
cp = split_dname(dname, ppa, errbuf);
|
||||
if (cp == NULL)
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
|
||||
/*
|
||||
* Make a copy of the device pathname, and then remove the unit
|
||||
* number from the device pathname.
|
||||
*/
|
||||
strlcpy(dname2, dname, sizeof(dname));
|
||||
*cp = '\0';
|
||||
|
||||
/* Try device without unit number */
|
||||
if ((fd = open(dname, O_RDWR)) < 0) {
|
||||
if (errno != ENOENT) {
|
||||
if (errno == EPERM || errno == EACCES)
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
status = PCAP_ERROR;
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
|
||||
pcap_strerror(errno));
|
||||
return (status);
|
||||
}
|
||||
|
||||
/* Try again with unit number */
|
||||
if ((fd = open(dname2, O_RDWR)) < 0) {
|
||||
if (errno == ENOENT) {
|
||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
|
||||
/*
|
||||
* We provide an error message even
|
||||
* for this error, for diagnostic
|
||||
* purposes (so that, for example,
|
||||
* the app can show the message if the
|
||||
* user requests it).
|
||||
*
|
||||
* In it, we just report "No DLPI device
|
||||
* found" with the device name, so people
|
||||
* don't get confused and think, for example,
|
||||
* that if they can't capture on "lo0"
|
||||
* on Solaris prior to Solaris 11 the fix
|
||||
* is to change libpcap (or the application
|
||||
* that uses it) to look for something other
|
||||
* than "/dev/lo0", as the fix is to use
|
||||
* Solaris 11 or some operating system
|
||||
* other than Solaris - you just *can't*
|
||||
* capture on a loopback interface
|
||||
* on Solaris prior to Solaris 11, the lack
|
||||
* of a DLPI device for the loopback
|
||||
* interface is just a symptom of that
|
||||
* inability.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: No DLPI device found", name);
|
||||
} else {
|
||||
if (errno == EPERM || errno == EACCES)
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
status = PCAP_ERROR;
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
||||
dname2, pcap_strerror(errno));
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
/* XXX Assume unit zero */
|
||||
*ppa = 0;
|
||||
}
|
||||
#endif
|
||||
return (fd);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_activate_dlpi(pcap_t *p)
|
||||
{
|
||||
#ifdef DL_HP_RAWDLS
|
||||
struct pcap_dlpi *pd = p->priv;
|
||||
#endif
|
||||
int status = 0;
|
||||
int retv;
|
||||
int ppa;
|
||||
#ifdef HAVE_SOLARIS
|
||||
int isatm = 0;
|
||||
#endif
|
||||
register dl_info_ack_t *infop;
|
||||
#ifdef HAVE_SYS_BUFMOD_H
|
||||
bpf_u_int32 ss;
|
||||
#ifdef HAVE_SOLARIS
|
||||
char release[GET_RELEASE_BUFSIZE];
|
||||
bpf_u_int32 osmajor, osminor, osmicro;
|
||||
#endif
|
||||
#endif
|
||||
bpf_u_int32 buf[MAXDLBUF];
|
||||
|
||||
p->fd = open_dlpi_device(p->opt.device, &ppa, p->errbuf);
|
||||
if (p->fd < 0) {
|
||||
status = p->fd;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -412,101 +521,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||
* to open it for reading only and, if that succeeds, just let
|
||||
* the send attempts fail.
|
||||
*/
|
||||
pd->send_fd = open(cp, O_RDWR);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get a table of all PPAs for that device, and search that
|
||||
* table for the specified device type name and unit number.
|
||||
*/
|
||||
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
|
||||
if (ppa < 0) {
|
||||
status = ppa;
|
||||
goto bad;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* If the device name begins with "/", assume it begins with
|
||||
* the pathname of the directory containing the device to open;
|
||||
* otherwise, concatenate the device directory name and the
|
||||
* device name.
|
||||
*/
|
||||
if (*p->opt.source == '/')
|
||||
strlcpy(dname, p->opt.source, sizeof(dname));
|
||||
else
|
||||
snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
|
||||
p->opt.source);
|
||||
|
||||
/*
|
||||
* Get the unit number, and a pointer to the end of the device
|
||||
* type name.
|
||||
*/
|
||||
cp = split_dname(dname, &ppa, p->errbuf);
|
||||
if (cp == NULL) {
|
||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of the device pathname, and then remove the unit
|
||||
* number from the device pathname.
|
||||
*/
|
||||
strlcpy(dname2, dname, sizeof(dname));
|
||||
*cp = '\0';
|
||||
|
||||
/* Try device without unit number */
|
||||
if ((p->fd = open(dname, O_RDWR)) < 0) {
|
||||
if (errno != ENOENT) {
|
||||
if (errno == EPERM || errno == EACCES)
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
status = PCAP_ERROR;
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Try again with unit number */
|
||||
if ((p->fd = open(dname2, O_RDWR)) < 0) {
|
||||
if (errno == ENOENT) {
|
||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
|
||||
/*
|
||||
* We provide an error message even
|
||||
* for this error, for diagnostic
|
||||
* purposes (so that, for example,
|
||||
* the app can show the message if the
|
||||
* user requests it).
|
||||
*
|
||||
* In it, we just report "No DLPI device
|
||||
* found" with the device name, so people
|
||||
* don't get confused and think, for example,
|
||||
* that if they can't capture on "lo0"
|
||||
* on Solaris the fix is to change libpcap
|
||||
* (or the application that uses it) to
|
||||
* look for something other than "/dev/lo0",
|
||||
* as the fix is to look for an operating
|
||||
* system other than Solaris - you just
|
||||
* *can't* capture on a loopback interface
|
||||
* on Solaris, the lack of a DLPI device
|
||||
* for the loopback interface is just a
|
||||
* symptom of that inability.
|
||||
*/
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: No DLPI device found", p->opt.source);
|
||||
} else {
|
||||
if (errno == EPERM || errno == EACCES)
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
status = PCAP_ERROR;
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
||||
dname2, pcap_strerror(errno));
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
/* XXX Assume unit zero */
|
||||
ppa = 0;
|
||||
}
|
||||
pd->send_fd = open("/dev/dlpi", O_RDWR);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -627,7 +642,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||
*/
|
||||
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
|
||||
status = PCAP_ERROR;
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"A_PROMISCON_REQ: %s", pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -745,7 +760,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||
*/
|
||||
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
|
||||
status = PCAP_ERROR;
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -763,10 +778,10 @@ pcap_activate_dlpi(pcap_t *p)
|
||||
** Ask for bugid 1149065.
|
||||
*/
|
||||
#ifdef HAVE_SOLARIS
|
||||
release = get_release(&osmajor, &osminor, &osmicro);
|
||||
get_release(release, sizeof (release), &osmajor, &osminor, &osmicro);
|
||||
if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
|
||||
getenv("BUFMOD_FIXED") == NULL) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.",
|
||||
release);
|
||||
ss = 0;
|
||||
@ -786,7 +801,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||
*/
|
||||
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
||||
status = PCAP_ERROR;
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -841,7 +856,7 @@ split_dname(char *device, int *unitp, char *ebuf)
|
||||
*/
|
||||
cp = device + strlen(device) - 1;
|
||||
if (*cp < '0' || *cp > '9') {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number",
|
||||
device);
|
||||
return (NULL);
|
||||
}
|
||||
@ -853,16 +868,16 @@ split_dname(char *device, int *unitp, char *ebuf)
|
||||
errno = 0;
|
||||
unit = strtol(cp, &eos, 10);
|
||||
if (*eos != '\0') {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device);
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device);
|
||||
return (NULL);
|
||||
}
|
||||
if (errno == ERANGE || unit > INT_MAX) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large",
|
||||
device);
|
||||
return (NULL);
|
||||
}
|
||||
if (unit < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative",
|
||||
device);
|
||||
return (NULL);
|
||||
}
|
||||
@ -960,6 +975,56 @@ dlpromiscon(pcap_t *p, bpf_u_int32 level)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Not all interfaces are DLPI interfaces, and thus not all interfaces
|
||||
* can be opened with DLPI (for example, the loopback interface is not
|
||||
* a DLPI interface on Solaris prior to Solaris 11), so try to open
|
||||
* the specified interface; return 0 if we fail with PCAP_ERROR_NO_SUCH_DEVICE
|
||||
* and 1 otherwise.
|
||||
*/
|
||||
static int
|
||||
is_dlpi_interface(const char *name)
|
||||
{
|
||||
int fd;
|
||||
int ppa;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
fd = open_dlpi_device(name, &ppa, errbuf);
|
||||
if (fd < 0) {
|
||||
/*
|
||||
* Error - was it PCAP_ERROR_NO_SUCH_DEVICE?
|
||||
*/
|
||||
if (fd == PCAP_ERROR_NO_SUCH_DEVICE) {
|
||||
/*
|
||||
* Yes, so we can't open this because it's
|
||||
* not a DLPI interface.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* No, so, in the case where there's a single DLPI
|
||||
* device for all interfaces of this type ("style
|
||||
* 2" providers?), we don't know whether it's a DLPI
|
||||
* interface or not, as we didn't try an attach.
|
||||
* Say it is a DLPI device, so that the user can at
|
||||
* least try to open it and report the error (which
|
||||
* is probably "you don't have permission to open that
|
||||
* DLPI device"; reporting those interfaces means
|
||||
* users will ask "why am I getting a permissions error
|
||||
* when I try to capture" rather than "why am I not
|
||||
* seeing any interfaces", making the underlying problem
|
||||
* clearer).
|
||||
*/
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Success.
|
||||
*/
|
||||
close(fd);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
@ -972,7 +1037,15 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
} buf;
|
||||
char baname[2+1+1];
|
||||
u_int i;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the list of regular interfaces first.
|
||||
*/
|
||||
if (pcap_findalldevs_interfaces(alldevsp, errbuf, is_dlpi_interface) == -1)
|
||||
return (-1); /* failure */
|
||||
|
||||
#ifdef HAVE_SOLARIS
|
||||
/*
|
||||
* We may have to do special magic to get ATM devices.
|
||||
*/
|
||||
@ -989,12 +1062,12 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
}
|
||||
|
||||
if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
for (i = 0; i < buf.nunits; i++) {
|
||||
snprintf(baname, sizeof baname, "ba%u", i);
|
||||
pcap_snprintf(baname, sizeof baname, "ba%u", i);
|
||||
if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
|
||||
return (-1);
|
||||
}
|
||||
@ -1015,7 +1088,7 @@ send_request(int fd, char *ptr, int len, char *what, char *ebuf)
|
||||
|
||||
flags = 0;
|
||||
if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"send_request: putmsg \"%s\": %s",
|
||||
what, pcap_strerror(errno));
|
||||
return (-1);
|
||||
@ -1029,6 +1102,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
|
||||
union DL_primitives *dlp;
|
||||
struct strbuf ctl;
|
||||
int flags;
|
||||
char errmsgbuf[PCAP_ERRBUF_SIZE];
|
||||
char dlprimbuf[64];
|
||||
|
||||
/*
|
||||
* Clear out "*uerror", so it's only set for DL_ERROR_ACK/DL_SYSERR,
|
||||
@ -1043,7 +1118,7 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
|
||||
|
||||
flags = 0;
|
||||
if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
|
||||
what, pcap_strerror(errno));
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
@ -1066,7 +1141,7 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
|
||||
case DL_SYSERR:
|
||||
if (uerror != NULL)
|
||||
*uerror = dlp->error_ack.dl_unix_errno;
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"recv_ack: %s: UNIX error - %s",
|
||||
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
|
||||
if (dlp->error_ack.dl_unix_errno == EPERM ||
|
||||
@ -1075,8 +1150,9 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
|
||||
what, dlstrerror(dlp->error_ack.dl_errno));
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"recv_ack: %s: %s", what,
|
||||
dlstrerror(errmsgbuf, sizeof (errmsgbuf), dlp->error_ack.dl_errno));
|
||||
if (dlp->error_ack.dl_errno == DL_BADPPA)
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
else if (dlp->error_ack.dl_errno == DL_ACCESS)
|
||||
@ -1086,14 +1162,14 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
|
||||
return (PCAP_ERROR);
|
||||
|
||||
default:
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"recv_ack: %s: Unexpected primitive ack %s",
|
||||
what, dlprim(dlp->dl_primitive));
|
||||
what, dlprim(dlprimbuf, sizeof (dlprimbuf), dlp->dl_primitive));
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
if (ctl.len < size) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"recv_ack: %s: Ack too small (%d < %d)",
|
||||
what, ctl.len, size);
|
||||
return (PCAP_ERROR);
|
||||
@ -1102,10 +1178,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
|
||||
}
|
||||
|
||||
static char *
|
||||
dlstrerror(bpf_u_int32 dl_errno)
|
||||
dlstrerror(char *errbuf, size_t errbufsize, bpf_u_int32 dl_errno)
|
||||
{
|
||||
static char errstring[6+2+8+1];
|
||||
|
||||
switch (dl_errno) {
|
||||
|
||||
case DL_ACCESS:
|
||||
@ -1206,16 +1280,14 @@ dlstrerror(bpf_u_int32 dl_errno)
|
||||
return ("Pending outstanding connect indications");
|
||||
|
||||
default:
|
||||
sprintf(errstring, "Error %02x", dl_errno);
|
||||
return (errstring);
|
||||
pcap_snprintf(errbuf, errbufsize, "Error %02x", dl_errno);
|
||||
return (errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
dlprim(bpf_u_int32 prim)
|
||||
dlprim(char *primbuf, size_t primbufsize, bpf_u_int32 prim)
|
||||
{
|
||||
static char primbuf[80];
|
||||
|
||||
switch (prim) {
|
||||
|
||||
case DL_INFO_REQ:
|
||||
@ -1300,7 +1372,8 @@ dlprim(bpf_u_int32 prim)
|
||||
return ("DL_RESET_CON");
|
||||
|
||||
default:
|
||||
(void) sprintf(primbuf, "unknown primitive 0x%x", prim);
|
||||
pcap_snprintf(primbuf, primbufsize, "unknown primitive 0x%x",
|
||||
prim);
|
||||
return (primbuf);
|
||||
}
|
||||
}
|
||||
@ -1412,28 +1485,29 @@ dlrawdatareq(int fd, const u_char *datap, int datalen)
|
||||
#endif /* DL_HP_RAWDLS */
|
||||
|
||||
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
|
||||
static char *
|
||||
get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
|
||||
static void
|
||||
get_release(char *buf, size_t bufsize, bpf_u_int32 *majorp,
|
||||
bpf_u_int32 *minorp, bpf_u_int32 *microp)
|
||||
{
|
||||
char *cp;
|
||||
static char buf[32];
|
||||
|
||||
*majorp = 0;
|
||||
*minorp = 0;
|
||||
*microp = 0;
|
||||
if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0)
|
||||
return ("?");
|
||||
if (sysinfo(SI_RELEASE, buf, bufsize) < 0) {
|
||||
strlcpy(buf, "?", bufsize);
|
||||
return;
|
||||
}
|
||||
cp = buf;
|
||||
if (!isdigit((unsigned char)*cp))
|
||||
return (buf);
|
||||
return;
|
||||
*majorp = strtol(cp, &cp, 10);
|
||||
if (*cp++ != '.')
|
||||
return (buf);
|
||||
return;
|
||||
*minorp = strtol(cp, &cp, 10);
|
||||
if (*cp++ != '.')
|
||||
return (buf);
|
||||
return;
|
||||
*microp = strtol(cp, &cp, 10);
|
||||
return (buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1521,21 +1595,21 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
|
||||
*/
|
||||
/* get the head first */
|
||||
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
dlp = (dl_hp_ppa_ack_t *)ctl.buf;
|
||||
if (dlp->dl_primitive != DL_HP_PPA_ACK) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",
|
||||
(bpf_u_int32)dlp->dl_primitive);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
|
||||
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
|
||||
return (PCAP_ERROR);
|
||||
@ -1543,7 +1617,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
|
||||
|
||||
/* allocate buffer */
|
||||
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
@ -1552,13 +1626,13 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
|
||||
ctl.buf = (char *)ppa_data_buf;
|
||||
/* get the data */
|
||||
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
|
||||
free(ppa_data_buf);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
if (ctl.len < dlp->dl_length) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
|
||||
ctl.len, (unsigned long)dlp->dl_length);
|
||||
free(ppa_data_buf);
|
||||
@ -1615,9 +1689,9 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
|
||||
* device number of a device with the name "/dev/<dev><unit>",
|
||||
* if such a device exists, as the old code did.
|
||||
*/
|
||||
snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);
|
||||
pcap_snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);
|
||||
if (stat(dname, &statbuf) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
|
||||
dname, pcap_strerror(errno));
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
@ -1634,12 +1708,12 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
|
||||
}
|
||||
}
|
||||
if (i == ap->dl_count) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"can't find /dev/dlpi PPA for %s%d", device, unit);
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
}
|
||||
if (ip->dl_hdw_state == HDW_DEAD) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"%s%d: hardware state: DOWN\n", device, unit);
|
||||
free(ppa_data_buf);
|
||||
return (PCAP_ERROR);
|
||||
@ -1678,19 +1752,19 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
|
||||
if (cp != NULL)
|
||||
ifname = cp + 1;
|
||||
if (nlist(path_vmunix, &nl) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",
|
||||
path_vmunix);
|
||||
return (-1);
|
||||
}
|
||||
if (nl[NL_IFNET].n_value == 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"could't find %s kernel symbol",
|
||||
nl[NL_IFNET].n_name);
|
||||
return (-1);
|
||||
}
|
||||
kd = open("/dev/kmem", O_RDONLY);
|
||||
if (kd < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -1712,7 +1786,7 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
|
||||
return (ifnet.if_index);
|
||||
}
|
||||
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -1723,17 +1797,17 @@ dlpi_kread(register int fd, register off_t addr,
|
||||
register int cc;
|
||||
|
||||
if (lseek(fd, addr, SEEK_SET) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
cc = read(fd, buf, len);
|
||||
if (cc < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
} else if (cc != len) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,
|
||||
len);
|
||||
return (-1);
|
||||
}
|
||||
@ -1742,14 +1816,14 @@ dlpi_kread(register int fd, register off_t addr,
|
||||
#endif
|
||||
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *ebuf)
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
#ifdef DL_HP_RAWDLS
|
||||
struct pcap_dlpi *pd;
|
||||
#endif
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of DOS-libpcap
|
||||
* Ported to DOS/DOSX by G. Vanem <gvanem@broadpark.no>
|
||||
* Ported to DOS/DOSX by G. Vanem <gvanem@yahoo.no>
|
||||
*
|
||||
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
|
||||
* network drivers.
|
||||
@ -145,15 +145,15 @@ static struct device *get_device (int fd)
|
||||
* Private data for capturing on MS-DOS.
|
||||
*/
|
||||
struct pcap_dos {
|
||||
void (*wait_proc)(void); /* call proc while waiting */
|
||||
void (*wait_proc)(void); /* call proc while waiting */
|
||||
struct pcap_stat stat;
|
||||
};
|
||||
|
||||
pcap_t *pcap_create_interface (const char *device, char *ebuf)
|
||||
pcap_t *pcap_create_interface (const char *device _U_, char *ebuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dos));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_dos));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -166,9 +166,7 @@ pcap_t *pcap_create_interface (const char *device, char *ebuf)
|
||||
* network packets.
|
||||
*/
|
||||
static int pcap_activate_dos (pcap_t *pcap)
|
||||
{
|
||||
struct pcap_dos *pcapd = pcap->priv;
|
||||
|
||||
{
|
||||
if (pcap->opt.rfmon) {
|
||||
/*
|
||||
* No monitor mode on DOS.
|
||||
@ -188,23 +186,26 @@ static int pcap_activate_dos (pcap_t *pcap)
|
||||
pcap->stats_op = pcap_stats_dos;
|
||||
pcap->inject_op = pcap_sendpacket_dos;
|
||||
pcap->setfilter_op = pcap_setfilter_dos;
|
||||
pcap->setdirection_op = NULL; /* Not implemented.*/
|
||||
pcap->setdirection_op = NULL; /* Not implemented.*/
|
||||
pcap->fd = ++ref_count;
|
||||
|
||||
pcap->bufsize = ETH_MAX+100; /* add some margin */
|
||||
pcap->buffer = calloc (pcap->bufsize, 1);
|
||||
|
||||
if (pcap->fd == 1) /* first time we're called */
|
||||
{
|
||||
if (!init_watt32(pcap, pcap->opt.source, pcap->errbuf) ||
|
||||
!first_init(pcap->opt.source, pcap->errbuf, pcap->opt.promisc))
|
||||
if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) ||
|
||||
!first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))
|
||||
{
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
}
|
||||
atexit (close_driver);
|
||||
}
|
||||
else if (stricmp(active_dev->name,pcap->opt.source))
|
||||
else if (stricmp(active_dev->name,pcap->opt.device))
|
||||
{
|
||||
snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Cannot use different devices simultaneously "
|
||||
"(`%s' vs. `%s')", active_dev->name, pcap->opt.source);
|
||||
pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Cannot use different devices simultaneously "
|
||||
"(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
handle_to_device [pcap->fd-1] = active_dev;
|
||||
@ -221,7 +222,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||
struct pcap_dos *pd = p->priv;
|
||||
struct pcap_pkthdr pcap;
|
||||
struct timeval now, expiry = { 0,0 };
|
||||
BYTE *rx_buf;
|
||||
int rx_len = 0;
|
||||
|
||||
if (p->opt.timeout > 0)
|
||||
@ -253,13 +253,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||
if (dev->peek_rx_buf)
|
||||
{
|
||||
PCAP_ASSERT (dev->release_rx_buf);
|
||||
rx_len = (*dev->peek_rx_buf) (&rx_buf);
|
||||
rx_len = (*dev->peek_rx_buf) (&p->buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE buf [ETH_MAX+100]; /* add some margin */
|
||||
rx_len = (*dev->copy_rx_buf) (buf, p->snapshot);
|
||||
rx_buf = buf;
|
||||
rx_len = (*dev->copy_rx_buf) (p->buffer, p->snapshot);
|
||||
}
|
||||
|
||||
if (rx_len > 0) /* got a packet */
|
||||
@ -272,7 +270,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||
pcap.len = rx_len;
|
||||
|
||||
if (callback &&
|
||||
(!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, rx_buf, pcap.len, pcap.caplen)))
|
||||
(!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen)))
|
||||
{
|
||||
filter_count++;
|
||||
|
||||
@ -280,11 +278,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||
* capture.
|
||||
*/
|
||||
gettimeofday2 (&pcap.ts, NULL);
|
||||
(*callback) (data, &pcap, rx_buf);
|
||||
(*callback) (data, &pcap, p->buffer);
|
||||
}
|
||||
|
||||
if (dev->release_rx_buf)
|
||||
(*dev->release_rx_buf) (rx_buf);
|
||||
(*dev->release_rx_buf) (p->buffer);
|
||||
|
||||
if (pcap_pkt_debug > 0)
|
||||
{
|
||||
@ -296,6 +294,18 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Has "pcap_breakloop()" been called?
|
||||
*/
|
||||
if (p->break_loop) {
|
||||
/*
|
||||
* Yes - clear the flag that indicates that it
|
||||
* has, and return -2 to indicate that we were
|
||||
* told to break out of the loop.
|
||||
*/
|
||||
p->break_loop = 0;
|
||||
return (-2);
|
||||
}
|
||||
|
||||
/* If not to wait for a packet or pcap_cleanup_dos() called from
|
||||
* e.g. SIGINT handler, exit loop now.
|
||||
*/
|
||||
@ -311,8 +321,8 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||
kbhit(); /* a real CPU hog */
|
||||
#endif
|
||||
|
||||
if (p->wait_proc)
|
||||
(*p->wait_proc)(); /* call yield func */
|
||||
if (pd->wait_proc)
|
||||
(*pd->wait_proc)(); /* call yield func */
|
||||
}
|
||||
|
||||
if (rx_len < 0) /* receive error */
|
||||
@ -330,7 +340,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||
static int
|
||||
pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
|
||||
{
|
||||
struct pcap_dos *pd = p->priv;
|
||||
int rc, num = 0;
|
||||
|
||||
while (num <= cnt || PACKET_COUNT_IS_UNLIMITED(cnt))
|
||||
@ -401,7 +410,7 @@ int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)
|
||||
strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
memcpy (se, (*dev->get_stats)(dev), sizeof(*se));
|
||||
return (0);
|
||||
}
|
||||
@ -442,7 +451,7 @@ static void pcap_cleanup_dos (pcap_t *p)
|
||||
{
|
||||
struct pcap_dos *pd;
|
||||
|
||||
if (p && !exc_occured)
|
||||
if (!exc_occured)
|
||||
{
|
||||
pd = p->priv;
|
||||
if (pcap_stats(p,NULL) < 0)
|
||||
@ -495,6 +504,8 @@ char *pcap_lookupdev (char *ebuf)
|
||||
int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
|
||||
bpf_u_int32 *netmask, char *errbuf)
|
||||
{
|
||||
DWORD mask, net;
|
||||
|
||||
if (!_watt_is_init)
|
||||
{
|
||||
strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
|
||||
@ -502,40 +513,43 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*netmask = _w32_sin_mask;
|
||||
*localnet = my_ip_addr & *netmask;
|
||||
if (*localnet == 0)
|
||||
mask = _w32_sin_mask;
|
||||
net = my_ip_addr & mask;
|
||||
if (net == 0)
|
||||
{
|
||||
if (IN_CLASSA(*netmask))
|
||||
*localnet = IN_CLASSA_NET;
|
||||
net = IN_CLASSA_NET;
|
||||
else if (IN_CLASSB(*netmask))
|
||||
*localnet = IN_CLASSB_NET;
|
||||
net = IN_CLASSB_NET;
|
||||
else if (IN_CLASSC(*netmask))
|
||||
*localnet = IN_CLASSC_NET;
|
||||
net = IN_CLASSC_NET;
|
||||
else
|
||||
{
|
||||
sprintf (errbuf, "inet class for 0x%lx unknown", *netmask);
|
||||
pcap_snprintf (errbuf, PCAP_ERRBUF_SIZE, "inet class for 0x%lx unknown", mask);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
*localnet = htonl (net);
|
||||
*netmask = htonl (mask);
|
||||
|
||||
ARGSUSED (device);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a list of all interfaces that are present and that we probe okay.
|
||||
* Returns -1 on error, 0 otherwise.
|
||||
* The list, as returned through "alldevsp", may be null if no interfaces
|
||||
* The list, as returned through "alldevsp", may be NULL if no interfaces
|
||||
* were up and could be opened.
|
||||
*/
|
||||
int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
|
||||
int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
struct device *dev;
|
||||
struct sockaddr_ll sa_ll_1, sa_ll_2;
|
||||
struct sockaddr_in sa_ll_1, sa_ll_2;
|
||||
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
|
||||
pcap_if_t *devlist = NULL;
|
||||
int ret = 0;
|
||||
size_t addr_size = sizeof(struct sockaddr_ll);
|
||||
size_t addr_size = sizeof(*addr);
|
||||
|
||||
for (dev = (struct device*)dev_base; dev; dev = dev->next)
|
||||
{
|
||||
@ -550,14 +564,14 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
|
||||
|
||||
memset (&sa_ll_1, 0, sizeof(sa_ll_1));
|
||||
memset (&sa_ll_2, 0, sizeof(sa_ll_2));
|
||||
sa_ll_1.sll_family = AF_PACKET;
|
||||
sa_ll_2.sll_family = AF_PACKET;
|
||||
sa_ll_1.sin_family = AF_INET;
|
||||
sa_ll_2.sin_family = AF_INET;
|
||||
|
||||
addr = (struct sockaddr*) &sa_ll_1;
|
||||
netmask = (struct sockaddr*) &sa_ll_1;
|
||||
dstaddr = (struct sockaddr*) &sa_ll_1;
|
||||
broadaddr = (struct sockaddr*) &sa_ll_2;
|
||||
memset (&sa_ll_2.sll_addr, 0xFF, sizeof(sa_ll_2.sll_addr));
|
||||
memset (&sa_ll_2.sin_addr, 0xFF, sizeof(sa_ll_2.sin_addr));
|
||||
|
||||
if (pcap_add_if(&devlist, dev->name, dev->flags,
|
||||
dev->long_name, errbuf) < 0)
|
||||
@ -565,13 +579,15 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (add_addr_to_iflist(&devlist,dev->name, dev->flags, addr, addr_size,
|
||||
#if 0 /* Pkt drivers should have no addresses */
|
||||
if (add_addr_to_iflist(&devlist, dev->name, dev->flags, addr, addr_size,
|
||||
netmask, addr_size, broadaddr, addr_size,
|
||||
dstaddr, addr_size, errbuf) < 0)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (devlist && ret < 0)
|
||||
@ -605,12 +621,12 @@ void pcap_assert (const char *what, const char *file, unsigned line)
|
||||
*/
|
||||
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
|
||||
{
|
||||
struct pcap_dos *pd;
|
||||
if (p)
|
||||
{
|
||||
pd = p->priv;
|
||||
pd->wait_proc = yield;
|
||||
p->opt.timeout = wait;
|
||||
struct pcap_dos *pd = p->priv;
|
||||
|
||||
pd->wait_proc = yield;
|
||||
p->opt.timeout = wait;
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,7 +651,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
|
||||
|
||||
if (!(*dev->probe)(dev)) /* call the xx_probe() function */
|
||||
{
|
||||
sprintf (ebuf, "failed to detect device `%s'", dev_name);
|
||||
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to detect device `%s'", dev_name);
|
||||
return (NULL);
|
||||
}
|
||||
probed_dev = dev; /* device is probed okay and may be used */
|
||||
@ -657,7 +673,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
|
||||
|
||||
if (!(*dev->open)(dev))
|
||||
{
|
||||
sprintf (ebuf, "failed to activate device `%s'", dev_name);
|
||||
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to activate device `%s'", dev_name);
|
||||
if (pktInfo.error && !strncmp(dev->name,"pkt",3))
|
||||
{
|
||||
strcat (ebuf, ": ");
|
||||
@ -679,14 +695,14 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
|
||||
*/
|
||||
if (!dev)
|
||||
{
|
||||
sprintf (ebuf, "device `%s' not supported", dev_name);
|
||||
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not supported", dev_name);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
not_probed:
|
||||
if (!probed_dev)
|
||||
{
|
||||
sprintf (ebuf, "device `%s' not probed", dev_name);
|
||||
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not probed", dev_name);
|
||||
return (NULL);
|
||||
}
|
||||
return (dev);
|
||||
@ -756,7 +772,7 @@ static void exc_handler (int sig)
|
||||
fprintf (stderr, "Catching signal %d.\n", sig);
|
||||
}
|
||||
exc_occured = 1;
|
||||
pcap_cleanup_dos (NULL);
|
||||
close_driver();
|
||||
}
|
||||
#endif /* __DJGPP__ */
|
||||
|
||||
@ -933,7 +949,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
|
||||
if (_watt_is_init)
|
||||
sock_exit();
|
||||
|
||||
env = getenv ("PCAP_DEBUG");
|
||||
env = getenv ("PCAP_TRACE");
|
||||
if (env && atoi(env) > 0 &&
|
||||
pcap_pkt_debug < 0) /* if not already set */
|
||||
{
|
||||
@ -960,7 +976,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
|
||||
* have default values. Should be taken from another
|
||||
* ini-file/environment in any case (ref. tcpdump.ini)
|
||||
*/
|
||||
_watt_is_init = 1;
|
||||
_watt_is_init = 1;
|
||||
|
||||
if (!using_pktdrv || !has_ip_addr) /* for now .... */
|
||||
{
|
||||
@ -973,7 +989,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
|
||||
}
|
||||
else if (rc && using_pktdrv)
|
||||
{
|
||||
sprintf (err_buf, "sock_init() failed, code %d", rc);
|
||||
pcap_snprintf (err_buf, PCAP_ERRBUF_SIZE, "sock_init() failed, code %d", rc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1053,9 +1069,9 @@ static const struct config_table debug_tab[] = {
|
||||
* pcap_config_hook() is an extension to application's config
|
||||
* handling. Uses Watt-32's config-table function.
|
||||
*/
|
||||
int pcap_config_hook (const char *name, const char *value)
|
||||
int pcap_config_hook (const char *keyword, const char *value)
|
||||
{
|
||||
return parse_config_table (debug_tab, NULL, name, value);
|
||||
return parse_config_table (debug_tab, NULL, keyword, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1092,7 +1108,7 @@ static int pkt_open (struct device *dev)
|
||||
|
||||
if (!PktInitDriver(mode))
|
||||
return (0);
|
||||
|
||||
|
||||
PktResetStatistics (pktInfo.handle);
|
||||
PktQueueBusy (FALSE);
|
||||
return (1);
|
||||
@ -1290,7 +1306,7 @@ struct device rtl8139_dev LOCKED_VAR = {
|
||||
0,0,0,0,0,0,
|
||||
&cs89_dev,
|
||||
rtl8139_probe /* dev->probe routine */
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Dequeue routine is called by polling.
|
||||
|
@ -214,7 +214,7 @@ extern void _w32_os_yield (void); /* Watt-32's misc.c */
|
||||
#define PCAP_ASSERT(x) ((void)0)
|
||||
|
||||
#else
|
||||
void pcap_assert (const char *what, const char *file, unsigned line);
|
||||
void pcap_assert (const char *what, const char *file, unsigned line);
|
||||
|
||||
#define PCAP_ASSERT(x) do { \
|
||||
if (!(x)) \
|
||||
|
@ -18,7 +18,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP-FILTER @MAN_MISC_INFO@ "17 May 2013"
|
||||
.TH PCAP-FILTER @MAN_MISC_INFO@ "3 August 2015"
|
||||
.SH NAME
|
||||
pcap-filter \- packet filter syntax
|
||||
.br
|
||||
@ -298,7 +298,7 @@ of protocol type \fIprotocol\fP.
|
||||
\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP,
|
||||
\fBesp\fP, \fBvrrp\fP, \fBudp\fP, or \fBtcp\fP.
|
||||
Note that the identifiers \fBtcp\fP, \fBudp\fP, and \fBicmp\fP are also
|
||||
keywords and must be escaped via backslash (\\), which is \\\\ in the C-shell.
|
||||
keywords and must be escaped via backslash (\\).
|
||||
Note that this primitive does not chase the protocol header chain.
|
||||
.IP "\fBip6 proto \fIprotocol\fR"
|
||||
True if the packet is an IPv6 packet of protocol type \fIprotocol\fP.
|
||||
@ -372,9 +372,9 @@ True if the packet is of ether type \fIprotocol\fR.
|
||||
Note these identifiers are also keywords
|
||||
and must be escaped via backslash (\\).
|
||||
.IP
|
||||
[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), Token Ring
|
||||
(e.g., `\fBtr protocol arp\fR'), and IEEE 802.11 wireless LANS (e.g.,
|
||||
`\fBwlan protocol arp\fR'), for most of those protocols, the
|
||||
[In the case of FDDI (e.g., `\fBfddi proto arp\fR'), Token Ring
|
||||
(e.g., `\fBtr proto arp\fR'), and IEEE 802.11 wireless LANS (e.g.,
|
||||
`\fBwlan proto arp\fR'), for most of those protocols, the
|
||||
protocol identification comes from the 802.2 Logical Link Control (LLC)
|
||||
header, which is usually layered on top of the FDDI, Token Ring, or
|
||||
802.11 header.
|
||||
@ -697,7 +697,7 @@ changes the decoding offsets for the remainder of \fIexpression\fR on
|
||||
the assumption that the packet is a MPLS-encapsulated IP packet. The
|
||||
\fBmpls \fI[label_num]\fR expression may be used more than once, to
|
||||
filter on MPLS hierarchies. Each use of that expression increments the
|
||||
filter offsets by 4.
|
||||
filter offsets by 4.
|
||||
.IP
|
||||
For example:
|
||||
.in +.5i
|
||||
@ -733,6 +733,22 @@ For example:
|
||||
.fi
|
||||
.in -.5i
|
||||
filters IPv4 protocols encapsulated in PPPoE session id 0x27.
|
||||
.IP "\fBgeneve \fI[vni]\fR"
|
||||
True if the packet is a Geneve packet (UDP port 6081). If \fI[vni]\fR
|
||||
is specified, only true if the packet has the specified \fIvni\fR.
|
||||
Note that when the \fBgeneve\fR keyword is encountered in
|
||||
\fIexpression\fR, it changes the decoding offsets for the remainder of
|
||||
\fIexpression\fR on the assumption that the packet is a Geneve packet.
|
||||
.IP
|
||||
For example:
|
||||
.in +.5i
|
||||
.nf
|
||||
\fBgeneve 0xb && ip\fR
|
||||
.fi
|
||||
.in -.5i
|
||||
filters IPv4 protocols encapsulated in Geneve with VNI 0xb. This will
|
||||
match both IP directly encapsulated in Geneve as well as IP contained
|
||||
inside an Ethernet frame.
|
||||
.IP "\fBiso proto \fIprotocol\fR"
|
||||
True if the packet is an OSI packet of protocol type \fIprotocol\fP.
|
||||
\fIProtocol\fP can be a number or one of the names
|
||||
@ -864,8 +880,7 @@ The following TCP flags field values are available: \fBtcp-fin\fP,
|
||||
.LP
|
||||
Primitives may be combined using:
|
||||
.IP
|
||||
A parenthesized group of primitives and operators
|
||||
(parentheses are special to the Shell and must be escaped).
|
||||
A parenthesized group of primitives and operators.
|
||||
.IP
|
||||
Negation (`\fB!\fP' or `\fBnot\fP').
|
||||
.IP
|
||||
|
@ -40,14 +40,16 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Packet32.h>
|
||||
extern CRITICAL_SECTION g_PcapCompileCriticalSection;
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef MSDOS
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
* Make sure Packet32.h doesn't define BPF structures that we've
|
||||
* probably already defined as a result of including <pcap/pcap.h>.
|
||||
*/
|
||||
#define BPF_MAJOR_VERSION
|
||||
#include <Packet32.h>
|
||||
#elif defined(MSDOS)
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/
|
||||
@ -106,9 +108,9 @@ extern CRITICAL_SECTION g_PcapCompileCriticalSection;
|
||||
#define MAXIMUM_SNAPLEN 262144
|
||||
|
||||
struct pcap_opt {
|
||||
char *source;
|
||||
char *device;
|
||||
int timeout; /* timeout for buffering */
|
||||
int buffer_size;
|
||||
u_int buffer_size;
|
||||
int promisc;
|
||||
int rfmon; /* monitor mode */
|
||||
int immediate; /* immediate mode - deliver packets as soon as they arrive */
|
||||
@ -126,11 +128,19 @@ typedef int (*set_datalink_op_t)(pcap_t *, int);
|
||||
typedef int (*getnonblock_op_t)(pcap_t *, char *);
|
||||
typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
|
||||
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
typedef struct pcap_stat *(*stats_ex_op_t)(pcap_t *, int *);
|
||||
typedef int (*setbuff_op_t)(pcap_t *, int);
|
||||
typedef int (*setmode_op_t)(pcap_t *, int);
|
||||
typedef int (*setmintocopy_op_t)(pcap_t *, int);
|
||||
typedef Adapter *(*getadapter_op_t)(pcap_t *);
|
||||
typedef HANDLE (*getevent_op_t)(pcap_t *);
|
||||
typedef int (*oid_get_request_op_t)(pcap_t *, bpf_u_int32, void *, size_t *);
|
||||
typedef int (*oid_set_request_op_t)(pcap_t *, bpf_u_int32, const void *, size_t *);
|
||||
typedef u_int (*sendqueue_transmit_op_t)(pcap_t *, pcap_send_queue *, int);
|
||||
typedef int (*setuserbuffer_op_t)(pcap_t *, int);
|
||||
typedef int (*live_dump_op_t)(pcap_t *, char *, int, int);
|
||||
typedef int (*live_dump_ended_op_t)(pcap_t *, int);
|
||||
typedef PAirpcapHandle (*get_airpcap_handle_op_t)(pcap_t *);
|
||||
#endif
|
||||
typedef void (*cleanup_op_t)(pcap_t *);
|
||||
|
||||
@ -145,24 +155,22 @@ struct pcap {
|
||||
read_op_t read_op;
|
||||
|
||||
/*
|
||||
* Method to call to read to read packets from a savefile.
|
||||
* Method to call to read packets from a savefile.
|
||||
*/
|
||||
int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
ADAPTER *adapter;
|
||||
LPPACKET Packet;
|
||||
int nonblock;
|
||||
#else
|
||||
int fd;
|
||||
int selectable_fd;
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
* Read buffer.
|
||||
*/
|
||||
int bufsize;
|
||||
u_char *buffer;
|
||||
u_int bufsize;
|
||||
void *buffer;
|
||||
u_char *bp;
|
||||
int cc;
|
||||
|
||||
@ -172,7 +180,7 @@ struct pcap {
|
||||
|
||||
int swapped;
|
||||
FILE *rfile; /* null if live capture, non-null if savefile */
|
||||
int fddipad;
|
||||
u_int fddipad;
|
||||
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
|
||||
|
||||
/*
|
||||
@ -199,9 +207,18 @@ struct pcap {
|
||||
*/
|
||||
u_char *pkt;
|
||||
|
||||
#ifdef _WIN32
|
||||
struct pcap_stat stat; /* used for pcap_stats_ex() */
|
||||
#endif
|
||||
|
||||
/* We're accepting only packets in this direction/these directions. */
|
||||
pcap_direction_t direction;
|
||||
|
||||
/*
|
||||
* Flags to affect BPF code generation.
|
||||
*/
|
||||
int bpf_codegen_flags;
|
||||
|
||||
/*
|
||||
* Placeholder for filter code if bpf not in kernel.
|
||||
*/
|
||||
@ -235,19 +252,32 @@ struct pcap {
|
||||
*/
|
||||
pcap_handler oneshot_callback;
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* These are, at least currently, specific to the Win32 NPF
|
||||
* driver.
|
||||
*/
|
||||
stats_ex_op_t stats_ex_op;
|
||||
setbuff_op_t setbuff_op;
|
||||
setmode_op_t setmode_op;
|
||||
setmintocopy_op_t setmintocopy_op;
|
||||
getadapter_op_t getadapter_op;
|
||||
getevent_op_t getevent_op;
|
||||
oid_get_request_op_t oid_get_request_op;
|
||||
oid_set_request_op_t oid_set_request_op;
|
||||
sendqueue_transmit_op_t sendqueue_transmit_op;
|
||||
setuserbuffer_op_t setuserbuffer_op;
|
||||
live_dump_op_t live_dump_op;
|
||||
live_dump_ended_op_t live_dump_ended_op;
|
||||
get_airpcap_handle_op_t get_airpcap_handle_op;
|
||||
#endif
|
||||
cleanup_op_t cleanup_op;
|
||||
};
|
||||
|
||||
/*
|
||||
* BPF code generation flags.
|
||||
*/
|
||||
#define BPF_SPECIAL_VLAN_HANDLING 0x00000001 /* special VLAN handling for Linux */
|
||||
|
||||
/*
|
||||
* This is a timeval as stored in a savefile.
|
||||
* It has to use the same types everywhere, independent of the actual
|
||||
@ -328,34 +358,15 @@ struct oneshot_userdata {
|
||||
pcap_t *pd;
|
||||
};
|
||||
|
||||
int yylex(void);
|
||||
|
||||
#ifndef min
|
||||
#define min(a, b) ((a) > (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
/* XXX should these be in pcap.h? */
|
||||
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
|
||||
int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
#define strlcpy(x, y, z) \
|
||||
(strncpy((x), (y), (z)), \
|
||||
((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \
|
||||
strlen((y)))
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined(HAVE_SNPRINTF)
|
||||
#define snprintf pcap_snprintf
|
||||
extern int snprintf (char *, size_t, const char *, ...);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_VSNPRINTF)
|
||||
#define vsnprintf pcap_vsnprintf
|
||||
extern int vsnprintf (char *, size_t, const char *, va_list ap);
|
||||
#endif
|
||||
#include "portability.h"
|
||||
|
||||
/*
|
||||
* Does the packet count argument to a module's read routine say
|
||||
@ -366,7 +377,7 @@ extern int vsnprintf (char *, size_t, const char *, va_list ap);
|
||||
/*
|
||||
* Routines that most pcap implementations can use for non-blocking mode.
|
||||
*/
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
#if !defined(_WIN32) && !defined(MSDOS)
|
||||
int pcap_getnonblock_fd(pcap_t *, char *);
|
||||
int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
||||
#endif
|
||||
@ -383,38 +394,43 @@ int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
||||
* by pcap_create routines.
|
||||
*/
|
||||
pcap_t *pcap_create_interface(const char *, char *);
|
||||
pcap_t *pcap_create_common(const char *, char *, size_t);
|
||||
pcap_t *pcap_create_common(char *, size_t);
|
||||
int pcap_do_addexit(pcap_t *);
|
||||
void pcap_add_to_pcaps_to_close(pcap_t *);
|
||||
void pcap_remove_from_pcaps_to_close(pcap_t *);
|
||||
void pcap_cleanup_live_common(pcap_t *);
|
||||
int pcap_not_initialized(pcap_t *);
|
||||
int pcap_check_activated(pcap_t *);
|
||||
|
||||
/*
|
||||
* Internal interfaces for "pcap_findalldevs()".
|
||||
*
|
||||
* "pcap_findalldevs_interfaces()" finds interfaces using the
|
||||
* "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
|
||||
*
|
||||
* "pcap_platform_finddevs()" is a platform-dependent routine to
|
||||
* add devices not found by the "standard" mechanisms.
|
||||
* find local network interfaces.
|
||||
*
|
||||
* "pcap_findalldevs_interfaces()" is a helper to find those interfaces
|
||||
* using the "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
|
||||
*
|
||||
* "pcap_add_if()" adds an interface to the list of interfaces, for
|
||||
* use by various "find interfaces" routines.
|
||||
*/
|
||||
int pcap_findalldevs_interfaces(pcap_if_t **, char *);
|
||||
int pcap_platform_finddevs(pcap_if_t **, char *);
|
||||
int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *,
|
||||
size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
|
||||
struct sockaddr *, size_t, char *);
|
||||
#if !defined(_WIN32) && !defined(MSDOS)
|
||||
int pcap_findalldevs_interfaces(pcap_if_t **, char *,
|
||||
int (*)(const char *));
|
||||
#endif
|
||||
int add_addr_to_iflist(pcap_if_t **, const char *, bpf_u_int32,
|
||||
struct sockaddr *, size_t, struct sockaddr *, size_t,
|
||||
struct sockaddr *, size_t, struct sockaddr *, size_t, char *);
|
||||
int add_addr_to_dev(pcap_if_t *, struct sockaddr *, size_t,
|
||||
struct sockaddr *, size_t, struct sockaddr *, size_t,
|
||||
struct sockaddr *dstaddr, size_t, char *errbuf);
|
||||
int pcap_add_if(pcap_if_t **, const char *, u_int, const char *, char *);
|
||||
struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
|
||||
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
|
||||
int pcap_add_if(pcap_if_t **, const char *, bpf_u_int32, const char *,
|
||||
char *);
|
||||
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, bpf_u_int32,
|
||||
const char *, char *);
|
||||
#ifndef _WIN32
|
||||
bpf_u_int32 if_flags_to_pcap_flags(const char *, u_int);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internal interfaces for "pcap_open_offline()".
|
||||
@ -438,8 +454,8 @@ void sf_cleanup(pcap_t *p);
|
||||
*/
|
||||
void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
|
||||
#ifdef WIN32
|
||||
char *pcap_win32strerror(void);
|
||||
#ifdef _WIN32
|
||||
void pcap_win32_err_to_str(DWORD, char *);
|
||||
#endif
|
||||
|
||||
int install_bpf_program(pcap_t *, struct bpf_program *);
|
||||
|
@ -106,7 +106,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||
* dlpi_open() will not fail if the underlying link does not support
|
||||
* passive mode. See dlpi(7P) for details.
|
||||
*/
|
||||
retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
|
||||
retv = dlpi_open(p->opt.device, &dh, DLPI_RAW|DLPI_PASSIVE);
|
||||
if (retv != DLPI_SUCCESS) {
|
||||
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
|
||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
@ -115,7 +115,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
status = PCAP_ERROR;
|
||||
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
|
||||
pcap_libdlpi_err(p->opt.device, "dlpi_open", retv,
|
||||
p->errbuf);
|
||||
return (status);
|
||||
}
|
||||
@ -133,7 +133,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||
/* Bind with DLPI_ANY_SAP. */
|
||||
if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
|
||||
status = PCAP_ERROR;
|
||||
pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
|
||||
pcap_libdlpi_err(p->opt.device, "dlpi_bind", retv, p->errbuf);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||
/* Determine link type. */
|
||||
if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
|
||||
status = PCAP_ERROR;
|
||||
pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
|
||||
pcap_libdlpi_err(p->opt.device, "dlpi_info", retv, p->errbuf);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||
*/
|
||||
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
||||
status = PCAP_ERROR;
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -258,13 +258,24 @@ dlpromiscon(pcap_t *p, bpf_u_int32 level)
|
||||
err = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
err = PCAP_ERROR;
|
||||
pcap_libdlpi_err(p->opt.source, "dlpi_promiscon" STRINGIFY(level),
|
||||
pcap_libdlpi_err(p->opt.device, "dlpi_promiscon" STRINGIFY(level),
|
||||
retv, p->errbuf);
|
||||
return (err);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Presumably everything returned by dlpi_walk() is a DLPI device,
|
||||
* so there's no work to be done here to check whether name refers
|
||||
* to a DLPI device.
|
||||
*/
|
||||
static int
|
||||
is_dlpi_interface(const char *name _U_)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
|
||||
* network links that are plumbed and are up. dlpi_walk(3DLPI) will find
|
||||
@ -279,12 +290,18 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
linkwalk_t lw = {NULL, 0};
|
||||
int save_errno;
|
||||
|
||||
/*
|
||||
* Get the list of regular interfaces first.
|
||||
*/
|
||||
if (pcap_findalldevs_interfaces(alldevsp, errbuf, is_dlpi_interface) == -1)
|
||||
return (-1); /* failure */
|
||||
|
||||
/* dlpi_walk() for loopback will be added here. */
|
||||
|
||||
dlpi_walk(list_interfaces, &lw, 0);
|
||||
|
||||
if (lw.lw_err != 0) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"dlpi_walk: %s", pcap_strerror(lw.lw_err));
|
||||
retv = -1;
|
||||
goto done;
|
||||
@ -337,7 +354,7 @@ pcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user)
|
||||
}
|
||||
|
||||
msglen = p->bufsize;
|
||||
bufp = p->buffer + p->offset;
|
||||
bufp = (u_char *)p->buffer + p->offset;
|
||||
|
||||
retv = dlpi_recv(pd->dlpi_hd, NULL, NULL, bufp,
|
||||
&msglen, -1, NULL);
|
||||
@ -404,16 +421,16 @@ pcap_cleanup_libdlpi(pcap_t *p)
|
||||
static void
|
||||
pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
|
||||
func, linkname, dlpi_strerror(err));
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *ebuf)
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "12 March 2011"
|
||||
.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "7 April 2014"
|
||||
.SH NAME
|
||||
pcap-linktype \- link-layer header types supported by libpcap
|
||||
.SH DESCRIPTION
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,8 +11,8 @@
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
@ -57,14 +57,14 @@
|
||||
#include <linux/netfilter/nfnetlink_queue.h>
|
||||
|
||||
/* NOTE: if your program drops privilages after pcap_activate() it WON'T work with nfqueue.
|
||||
* It took me quite some time to debug ;/
|
||||
* It took me quite some time to debug ;/
|
||||
*
|
||||
* Sending any data to nfnetlink socket requires CAP_NET_ADMIN privilages,
|
||||
* and in nfqueue we need to send verdict reply after recving packet.
|
||||
*
|
||||
* In tcpdump you can disable dropping privilages with -Z root
|
||||
*/
|
||||
|
||||
|
||||
#include "pcap-netfilter-linux.h"
|
||||
|
||||
#define HDR_LENGTH (NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg))))
|
||||
@ -79,10 +79,12 @@ typedef enum { OTHER = -1, NFLOG, NFQUEUE } nftype_t;
|
||||
*/
|
||||
struct pcap_netfilter {
|
||||
u_int packets_read; /* count of packets read with recvfrom() */
|
||||
u_int packets_nobufs; /* ENOBUFS counter */
|
||||
};
|
||||
|
||||
static int nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict);
|
||||
|
||||
|
||||
static int
|
||||
netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
|
||||
{
|
||||
@ -98,28 +100,29 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
|
||||
handle->break_loop = 0;
|
||||
return -2;
|
||||
}
|
||||
} while ((len == -1) && (errno == EINTR));
|
||||
if(errno == ENOBUFS) handlep->packets_nobufs++;
|
||||
} while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
|
||||
|
||||
if (len < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s", errno, pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s", errno, pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = handle->buffer;
|
||||
while (len >= NLMSG_SPACE(0)) {
|
||||
buf = (unsigned char *)handle->buffer;
|
||||
while ((u_int)len >= NLMSG_SPACE(0)) {
|
||||
const struct nlmsghdr *nlh = (const struct nlmsghdr *) buf;
|
||||
u_int32_t msg_len;
|
||||
nftype_t type = OTHER;
|
||||
|
||||
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || len < nlh->nlmsg_len) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len);
|
||||
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || (u_int)len < nlh->nlmsg_len) {
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG &&
|
||||
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET)
|
||||
if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG &&
|
||||
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET)
|
||||
type = NFLOG;
|
||||
else if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE &&
|
||||
else if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE &&
|
||||
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFQNL_MSG_PACKET)
|
||||
type = NFQUEUE;
|
||||
|
||||
@ -127,14 +130,14 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
|
||||
const unsigned char *payload = NULL;
|
||||
struct pcap_pkthdr pkth;
|
||||
|
||||
const struct nfgenmsg *nfg;
|
||||
const struct nfgenmsg *nfg = NULL;
|
||||
int id = 0;
|
||||
|
||||
if (handle->linktype != DLT_NFLOG) {
|
||||
const struct nfattr *payload_attr = NULL;
|
||||
|
||||
if (nlh->nlmsg_len < HDR_LENGTH) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Malformed message: (nlmsg_len: %u)", nlh->nlmsg_len);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Malformed message: (nlmsg_len: %u)", nlh->nlmsg_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -184,7 +187,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
|
||||
|
||||
gettimeofday(&pkth.ts, NULL);
|
||||
if (handle->fcode.bf_insns == NULL ||
|
||||
bpf_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen))
|
||||
bpf_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen))
|
||||
{
|
||||
handlep->packets_read++;
|
||||
callback(user, &pkth, payload);
|
||||
@ -194,13 +197,16 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
|
||||
|
||||
if (type == NFQUEUE) {
|
||||
/* XXX, possible responses: NF_DROP, NF_ACCEPT, NF_STOLEN, NF_QUEUE, NF_REPEAT, NF_STOP */
|
||||
nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
|
||||
/* if type == NFQUEUE, handle->linktype is always != DLT_NFLOG,
|
||||
so nfg is always initialized to NLMSG_DATA(nlh). */
|
||||
if (nfg != NULL)
|
||||
nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
|
||||
}
|
||||
}
|
||||
|
||||
msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
|
||||
if (msg_len > len)
|
||||
msg_len = len;
|
||||
if (msg_len > (u_int)len)
|
||||
msg_len = (u_int)len;
|
||||
|
||||
len -= msg_len;
|
||||
buf += msg_len;
|
||||
@ -221,7 +227,7 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
struct pcap_netfilter *handlep = handle->priv;
|
||||
|
||||
stats->ps_recv = handlep->packets_read;
|
||||
stats->ps_drop = 0;
|
||||
stats->ps_drop = handlep->packets_nobufs;
|
||||
stats->ps_ifdrop = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -229,9 +235,9 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
static int
|
||||
netfilter_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on netfilter devices");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on netfilter devices");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
struct my_nfattr {
|
||||
u_int16_t nfa_len;
|
||||
@ -249,7 +255,7 @@ netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_i
|
||||
|
||||
struct sockaddr_nl snl;
|
||||
static unsigned int seq_id;
|
||||
|
||||
|
||||
if (!seq_id)
|
||||
seq_id = time(NULL);
|
||||
++seq_id;
|
||||
@ -304,7 +310,7 @@ netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_i
|
||||
if (snl.nl_pid != 0 || seq_id != nlh->nlmsg_seq) /* if not from kernel or wrong sequence skip */
|
||||
continue;
|
||||
|
||||
while (len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, len)) {
|
||||
while ((u_int)len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, len)) {
|
||||
if (nlh->nlmsg_type == NLMSG_ERROR || (nlh->nlmsg_type == NLMSG_DONE && nlh->nlmsg_flags & NLM_F_MULTI)) {
|
||||
if (nlh->nlmsg_len < NLMSG_ALIGN(sizeof(struct nlmsgerr))) {
|
||||
errno = EBADMSG;
|
||||
@ -341,7 +347,7 @@ nflog_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_
|
||||
return nflog_send_config_msg(handle, family, group_id, &nfa);
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
nflog_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
|
||||
{
|
||||
struct nfulnl_msg_config_mode msg;
|
||||
@ -395,7 +401,7 @@ nfqueue_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd,
|
||||
return nfqueue_send_config_msg(handle, AF_UNSPEC, group_id, &nfa);
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
nfqueue_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
|
||||
{
|
||||
struct nfqnl_msg_config_params msg;
|
||||
@ -414,7 +420,7 @@ nfqueue_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy
|
||||
static int
|
||||
netfilter_activate(pcap_t* handle)
|
||||
{
|
||||
const char *dev = handle->opt.source;
|
||||
const char *dev = handle->opt.device;
|
||||
unsigned short groups[32];
|
||||
int group_count = 0;
|
||||
nftype_t type = OTHER;
|
||||
@ -428,7 +434,7 @@ netfilter_activate(pcap_t* handle)
|
||||
dev += strlen(NFQUEUE_IFACE);
|
||||
type = NFQUEUE;
|
||||
}
|
||||
|
||||
|
||||
if (type != OTHER && *dev == ':') {
|
||||
dev++;
|
||||
while (*dev) {
|
||||
@ -436,16 +442,16 @@ netfilter_activate(pcap_t* handle)
|
||||
char *end_dev;
|
||||
|
||||
if (group_count == 32) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Maximum 32 netfilter groups! dev: %s",
|
||||
handle->opt.source);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Maximum 32 netfilter groups! dev: %s",
|
||||
handle->opt.device);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
group_id = strtol(dev, &end_dev, 0);
|
||||
if (end_dev != dev) {
|
||||
if (group_id < 0 || group_id > 65535) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Netfilter group range from 0 to 65535 (got %ld)",
|
||||
group_id);
|
||||
return PCAP_ERROR;
|
||||
@ -461,9 +467,9 @@ netfilter_activate(pcap_t* handle)
|
||||
}
|
||||
|
||||
if (type == OTHER || *dev) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't get netfilter group(s) index from %s",
|
||||
handle->opt.source);
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't get netfilter group(s) index from %s",
|
||||
handle->opt.device);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
@ -488,7 +494,7 @@ netfilter_activate(pcap_t* handle)
|
||||
/* Create netlink socket */
|
||||
handle->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
|
||||
if (handle->fd < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s", errno, pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s", errno, pcap_strerror(errno));
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
@ -506,54 +512,54 @@ netfilter_activate(pcap_t* handle)
|
||||
|
||||
handle->buffer = malloc(handle->bufsize);
|
||||
if (!handle->buffer) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
if (type == NFLOG) {
|
||||
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
/* Bind socket to the nflog groups */
|
||||
for (i = 0; i < group_count; i++) {
|
||||
if (nflog_send_config_cmd(handle, groups[i], NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
if (nflog_send_config_mode(handle, groups[i], NFULNL_COPY_PACKET, handle->snapshot) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_COPY_PACKET: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_COPY_PACKET: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
/* Bind socket to the nfqueue groups */
|
||||
for (i = 0; i < group_count; i++) {
|
||||
if (nfqueue_send_config_cmd(handle, groups[i], NFQNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
|
||||
if (nfqueue_send_config_mode(handle, groups[i], NFQNL_COPY_PACKET, handle->snapshot) < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_COPY_PACKET: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_COPY_PACKET: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
}
|
||||
@ -572,7 +578,7 @@ netfilter_activate(pcap_t* handle)
|
||||
* Set the socket buffer size to the specified value.
|
||||
*/
|
||||
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF, &handle->opt.buffer_size, sizeof(handle->opt.buffer_size)) == -1) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "SO_RCVBUF: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "SO_RCVBUF: %s", pcap_strerror(errno));
|
||||
goto close_fail;
|
||||
}
|
||||
}
|
||||
@ -599,7 +605,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
|
||||
/* Does it begin with NFLOG_IFACE or NFQUEUE_IFACE? */
|
||||
if (strncmp(cp, NFLOG_IFACE, sizeof NFLOG_IFACE - 1) == 0)
|
||||
cp += sizeof NFLOG_IFACE - 1;
|
||||
else if (strncmp(cp, NFQUEUE_IFACE, sizeof NFQUEUE_IFACE - 1) == 0)
|
||||
else if (strncmp(cp, NFQUEUE_IFACE, sizeof NFQUEUE_IFACE - 1) == 0)
|
||||
cp += sizeof NFQUEUE_IFACE - 1;
|
||||
else {
|
||||
/* Nope, doesn't begin with NFLOG_IFACE nor NFQUEUE_IFACE */
|
||||
@ -620,7 +626,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
|
||||
/* OK, it's probably ours. */
|
||||
*is_ours = 1;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_netfilter));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_netfilter));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -628,17 +634,17 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
|
||||
return (p);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||
{
|
||||
int sock;
|
||||
|
||||
|
||||
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
|
||||
if (sock < 0) {
|
||||
/* if netlink is not supported this is not fatal */
|
||||
if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
|
||||
return 0;
|
||||
snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open netlink socket %d:%s",
|
||||
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open netlink socket %d:%s",
|
||||
errno, pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
|
1265
contrib/libpcap/pcap-new.c
Normal file
1265
contrib/libpcap/pcap-new.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -114,11 +114,11 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
if (cc < 0) {
|
||||
if (errno == EWOULDBLOCK)
|
||||
return (0);
|
||||
snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
bp = p->buffer;
|
||||
bp = (u_char *)p->buffer;
|
||||
} else
|
||||
bp = p->bp;
|
||||
|
||||
@ -168,7 +168,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
continue;
|
||||
|
||||
default:
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"bad nit state %d", nh->nh_state);
|
||||
return (-1);
|
||||
}
|
||||
@ -206,12 +206,12 @@ pcap_inject_nit(pcap_t *p, const void *buf, size_t size)
|
||||
strncpy(sa.sa_data, device, sizeof(sa.sa_data));
|
||||
ret = sendto(p->fd, buf, size, 0, &sa, sizeof(sa));
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
nit_setflags(pcap_t *p)
|
||||
@ -249,7 +249,7 @@ nit_setflags(pcap_t *p)
|
||||
nioc.nioc_flags |= NF_PROMISC;
|
||||
|
||||
if (ioctl(p->fd, SIOCSNIT, &nioc) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -280,15 +280,22 @@ pcap_activate_nit(pcap_t *p)
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
|
||||
if (fd < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"socket: %s", pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
snit.snit_family = AF_NIT;
|
||||
(void)strncpy(snit.snit_ifname, p->opt.source, NITIFSIZ);
|
||||
(void)strncpy(snit.snit_ifname, p->opt.device, NITIFSIZ);
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
/*
|
||||
* XXX - there's probably a particular bind error that
|
||||
* means "there's no such device" and a particular bind
|
||||
* error that means "that device doesn't support NIT";
|
||||
* they might be the same error, if they both end up
|
||||
* meaning "NIT doesn't know about that device".
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -301,7 +308,7 @@ pcap_activate_nit(pcap_t *p)
|
||||
p->linktype = DLT_EN10MB;
|
||||
|
||||
p->bufsize = BUFSPACE;
|
||||
p->buffer = (u_char *)malloc(p->bufsize);
|
||||
p->buffer = malloc(p->bufsize);
|
||||
if (p->buffer == NULL) {
|
||||
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||
goto bad;
|
||||
@ -348,11 +355,11 @@ pcap_activate_nit(pcap_t *p)
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *ebuf)
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_nit));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_nit));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -360,8 +367,18 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - there's probably a particular bind error that means "that device
|
||||
* doesn't support NIT"; if so, we should try a bind and use that.
|
||||
*/
|
||||
static int
|
||||
can_be_bound(const char *name _U_)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
return (0);
|
||||
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
static char nosup[] = "live packet capture not supported on this system";
|
||||
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *ebuf)
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
return (NULL);
|
||||
@ -45,5 +45,9 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
/*
|
||||
* There are no interfaces on which we can capture.
|
||||
*/
|
||||
*alldevsp = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
#ifdef LBL_ALIGN
|
||||
struct enstamp stamp;
|
||||
#endif
|
||||
register int pad;
|
||||
register u_int pad;
|
||||
|
||||
again:
|
||||
cc = pc->cc;
|
||||
@ -127,11 +127,11 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
(void)lseek(pc->fd, 0L, SEEK_SET);
|
||||
goto again;
|
||||
}
|
||||
snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
|
||||
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
bp = pc->buffer + pc->offset;
|
||||
bp = (u_char *)pc->buffer + pc->offset;
|
||||
} else
|
||||
bp = pc->bp;
|
||||
/*
|
||||
@ -160,7 +160,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
}
|
||||
}
|
||||
if (cc < sizeof(*sp)) {
|
||||
snprintf(pc->errbuf, sizeof(pc->errbuf),
|
||||
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf),
|
||||
"pf short read (%d)", cc);
|
||||
return (-1);
|
||||
}
|
||||
@ -172,7 +172,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
#endif
|
||||
sp = (struct enstamp *)bp;
|
||||
if (sp->ens_stamplen != sizeof(*sp)) {
|
||||
snprintf(pc->errbuf, sizeof(pc->errbuf),
|
||||
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf),
|
||||
"pf short stamplen (%d)",
|
||||
sp->ens_stamplen);
|
||||
return (-1);
|
||||
@ -232,12 +232,12 @@ pcap_inject_pf(pcap_t *p, const void *buf, size_t size)
|
||||
|
||||
ret = write(p->fd, buf, size);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
|
||||
@ -321,14 +321,17 @@ pcap_activate_pf(pcap_t *p)
|
||||
* its argument, even though it takes a "char *" rather than a
|
||||
* "const char *" as its first argument. That appears to be
|
||||
* the case, at least on Digital UNIX 4.0.
|
||||
*
|
||||
* XXX - is there an error that means "no such device"? Is
|
||||
* there one that means "that device doesn't support pf"?
|
||||
*/
|
||||
p->fd = pfopen(p->opt.source, O_RDWR);
|
||||
p->fd = pfopen(p->opt.device, O_RDWR);
|
||||
if (p->fd == -1 && errno == EACCES)
|
||||
p->fd = pfopen(p->opt.source, O_RDONLY);
|
||||
p->fd = pfopen(p->opt.device, O_RDONLY);
|
||||
if (p->fd < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
|
||||
your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
p->opt.source, pcap_strerror(errno));
|
||||
p->opt.device, pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
pf->OrigMissed = -1;
|
||||
@ -338,7 +341,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
if (p->opt.promisc)
|
||||
enmode |= ENPROMISC;
|
||||
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -349,13 +352,13 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
#endif
|
||||
/* set the backlog */
|
||||
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
/* discover interface type */
|
||||
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -437,7 +440,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
* framing", there's not much we can do, as that
|
||||
* doesn't specify a particular type of header.
|
||||
*/
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"unknown data-link type %u", devparams.end_dev_type);
|
||||
goto bad;
|
||||
}
|
||||
@ -450,7 +453,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
} else
|
||||
p->fddipad = 0;
|
||||
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -459,7 +462,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
Filter.enf_Priority = 37; /* anything > 2 */
|
||||
Filter.enf_FilterLen = 0; /* means "always true" */
|
||||
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -469,14 +472,14 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
timeout.tv_sec = p->opt.timeout / 1000;
|
||||
timeout.tv_usec = (p->opt.timeout * 1000) % 1000000;
|
||||
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
p->bufsize = BUFSPACE;
|
||||
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
|
||||
p->buffer = malloc(p->bufsize + p->offset);
|
||||
if (p->buffer == NULL) {
|
||||
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||
goto bad;
|
||||
@ -503,11 +506,11 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *ebuf)
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_pf));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_pf));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -515,10 +518,20 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - is there an error from pfopen() that means "no such device"?
|
||||
* Is there one that means "that device doesn't support pf"?
|
||||
*/
|
||||
static int
|
||||
can_be_bound(const char *name _U_)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
return (0);
|
||||
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -547,7 +560,7 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
|
||||
* Yes. Try to install the filter.
|
||||
*/
|
||||
if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"BIOCSETF: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
2127
contrib/libpcap/pcap-rpcap.c
Normal file
2127
contrib/libpcap/pcap-rpcap.c
Normal file
File diff suppressed because it is too large
Load Diff
465
contrib/libpcap/pcap-rpcap.h
Normal file
465
contrib/libpcap/pcap-rpcap.h
Normal file
@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 - 2008 CACE Technologies, Davis (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. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
|
||||
* OWNER 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 __PCAP_RPCAP_H__
|
||||
#define __PCAP_RPCAP_H__
|
||||
|
||||
|
||||
#include "pcap.h"
|
||||
#include "sockutils.h" /* Needed for some structures (like SOCKET, sockaddr_in) which are used here */
|
||||
|
||||
|
||||
/*
|
||||
* \file pcap-pcap.h
|
||||
*
|
||||
* This file keeps all the new definitions and typedefs that are exported to the user and
|
||||
* that are needed for the RPCAP protocol.
|
||||
*
|
||||
* \warning All the RPCAP functions that are allowed to return a buffer containing
|
||||
* the error description can return max PCAP_ERRBUF_SIZE characters.
|
||||
* However there is no guarantees that the string will be zero-terminated.
|
||||
* Best practice is to define the errbuf variable as a char of size 'PCAP_ERRBUF_SIZE+1'
|
||||
* and to insert manually the termination char at the end of the buffer. This will
|
||||
* guarantee that no buffer overflows occur even if we use the printf() to show
|
||||
* the error on the screen.
|
||||
*
|
||||
* \warning This file declares some typedefs that MUST be of a specific size.
|
||||
* These definitions (i.e. typedefs) could need to be changed on other platforms than
|
||||
* Intel IA32.
|
||||
*
|
||||
* \warning This file defines some structures that are used to transfer data on the network.
|
||||
* Be careful that you compiler MUST not insert padding into these structures
|
||||
* for better alignment.
|
||||
* These structures have been created in order to be correctly aligned to a 32 bits
|
||||
* boundary, but be careful in any case.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************
|
||||
* *
|
||||
* General definitions / typedefs for the RPCAP protocol *
|
||||
* *
|
||||
*********************************************************/
|
||||
|
||||
/* All the following structures and typedef belongs to the Private Documentation */
|
||||
/*
|
||||
* \addtogroup remote_pri_struct
|
||||
* \{
|
||||
*/
|
||||
|
||||
#define RPCAP_DEFAULT_NETPORT "2002" /* Default port on which the RPCAP daemon is waiting for connections. */
|
||||
/* Default port on which the client workstation is waiting for connections in case of active mode. */
|
||||
#define RPCAP_DEFAULT_NETPORT_ACTIVE "2003"
|
||||
#define RPCAP_DEFAULT_NETADDR "" /* Default network address on which the RPCAP daemon binds to. */
|
||||
#define RPCAP_VERSION 0 /* Present version of the RPCAP protocol (0 = Experimental). */
|
||||
#define RPCAP_TIMEOUT_INIT 90 /* Initial timeout for RPCAP connections (default: 90 sec) */
|
||||
#define RPCAP_TIMEOUT_RUNTIME 180 /* Run-time timeout for RPCAP connections (default: 3 min) */
|
||||
#define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
|
||||
#define RPCAP_SUSPEND_WRONGAUTH 1 /* If the authentication is wrong, stops 1 sec before accepting a new auth message */
|
||||
|
||||
/*
|
||||
* \brief Buffer used by socket functions to send-receive packets.
|
||||
* In case you plan to have messages larger than this value, you have to increase it.
|
||||
*/
|
||||
#define RPCAP_NETBUF_SIZE 64000
|
||||
|
||||
|
||||
/*
|
||||
* \brief Separators used for the host list.
|
||||
*
|
||||
* It is used:
|
||||
* - by the rpcapd daemon, when you types a list of allowed connecting hosts
|
||||
* - by the rpcap in active mode, when the client waits for incoming connections from other hosts
|
||||
*/
|
||||
#define RPCAP_HOSTLIST_SEP " ,;\n\r"
|
||||
|
||||
|
||||
|
||||
|
||||
/* WARNING: These could need to be changed on other platforms */
|
||||
typedef unsigned char uint8; /* Provides an 8-bits unsigned integer */
|
||||
typedef unsigned short uint16; /* Provides a 16-bits unsigned integer */
|
||||
typedef unsigned int uint32; /* Provides a 32-bits unsigned integer */
|
||||
typedef int int32; /* Provides a 32-bits integer */
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* \brief Keeps a list of all the opened connections in the active mode.
|
||||
*
|
||||
* This structure defines a linked list of items that are needed to keep the info required to
|
||||
* manage the active mode.
|
||||
* In other words, when a new connection in active mode starts, this structure is updated so that
|
||||
* it reflects the list of active mode connections currently opened.
|
||||
* This structure is required by findalldevs() and open_remote() to see if they have to open a new
|
||||
* control connection toward the host, or they already have a control connection in place.
|
||||
*/
|
||||
struct activehosts
|
||||
{
|
||||
struct sockaddr_storage host;
|
||||
SOCKET sockctrl;
|
||||
struct activehosts *next;
|
||||
};
|
||||
|
||||
|
||||
/*********************************************************
|
||||
* *
|
||||
* Protocol messages formats *
|
||||
* *
|
||||
*********************************************************/
|
||||
/* WARNING Take care you compiler does not insert padding for better alignments into these structs */
|
||||
|
||||
|
||||
/* Common header for all the RPCAP messages */
|
||||
struct rpcap_header
|
||||
{
|
||||
uint8 ver; /* RPCAP version number */
|
||||
uint8 type; /* RPCAP message type (error, findalldevs, ...) */
|
||||
uint16 value; /* Message-dependent value (not always used) */
|
||||
uint32 plen; /* Length of the payload of this RPCAP message */
|
||||
};
|
||||
|
||||
|
||||
/* Format of the message for the interface description (findalldevs command) */
|
||||
struct rpcap_findalldevs_if
|
||||
{
|
||||
uint16 namelen; /* Length of the interface name */
|
||||
uint16 desclen; /* Length of the interface description */
|
||||
uint32 flags; /* Interface flags */
|
||||
uint16 naddr; /* Number of addresses */
|
||||
uint16 dummy; /* Must be zero */
|
||||
};
|
||||
|
||||
|
||||
/* Format of the message for the address listing (findalldevs command) */
|
||||
struct rpcap_findalldevs_ifaddr
|
||||
{
|
||||
struct sockaddr_storage addr; /* Network address */
|
||||
struct sockaddr_storage netmask; /* Netmask for that address */
|
||||
struct sockaddr_storage broadaddr; /* Broadcast address for that address */
|
||||
struct sockaddr_storage dstaddr; /* P2P destination address for that address */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* \brief Format of the message of the connection opening reply (open command).
|
||||
*
|
||||
* This structure transfers over the network some of the values useful on the client side.
|
||||
*/
|
||||
struct rpcap_openreply
|
||||
{
|
||||
int32 linktype; /* Link type */
|
||||
int32 tzoff; /* Timezone offset */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Format of the message that starts a remote capture (startcap command) */
|
||||
struct rpcap_startcapreq
|
||||
{
|
||||
uint32 snaplen; /* Length of the snapshot (number of bytes to capture for each packet) */
|
||||
uint32 read_timeout; /* Read timeout in milliseconds */
|
||||
uint16 flags; /* Flags (see RPCAP_STARTCAPREQ_FLAG_xxx) */
|
||||
uint16 portdata; /* Network port on which the client is waiting at (if 'serveropen') */
|
||||
};
|
||||
|
||||
|
||||
/* Format of the reply message that devoted to start a remote capture (startcap reply command) */
|
||||
struct rpcap_startcapreply
|
||||
{
|
||||
int32 bufsize; /* Size of the user buffer allocated by WinPcap; it can be different from the one we chose */
|
||||
uint16 portdata; /* Network port on which the server is waiting at (passive mode only) */
|
||||
uint16 dummy; /* Must be zero */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* \brief Format of the header which encapsulates captured packets when transmitted on the network.
|
||||
*
|
||||
* This message requires the general header as well, since we want to be able to exchange
|
||||
* more information across the network in the future (for example statistics, and kind like that).
|
||||
*/
|
||||
struct rpcap_pkthdr
|
||||
{
|
||||
uint32 timestamp_sec; /* 'struct timeval' compatible, it represents the 'tv_sec' field */
|
||||
uint32 timestamp_usec; /* 'struct timeval' compatible, it represents the 'tv_usec' field */
|
||||
uint32 caplen; /* Length of portion present in the capture */
|
||||
uint32 len; /* Real length this packet (off wire) */
|
||||
uint32 npkt; /* Ordinal number of the packet (i.e. the first one captured has '1', the second one '2', etc) */
|
||||
};
|
||||
|
||||
|
||||
/* General header used for the pcap_setfilter() command; keeps just the number of BPF instructions */
|
||||
struct rpcap_filter
|
||||
{
|
||||
uint16 filtertype; /* type of the filter transferred (BPF instructions, ...) */
|
||||
uint16 dummy; /* Must be zero */
|
||||
uint32 nitems; /* Number of items contained into the filter (e.g. BPF instructions for BPF filters) */
|
||||
};
|
||||
|
||||
|
||||
/* Structure that keeps a single BPF instuction; it is repeated 'ninsn' times according to the 'rpcap_filterbpf' header */
|
||||
struct rpcap_filterbpf_insn
|
||||
{
|
||||
uint16 code; /* opcode of the instruction */
|
||||
uint8 jt; /* relative offset to jump to in case of 'true' */
|
||||
uint8 jf; /* relative offset to jump to in case of 'false' */
|
||||
int32 k; /* instruction-dependent value */
|
||||
};
|
||||
|
||||
|
||||
/* Structure that keeps the data required for the authentication on the remote host */
|
||||
struct rpcap_auth
|
||||
{
|
||||
uint16 type; /* Authentication type */
|
||||
uint16 dummy; /* Must be zero */
|
||||
uint16 slen1; /* Length of the first authentication item (e.g. username) */
|
||||
uint16 slen2; /* Length of the second authentication item (e.g. password) */
|
||||
};
|
||||
|
||||
|
||||
/* Structure that keeps the statistics about the number of packets captured, dropped, etc. */
|
||||
struct rpcap_stats
|
||||
{
|
||||
uint32 ifrecv; /* Packets received by the kernel filter (i.e. pcap_stats.ps_recv) */
|
||||
uint32 ifdrop; /* Packets dropped by the network interface (e.g. not enough buffers) (i.e. pcap_stats.ps_ifdrop) */
|
||||
uint32 krnldrop; /* Packets dropped by the kernel filter (i.e. pcap_stats.ps_drop) */
|
||||
uint32 svrcapt; /* Packets captured by the RPCAP daemon and sent on the network */
|
||||
};
|
||||
|
||||
|
||||
/* Structure that is needed to set sampling parameters */
|
||||
struct rpcap_sampling
|
||||
{
|
||||
uint8 method; /* Sampling method */
|
||||
uint8 dummy1; /* Must be zero */
|
||||
uint16 dummy2; /* Must be zero */
|
||||
uint32 value; /* Parameter related to the sampling method */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Private data for doing a live capture.
|
||||
*/
|
||||
struct pcap_md {
|
||||
struct pcap_stat stat;
|
||||
/* XXX */
|
||||
int use_bpf; /* using kernel filter */
|
||||
u_long TotPkts; /* can't overflow for 79 hrs on ether */
|
||||
u_long TotAccepted; /* count accepted by filter */
|
||||
u_long TotDrops; /* count of dropped packets */
|
||||
long TotMissed; /* missed by i/f during this run */
|
||||
long OrigMissed; /* missed by i/f before this run */
|
||||
char *device; /* device name */
|
||||
int timeout; /* timeout for buffering */
|
||||
int must_clear; /* stuff we must clear when we close */
|
||||
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
|
||||
#ifdef linux
|
||||
int sock_packet; /* using Linux 2.0 compatible interface */
|
||||
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
|
||||
int ifindex; /* interface index of device we're bound to */
|
||||
int lo_ifindex; /* interface index of the loopback device */
|
||||
u_int packets_read; /* count of packets read with recvfrom() */
|
||||
bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
|
||||
u_int tp_version; /* version of tpacket_hdr for mmaped ring */
|
||||
u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */
|
||||
#endif /* linux */
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
u_char *dag_mem_bottom;/* DAG card current memory bottom pointer */
|
||||
u_char *dag_mem_top; /* DAG card current memory top pointer */
|
||||
#else /* HAVE_DAG_STREAMS_API */
|
||||
void *dag_mem_base; /* DAG card memory base address */
|
||||
u_int dag_mem_bottom; /* DAG card current memory bottom offset */
|
||||
u_int dag_mem_top; /* DAG card current memory top offset */
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
int dag_fcs_bits; /* Number of checksum bits from link layer */
|
||||
int dag_offset_flags; /* Flags to pass to dag_offset(). */
|
||||
int dag_stream; /* DAG stream number */
|
||||
int dag_timeout; /* timeout specified to pcap_open_live.
|
||||
* Same as in linux above, introduce
|
||||
* generally?
|
||||
*/
|
||||
#endif /* HAVE_DAG_API */
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
/*
|
||||
* Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will
|
||||
* alternative between these two actual mmap'd buffers as required.
|
||||
* As there is a header on the front size of the mmap'd buffer, only
|
||||
* some of the buffer is exposed to libpcap as a whole via bufsize;
|
||||
* zbufsize is the true size. zbuffer tracks the current zbuf
|
||||
* associated with buffer so that it can be used to decide which the
|
||||
* next buffer to read will be.
|
||||
*/
|
||||
u_char *zbuf1, *zbuf2, *zbuffer;
|
||||
u_int zbufsize;
|
||||
u_int zerocopy;
|
||||
u_int interrupted;
|
||||
struct timespec firstsel;
|
||||
/*
|
||||
* If there's currently a buffer being actively processed, then it is
|
||||
* referenced here; 'buffer' is also pointed at it, but offset by the
|
||||
* size of the header.
|
||||
*/
|
||||
struct bpf_zbuf_header *bzh;
|
||||
#endif /* HAVE_ZEROCOPY_BPF */
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_REMOTE
|
||||
/*
|
||||
* There is really a mess with previous variables, and it seems to me that they are not used
|
||||
* (they are used in pcap_pf.c only). I think we have to start using them.
|
||||
* The meaning is the following:
|
||||
*
|
||||
* - TotPkts: the amount of packets received by the bpf filter, *before* applying the filter
|
||||
* - TotAccepted: the amount of packets that satisfies the filter
|
||||
* - TotDrops: the amount of packet that were dropped into the kernel buffer because of lack of space
|
||||
* - TotMissed: the amount of packets that were dropped by the physical interface; it is basically
|
||||
* the value of the hardware counter into the card. This number is never put to zero, so this number
|
||||
* takes into account the *total* number of interface drops starting from the interface power-on.
|
||||
* - OrigMissed: the amount of packets that were dropped by the interface *when the capture begins*.
|
||||
* This value is used to detect the number of packets dropped by the interface *during the present
|
||||
* capture*, so that (ps_ifdrops= TotMissed - OrigMissed).
|
||||
*/
|
||||
unsigned int TotNetDrops; /* keeps the number of packets that have been dropped by the network */
|
||||
/*
|
||||
* \brief It keeps the number of packets that have been received by the application.
|
||||
*
|
||||
* Packets dropped by the kernel buffer are not counted in this variable. The variable is always
|
||||
* equal to (TotAccepted - TotDrops), except for the case of remote capture, in which we have also
|
||||
* packets in flight, i.e. that have been transmitted by the remote host, but that have not been
|
||||
* received (yet) from the client. In this case, (TotAccepted - TotDrops - TotNetDrops) gives a
|
||||
* wrong result, since this number does not corresponds always to the number of packet received by
|
||||
* the application. For this reason, in the remote capture we need another variable that takes
|
||||
* into account of the number of packets actually received by the application.
|
||||
*/
|
||||
unsigned int TotCapt;
|
||||
|
||||
/*! \brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if
|
||||
they have to use the socket or they have to open the local adapter. */
|
||||
int rmt_clientside;
|
||||
|
||||
SOCKET rmt_sockctrl; //!< socket ID of the socket used for the control connection
|
||||
SOCKET rmt_sockdata; //!< socket ID of the socket used for the data connection
|
||||
int rmt_flags; //!< we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture()
|
||||
int rmt_capstarted; //!< 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture()
|
||||
struct pcap_samp rmt_samp; //!< Keeps the parameters related to the sampling process.
|
||||
char *currentfilter; //!< Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on.
|
||||
#endif /* HAVE_REMOTE */
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* Messages field coding */
|
||||
#define RPCAP_MSG_ERROR 1 /* Message that keeps an error notification */
|
||||
#define RPCAP_MSG_FINDALLIF_REQ 2 /* Request to list all the remote interfaces */
|
||||
#define RPCAP_MSG_OPEN_REQ 3 /* Request to open a remote device */
|
||||
#define RPCAP_MSG_STARTCAP_REQ 4 /* Request to start a capture on a remote device */
|
||||
#define RPCAP_MSG_UPDATEFILTER_REQ 5 /* Send a compiled filter into the remote device */
|
||||
#define RPCAP_MSG_CLOSE 6 /* Close the connection with the remote peer */
|
||||
#define RPCAP_MSG_PACKET 7 /* This is a 'data' message, which carries a network packet */
|
||||
#define RPCAP_MSG_AUTH_REQ 8 /* Message that keeps the authentication parameters */
|
||||
#define RPCAP_MSG_STATS_REQ 9 /* It requires to have network statistics */
|
||||
#define RPCAP_MSG_ENDCAP_REQ 10 /* Stops the current capture, keeping the device open */
|
||||
#define RPCAP_MSG_SETSAMPLING_REQ 11 /* Set sampling parameters */
|
||||
|
||||
#define RPCAP_MSG_FINDALLIF_REPLY (128+RPCAP_MSG_FINDALLIF_REQ) /* Keeps the list of all the remote interfaces */
|
||||
#define RPCAP_MSG_OPEN_REPLY (128+RPCAP_MSG_OPEN_REQ) /* The remote device has been opened correctly */
|
||||
#define RPCAP_MSG_STARTCAP_REPLY (128+RPCAP_MSG_STARTCAP_REQ) /* The capture is starting correctly */
|
||||
#define RPCAP_MSG_UPDATEFILTER_REPLY (128+RPCAP_MSG_UPDATEFILTER_REQ) /* The filter has been applied correctly on the remote device */
|
||||
#define RPCAP_MSG_AUTH_REPLY (128+RPCAP_MSG_AUTH_REQ) /* Sends a message that says 'ok, authorization successful' */
|
||||
#define RPCAP_MSG_STATS_REPLY (128+RPCAP_MSG_STATS_REQ) /* Message that keeps the network statistics */
|
||||
#define RPCAP_MSG_ENDCAP_REPLY (128+RPCAP_MSG_ENDCAP_REQ) /* Confirms that the capture stopped successfully */
|
||||
#define RPCAP_MSG_SETSAMPLING_REPLY (128+RPCAP_MSG_SETSAMPLING_REQ) /* Confirms that the capture stopped successfully */
|
||||
|
||||
#define RPCAP_STARTCAPREQ_FLAG_PROMISC 1 /* Enables promiscuous mode (default: disabled) */
|
||||
#define RPCAP_STARTCAPREQ_FLAG_DGRAM 2 /* Use a datagram (i.e. UDP) connection for the data stream (default: use TCP)*/
|
||||
#define RPCAP_STARTCAPREQ_FLAG_SERVEROPEN 4 /* The server has to open the data connection toward the client */
|
||||
#define RPCAP_STARTCAPREQ_FLAG_INBOUND 8 /* Capture only inbound packets (take care: the flag has no effects with promiscuous enabled) */
|
||||
#define RPCAP_STARTCAPREQ_FLAG_OUTBOUND 16 /* Capture only outbound packets (take care: the flag has no effects with promiscuous enabled) */
|
||||
|
||||
#define RPCAP_UPDATEFILTER_BPF 1 /* This code tells us that the filter is encoded with the BPF/NPF syntax */
|
||||
|
||||
|
||||
/* Network error codes */
|
||||
#define PCAP_ERR_NETW 1 /* Network error */
|
||||
#define PCAP_ERR_INITTIMEOUT 2 /* The RPCAP initial timeout has expired */
|
||||
#define PCAP_ERR_AUTH 3 /* Generic authentication error */
|
||||
#define PCAP_ERR_FINDALLIF 4 /* Generic findalldevs error */
|
||||
#define PCAP_ERR_NOREMOTEIF 5 /* The findalldevs was ok, but the remote end had no interfaces to list */
|
||||
#define PCAP_ERR_OPEN 6 /* Generic pcap_open error */
|
||||
#define PCAP_ERR_UPDATEFILTER 7 /* Generic updatefilter error */
|
||||
#define PCAP_ERR_GETSTATS 8 /* Generic pcap_stats error */
|
||||
#define PCAP_ERR_READEX 9 /* Generic pcap_next_ex error */
|
||||
#define PCAP_ERR_HOSTNOAUTH 10 /* The host is not authorized to connect to this server */
|
||||
#define PCAP_ERR_REMOTEACCEPT 11 /* Generic pcap_remoteaccept error */
|
||||
#define PCAP_ERR_STARTCAPTURE 12 /* Generic pcap_startcapture error */
|
||||
#define PCAP_ERR_ENDCAPTURE 13 /* Generic pcap_endcapture error */
|
||||
#define PCAP_ERR_RUNTIMETIMEOUT 14 /* The RPCAP run-time timeout has expired */
|
||||
#define PCAP_ERR_SETSAMPLING 15 /* Error during the settings of sampling parameters */
|
||||
#define PCAP_ERR_WRONGMSG 16 /* The other end endpoint sent a message which has not been recognized */
|
||||
#define PCAP_ERR_WRONGVER 17 /* The other end endpoint has a version number that is not compatible with our */
|
||||
/*
|
||||
* \}
|
||||
* // end of private documentation
|
||||
*/
|
||||
|
||||
|
||||
/*********************************************************
|
||||
* *
|
||||
* Exported function prototypes *
|
||||
* *
|
||||
*********************************************************/
|
||||
int pcap_opensource_remote(pcap_t *p, struct pcap_rmtauth *auth);
|
||||
int pcap_startcapture_remote(pcap_t *fp);
|
||||
|
||||
void rpcap_createhdr(struct rpcap_header *header, uint8 type, uint16 value, uint32 length);
|
||||
int rpcap_deseraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage **sockaddrout, char *errbuf);
|
||||
int rpcap_checkmsg(char *errbuf, SOCKET sock, struct rpcap_header *header, uint8 first, ...);
|
||||
int rpcap_senderror(SOCKET sock, char *error, unsigned short errcode, char *errbuf);
|
||||
int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf);
|
||||
|
||||
SOCKET rpcap_remoteact_getsock(const char *host, int *isactive, char *errbuf);
|
||||
|
||||
#endif
|
||||
|
@ -17,12 +17,12 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "29 July 2013"
|
||||
.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "8 March 2015"
|
||||
.SH NAME
|
||||
pcap-savefile \- libpcap savefile format
|
||||
.SH DESCRIPTION
|
||||
NOTE: applications and libraries should, if possible, use libpcap to
|
||||
read savefiles, rather than having their own code to read savefiles.
|
||||
read savefiles, rather than having their own code to read savefiles.
|
||||
If, in the future, a new file format is supported by libpcap,
|
||||
applications and libraries using libpcap to read savefiles will be able
|
||||
to read the new format of savefiles, but applications and libraries
|
||||
|
@ -194,9 +194,9 @@ septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
* See also pcap(3).
|
||||
*/
|
||||
static pcap_t *septel_activate(pcap_t* handle) {
|
||||
/* Initialize some components of the pcap structure. */
|
||||
/* Initialize some components of the pcap structure. */
|
||||
handle->linktype = DLT_MTP2;
|
||||
|
||||
|
||||
handle->bufsize = 0;
|
||||
|
||||
/*
|
||||
@ -232,7 +232,7 @@ pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
|
||||
/* OK, it's probably ours. */
|
||||
*is_ours = 1;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_septel));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_septel));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -244,9 +244,9 @@ static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||
struct pcap_septel *handlep = p->priv;
|
||||
/*handlep->stat.ps_recv = 0;*/
|
||||
/*handlep->stat.ps_drop = 0;*/
|
||||
|
||||
|
||||
*ps = handlep->stat;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -276,7 +276,7 @@ static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
|
||||
/* Make our private copy of the filter */
|
||||
|
||||
if (install_bpf_program(p, fp) < 0) {
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@ -291,3 +291,31 @@ septel_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
fprintf(errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifdef SEPTEL_ONLY
|
||||
/*
|
||||
* This libpcap build supports only Septel cards, not regular network
|
||||
* interfaces.
|
||||
*/
|
||||
|
||||
/*
|
||||
* There are no regular interfaces, just Septel interfaces.
|
||||
*/
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
*alldevsp = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempts to open a regular interface fail.
|
||||
*/
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *errbuf)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"This version of libpcap only supports Septel cards");
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
|
@ -183,7 +183,7 @@ static int read_client_nbytes(int fd, int count, unsigned char *buf) {
|
||||
find_unit_by_fd(fd, &chassis, &geoslot, &u);
|
||||
while (count) {
|
||||
if ((len = recv(fd, buf, count, 0)) <= 0) return -1; /* read in whatever data was sent to us */
|
||||
count -= len;
|
||||
count -= len;
|
||||
buf += len;
|
||||
} /* till we have everything we are looking for */
|
||||
return 0;
|
||||
@ -208,10 +208,14 @@ static void empty_unit(int chassis, int geoslot) {
|
||||
|
||||
empty_unit_iface(u);
|
||||
if (u->imsg) { /* then if an inbound message buffer exists */
|
||||
u->imsg = (char *)realloc(u->imsg, 1); /* and re-allocate the old large buffer into a new small one */
|
||||
if (u->imsg == NULL) { /* oops, realloc call failed */
|
||||
void *bigger_buffer;
|
||||
|
||||
bigger_buffer = (char *)realloc(u->imsg, 1); /* and re-allocate the old large buffer into a new small one */
|
||||
if (bigger_buffer == NULL) { /* oops, realloc call failed */
|
||||
fprintf(stderr, "Warning...call to realloc() failed, value of errno is %d\n", errno);
|
||||
|
||||
return;
|
||||
}
|
||||
u->imsg = bigger_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,7 +266,7 @@ int acn_parse_hosts_file(char *errbuf) { /* returns: -1 = error, 0 = OK */
|
||||
|
||||
empty_unit_table();
|
||||
if ((fp = fopen("/etc/hosts", "r")) == NULL) { /* try to open the hosts file and if it fails */
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading."); /* return the nohostsfile error response */
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading."); /* return the nohostsfile error response */
|
||||
return -1;
|
||||
}
|
||||
while (fgets(buf, MAX_LINE_SIZE-1, fp)) { /* while looping over the file */
|
||||
@ -285,11 +289,11 @@ int acn_parse_hosts_file(char *errbuf) { /* returns: -1 = error, 0 = OK */
|
||||
geoslot = *(ptr2 + 5) - '0'; /* and geo-slot number */
|
||||
if (chassis < 1 || chassis > MAX_CHASSIS ||
|
||||
geoslot < 1 || geoslot > MAX_GEOSLOT) { /* if the chassis and/or slot numbers appear to be bad... */
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'."); /* warn the user */
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'."); /* warn the user */
|
||||
continue; /* and ignore the entry */
|
||||
}
|
||||
if ((ptr2 = (char *)malloc(strlen(ptr) + 1)) == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
continue;
|
||||
}
|
||||
strcpy(ptr2, ptr); /* copy the IP address into our malloc'ed memory */
|
||||
@ -402,14 +406,14 @@ static void acn_freealldevs(void) {
|
||||
|
||||
static void nonUnified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u) {
|
||||
|
||||
snprintf(buf, bufsize, "%s_%d_%d", proto, u->chassis, u->geoslot);
|
||||
pcap_snprintf(buf, bufsize, "%s_%d_%d", proto, u->chassis, u->geoslot);
|
||||
}
|
||||
|
||||
static void unified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u, int IOPportnum) {
|
||||
int portnum;
|
||||
|
||||
portnum = ((u->chassis - 1) * 64) + ((u->geoslot - 1) * 8) + IOPportnum + 1;
|
||||
snprintf(buf, bufsize, "%s_%d", proto, portnum);
|
||||
pcap_snprintf(buf, bufsize, "%s_%d", proto, portnum);
|
||||
}
|
||||
|
||||
static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 iftype) {
|
||||
@ -553,10 +557,10 @@ static void sort_if_table(void) {
|
||||
}
|
||||
if (has_swapped == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int process_client_data (char *errbuf) { /* returns: -1 = error, 0 = OK */
|
||||
int chassis, geoslot;
|
||||
unit_t *u;
|
||||
@ -568,6 +572,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
char *newname;
|
||||
bpf_u_int32 interfaceType;
|
||||
unsigned char flags;
|
||||
void *bigger_buffer;
|
||||
|
||||
prev_iff = 0;
|
||||
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
|
||||
@ -577,7 +582,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
ptr = u->imsg; /* point to the start of the msg for this IOP */
|
||||
while (ptr < (u->imsg + u->len)) {
|
||||
if ((iff = malloc(sizeof(pcap_if_t))) == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
memset((char *)iff, 0, sizeof(pcap_if_t)); /* bzero() is deprecated, replaced with memset() */
|
||||
@ -586,7 +591,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
|
||||
if (*ptr) { /* if there is a count for the name */
|
||||
if ((iff->name = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
memcpy(iff->name, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
|
||||
@ -597,7 +602,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
|
||||
if (*ptr) { /* if there is a count for the description */
|
||||
if ((iff->description = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
memcpy(iff->description, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
|
||||
@ -617,15 +622,15 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
prev_addr = 0;
|
||||
while (address_count--) {
|
||||
if ((addr = malloc(sizeof(pcap_addr_t))) == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
+ memset((char *)addr, 0, sizeof(pcap_addr_t)); /* bzero() is deprecated, replaced with memset() */
|
||||
memset((char *)addr, 0, sizeof(pcap_addr_t)); /* bzero() is deprecated, replaced with memset() */
|
||||
if (iff->addresses == 0) iff->addresses = addr;
|
||||
if (prev_addr) prev_addr->next = addr; /* insert a forward link */
|
||||
if (*ptr) { /* if there is a count for the address */
|
||||
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) { /* get that amount of space */
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
memset((char *)s, 0, sizeof(struct sockaddr_in)); /* bzero() is deprecated, replaced with memset() */
|
||||
@ -637,7 +642,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
ptr++; /* then forwards one more for the 'length of the address' field */
|
||||
if (*ptr) { /* process any netmask */
|
||||
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/* bzero() is deprecated, replaced with memset() */
|
||||
@ -651,7 +656,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
ptr++;
|
||||
if (*ptr) { /* process any broadcast address */
|
||||
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/* bzero() is deprecated, replaced with memset() */
|
||||
@ -665,7 +670,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
ptr++;
|
||||
if (*ptr) { /* process any destination address */
|
||||
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/* bzero() is deprecated, replaced with memset() */
|
||||
@ -682,10 +687,12 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||
prev_iff = iff;
|
||||
|
||||
newname = translate_IOP_to_pcap_name(u, iff->name, interfaceType); /* add a translation entry and get a point to the mangled name */
|
||||
if ((iff->name = realloc(iff->name, strlen(newname) + 1)) == NULL) { /* we now re-write the name stored in the interface list */
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "realloc: %s", pcap_strerror(errno));
|
||||
bigger_buffer = realloc(iff->name, strlen(newname) + 1));
|
||||
if (bigger_buffer == NULL) { /* we now re-write the name stored in the interface list */
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "realloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
iff->name = bigger_buffer;
|
||||
strcpy(iff->name, newname); /* to this new name */
|
||||
}
|
||||
}
|
||||
@ -816,7 +823,7 @@ static int acn_open_live(const char *name, char *errbuf, int *linktype) { /* re
|
||||
iface_t *p;
|
||||
pcap_if_t *alldevsp;
|
||||
|
||||
pcap_findalldevs_interfaces(&alldevsp, errbuf);
|
||||
pcap_platform_finddevs(&alldevsp, errbuf);
|
||||
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) { /* scan the table... */
|
||||
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
|
||||
u = &units[chassis][geoslot];
|
||||
@ -892,7 +899,7 @@ static int pcap_setfilter_acn(pcap_t *handle, struct bpf_program *bpf) {
|
||||
}
|
||||
|
||||
static int pcap_setdirection_acn(pcap_t *handle, pcap_direction_t d) {
|
||||
snprintf(handle->errbuf, sizeof(handle->errbuf),
|
||||
pcap_snprintf(handle->errbuf, sizeof(handle->errbuf),
|
||||
"Setting direction is not supported on ACN adapters");
|
||||
return -1;
|
||||
}
|
||||
@ -951,7 +958,7 @@ static int pcap_read_acn(pcap_t *handle, int max_packets, pcap_handler callback,
|
||||
pcap_header.caplen = ntohl(*(uint32_t *)&packet_header[8]); /* caplen */
|
||||
pcap_header.len = ntohl(*(uint32_t *)&packet_header[12]); /* len */
|
||||
|
||||
handle->bp = handle->buffer + handle->offset; /* start off the receive pointer at the right spot */
|
||||
handle->bp = (u_char *)handle->buffer + handle->offset; /* start off the receive pointer at the right spot */
|
||||
if (acn_read_n_bytes_with_timeout(handle, pcap_header.caplen) == -1) return 0; /* then try to read in the rest of the data */
|
||||
|
||||
callback(user, &pcap_header, handle->bp); /* call the user supplied callback function */
|
||||
@ -981,7 +988,7 @@ static int pcap_activate_sita(pcap_t *handle) {
|
||||
handle->read_op = pcap_read_acn;
|
||||
handle->stats_op = pcap_stats_acn;
|
||||
|
||||
fd = acn_open_live(handle->opt.source, handle->errbuf,
|
||||
fd = acn_open_live(handle->opt.device, handle->errbuf,
|
||||
&handle->linktype);
|
||||
if (fd == -1)
|
||||
return PCAP_ERROR;
|
||||
@ -992,7 +999,7 @@ static int pcap_activate_sita(pcap_t *handle) {
|
||||
|
||||
handle->buffer = malloc(handle->bufsize + handle->offset);
|
||||
if (!handle->buffer) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
pcap_cleanup_acn(handle);
|
||||
return PCAP_ERROR;
|
||||
@ -1007,13 +1014,36 @@ static int pcap_activate_sita(pcap_t *handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pcap_t *pcap_create_interface(const char *device, char *ebuf) {
|
||||
pcap_t *pcap_create_interface(const char *device _U_, char *ebuf) {
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_create_common(device, ebuf, 0);
|
||||
p = pcap_create_common(ebuf, 0);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
p->activate_op = pcap_activate_sita;
|
||||
return (p);
|
||||
}
|
||||
|
||||
int pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) {
|
||||
|
||||
//printf("pcap_findalldevs()\n"); // fulko
|
||||
|
||||
*alldevsp = 0; /* initialize the returned variables before we do anything */
|
||||
strcpy(errbuf, "");
|
||||
if (acn_parse_hosts_file(errbuf)) /* scan the hosts file for potential IOPs */
|
||||
{
|
||||
//printf("pcap_findalldevs() returning BAD after parsehosts\n"); // fulko
|
||||
return -1;
|
||||
}
|
||||
//printf("pcap_findalldevs() got hostlist now finding devs\n"); // fulko
|
||||
if (acn_findalldevs(errbuf)) /* then ask the IOPs for their monitorable devices */
|
||||
{
|
||||
//printf("pcap_findalldevs() returning BAD after findalldevs\n"); // fulko
|
||||
return -1;
|
||||
}
|
||||
*alldevsp = acn_if_list;
|
||||
acn_if_list = 0; /* then forget our list head, because someone will call pcap_freealldevs() to empty the malloc'ed stuff */
|
||||
//printf("pcap_findalldevs() returning ZERO OK\n"); // fulko
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <snf.h>
|
||||
#if SNF_VERSION_API >= 0x0003
|
||||
#define SNF_HAVE_INJECT_API
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
#include "pcap-snf.h"
|
||||
@ -26,6 +29,9 @@
|
||||
struct pcap_snf {
|
||||
snf_handle_t snf_handle; /* opaque device handle */
|
||||
snf_ring_t snf_ring; /* opaque device ring handle */
|
||||
#ifdef SNF_HAVE_INJECT_API
|
||||
snf_inject_t snf_inj; /* inject handle, if inject is used */
|
||||
#endif
|
||||
int snf_timeout;
|
||||
int snf_boardnum;
|
||||
};
|
||||
@ -41,10 +47,11 @@ static int
|
||||
snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
struct snf_ring_stats stats;
|
||||
struct pcap_snf *snfps = p->priv;
|
||||
int rc;
|
||||
|
||||
if ((rc = snf_ring_getstats(ps->snf_ring, &stats))) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
|
||||
if ((rc = snf_ring_getstats(snfps->snf_ring, &stats))) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
|
||||
pcap_strerror(rc));
|
||||
return -1;
|
||||
}
|
||||
@ -57,12 +64,12 @@ snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
static void
|
||||
snf_platform_cleanup(pcap_t *p)
|
||||
{
|
||||
struct pcap_snf *ps;
|
||||
|
||||
if (p == NULL)
|
||||
return;
|
||||
ps = p->priv;
|
||||
struct pcap_snf *ps = p->priv;
|
||||
|
||||
#ifdef SNF_HAVE_INJECT_API
|
||||
if (ps->snf_inj)
|
||||
snf_inject_close(ps->snf_inj);
|
||||
#endif
|
||||
snf_ring_close(ps->snf_ring);
|
||||
snf_close(ps->snf_handle);
|
||||
pcap_cleanup_live_common(p);
|
||||
@ -96,14 +103,23 @@ snf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
|
||||
static inline
|
||||
struct timeval
|
||||
snf_timestamp_to_timeval(const int64_t ts_nanosec)
|
||||
snf_timestamp_to_timeval(const int64_t ts_nanosec, const int tstamp_precision)
|
||||
{
|
||||
struct timeval tv;
|
||||
int32_t rem;
|
||||
long tv_nsec;
|
||||
|
||||
if (ts_nanosec == 0)
|
||||
return (struct timeval) { 0, 0 };
|
||||
|
||||
tv.tv_sec = ts_nanosec / _NSEC_PER_SEC;
|
||||
tv.tv_usec = (ts_nanosec % _NSEC_PER_SEC) / 1000;
|
||||
tv_nsec = (ts_nanosec % _NSEC_PER_SEC);
|
||||
|
||||
/* libpcap expects tv_usec to be nanos if using nanosecond precision. */
|
||||
if (tstamp_precision == PCAP_TSTAMP_PRECISION_NANO)
|
||||
tv.tv_usec = tv_nsec;
|
||||
else
|
||||
tv.tv_usec = tv_nsec / 1000;
|
||||
|
||||
return tv;
|
||||
}
|
||||
|
||||
@ -114,11 +130,13 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
struct pcap_pkthdr hdr;
|
||||
int i, flags, err, caplen, n;
|
||||
struct snf_recv_req req;
|
||||
int nonblock, timeout;
|
||||
|
||||
if (!p || cnt == 0)
|
||||
if (!p)
|
||||
return -1;
|
||||
|
||||
n = 0;
|
||||
timeout = ps->snf_timeout;
|
||||
while (n < cnt || PACKET_COUNT_IS_UNLIMITED(cnt)) {
|
||||
/*
|
||||
* Has "pcap_breakloop()" been called?
|
||||
@ -132,15 +150,18 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
}
|
||||
}
|
||||
|
||||
err = snf_ring_recv(ps->snf_ring, ps->snf_timeout, &req);
|
||||
err = snf_ring_recv(ps->snf_ring, timeout, &req);
|
||||
|
||||
if (err) {
|
||||
if (err == EBUSY || err == EAGAIN)
|
||||
return (0);
|
||||
if (err == EINTR)
|
||||
if (err == EBUSY || err == EAGAIN) {
|
||||
return (n);
|
||||
}
|
||||
else if (err == EINTR) {
|
||||
timeout = 0;
|
||||
continue;
|
||||
if (err != 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_read: %s",
|
||||
}
|
||||
else {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_read: %s",
|
||||
pcap_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
@ -152,12 +173,17 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
|
||||
if ((p->fcode.bf_insns == NULL) ||
|
||||
bpf_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) {
|
||||
hdr.ts = snf_timestamp_to_timeval(req.timestamp);
|
||||
hdr.ts = snf_timestamp_to_timeval(req.timestamp, p->opt.tstamp_precision);
|
||||
hdr.caplen = caplen;
|
||||
hdr.len = req.length;
|
||||
callback(user, &hdr, req.pkt_addr);
|
||||
}
|
||||
n++;
|
||||
|
||||
/* After one successful packet is received, we won't block
|
||||
* again for that timeout. */
|
||||
if (timeout != 0)
|
||||
timeout = 0;
|
||||
}
|
||||
return (n);
|
||||
}
|
||||
@ -184,30 +210,55 @@ snf_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
static int
|
||||
snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported with snf",
|
||||
#ifdef SNF_HAVE_INJECT_API
|
||||
struct pcap_snf *ps = p->priv;
|
||||
int rc;
|
||||
if (ps->snf_inj == NULL) {
|
||||
rc = snf_inject_open(ps->snf_boardnum, 0, &ps->snf_inj);
|
||||
if (rc) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_inject_open: %s", pcap_strerror(rc));
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = snf_inject_send(ps->snf_inj, -1, 0, buf, size);
|
||||
if (!rc) {
|
||||
return (size);
|
||||
}
|
||||
else {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_inject_send: %s",
|
||||
pcap_strerror(rc));
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported with this snf version",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
snf_activate(pcap_t* p)
|
||||
{
|
||||
struct pcap_snf *ps = p->priv;
|
||||
char *device = p->opt.source;
|
||||
char *device = p->opt.device;
|
||||
const char *nr = NULL;
|
||||
int err;
|
||||
int flags = 0;
|
||||
int flags = -1, ring_id = -1;
|
||||
|
||||
if (device == NULL) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"device is NULL: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* In Libpcap, we set pshared by default if NUM_RINGS is set to > 1.
|
||||
* Since libpcap isn't thread-safe */
|
||||
if ((nr = getenv("SNF_NUM_RINGS")) && *nr && atoi(nr) > 1)
|
||||
flags |= SNF_F_PSHARED;
|
||||
if ((nr = getenv("SNF_FLAGS")) && *nr)
|
||||
flags = strtol(nr, NULL, 0);
|
||||
else if ((nr = getenv("SNF_NUM_RINGS")) && *nr && atoi(nr) > 1)
|
||||
flags = SNF_F_PSHARED;
|
||||
else
|
||||
nr = NULL;
|
||||
|
||||
@ -218,15 +269,19 @@ snf_activate(pcap_t* p)
|
||||
flags, /* may want pshared */
|
||||
&ps->snf_handle);
|
||||
if (err != 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_open failed: %s", pcap_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = snf_ring_open(ps->snf_handle, &ps->snf_ring);
|
||||
if ((nr = getenv("SNF_PCAP_RING_ID")) && *nr) {
|
||||
ring_id = (int) strtol(nr, NULL, 0);
|
||||
}
|
||||
err = snf_ring_open_id(ps->snf_handle, ring_id, &ps->snf_ring);
|
||||
if (err != 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_ring_open failed: %s", pcap_strerror(err));
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_ring_open_id(ring=%d) failed: %s",
|
||||
ring_id, pcap_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -237,7 +292,7 @@ snf_activate(pcap_t* p)
|
||||
|
||||
err = snf_start(ps->snf_handle);
|
||||
if (err != 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_start failed: %s", pcap_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
@ -256,12 +311,104 @@ snf_activate(pcap_t* p)
|
||||
p->setnonblock_op = snf_setnonblock;
|
||||
p->stats_op = snf_pcap_stats;
|
||||
p->cleanup_op = snf_platform_cleanup;
|
||||
#ifdef SNF_HAVE_INJECT_API
|
||||
ps->snf_inj = NULL;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_DESC_LENGTH 128
|
||||
int
|
||||
snf_findalldevs(pcap_if_t **devlistp, char *errbuf)
|
||||
{
|
||||
pcap_if_t *devlist = NULL,*curdev,*prevdev;
|
||||
pcap_addr_t *curaddr;
|
||||
struct snf_ifaddrs *ifaddrs, *ifa;
|
||||
char desc[MAX_DESC_LENGTH];
|
||||
int ret;
|
||||
|
||||
if (snf_init(SNF_VERSION_API))
|
||||
return (-1);
|
||||
|
||||
if (snf_getifaddrs(&ifaddrs) || ifaddrs == NULL)
|
||||
{
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_getifaddrs: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
ifa = ifaddrs;
|
||||
while (ifa)
|
||||
{
|
||||
/*
|
||||
* Allocate a new entry
|
||||
*/
|
||||
curdev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
|
||||
if (curdev == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_findalldevs malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
if (devlist == NULL) /* save first entry */
|
||||
devlist = curdev;
|
||||
else
|
||||
prevdev->next = curdev;
|
||||
/*
|
||||
* Fill in the entry.
|
||||
*/
|
||||
curdev->next = NULL;
|
||||
curdev->name = strdup(ifa->snf_ifa_name);
|
||||
if (curdev->name == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_findalldevs strdup: %s", pcap_strerror(errno));
|
||||
free(curdev);
|
||||
return (-1);
|
||||
}
|
||||
(void)pcap_snprintf(desc,MAX_DESC_LENGTH,"Myricom snf%d",
|
||||
ifa->snf_ifa_portnum);
|
||||
curdev->description = strdup(desc);
|
||||
if (curdev->description == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_findalldevs strdup1: %s", pcap_strerror(errno));
|
||||
free(curdev->name);
|
||||
free(curdev);
|
||||
return (-1);
|
||||
}
|
||||
curdev->addresses = NULL;
|
||||
curdev->flags = 0;
|
||||
|
||||
curaddr = (pcap_addr_t *)malloc(sizeof(pcap_addr_t));
|
||||
if (curaddr == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snf_findalldevs malloc1: %s", pcap_strerror(errno));
|
||||
free(curdev->description);
|
||||
free(curdev->name);
|
||||
free(curdev);
|
||||
return (-1);
|
||||
}
|
||||
curdev->addresses = curaddr;
|
||||
curaddr->next = NULL;
|
||||
curaddr->addr = (struct sockaddr*)malloc(sizeof(struct sockaddr_storage));
|
||||
if (curaddr->addr == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc2: %s", pcap_strerror(errno));
|
||||
free(curdev->description);
|
||||
free(curdev->name);
|
||||
free(curaddr);
|
||||
free(curdev);
|
||||
return (-1);
|
||||
}
|
||||
curaddr->addr->sa_family = AF_INET;
|
||||
curaddr->netmask = NULL;
|
||||
curaddr->broadaddr = NULL;
|
||||
curaddr->dstaddr = NULL;
|
||||
curaddr->next = NULL;
|
||||
|
||||
prevdev = curdev;
|
||||
ifa = ifa->snf_ifa_next;
|
||||
}
|
||||
snf_freeifaddrs(ifaddrs);
|
||||
*devlistp = devlist;
|
||||
|
||||
/*
|
||||
* There are no platform-specific devices since each device
|
||||
* exists as a regular Ethernet device.
|
||||
@ -320,12 +467,54 @@ snf_create(const char *device, char *ebuf, int *is_ours)
|
||||
/* OK, it's probably ours. */
|
||||
*is_ours = 1;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_snf));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_snf));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
ps = p->priv;
|
||||
|
||||
/*
|
||||
* We support microsecond and nanosecond time stamps.
|
||||
*/
|
||||
p->tstamp_precision_count = 2;
|
||||
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
|
||||
if (p->tstamp_precision_list == NULL) {
|
||||
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
pcap_strerror(errno));
|
||||
pcap_close(p);
|
||||
return NULL;
|
||||
}
|
||||
p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
|
||||
p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
|
||||
|
||||
p->activate_op = snf_activate;
|
||||
ps->snf_boardnum = boardnum;
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifdef SNF_ONLY
|
||||
/*
|
||||
* This libpcap build supports only SNF cards, not regular network
|
||||
* interfaces..
|
||||
*/
|
||||
|
||||
/*
|
||||
* There are no regular interfaces, just DAG interfaces.
|
||||
*/
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
*alldevsp = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempts to open a regular interface fail.
|
||||
*/
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *errbuf)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"This version of libpcap only supports SNF cards");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
@ -130,11 +130,11 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
if (cc < 0) {
|
||||
if (errno == EWOULDBLOCK)
|
||||
return (0);
|
||||
snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
bp = p->buffer;
|
||||
bp = (u_char *)p->buffer;
|
||||
} else
|
||||
bp = p->bp;
|
||||
|
||||
@ -211,7 +211,7 @@ static int
|
||||
pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
|
||||
{
|
||||
struct strbuf ctl, data;
|
||||
|
||||
|
||||
/*
|
||||
* XXX - can we just do
|
||||
*
|
||||
@ -223,7 +223,7 @@ pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
|
||||
data.len = size;
|
||||
ret = putmsg(p->fd, &ctl, &data);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -247,7 +247,7 @@ nit_setflags(pcap_t *p)
|
||||
si.ic_len = sizeof(zero);
|
||||
si.ic_dp = (char *)&zero;
|
||||
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -260,7 +260,7 @@ nit_setflags(pcap_t *p)
|
||||
si.ic_len = sizeof(timeout);
|
||||
si.ic_dp = (char *)&timeout;
|
||||
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -272,7 +272,7 @@ nit_setflags(pcap_t *p)
|
||||
si.ic_len = sizeof(flags);
|
||||
si.ic_dp = (char *)&flags;
|
||||
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -286,7 +286,7 @@ pcap_activate_snit(pcap_t *p)
|
||||
struct ifreq ifr; /* interface request struct */
|
||||
int chunksize = CHUNKSIZE;
|
||||
int fd;
|
||||
static char dev[] = "/dev/nit";
|
||||
static const char dev[] = "/dev/nit";
|
||||
|
||||
if (p->opt.rfmon) {
|
||||
/*
|
||||
@ -320,19 +320,19 @@ pcap_activate_snit(pcap_t *p)
|
||||
if (fd < 0 && errno == EACCES)
|
||||
p->fd = fd = open(dev, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
|
||||
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -342,19 +342,24 @@ pcap_activate_snit(pcap_t *p)
|
||||
si.ic_len = sizeof(chunksize);
|
||||
si.ic_dp = (char *)&chunksize;
|
||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* request the interface */
|
||||
strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
|
||||
strncpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
|
||||
si.ic_cmd = NIOCBIND;
|
||||
si.ic_len = sizeof(ifr);
|
||||
si.ic_dp = (char *)𝔦
|
||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
|
||||
/*
|
||||
* XXX - is there an error that means "no such device"?
|
||||
* Is there one that means "that device doesn't support
|
||||
* STREAMS NIT"?
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
|
||||
ifr.ifr_name, pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -364,7 +369,7 @@ pcap_activate_snit(pcap_t *p)
|
||||
si.ic_len = sizeof(p->snapshot);
|
||||
si.ic_dp = (char *)&p->snapshot;
|
||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -378,7 +383,7 @@ pcap_activate_snit(pcap_t *p)
|
||||
p->linktype = DLT_EN10MB;
|
||||
|
||||
p->bufsize = BUFSPACE;
|
||||
p->buffer = (u_char *)malloc(p->bufsize);
|
||||
p->buffer = malloc(p->bufsize);
|
||||
if (p->buffer == NULL) {
|
||||
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||
goto bad;
|
||||
@ -426,11 +431,11 @@ pcap_activate_snit(pcap_t *p)
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *ebuf)
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_snit));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_snit));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -438,8 +443,18 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - there's probably a NIOCBIND error that means "that device
|
||||
* doesn't support NIT"; if so, we should try an NIOCBIND and use that.
|
||||
*/
|
||||
static int
|
||||
can_be_bound(const char *name _U_)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
return (0);
|
||||
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ again:
|
||||
case EWOULDBLOCK:
|
||||
return (0); /* XXX */
|
||||
}
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"read: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -114,7 +114,7 @@ again:
|
||||
caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
|
||||
cp = (u_char *)(sh + 1) + p->offset; /* XXX */
|
||||
|
||||
/*
|
||||
/*
|
||||
* XXX unfortunately snoop loopback isn't exactly like
|
||||
* BSD's. The address family is encoded in the first 2
|
||||
* bytes rather than the first 4 bytes! Luckily the last
|
||||
@ -150,12 +150,12 @@ pcap_inject_snoop(pcap_t *p, const void *buf, size_t size)
|
||||
*/
|
||||
ret = write(p->fd, buf, size);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
|
||||
@ -167,7 +167,7 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
|
||||
rs = &rawstats;
|
||||
memset(rs, 0, sizeof(*rs));
|
||||
if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"SIOCRAWSTATS: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -212,22 +212,29 @@ pcap_activate_snoop(pcap_t *p)
|
||||
|
||||
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
|
||||
if (fd < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
p->fd = fd;
|
||||
memset(&sr, 0, sizeof(sr));
|
||||
sr.sr_family = AF_RAW;
|
||||
(void)strncpy(sr.sr_ifname, p->opt.source, sizeof(sr.sr_ifname));
|
||||
(void)strncpy(sr.sr_ifname, p->opt.device, sizeof(sr.sr_ifname));
|
||||
if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
|
||||
/*
|
||||
* XXX - there's probably a particular bind error that
|
||||
* means "there's no such device" and a particular bind
|
||||
* error that means "that device doesn't support snoop";
|
||||
* they might be the same error, if they both end up
|
||||
* meaning "snoop doesn't know about that device".
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
memset(&sf, 0, sizeof(sf));
|
||||
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -239,19 +246,19 @@ pcap_activate_snoop(pcap_t *p)
|
||||
/*
|
||||
* XXX hack - map device name to link layer type
|
||||
*/
|
||||
if (strncmp("et", p->opt.source, 2) == 0 || /* Challenge 10 Mbit */
|
||||
strncmp("ec", p->opt.source, 2) == 0 || /* Indigo/Indy 10 Mbit,
|
||||
if (strncmp("et", p->opt.device, 2) == 0 || /* Challenge 10 Mbit */
|
||||
strncmp("ec", p->opt.device, 2) == 0 || /* Indigo/Indy 10 Mbit,
|
||||
O2 10/100 */
|
||||
strncmp("ef", p->opt.source, 2) == 0 || /* O200/2000 10/100 Mbit */
|
||||
strncmp("eg", p->opt.source, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
|
||||
strncmp("gfe", p->opt.source, 3) == 0 || /* GIO 100 Mbit */
|
||||
strncmp("fxp", p->opt.source, 3) == 0 || /* Challenge VME Enet */
|
||||
strncmp("ep", p->opt.source, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
|
||||
strncmp("vfe", p->opt.source, 3) == 0 || /* Challenge VME 100Mbit */
|
||||
strncmp("fa", p->opt.source, 2) == 0 ||
|
||||
strncmp("qaa", p->opt.source, 3) == 0 ||
|
||||
strncmp("cip", p->opt.source, 3) == 0 ||
|
||||
strncmp("el", p->opt.source, 2) == 0) {
|
||||
strncmp("ef", p->opt.device, 2) == 0 || /* O200/2000 10/100 Mbit */
|
||||
strncmp("eg", p->opt.device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
|
||||
strncmp("gfe", p->opt.device, 3) == 0 || /* GIO 100 Mbit */
|
||||
strncmp("fxp", p->opt.device, 3) == 0 || /* Challenge VME Enet */
|
||||
strncmp("ep", p->opt.device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
|
||||
strncmp("vfe", p->opt.device, 3) == 0 || /* Challenge VME 100Mbit */
|
||||
strncmp("fa", p->opt.device, 2) == 0 ||
|
||||
strncmp("qaa", p->opt.device, 3) == 0 ||
|
||||
strncmp("cip", p->opt.device, 3) == 0 ||
|
||||
strncmp("el", p->opt.device, 2) == 0) {
|
||||
p->linktype = DLT_EN10MB;
|
||||
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
|
||||
ll_hdrlen = sizeof(struct ether_header);
|
||||
@ -284,26 +291,26 @@ pcap_activate_snoop(pcap_t *p)
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
p->dlt_count = 2;
|
||||
}
|
||||
} else if (strncmp("ipg", p->opt.source, 3) == 0 ||
|
||||
strncmp("rns", p->opt.source, 3) == 0 || /* O2/200/2000 FDDI */
|
||||
strncmp("xpi", p->opt.source, 3) == 0) {
|
||||
} else if (strncmp("ipg", p->opt.device, 3) == 0 ||
|
||||
strncmp("rns", p->opt.device, 3) == 0 || /* O2/200/2000 FDDI */
|
||||
strncmp("xpi", p->opt.device, 3) == 0) {
|
||||
p->linktype = DLT_FDDI;
|
||||
p->offset = 3; /* XXX yeah? */
|
||||
ll_hdrlen = 13;
|
||||
} else if (strncmp("ppp", p->opt.source, 3) == 0) {
|
||||
} else if (strncmp("ppp", p->opt.device, 3) == 0) {
|
||||
p->linktype = DLT_RAW;
|
||||
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
|
||||
} else if (strncmp("qfa", p->opt.source, 3) == 0) {
|
||||
} else if (strncmp("qfa", p->opt.device, 3) == 0) {
|
||||
p->linktype = DLT_IP_OVER_FC;
|
||||
ll_hdrlen = 24;
|
||||
} else if (strncmp("pl", p->opt.source, 2) == 0) {
|
||||
} else if (strncmp("pl", p->opt.device, 2) == 0) {
|
||||
p->linktype = DLT_RAW;
|
||||
ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */
|
||||
} else if (strncmp("lo", p->opt.source, 2) == 0) {
|
||||
} else if (strncmp("lo", p->opt.device, 2) == 0) {
|
||||
p->linktype = DLT_NULL;
|
||||
ll_hdrlen = 4;
|
||||
} else {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"snoop: unknown physical layer type");
|
||||
goto bad;
|
||||
}
|
||||
@ -323,9 +330,9 @@ pcap_activate_snoop(pcap_t *p)
|
||||
* the MTU first and, if that succeeds, trim the snap length
|
||||
* to be no greater than the MTU.
|
||||
*/
|
||||
(void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
|
||||
(void)strncpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -359,21 +366,21 @@ pcap_activate_snoop(pcap_t *p)
|
||||
if (snooplen < 0)
|
||||
snooplen = 0;
|
||||
if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
v = 1;
|
||||
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
p->bufsize = 4096; /* XXX */
|
||||
p->buffer = (u_char *)malloc(p->bufsize);
|
||||
p->buffer = malloc(p->bufsize);
|
||||
if (p->buffer == NULL) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
@ -399,11 +406,11 @@ pcap_activate_snoop(pcap_t *p)
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device, char *ebuf)
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_snoop));
|
||||
p = pcap_create_common(ebuf, sizeof (struct pcap_snoop));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -411,8 +418,18 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - there's probably a particular bind error that means "that device
|
||||
* doesn't support snoop"; if so, we should try a bind and use that.
|
||||
*/
|
||||
static int
|
||||
can_be_bound(const char *name _U_)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
return (0);
|
||||
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
|
||||
}
|
||||
|
@ -28,6 +28,35 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1999 WIDE Project.
|
||||
* 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. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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 pcap_stdinc_h
|
||||
#define pcap_stdinc_h
|
||||
|
||||
@ -45,39 +74,53 @@
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
|
||||
#include "bittypes.h"
|
||||
#include "IP6_misc.h"
|
||||
|
||||
#define caddr_t char*
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#define strdup _strdup
|
||||
/*
|
||||
* MSVC.
|
||||
*/
|
||||
#if _MSC_VER >= 1800
|
||||
/*
|
||||
* VS 2013 or newer; we have <inttypes.h>.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
|
||||
#define u_int8_t uint8_t
|
||||
#define u_int16_t uint16_t
|
||||
#define u_int32_t uint32_t
|
||||
#define u_int64_t uint64_t
|
||||
#else
|
||||
/*
|
||||
* Earlier VS; we have to define this stuff ourselves.
|
||||
*/
|
||||
#ifndef HAVE_U_INT8_T
|
||||
typedef unsigned char u_int8_t;
|
||||
typedef signed char int8_t;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_U_INT16_T
|
||||
typedef unsigned short u_int16_t;
|
||||
typedef signed short int16_t;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_U_INT32_T
|
||||
typedef unsigned int u_int32_t;
|
||||
typedef signed int int32_t;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_U_INT64_T
|
||||
#ifdef _MSC_EXTENSIONS
|
||||
typedef unsigned _int64 u_int64_t;
|
||||
typedef _int64 int64_t;
|
||||
#else /* _MSC_EXTENSIONS */
|
||||
typedef unsigned long long u_int64_t;
|
||||
typedef long long int64_t;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(__MINGW32__)
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define inline __inline
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifndef _UINTPTR_T_DEFINED
|
||||
#ifdef _WIN64
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif
|
||||
#define _UINTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef _INTPTR_T_DEFINED
|
||||
#ifdef _WIN64
|
||||
typedef __int64 intptr_t;
|
||||
#else
|
||||
typedef _W64 int intptr_t;
|
||||
#endif
|
||||
#define _INTPTR_T_DEFINED
|
||||
#endif
|
||||
#endif /*__MINGW32__*/
|
||||
|
||||
#endif /* pcap_stdinc_h */
|
||||
|
1284
contrib/libpcap/pcap-tc.c
Normal file
1284
contrib/libpcap/pcap-tc.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user