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 @@ static int dag_activate(pcap_t* handle)
|
||||
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 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
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 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
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…
Reference in New Issue
Block a user