build standalone ipx utilities without ncpfs private headers
This commit is contained in:
45
tools/README
Normal file
45
tools/README
Normal file
@@ -0,0 +1,45 @@
|
||||
This is a VERY stupid packet sniffer for IPX ethernet packets.
|
||||
|
||||
=============================================
|
||||
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|
||||
! ! ! S E C U R I T Y W A R N I N G ! ! !
|
||||
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|
||||
=============================================
|
||||
|
||||
If you are using unencrypted passwords, and use this tool to send a
|
||||
dump to somebody else or store it on a computer, you might very well
|
||||
store passwords there. So, be VERY careful! This is exactly the kind
|
||||
of tools Novell designed the encrypted passwords for (or against).
|
||||
|
||||
|
||||
|
||||
I hacked it together to be able to help people with problems with
|
||||
ncpfs. The socket handling was taken from Statnet-2.0.
|
||||
|
||||
You can use it to watch commercial NetWare clients when they talk to
|
||||
servers. I divided the program into 2 parts, ipxdump and ipxparse.
|
||||
|
||||
ipxdump simply pumps all the IPX frames it receives to stdout.
|
||||
|
||||
If you use ipxdump to watch a workstation, you can use the simple
|
||||
filter function ipxdump provides. You can call ipxdump with the node
|
||||
address of the workstation you want to watch. This way only the
|
||||
packets this workstation sends and receives are monitored. As an
|
||||
example, I call ipxdump as
|
||||
|
||||
./ipxdump 00001B038B11
|
||||
|
||||
to look at my 286/10MHz test 'workstation'. ipxdump still generates
|
||||
huge amounts of data, so you should be very careful to start it just
|
||||
before you perform the operation (such as file creation for OS/2
|
||||
clients with NW4.1 as a server, or a 'dir' on a directory with long
|
||||
and short file names, or an encrypted password change ;-)) and stop it
|
||||
directly after that. And, please gzip -9 and uuencode it before you
|
||||
send it to anybody.
|
||||
|
||||
ipxparse will eventually take apart the dump that ipxdump
|
||||
generates. They can as well be used in a pipe. Currently ipxparse does
|
||||
not do anything sensible, but that will definitely change.
|
||||
|
||||
Volker Lendecke
|
||||
<lendecke@namu01.gwdg.de>
|
||||
305
tools/ipxdump.c
Normal file
305
tools/ipxdump.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
ipxdump.c
|
||||
Copyright 1996 Volker Lendecke, Goettingen, Germany
|
||||
Copyright 1999, 2001 Petr Vandrovec, Prague, Czech Republic
|
||||
|
||||
This program 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
|
||||
(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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Revision History:
|
||||
|
||||
1.01 1999, December, 15 Petr Vandrovec <vandrove@vc.cvut.cz>
|
||||
Use sigaction instead of signal, so ^C works
|
||||
immediately and not after next frame comes
|
||||
(bsd vs. sysv signal() semantic bug)
|
||||
|
||||
1.02 2001, July 15 Petr Vandrovec <vandrove@vc.cvut.cz>
|
||||
Add #include <stdlib> to fix some warnings.
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <ncp/ext/socket.h>
|
||||
/* TBD */
|
||||
#include <netinet/in.h>
|
||||
#ifdef HAVE_NETINET_IF_ETHER_H
|
||||
#include <netinet/if_ether.h>
|
||||
#else
|
||||
#include <linux/if_ether.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <ncp/kernel/if.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
/* TBD */
|
||||
#include <netinet/ip.h>
|
||||
/* TBD */
|
||||
#include <netinet/tcp.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include "ipxutil.h"
|
||||
|
||||
struct ipx_address
|
||||
{
|
||||
IPXNet net __attribute__((packed));
|
||||
IPXNode node __attribute__((packed));
|
||||
IPXPort sock __attribute__((packed));
|
||||
};
|
||||
|
||||
struct ipx_packet
|
||||
{
|
||||
unsigned short ipx_checksum __attribute__((packed));
|
||||
#define IPX_NO_CHECKSUM 0xFFFF
|
||||
unsigned short ipx_pktsize __attribute__((packed));
|
||||
unsigned char ipx_tctrl __attribute__((packed));
|
||||
unsigned char ipx_type __attribute__((packed));
|
||||
#define IPX_TYPE_UNKNOWN 0x00
|
||||
#define IPX_TYPE_RIP 0x01 /* may also be 0 */
|
||||
#define IPX_TYPE_SAP 0x04 /* may also be 0 */
|
||||
#define IPX_TYPE_SPX 0x05 /* Not yet implemented */
|
||||
#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */
|
||||
#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast [Not supported] */
|
||||
struct ipx_address ipx_dest __attribute__((packed));
|
||||
struct ipx_address ipx_source __attribute__((packed));
|
||||
};
|
||||
|
||||
|
||||
void handle_frame(unsigned char *buf, int length, struct sockaddr *saddr);
|
||||
void handle_ipx(const char *frame, unsigned char *buf);
|
||||
|
||||
static int filter = 0;
|
||||
static int allframes = 0;
|
||||
static IPXNode filter_node;
|
||||
|
||||
static const char* progname;
|
||||
|
||||
static void usage(void) {
|
||||
fprintf(stderr, "usage: %s [-r] [-d device] [node]\n", progname);
|
||||
}
|
||||
|
||||
static int exit_request = 0;
|
||||
static void
|
||||
int_handler(int dummy)
|
||||
{
|
||||
exit_request = 1;
|
||||
(void)dummy;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int sd;
|
||||
struct ifreq ifr, oldifr;
|
||||
const char *device = "eth0";
|
||||
struct sockaddr saddr;
|
||||
int sizeaddr;
|
||||
unsigned char buf[4096];
|
||||
int length;
|
||||
int opt;
|
||||
struct sigaction saint;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname)
|
||||
progname++;
|
||||
else
|
||||
progname = argv[0];
|
||||
|
||||
saint.sa_handler = int_handler;
|
||||
saint.sa_flags = 0;
|
||||
sigemptyset(&saint.sa_mask);
|
||||
sigaction(SIGINT, &saint, NULL);
|
||||
|
||||
while ((opt = getopt(argc, argv, "rd:h")) != -1) {
|
||||
switch (opt) {
|
||||
case 'r':allframes = 1;
|
||||
break;
|
||||
case 'd':device = optarg;
|
||||
break;
|
||||
case 'h':usage();
|
||||
return 5;
|
||||
case ':':;
|
||||
case '?':break;
|
||||
default: printf("?? unknown option returned by getopt\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (optind < argc)
|
||||
{
|
||||
if (ipx_sscanf_node(argv[optind], filter_node) != 0)
|
||||
{
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
filter = 1;
|
||||
}
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
// if ((sd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0)
|
||||
if ((sd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0)
|
||||
{
|
||||
perror("Can't get socket");
|
||||
fprintf(stderr, "You must run %s as root\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
/* SET PROMISC */
|
||||
|
||||
strcpy(oldifr.ifr_name, device);
|
||||
if (ioctl(sd, SIOCGIFFLAGS, &oldifr) < 0)
|
||||
{
|
||||
close(sd);
|
||||
perror("Can't get flags");
|
||||
exit(2);
|
||||
}
|
||||
/* This should be rewritten to cooperate with other net tools */
|
||||
ifr = oldifr;
|
||||
ifr.ifr_flags |= IFF_PROMISC;
|
||||
|
||||
if (ioctl(sd, SIOCSIFFLAGS, &ifr) < 0)
|
||||
{
|
||||
close(sd);
|
||||
perror("Can't set flags");
|
||||
exit(3);
|
||||
}
|
||||
while (exit_request == 0)
|
||||
{
|
||||
/* This is the main data-gathering loop; keep it small
|
||||
and fast */
|
||||
sizeaddr = sizeof(saddr);
|
||||
length = recvfrom(sd, buf, sizeof(buf), 0,
|
||||
&saddr, &sizeaddr);
|
||||
if (length < 0)
|
||||
continue;
|
||||
if (allframes) {
|
||||
unsigned char* ptr = buf;
|
||||
if (filter) {
|
||||
if (memcmp(filter_node, buf, 6)&&memcmp(filter_node, buf+6, 6))
|
||||
continue;
|
||||
}
|
||||
printf("raweth ");
|
||||
while (length--) printf("%02X", *ptr++);
|
||||
printf("\n");
|
||||
} else {
|
||||
handle_frame(buf, length, &saddr);
|
||||
}
|
||||
}
|
||||
|
||||
/* This should be rewritten to cooperate with other net tools */
|
||||
if (ioctl(sd, SIOCSIFFLAGS, &oldifr) < 0)
|
||||
{
|
||||
close(sd);
|
||||
perror("Can't set flags");
|
||||
exit(4);
|
||||
}
|
||||
close(sd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
handle_ipx(const char *frame, unsigned char *buf)
|
||||
{
|
||||
int i;
|
||||
struct ipx_packet *h = (struct ipx_packet *) buf;
|
||||
struct sockaddr_ipx s_addr;
|
||||
struct sockaddr_ipx d_addr;
|
||||
int length = ntohs(h->ipx_pktsize);
|
||||
|
||||
|
||||
memset(&s_addr, 0, sizeof(s_addr));
|
||||
memset(&d_addr, 0, sizeof(d_addr));
|
||||
|
||||
memcpy(s_addr.sipx_node, h->ipx_source.node, sizeof(s_addr.sipx_node));
|
||||
s_addr.sipx_port = h->ipx_source.sock;
|
||||
s_addr.sipx_network = h->ipx_source.net;
|
||||
|
||||
memcpy(d_addr.sipx_node, h->ipx_dest.node, sizeof(d_addr.sipx_node));
|
||||
d_addr.sipx_port = h->ipx_dest.sock;
|
||||
d_addr.sipx_network = h->ipx_dest.net;
|
||||
|
||||
if (filter != 0)
|
||||
{
|
||||
if ((memcmp(filter_node, s_addr.sipx_node,
|
||||
sizeof(filter_node)) != 0)
|
||||
&& (memcmp(filter_node, d_addr.sipx_node,
|
||||
sizeof(filter_node)) != 0))
|
||||
{
|
||||
/* Not for us */
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("%s ", frame);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
printf("%2.2X", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
if (!isatty(STDOUT_FILENO))
|
||||
{
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handle_other(unsigned char *buf, int length, struct sockaddr *saddr)
|
||||
{
|
||||
struct ethhdr *eth = (struct ethhdr *) buf;
|
||||
unsigned char *p = &(buf[sizeof(struct ethhdr)]);
|
||||
|
||||
if (ntohs(eth->h_proto) < 1536)
|
||||
{
|
||||
/* This is a magic hack to spot IPX packets. Older
|
||||
* Novell breaks the protocol design and runs IPX over
|
||||
* 802.3 without an 802.2 LLC layer. We look for FFFF
|
||||
* which isnt a used 802.2 SSAP/DSAP. This won't work
|
||||
* for fault tolerant netware but does for the rest.
|
||||
*/
|
||||
|
||||
if (*(unsigned short *) p == 0xffff)
|
||||
{
|
||||
handle_ipx("802.3", p);
|
||||
return;
|
||||
}
|
||||
if ((*(unsigned short *) p == htons(0xe0e0))
|
||||
&& (p[2] == 0x03))
|
||||
{
|
||||
handle_ipx("802.2", p + 3);
|
||||
return;
|
||||
}
|
||||
if (memcmp(p, "\252\252\003\000\000\000\201\067", 8) == 0)
|
||||
{
|
||||
handle_ipx("snap", p + 8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handle_frame(unsigned char *buf, int length, struct sockaddr *saddr)
|
||||
{
|
||||
/* Ethernet packet type ID field */
|
||||
unsigned short packet_type = ((struct ethhdr *) buf)->h_proto;
|
||||
switch (htons(packet_type))
|
||||
{
|
||||
case ETH_P_IPX:
|
||||
handle_ipx("EtherII", &(buf[sizeof(struct ethhdr)]));
|
||||
break;
|
||||
default:
|
||||
handle_other(buf, length, saddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
1140
tools/ipxparse.c
Normal file
1140
tools/ipxparse.c
Normal file
File diff suppressed because it is too large
Load Diff
133
tools/ipxutil.c
Normal file
133
tools/ipxutil.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
IPX support library - general functions
|
||||
|
||||
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
|
||||
Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
|
||||
|
||||
This program 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
|
||||
(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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include "ipxutil.h"
|
||||
|
||||
void
|
||||
ipx_fprint_node(FILE * file, IPXNode node)
|
||||
{
|
||||
fprintf(file, "%02X%02X%02X%02X%02X%02X",
|
||||
(unsigned char) node[0],
|
||||
(unsigned char) node[1],
|
||||
(unsigned char) node[2],
|
||||
(unsigned char) node[3],
|
||||
(unsigned char) node[4],
|
||||
(unsigned char) node[5]
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_network(FILE * file, IPXNet net)
|
||||
{
|
||||
fprintf(file, "%08lX", (unsigned long)net);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_port(FILE * file, IPXPort port)
|
||||
{
|
||||
fprintf(file, "%04X", port);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx)
|
||||
{
|
||||
ipx_fprint_network(file, ntohl(sipx->sipx_network));
|
||||
fprintf(file, ":");
|
||||
ipx_fprint_node(file, sipx->sipx_node);
|
||||
fprintf(file, ":");
|
||||
ipx_fprint_port(file, ntohs(sipx->sipx_port));
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_node(IPXNode node)
|
||||
{
|
||||
ipx_fprint_node(stdout, node);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_network(IPXNet net)
|
||||
{
|
||||
ipx_fprint_network(stdout, net);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_port(IPXPort port)
|
||||
{
|
||||
ipx_fprint_port(stdout, port);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_saddr(struct sockaddr_ipx *sipx)
|
||||
{
|
||||
ipx_fprint_saddr(stdout, sipx);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_assign_node(IPXNode dest, IPXNode src)
|
||||
{
|
||||
memcpy(dest, src, sizeof(IPXNode));
|
||||
}
|
||||
|
||||
int
|
||||
ipx_node_equal(IPXNode n1, IPXNode n2)
|
||||
{
|
||||
return memcmp(n1, n2, sizeof(IPXNode)) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipx_sscanf_node(char *buf, IPXNode node)
|
||||
{
|
||||
int i;
|
||||
int n[6];
|
||||
|
||||
if ((i = sscanf(buf, "%2x%2x%2x%2x%2x%2x",
|
||||
&(n[0]), &(n[1]), &(n[2]),
|
||||
&(n[3]), &(n[4]), &(n[5]))) != 6)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
node[i] = n[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipx_sscanf_net(char *buf, IPXNet * target)
|
||||
{
|
||||
unsigned long net;
|
||||
|
||||
if (sscanf(buf, "%8lX", &net) == 1)
|
||||
{
|
||||
*target = net;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
IPXNode ipx_this_node =
|
||||
{0, 0, 0, 0, 0, 0};
|
||||
IPXNode ipx_broadcast_node =
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
char ipx_err_string[IPX_MAX_ERROR + 1] = "no error detected";
|
||||
65
tools/ipxutil.h
Normal file
65
tools/ipxutil.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
|
||||
IPX support library
|
||||
|
||||
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
|
||||
Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
|
||||
|
||||
This program 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
|
||||
(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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#ifndef __IPXUTIL_H__
|
||||
|
||||
#define __IPXUTIL_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ncp/kernel/ipx.h>
|
||||
|
||||
#define IPX_MAX_ERROR (255)
|
||||
#define IPX_THIS_NET (0)
|
||||
#define IPX_THIS_NODE (ipx_this_node)
|
||||
#define IPX_BROADCAST (ipx_broadcast_node)
|
||||
#define IPX_AUTO_PORT (0)
|
||||
#define IPX_USER_PTYPE (0)
|
||||
#define IPX_IS_INTERNAL (1)
|
||||
|
||||
typedef u_int8_t IPXNode[6];
|
||||
typedef u_int32_t IPXNet;
|
||||
typedef u_int16_t IPXPort;
|
||||
typedef u_int16_t hop_t;
|
||||
typedef u_int16_t tick_t;
|
||||
|
||||
void ipx_print_node(IPXNode node);
|
||||
void ipx_print_network(IPXNet net);
|
||||
void ipx_print_port(IPXPort port);
|
||||
void ipx_print_saddr(struct sockaddr_ipx *sipx);
|
||||
|
||||
void ipx_fprint_node(FILE * file, IPXNode node);
|
||||
void ipx_fprint_network(FILE * file, IPXNet net);
|
||||
void ipx_fprint_port(FILE * file, IPXPort port);
|
||||
void ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx);
|
||||
|
||||
int ipx_sscanf_node(char *buf, IPXNode node);
|
||||
int ipx_sscanf_net(char *buf, IPXNet * target);
|
||||
|
||||
void ipx_assign_node(IPXNode dest, IPXNode src);
|
||||
int ipx_node_equal(IPXNode n1, IPXNode n2);
|
||||
|
||||
extern IPXNode ipx_this_node;
|
||||
extern IPXNode ipx_broadcast_node;
|
||||
|
||||
extern char ipx_err_string[IPX_MAX_ERROR + 1];
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user