Import ncpfs 0.9

This commit is contained in:
ncpfs archive import
2026-04-28 20:39:57 +02:00
parent c6124785a9
commit 5d4b23a5c1
44 changed files with 1925 additions and 604 deletions

BIN
.downloads/ncpfs-0.9.tgz Normal file

Binary file not shown.

View File

@@ -6,13 +6,13 @@ KERNEL = 1.2
INCLUDES = -I/usr/src/linux/include -Ikernel
BINDIR = ./bin
SUBDIRS = kernel-$(KERNEL)/src util ipx-0.75
CFLAGS = -Wall $(INCLUDES)
CC = gcc
all: kernel
make -C util
make -C kernel/src ncpfs.o
for i in $(SUBDIRS); do make -C $$i; done
cp kernel/src/ncpfs.o bin
kernel:
@@ -20,7 +20,7 @@ kernel:
ln -s kernel-$(KERNEL) kernel
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
for i in $(SUBDIRS); do make -C $$i dep; done
clean:
rm -f kernel
@@ -28,7 +28,7 @@ clean:
rm -f `find . -type f -name '*~' -print`
rm -f `find . -type f -name '.depend' -print`
rm -f `find . -type f -name '*.out' -print`
for i in $(SUBDIRS); do make -C $$i clean; done
realclean: clean
rm -fr bin/* ncpfs.tgz

8
README
View File

@@ -1,14 +1,14 @@
This is version 0.7 of ncpfs, a free NetWare client filesystem for
This is version 0.8 of ncpfs, a free NetWare client filesystem for
Linux. This one currently works with Kernel 1.2.13. I do not know
whether it works with any other kernel of the 1.2.x series, I only
used it with 1.2.13.
Due to problems in the 1.3.x IPX kernel code, ncpfs-0.7 does NOT work
with any 1.3.x kernel up to 1.3.44, although there is a kernel-1.3
Due to problems in the 1.3.x IPX kernel code, ncpfs-0.8 does NOT work
with any 1.3.x kernel up to 1.3.45, although there is a kernel-1.3
subdirectory. It compiles fine and seems to work, but any connection
will block after a very short time. Please be patient. I'm sure this
will be solved. If you follow the kernel development closely, you
might want to try ncpfs with a kernel later than 1.3.44, but I can not
might want to try ncpfs with a kernel later than 1.3.45, but I can not
promise anything. To try it with 1.3, simply change the variable
KERNEL in the Makefile from 1.2 to 1.3 and continue as usual.

30
ipx-0.75/Makefile Normal file
View File

@@ -0,0 +1,30 @@
CFLAGS = -O2 -Wall
BINDIR = ../bin
UTILS = $(BINDIR)/ipx_configure $(BINDIR)/ipx_interface \
$(BINDIR)/ipx_internal_net $(BINDIR)/ipx_route
all: $(UTILS)
$(BINDIR)/ipx_configure: ipx_configure.o
$(CC) -o $(BINDIR)/ipx_configure ipx_configure.o
$(BINDIR)/ipx_interface: ipx_interface.o
$(CC) -o $(BINDIR)/ipx_interface ipx_interface.o
$(BINDIR)/ipx_internal_net: ipx_internal_net.o
$(CC) -o $(BINDIR)/ipx_internal_net ipx_internal_net.o
$(BINDIR)/ipx_route: ipx_route.o
$(CC) -o $(BINDIR)/ipx_route ipx_route.o
clean:
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
install: $(UTILS)
for i in $(UTILS); \
do \
install --strip $$i /sbin; \
install $$i.8 /usr/man/man8; \
done

65
ipx-0.75/README Normal file
View File

@@ -0,0 +1,65 @@
This file contains a very short introduction to the IPX implementation
on Linux. Feel free to forward comments (especially suggested additions)
to greg@caldera.com.
The following are important definitions in understanding the descriptions
in this README file.
IPX Interface - This is the item to which IPX sockets are bound.
An IPX interface corresponds to an IPX Network Number which corresponds
to a physical device and frame type. A sample IPX Interface would be:
Network Number: 0x00ABCDEF
Device: Eth0
Frame Type: 802.2.
The particular interface is selected during binding by using the
Network Number (see sample code below).
Primary Interface - The interface that is selected by default when
binding a socket. This is selected when binding by using
a network number of 0 (see sample code below).
Internal Network - This is a special kind of IPX interface that does
not have a physical device or frame type. It is used to provide
a route-independent address for service providers. Internal network
numbers are optional; however, when one is present it is also the
Primary Interface.
This tar file contains the following IPX utilities:
ipx_interface.c
This program is used to create an IPX interface.
ipx_internal_net.c
This program is used to create an IPX Internal Network number.
ipx_route.c
This program creates an IPX route.
ipx_configure.c
This program is used to read/write two configuration parameters:
AUTO INTERFACE CREATE - IPX should/shouldn't automatically create
an IPX interface when it discovers one that has not been
registered via ipx_interface above.
AUTO PRIMARY SELECT - IPX should/shouldn't automatically select
a primary interface when it one an interface exists and
none are designated as the primary. Manual designation
is performed via ipx_interface.
By default, these are both turned off.
The following are sample IPX programs:
ipxrcv.c and ipxsend.c
ipxsend will send a single packet to an instance of ipxrcv running on the
same machine. It uses getsockname(2) to determine the address to which to
send the packet.
rip.c
rip passively monitors the rip traffic on the attached IPX network.
sap.c
sap passively monitors the sap traffic on the attached IPX network.
There are three files in /proc/net that relate to IPX.
ipx_interface contains the list of IPX interfaces.
ipx_route contains the list of IPX routes.
ipx contains the list of IPX sockets in use.

303
ipx-0.75/ipx_interface.c Normal file
View File

@@ -0,0 +1,303 @@
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <netinet/in.h>
#include <linux/ipx.h>
#include <linux/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
static struct ifreq id;
static char *progname;
void
usage(void)
{
fprintf(stderr, "Usage: %s add [-p] device frame_type [net_number]\n\
Usage: %s del device frame_type\n\
Usage: %s check device frame_type\n", progname, progname, progname);
exit(-1);
}
struct frame_type {
char *ft_name;
unsigned char ft_val;
} frame_types[] = {
{"802.2", IPX_FRAME_8022},
{"802.3", IPX_FRAME_8023},
{"SNAP", IPX_FRAME_SNAP},
{"EtherII", IPX_FRAME_ETHERII}
};
#define NFTYPES (sizeof(frame_types)/sizeof(struct frame_type))
int
lookup_frame_type(char *frame)
{
int j;
for (j = 0; (j < NFTYPES) &&
(strcasecmp(frame_types[j].ft_name, frame));
j++)
;
if (j != NFTYPES)
return j;
fprintf(stderr, "%s: Frame type must be", progname);
for (j = 0; j < NFTYPES; j++) {
fprintf(stderr, "%s%s",
(j == NFTYPES-1) ? " or " : " ",
frame_types[j].ft_name);
}
fprintf(stderr, ".\n");
return -1;
}
int
ipx_add_interface(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
int s;
int result;
unsigned long netnum;
char errmsg[80];
int i, fti = 0;
char c;
sipx->sipx_special = IPX_SPECIAL_NONE;
sipx->sipx_network = 0L;
sipx->sipx_type = IPX_FRAME_NONE;
while ((c = getopt(argc, argv, "p")) > 0) {
switch (c) {
case 'p': sipx->sipx_special = IPX_PRIMARY; break;
}
}
if (((i = (argc - optind)) < 2) || (i > 3)) {
usage();
}
for (i = optind; i < argc; i++) {
switch (i-optind) {
case 0: /* Physical Device - Required */
strcpy(id.ifr_name, argv[i]);
break;
case 1: /* Frame Type - Required */
fti = lookup_frame_type(argv[i]);
if (fti < 0)
exit(-1);
sipx->sipx_type = frame_types[fti].ft_val;
break;
case 2: /* Network Number - Optional */
netnum = strtoul(argv[i], (char **)NULL, 16);
if (netnum == 0xffffffffL) {
fprintf(stderr,
"%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
sipx->sipx_network = htonl(netnum);
break;
}
}
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
i = 0;
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_CRTITF;
do {
result = ioctl(s, SIOCSIFADDR, &id);
i++;
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
if (result == 0) exit(0);
switch (errno) {
case EEXIST:
fprintf(stderr, "%s: Primary network already selected.\n",
progname);
break;
case EADDRINUSE:
fprintf(stderr, "%s: Network number (%08lX) already in use.\n",
progname, htonl(sipx->sipx_network));
break;
case EPROTONOSUPPORT:
fprintf(stderr, "%s: Invalid frame type (%s).\n",
progname, frame_types[fti].ft_name);
break;
case ENODEV:
fprintf(stderr, "%s: No such device (%s).\n", progname,
id.ifr_name);
break;
case ENETDOWN:
fprintf(stderr, "%s: Requested device (%s) is down.\n", progname,
id.ifr_name);
break;
case EINVAL:
fprintf(stderr, "%s: Invalid device (%s).\n", progname,
id.ifr_name);
break;
case EAGAIN:
fprintf(stderr,
"%s: Insufficient memory to create interface.\n",
progname);
break;
default:
sprintf(errmsg, "%s: ioctl", progname);
perror(errmsg);
break;
}
exit(-1);
}
int
ipx_del_interface(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
int s;
int result;
char errmsg[80];
int fti;
if (argc != 3) {
usage();
}
sipx->sipx_network = 0L;
strcpy(id.ifr_name, argv[1]);
fti = lookup_frame_type(argv[2]);
if (fti < 0)
exit(-1);
sipx->sipx_type = frame_types[fti].ft_val;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
sipx->sipx_action = IPX_DLTITF;
sipx->sipx_family = AF_IPX;
result = ioctl(s, SIOCSIFADDR, &id);
if (result == 0) exit(0);
switch (errno) {
case EPROTONOSUPPORT:
fprintf(stderr, "%s: Invalid frame type (%s).\n",
progname, frame_types[fti].ft_name);
break;
case ENODEV:
fprintf(stderr, "%s: No such device (%s).\n", progname,
id.ifr_name);
break;
case EINVAL:
fprintf(stderr, "%s: No such IPX interface %s %s.\n", progname,
id.ifr_name, frame_types[fti].ft_name);
break;
default:
sprintf(errmsg, "%s: ioctl", progname);
perror(errmsg);
break;
}
exit(-1);
}
int
ipx_check_interface(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
int s;
int result;
char errmsg[80];
int fti;
if (argc != 3) {
usage();
}
sipx->sipx_network = 0L;
strcpy(id.ifr_name, argv[1]);
fti = lookup_frame_type(argv[2]);
if (fti < 0)
exit(-1);
sipx->sipx_type = frame_types[fti].ft_val;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
sipx->sipx_family = AF_IPX;
result = ioctl(s, SIOCGIFADDR, &id);
if (result == 0) {
printf(
"IPX Address for (%s, %s) is %08lX:%02X%02X%02X%02X%02X%02X.\n",
argv[1], frame_types[fti].ft_name,
htonl(sipx->sipx_network), sipx->sipx_node[0],
sipx->sipx_node[1], sipx->sipx_node[2],
sipx->sipx_node[3], sipx->sipx_node[4],
sipx->sipx_node[5]);
exit(0);
}
switch (errno) {
case EPROTONOSUPPORT:
fprintf(stderr, "%s: Invalid frame type (%s).\n",
progname, frame_types[fti].ft_name);
break;
case ENODEV:
fprintf(stderr, "%s: No such device (%s).\n", progname,
id.ifr_name);
break;
case EADDRNOTAVAIL:
fprintf(stderr, "%s: No such IPX interface %s %s.\n", progname,
id.ifr_name, frame_types[fti].ft_name);
break;
default:
sprintf(errmsg, "%s: ioctl", progname);
perror(errmsg);
break;
}
exit(-1);
}
int
main(int argc, char **argv)
{
int i;
progname = argv[0];
if (argc < 2) {
usage();
exit(-1);
}
if (strncasecmp(argv[1], "add", 3) == 0) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_add_interface(argc-1, argv);
} else if (strncasecmp(argv[1], "del", 3) == 0) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_del_interface(argc-1, argv);
} else if (strncasecmp(argv[1], "check", 5) == 0) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_check_interface(argc-1, argv);
}
usage();
return 0;
}

195
ipx-0.75/ipx_internal_net.c Normal file
View File

@@ -0,0 +1,195 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <strings.h>
#include <netinet/in.h>
#include <linux/ipx.h>
#include <linux/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
static struct ifreq id;
static char *progname;
void
usage(void)
{
fprintf(stderr, "Usage: %s add net_number(hex) node(hex)\n\
Usage: %s del\n", progname, progname);
exit(-1);
}
int
map_char_to_val(char dig)
{
char digit = tolower(dig);
if ((digit >= '0') && (digit <= '9')) {
return digit - '0';
} else if ((digit >= 'a') && (digit <= 'f')) {
return (10 + (digit - 'a'));
} else {
return 0;
}
}
int
ipx_add_internal_net(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
int s;
int result;
unsigned long netnum;
char errmsg[80];
int nodelen;
char *node;
char tmpnode[13];
unsigned char *tout;
char *tin;
int i;
if (argc != 3) {
usage();
}
netnum = strtoul(argv[1], (char **)NULL, 16);
if ((netnum == 0L) || (netnum == 0xffffffffL)) {
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
node = argv[2];
nodelen = strlen(node);
if (nodelen > 12) {
fprintf(stderr, "%s: Node length is too long (> 12).\n", progname);
exit(-1);
}
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++)
;
if (i < nodelen) {
fprintf(stderr, "%s: Invalid value in node, must be hex digits.\n",
progname);
exit(-1);
}
strcpy(tmpnode, "000000000000");
memcpy(&(tmpnode[12-nodelen]), node, nodelen);
for (tin = tmpnode, tout = sipx->sipx_node; *tin != '\0'; tin += 2, tout++) {
*tout = (unsigned char) map_char_to_val(*tin);
*tout <<= 4;
*tout |= (unsigned char) map_char_to_val(*(tin+1));
}
if ((memcmp(sipx->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) ||
(memcmp(sipx->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)){
fprintf(stderr, "%s: Node is invalid.\n", progname);
exit(-1);
}
sipx->sipx_network = htonl(netnum);
sipx->sipx_type = IPX_FRAME_NONE;
sipx->sipx_special = IPX_INTERNAL;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_CRTITF;
i = 0;
do {
result = ioctl(s, SIOCSIFADDR, &id);
i++;
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
if (result == 0) exit(0);
switch (errno) {
case EEXIST:
fprintf(stderr, "%s: Primary network already selected.\n",
progname);
break;
case EADDRINUSE:
fprintf(stderr, "%s: Network number (%08lX) already in use.\n",
progname, htonl(sipx->sipx_network));
break;
case EAGAIN:
fprintf(stderr,
"%s: Insufficient memory to create internal net.\n",
progname);
break;
default:
sprintf(errmsg, "%s: ioctl", progname);
perror(errmsg);
break;
}
exit(-1);
}
int
ipx_del_internal_net(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
int s;
int result;
char errmsg[80];
if (argc != 1) {
usage();
}
sipx->sipx_network = 0L;
sipx->sipx_special = IPX_INTERNAL;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_DLTITF;
result = ioctl(s, SIOCSIFADDR, &id);
if (result == 0) exit(0);
switch (errno) {
case ENOENT:
fprintf(stderr, "%s: No internal network configured.\n", progname);
break;
default:
sprintf(errmsg, "%s: ioctl", progname);
perror(errmsg);
break;
}
exit(-1);
}
int
main(int argc, char **argv)
{
int i;
progname = argv[0];
if (argc < 2) {
usage();
exit(-1);
}
if (strncasecmp(argv[1], "add", 3) == 0) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_add_internal_net(argc-1, argv);
} else if (strncasecmp(argv[1], "del", 3) == 0) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_del_internal_net(argc-1, argv);
}
usage();
return 0;
}

215
ipx-0.75/ipx_route.c Normal file
View File

@@ -0,0 +1,215 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <strings.h>
#include <netinet/in.h>
#include <linux/ipx.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/route.h>
static struct rtentry rd;
static char *progname;
int
map_char_to_val(char dig)
{
char digit = tolower(dig);
if ((digit >= '0') && (digit <= '9')) {
return digit - '0';
} else if ((digit >= 'a') && (digit <= 'f')) {
return (10 + (digit - 'a'));
} else {
return 0;
}
}
void
usage(void)
{
fprintf(stderr,
"Usage: %s add network(hex) router_network(hex) router_node(hex)\n\
Usage: %s del network(hex)\n", progname, progname);
exit(-1);
}
int
ipx_add_route(int argc, char **argv)
{
/* Router */
struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway;
/* Target */
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst;
int s;
int result;
int nodelen;
int i;
unsigned long netnum;
char errmsg[80];
char *node;
char *tin;
char tmpnode[13];
unsigned char *tout;
if (argc != 4)
usage();
/* Network Number */
netnum = strtoul(argv[1], (char **)NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
rd.rt_flags = RTF_GATEWAY;
st->sipx_network = htonl(netnum);
/* Router Network Number */
netnum = strtoul(argv[2], (char **)NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
sr->sipx_network = htonl(netnum);
/* Router Node */
node = argv[3];
nodelen = strlen(node);
if (nodelen > 12) {
fprintf(stderr, "%s: Node length is too long (> 12).\n",
progname);
exit(-1);
}
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++)
;
if (i < nodelen) {
fprintf(stderr, "%s: Invalid value in node, must be hex digits.\n",
progname);
exit(-1);
}
strcpy(tmpnode, "000000000000");
memcpy(&(tmpnode[12-nodelen]), node, nodelen);
for (tin = tmpnode, tout = sr->sipx_node; *tin != '\0'; tin += 2, tout++) {
*tout = (unsigned char) map_char_to_val(*tin);
*tout <<= 4;
*tout |= (unsigned char) map_char_to_val(*(tin+1));
}
if ((memcmp(sr->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) ||
(memcmp(sr->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)){
fprintf(stderr, "%s: Node (%s) is invalid.\n", progname, tmpnode);
exit(-1);
}
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
sr->sipx_family = st->sipx_family = AF_IPX;
i = 0;
do {
result = ioctl(s, SIOCADDRT, &rd);
i++;
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
if (result == 0) exit(0);
switch (errno) {
case ENETUNREACH:
fprintf(stderr, "%s: Router network (%08lX) not reachable.\n",
progname, htonl(sr->sipx_network));
break;
default:
sprintf(errmsg, "%s: ioctl", progname);
perror(errmsg);
break;
}
exit(-1);
}
int
ipx_del_route(int argc, char **argv)
{
/* Router */
struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway;
/* Target */
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst;
int s;
int result;
unsigned long netnum;
char errmsg[80];
if (argc != 2) {
usage();
}
rd.rt_flags = RTF_GATEWAY;
/* Network Number */
netnum = strtoul(argv[1], (char **)NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
fprintf(stderr, "%s: Inappropriate network number %08lX.\n",
progname, netnum);
exit(-1);
}
st->sipx_network = htonl(netnum);
st->sipx_family = sr->sipx_family = AF_IPX;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
result = ioctl(s, SIOCDELRT, &rd);
if (result == 0) exit(0);
switch (errno) {
case ENOENT:
fprintf(stderr, "%s: Route not found for network %08lX.\n",
progname, netnum);
break;
case EPERM:
fprintf(stderr, "%s: Network %08lX is directly connected.\n",
progname, netnum);
break;
default:
sprintf(errmsg, "%s: ioctl", progname);
perror(errmsg);
break;
}
exit(-1);
}
int
main(int argc, char **argv)
{
int i;
progname = argv[0];
if (argc < 2) {
usage();
exit(-1);
}
if (strncasecmp(argv[1], "add", 3) == 0) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_add_route(argc-1, argv);
} else if (strncasecmp(argv[1], "del", 3) == 0) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_del_route(argc-1, argv);
}
usage();
return 0;
}

52
ipx-0.75/ipxrcv.c Normal file
View File

@@ -0,0 +1,52 @@
#include <stdio.h>
#include <sys/types.h>
#include <linux/ipx.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
int
main(int argc, char **argv)
{
struct sockaddr_ipx sipx;
int s;
int result;
char msg[100];
int len;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
perror("IPX: socket: ");
exit(-1);
}
sipx.sipx_family = AF_IPX;
sipx.sipx_network = 0;
sipx.sipx_port = htons(0x5000);
sipx.sipx_type = 17;
len = sizeof(sipx);
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
if (result < 0) {
perror("IPX: bind: ");
exit(-1);
}
msg[0] = '\0';
result = recvfrom(s, msg, sizeof(msg), 0, (struct sockaddr *)&sipx,
&len);
if (result < 0) {
perror("IPX: recvfrom: ");
}
printf("From %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
htonl(sipx.sipx_network),
sipx.sipx_node[0], sipx.sipx_node[1],
sipx.sipx_node[2], sipx.sipx_node[3],
sipx.sipx_node[4], sipx.sipx_node[5],
htons(sipx.sipx_port));
printf("\tGot \"%s\"\n", msg);
return 0;
}

46
ipx-0.75/ipxsend.c Normal file
View File

@@ -0,0 +1,46 @@
#include <stdio.h>
#include <sys/types.h>
#include <linux/ipx.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
int
main(int argc, char **argv)
{
struct sockaddr_ipx sipx;
int s;
int result;
char msg[100] = "Hi Mom";
int len = sizeof(sipx);
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
perror("IPX: socket: ");
exit(-1);
}
sipx.sipx_family = AF_IPX;
sipx.sipx_network = 0;
sipx.sipx_port = 0;
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
if (result < 0) {
perror("IPX: bind: ");
exit(-1);
}
result = getsockname(s, (struct sockaddr *)&sipx, &len);
sipx.sipx_port = htons(0x5000);
result = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *)&sipx,
sizeof(sipx));
if (result < 0) {
perror("IPX: send: ");
exit(-1);
}
return 0;
}

68
ipx-0.75/rip.c Normal file
View File

@@ -0,0 +1,68 @@
#include <stdio.h>
#include <sys/types.h>
#include <linux/ipx.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
struct rip_data {
unsigned long rip_net;
unsigned short rip_hops __attribute__ ((packed));
unsigned short rip_ticks __attribute__ ((packed));
};
int
main(int argc, char **argv)
{
struct sockaddr_ipx sipx;
int result;
int s;
char msg[1024];
int len;
char *bptr;
struct rip_data *rp;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
perror("IPX: socket: ");
exit(-1);
}
sipx.sipx_family = AF_IPX;
sipx.sipx_network = 0;
sipx.sipx_port = htons(0x453);
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
if (result < 0) {
perror("IPX: bind: ");
exit(-1);
}
while (1) {
len = sizeof(sipx);
result = recvfrom(s, msg, sizeof(msg), 0,
(struct sockaddr *)&sipx, &len);
if (result < 0) {
perror("IPX: recvfrom");
exit(-1);
}
bptr = msg;
result -= 2;
printf("RIP packet from: %08lX:%02X%02X%02X%02X%02X%02X\n",
htonl(sipx.sipx_network),
sipx.sipx_node[0], sipx.sipx_node[1],
sipx.sipx_node[2], sipx.sipx_node[3],
sipx.sipx_node[4], sipx.sipx_node[5]);
bptr += 2;
rp = (struct rip_data *) bptr;
while (result >= sizeof(struct rip_data)) {
printf("\tNET: %08lX HOPS: %d\n", ntohl(rp->rip_net),
ntohs(rp->rip_hops));
result -= sizeof(struct rip_data);
rp++;
}
}
}

96
ipx-0.75/sap.c Normal file
View File

@@ -0,0 +1,96 @@
#include <stdio.h>
#include <sys/types.h>
#include <linux/ipx.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
struct sap_data {
unsigned short sap_type __attribute__ ((packed));
char sap_name[48] __attribute__ ((packed));
unsigned long sap_net __attribute__ ((packed));
unsigned char sap_node[6] __attribute__ ((packed));
unsigned short sap_sock __attribute__ ((packed));
unsigned short sap_hops __attribute__ ((packed));
};
int
main(int argc, char **argv)
{
int s;
int result;
struct sockaddr_ipx sipx;
char msg[1024];
long val = 0;
int len;
char *bptr;
struct sap_data *sp;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
perror("IPX: socket: ");
exit(-1);
}
result = setsockopt(s, SOL_SOCKET, SO_DEBUG, &val, 4);
if (result < 0) {
perror("IPX: setsockopt: ");
exit(-1);
}
sipx.sipx_family = PF_IPX;
sipx.sipx_network = 0L;
sipx.sipx_port = htons(0x452);
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
if (result < 0) {
perror("IPX: bind: ");
exit(-1);
}
while (1) {
len = 1024;
result = recvfrom(s, msg, sizeof(msg), 0,
(struct sockaddr *)&sipx, &len);
if (result < 0) {
perror("IPX: recvfrom: ");
exit(-1);
}
bptr = msg;
result -= 2;
printf("SAP: OP is %x %x\n", bptr[0], bptr[1]);
printf("Length is %d\n", result);
if (bptr[1] != 2)
continue;
bptr += 2;
sp = (struct sap_data *) bptr;
while (result >= sizeof(struct sap_data)) {
int i;
sp->sap_name[32] = '\0';
for (i = 31; (i > 0) && (sp->sap_name[i] == '_'); i--);
i++;
sp->sap_name[i] = '\0';
printf("NAME: %s TYPE: %x HOPS: %x\n", sp->sap_name,
ntohs(sp->sap_type), ntohs(sp->sap_hops));
printf("%lx:%x %x %x %x %x %x: %x\n",
ntohl(sp->sap_net),
sp->sap_node[0],
sp->sap_node[1],
sp->sap_node[2],
sp->sap_node[3],
sp->sap_node[4],
sp->sap_node[5],
ntohs(sp->sap_sock));
result -= sizeof(struct sap_data);
sp++;
}
}
}

View File

@@ -9,6 +9,7 @@
#define _LINUX_NCP_H
#include <linux/types.h>
#include <linux/ipx.h>
#define NCP_PTYPE (0x11)
#define NCP_PORT (0x0451)
@@ -51,6 +52,9 @@ struct ncp_bindery_object {
__u32 object_id;
__u16 object_type;
__u8 object_name[NCP_BINDERY_NAME_LEN];
__u8 object_flags;
__u8 object_security;
__u8 object_has_prop;
};
struct nw_property {
@@ -59,6 +63,11 @@ struct nw_property {
__u8 property_flag;
};
struct prop_net_address {
__u32 network __attribute__ ((packed));
__u8 node[IPX_NODE_LEN] __attribute__ ((packed));
__u16 port __attribute__ ((packed));
};
#define NCP_VOLNAME_LEN (16)
#define NCP_NUMBER_OF_VOLUMES (64)
@@ -263,16 +272,23 @@ struct queue_job {
/* ClientRecordArea for print jobs */
#define KEEP_ON 0x0400
#define NO_FORM_FEED 0x0800
#define NOTIFICATION 0x1000
#define DELETE_FILE 0x2000
#define EXPAND_TABS 0x4000
#define PRINT_BANNER 0x8000
struct print_job_record {
__u8 Version __attribute__ ((packed));
__u16 TabSize __attribute__ ((packed));
__u8 TabSize __attribute__ ((packed));
__u16 Copies __attribute__ ((packed));
__u8 CtrlFlags __attribute__ ((packed));
__u16 CtrlFlags __attribute__ ((packed));
__u16 Lines __attribute__ ((packed));
__u16 Rows __attribute__ ((packed));
char FormName[16] __attribute__ ((packed));
__u8 Reserved[6] __attribute__ ((packed));
char Banner[13] __attribute__ ((packed));
char BannerName[13] __attribute__ ((packed));
char FnameBanner[13] __attribute__ ((packed));
char FnameHeader[14] __attribute__ ((packed));
char Path[80] __attribute__ ((packed));

View File

@@ -20,14 +20,14 @@ ARCH = i386
.s.o:
$(AS) -o $*.o $<
OBJS= dir.o inode.o file.o sock.o ioctl.o ncplib.o
OBJS= dir.o inode.o file.o sock.o ioctl.o ncplib_kernel.o
all: ncpfs.o
ncpfs.o: $(OBJS)
$(LD) -r -o ncpfs.o $(OBJS)
ncplib.o: ncplib.c ncplib.h
ncplib_kernel.o: ncplib_kernel.c ncplib_kernel.h
$(CC) $(CFLAGS) -finline-functions -c $<
dep:

View File

@@ -23,7 +23,7 @@
#include <linux/ncp_fs.h>
#include <asm/segment.h>
#include <linux/errno.h>
#include "ncplib.h"
#include "ncplib_kernel.h"
struct ncp_dirent {
struct nw_info_struct i;

View File

@@ -26,7 +26,7 @@
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/ncp_fs.h>
#include "ncplib.h"
#include "ncplib_kernel.h"
#include <linux/malloc.h>
static int

View File

@@ -27,7 +27,7 @@
#include <linux/locks.h>
#include <linux/fcntl.h>
#include <linux/malloc.h>
#include "ncplib.h"
#include "ncplib_kernel.h"
extern int close_fp(struct file *filp);

View File

@@ -9,7 +9,7 @@
#include "ncplib.h"
#include "ncplib_kernel.h"
typedef __u8 byte;
typedef __u16 word;

View File

@@ -11,6 +11,7 @@
#error "Please use kernel 1.2.13"
#include <linux/types.h>
#include <linux/ipx.h>
#define NCP_PTYPE (0x11)
#define NCP_PORT (0x0451)
@@ -53,6 +54,9 @@ struct ncp_bindery_object {
__u32 object_id;
__u16 object_type;
__u8 object_name[NCP_BINDERY_NAME_LEN];
__u8 object_flags;
__u8 object_security;
__u8 object_has_prop;
};
struct nw_property {
@@ -61,6 +65,11 @@ struct nw_property {
__u8 property_flag;
};
struct prop_net_address {
__u32 network __attribute__ ((packed));
__u8 node[IPX_NODE_LEN] __attribute__ ((packed));
__u16 port __attribute__ ((packed));
};
#define NCP_VOLNAME_LEN (16)
#define NCP_NUMBER_OF_VOLUMES (64)
@@ -265,16 +274,23 @@ struct queue_job {
/* ClientRecordArea for print jobs */
#define KEEP_ON 0x0400
#define NO_FORM_FEED 0x0800
#define NOTIFICATION 0x1000
#define DELETE_FILE 0x2000
#define EXPAND_TABS 0x4000
#define PRINT_BANNER 0x8000
struct print_job_record {
__u8 Version __attribute__ ((packed));
__u16 TabSize __attribute__ ((packed));
__u8 TabSize __attribute__ ((packed));
__u16 Copies __attribute__ ((packed));
__u8 CtrlFlags __attribute__ ((packed));
__u16 CtrlFlags __attribute__ ((packed));
__u16 Lines __attribute__ ((packed));
__u16 Rows __attribute__ ((packed));
char FormName[16] __attribute__ ((packed));
__u8 Reserved[6] __attribute__ ((packed));
char Banner[13] __attribute__ ((packed));
char BannerName[13] __attribute__ ((packed));
char FnameBanner[13] __attribute__ ((packed));
char FnameHeader[14] __attribute__ ((packed));
char Path[80] __attribute__ ((packed));

View File

@@ -20,14 +20,14 @@ ARCH = i386
.s.o:
$(AS) -o $*.o $<
OBJS= dir.o inode.o file.o sock.o ioctl.o ncplib.o
OBJS= dir.o inode.o file.o sock.o ioctl.o ncplib_kernel.o
all: ncpfs.o
ncpfs.o: $(OBJS)
$(LD) -r -o ncpfs.o $(OBJS)
ncplib.o: ncplib.c ncplib.h
ncplib_kernel.o: ncplib_kernel.c ncplib_kernel.h
$(CC) $(CFLAGS) -finline-functions -c $<
dep:

View File

@@ -14,7 +14,7 @@
#include <linux/ncp_fs.h>
#include <asm/segment.h>
#include <linux/errno.h>
#include "ncplib.h"
#include "ncplib_kernel.h"
struct ncp_dirent {
struct nw_info_struct i;

View File

@@ -15,7 +15,7 @@
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/ncp_fs.h>
#include "ncplib.h"
#include "ncplib_kernel.h"
#include <linux/malloc.h>
static int

View File

@@ -20,7 +20,7 @@
#include <linux/locks.h>
#include <linux/fcntl.h>
#include <linux/malloc.h>
#include "ncplib.h"
#include "ncplib_kernel.h"
extern int close_fp(struct file *filp);
@@ -142,7 +142,7 @@ ncp_put_inode(struct inode *inode)
printk("ncp_put_inode: could not close\n");
}
}
DDPRINTK("ncp_put_inode: put %s\n",
finfo->i.entryName);

View File

@@ -1,4 +1,4 @@
#include "ncplib.h"
#include "ncplib_kernel.h"
typedef __u8 byte;
typedef __u16 word;

61
man/ipx_interface.8 Normal file
View File

@@ -0,0 +1,61 @@
.TH IPX_INTERFACE 8 "IPX Utilities" "Caldera, Inc."
.SH NAME
ipx_interface \- add, delete, or display an IPX interface
.SH SYNOPSIS
.B ipx_interface
add [-p] device frame_type [network number]
.LP
.B ipx_interface
del device frame_type
.LP
.B ipx_interface
check device frame_type
.LP
.B ipx_interface
help
.SH DESCRIPTION
.B ipx_interface
adds, deletes, or displays IPX interfaces depending on the option selected.
.P
An IPX interface is the item to which IPX sockets are bound.
An IPX interface corresponds to an IPX Network Number which corresponds
to a physical device and frame type. A sample IPX Interface would be:
.LP
Network Number: 0x00ABCDEF
.LP
Device: Eth0
.LP
Frame Type: 802.2.
.P
There is a special IPX interface per host known as the
.B PRIMARY
or default interface.
.SS OPTIONS
.TP
.I add
This option is used to create an IPX interface. If the
.B -p
flag is used, the interface is made
.B
PRIMARY.
The network number can be optionally assigned. If it is not assigned, it
is set to 0 which indicates it should be detected from the traffic on the
network.
.TP
.I del
This option is used to delete an IPX interface.
.TP
.I check
This option is used to display the device, frame type, and network number
of an IPX interface.
.TP
.I help
This option displays information about the utility.
.SH FILES
.I /proc/net/ipx_interface /proc/net/ipx_route
.SH BUGS
This functionality really belongs in
.B
ifconfig(8).
.SH AUTHOR
Greg Page <greg.page@caldera.com>

32
man/ipx_internal_net.8 Normal file
View File

@@ -0,0 +1,32 @@
.TH IPX_INTERNAL_NET 8 "IPX Utilities" "Caldera, Inc."
.SH NAME
ipx_internal_net \- add or delete the IPX internal network
.SH SYNOPSIS
.B ipx_internal_net
add network_number node_number
.LP
.B ipx_internal_net
del
.SH DESCRIPTION
.B ipx_internal_net
adds or deletes the IPX internal network.
An IPX internal network is a special kind of IPX interface that does
not have a physical device or frame type. It is used to provide
a route-independent address for service providers. Internal networks
are optional; however, when one is present it is also the
Primary Interface. There can only be one internal network per host.
.SS OPTIONS
.TP
.I add
This option is used to create the IPX internal network.
.TP
.I del
This option is used to delete the IPX internal network.
.SH FILES
.I /proc/net/ipx_interface /proc/net/ipx_route
.SH BUGS
This functionality really belongs in
.B
ifconfig(8).
.SH AUTHOR
Greg Page <greg.page@caldera.com>

24
man/ipx_route.8 Normal file
View File

@@ -0,0 +1,24 @@
.TH IPX_ROUTE 8 "IPX Utilities" "Caldera, Inc."
.SH NAME
ipx_route \- add or delete IPX route
.SH SYNOPSIS
.B ipx_route
add target_network router_network router_node
.LP
.B ipx_route
del target_network
.SH DESCRIPTION
.B ipx_route
adds or deletes an IPX route.
The kernel IPX stores only one route per target network at a time.
.SS OPTIONS
.TP
.I add
This option is used to set up the route to a target network.
.TP
.I del
This option is used to delete the route to a target network.
.SH FILES
.I /proc/net/ipx_interface /proc/net/ipx_route
.SH AUTHOR
Greg Page <greg.page@caldera.com>

View File

@@ -1,4 +1,4 @@
.TH NCPMOUNT 8 25/11/1995 ncpmount ncpmount
.TH NCPMOUNT 8 11/25/1995 ncpmount ncpmount
.SH NAME
ncpmount \- mount program for ncpfs
.SH SYNOPSIS

View File

@@ -1,4 +1,4 @@
.TH NCPUMOUNT 8 25/11/1995 ncpumount ncpumount
.TH NCPUMOUNT 8 11/25/1995 ncpumount ncpumount
.SH NAME
ncpumount \- umount for normal users
.SH SYNOPSIS

44
man/slist.1 Normal file
View File

@@ -0,0 +1,44 @@
.TH SLIST 1 12/02/1995 slist slist
.SH NAME
slist \- list all know NetWare file servers
.SH SYNOPSIS
.B slist
[pattern]
.SH DESCRIPTION
With
.B slist
you can list all NetWare file servers that are known in your IPX network.
.B slist
is modeled after the well-know DOS utility. As an option, you can give
a wildcard pattern to slist. This can be convienient if you want to
know whether a specific server is reachable, of if your IPX network
contains a lot of servers.
The pattern is converted to upper case, because NetWare stores only upper-case name. So you can find out whether you can access FS311 by typing
.RS 3
slist fs311
.RE
Please note that the decorative header is
.I not
printed if slist prints to a pipe. So you can count the number of file
servers simply by typing
.RS 3
slist | wc -l
.RE
.SH BUGS
You might need superuser privileges to run slist. This sounds paradox,
but if your IPX routing table is not administered by an IPX routing
daemon, slist needs to add a route to the internal network of the
server that's nearest to you. For ncpmount, this is no problem, as it
has to be suid root anyway. So you could make slist setuid root. This
should be safe, because slist does not do much. The second option is
to run an IPX routing daemon, which automatically adjusts your routing
tables.
.SH AUTHOR
Volker Lendecke <lendecke@namu01.gwdg.de>

View File

@@ -1,14 +1,14 @@
Begin3
Title: ncpfs
Version: 0.8
Entered-date: 28. November 1995
Version: 0.9
Entered-date: 02. December 1995
Description: With ncpfs you can mount volumes of your novell
server under Linux.
Keywords: filesystem kernel ncp novell netware
Author: lendecke@namu01.gwdg.de (Volker Lendecke)
Maintained-by: lendecke@namu01.gwdg.de (Volker Lendecke)
Primary-site: linux01.gwdg.de:/pub/ncpfs
~80k ncpfs-0.8.tgz
~ 1k ncpfs-0.8.lsm
~81k ncpfs-0.9.tgz
~ 1k ncpfs-0.9.lsm
Copying-policy: GPL
End

View File

@@ -4,30 +4,24 @@
INCLUDES = -I/usr/src/linux/include -I../kernel
BINDIR = ../bin
UTILS = ncpmount ncpumount ncptest ipx_configure
UTILS = $(BINDIR)/ncpmount $(BINDIR)/ncpumount $(BINDIR)/slist ncptest
CFLAGS = -Wall $(INCLUDES) -O2
CC = gcc
all: $(UTILS)
ncpmount: ncpmount.o ncplib_user.o nwcrypt.o
$(CC) -o ncpmount ncpmount.o ncplib_user.o nwcrypt.o
cp ncpmount $(BINDIR)
$(BINDIR)/ncpmount: ncpmount.o ncplib.o
$(CC) -o $(BINDIR)/ncpmount ncpmount.o ncplib.o
ncpumount: ncpumount.o ncplib_user.o nwcrypt.o
$(CC) -o ncpumount ncpumount.o ncplib_user.o nwcrypt.o
cp ncpumount $(BINDIR)
$(BINDIR)/ncpumount: ncpumount.o ncplib.o
$(CC) -o $(BINDIR)/ncpumount ncpumount.o ncplib.o
ipx_configure: ipx_configure.c
$(CC) $(CFLAGS) ipx_configure.c -o ipx_configure
cp ipx_configure $(BINDIR)
$(BINDIR)/slist: slist.o ncplib.o
$(CC) -o $(BINDIR)/slist slist.o ncplib.o
ncptest: ncptest.o ncplib_user.o nwcrypt.o
$(CC) -o ncptest ncptest.o ncplib_user.o nwcrypt.o
nwcrypt.o: nwcrypt.c
$(CC) -c -O3 -Wall nwcrypt.c
ncptest: ncptest.o ncplib.o
$(CC) -o ncptest ncptest.o ncplib.o
dep:
$(CPP) -M $(INCLUDES) *.c > .depend

Binary file not shown.

View File

@@ -1,76 +0,0 @@
/*
IPX support library
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
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 <string.h>
#include <linux/ipx.h>
#define IPX_RIP_PTYPE (0x01)
#define IPX_SAP_PTYPE (0x04)
#define IPX_SAP_PORT (0x0452)
#define IPX_RIP_PORT (0x0453)
#define IPX_SAP_GENERAL_QUERY (0x0001)
#define IPX_SAP_GENERAL_RESPONSE (0x0002)
#define IPX_SAP_NEAREST_QUERY (0x0003)
#define IPX_SAP_NEAREST_RESPONSE (0x0004)
#define IPX_SAP_FILE_SERVER (0x0004)
#define IPX_RIP_REQUEST (0x1)
#define IPX_RIP_RESPONSE (0x2)
struct ipx_rip_packet {
__u16 operation __attribute__ ((packed));
struct ipx_rt_def {
__u32 network __attribute__ ((packed));
__u16 hops __attribute__ ((packed));
__u16 ticks __attribute__ ((packed));
} rt[1] __attribute__ ((packed));
};
#define IPX_BROADCAST_NODE "\xff\xff\xff\xff\xff\xff"
#define IPX_THIS_NODE "\0\0\0\0\0\0"
#ifndef IPX_NODE_LEN
#define IPX_NODE_LEN (6)
#endif
typedef unsigned long IPXNet;
typedef unsigned short IPXPort;
typedef unsigned char IPXNode[IPX_NODE_LEN];
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);
static __inline__ void
ipx_assign_node(IPXNode dest, IPXNode src) {
memcpy(dest, src, IPX_NODE_LEN);
}
#endif

View File

@@ -1,5 +1,4 @@
#include "ncplib_user.h"
#include "nwcrypt.h"
#include "ncplib.h"
typedef __u8 byte;
typedef __u16 word;
@@ -17,7 +16,93 @@ extern pid_t wait(int *);
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include "ipxutil.h"
#include <linux/route.h>
/* I know it's terrible to include a .c file here, but I want to keep
the file nwcrypt.c intact and separate for legal reasons */
#include "nwcrypt.c"
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",ntohl(net));
}
void
ipx_fprint_port(FILE* file,IPXPort port)
{
fprintf(file,"%04X",ntohs(port));
}
void
ipx_fprint_saddr(FILE* file,struct sockaddr_ipx* sipx)
{
ipx_fprint_network(file,sipx->sipx_network);
fprintf(file,":");
ipx_fprint_node(file,sipx->sipx_node);
fprintf(file,":");
ipx_fprint_port(file,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);
}
int
ipx_sscanf_node(char *buf, unsigned char node[6])
{
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 i;
}
for (i=0; i<6; i++) {
node[i] = n[i];
}
return 6;
}
void
ipx_assign_node(IPXNode dest, IPXNode src) {
memcpy(dest, src, IPX_NODE_LEN);
}
#define ncp_printf printf
@@ -79,17 +164,57 @@ ncp_ioctl_request(struct ncp_server *server, int function) {
return result;
}
static int
ipx_recvfrom(int sock, void *buf, int len, unsigned int flags,
struct sockaddr_ipx *sender, int *addrlen, int timeout)
{
fd_set rd, wr, ex;
struct timeval tv;
int result;
FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&ex);
FD_SET(sock, &rd);
tv.tv_sec = timeout;
tv.tv_usec = 0;
if ((result = select(sock+1, &rd, &wr, &ex, &tv)) == -1) {
return result;
}
if (FD_ISSET(sock, &rd)) {
result = recvfrom(sock, buf, len, flags,
(struct sockaddr *)sender, addrlen);
}
else
{
result = -1;
errno = ETIMEDOUT;
}
return result;
}
static int
ipx_recv(int sock, void *buf, int len, unsigned int flags, int timeout)
{
struct sockaddr_ipx sender;
int addrlen = sizeof(sender);
return ipx_recvfrom(sock, buf, len, flags, &sender, &addrlen, timeout);
}
static int
do_ncp_call(struct ncp_server *server, int request_size)
{
struct ncp_request_header request =
*((struct ncp_request_header *)(&(server->ncp_data)));
fd_set rd, wr, ex;
struct timeval tv;
int result;
int retries = 3;
int len;
struct ncp_reply_header *r =
(struct ncp_reply_header *)&(server->ncp_data);
while (retries > 0) {
retries -= 1;
@@ -104,37 +229,21 @@ do_ncp_call(struct ncp_server *server, int request_size)
}
re_select:
FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&ex);
FD_SET(server->ncp_sock, &rd);
tv.tv_sec = 3;
tv.tv_usec = 0;
if (select(server->ncp_sock+1, &rd, &wr, &ex, &tv) == -1) {
perror("select");
return -1;
}
if (FD_ISSET(server->ncp_sock, &rd)) {
int len = recv(server->ncp_sock,
server->ncp_data, NCP_PACKET_SIZE,
0);
struct ncp_reply_header *r =
(struct ncp_reply_header *)&(server->ncp_data);
len = ipx_recv(server->ncp_sock,
server->ncp_data, NCP_PACKET_SIZE, 0, 1);
if ( (len == sizeof(*r))
&& (r->type == NCP_POSITIVE_ACK)) {
goto re_select;
}
if ( (len >= sizeof(*r))
&& (r->type == NCP_REPLY)
&& ( (request.type == NCP_ALLOC_SLOT_REQUEST)
|| ( (r->sequence == request.sequence)
&& (r->conn_low == request.conn_low)
&& (r->conn_high == request.conn_high)))) {
server->reply_size = len;
break;
}
if ( (len == sizeof(*r))
&& (r->type == NCP_POSITIVE_ACK)) {
goto re_select;
}
if ( (len >= sizeof(*r))
&& (r->type == NCP_REPLY)
&& ( (request.type == NCP_ALLOC_SLOT_REQUEST)
|| ( (r->sequence == request.sequence)
&& (r->conn_low == request.conn_low)
&& (r->conn_high == request.conn_high)))) {
server->reply_size = len;
break;
}
}
return 0;
@@ -189,8 +298,6 @@ install_wdog(struct ncp_server *server)
int pid;
int sock = server->wdog_sock;
fd_set rd, wr, ex;
struct timeval tv;
char buf[1024];
struct sockaddr_ipx sender;
int sizeofaddr = sizeof(struct sockaddr_ipx);
@@ -209,17 +316,10 @@ install_wdog(struct ncp_server *server)
while (1) {
FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&ex);
FD_SET(sock, &rd);
/* every 120 seconds we look if our parent is
still alive */
tv.tv_sec = 120;
tv.tv_usec = 0;
if (select(sock+1, &rd, &wr, &ex, &tv) == -1) {
continue;
}
pktsize = ipx_recvfrom(sock, buf, sizeof(buf), 0,
&sender, &sizeofaddr, 120);
if (getppid() != parent_pid) {
/* our parent has died, so nothing to do
@@ -227,31 +327,121 @@ install_wdog(struct ncp_server *server)
exit(0);
}
if (FD_ISSET(sock, &rd)) {
pktsize = recvfrom(sock, buf, sizeof(buf), 0,
(struct sockaddr *)&sender,
&sizeofaddr);
if (pktsize < 0) {
perror("recvfrom");
continue;
}
if ( (pktsize != 2)
|| (buf[1] != '?')) {
continue;
}
buf[1] = 'Y';
pktsize = sendto(sock, buf, 2, 0,
(struct sockaddr *)&sender,
sizeof(sender));
if (pktsize < 0) {
perror("send");
}
if ( (pktsize != 2)
|| (buf[1] != '?')) {
continue;
}
buf[1] = 'Y';
pktsize = sendto(sock, buf, 2, 0,
(struct sockaddr *)&sender,
sizeof(sender));
}
}
static int
ipx_make_reachable(IPXNet network)
{
struct rtentry rt_def;
/* Router */
struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rt_def.rt_gateway;
/* Target */
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rt_def.rt_dst;
struct ipx_rip_packet rip;
struct sockaddr_ipx addr;
int addrlen;
int sock;
int opt;
int res=-1;
int i;
int packets;
if (geteuid() != 0) {
errno = EPERM;
return -1;
}
memset(&rip, 0, sizeof(rip));
sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (sock == -1) {
return -1;
}
opt=1;
/* Permit broadcast output */
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt,sizeof(opt)) != 0){
goto finished;
}
memset(&addr, 0, sizeof(addr));
addr.sipx_family=AF_IPX;
addr.sipx_network=htonl(0x0);
addr.sipx_port=htons(0x0);
addr.sipx_type=IPX_RIP_PTYPE;
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
goto finished;
}
addr.sipx_family = AF_IPX;
addr.sipx_network = htonl(0x0);
addr.sipx_port = htons(IPX_RIP_PORT);
addr.sipx_type = IPX_RIP_PTYPE;
ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE);
rip.operation = htons(IPX_RIP_REQUEST);
rip.rt[0].network = htonl(network);
if (sendto(sock, &rip, sizeof(rip), 0,
(struct sockaddr *)&addr, sizeof(addr)) < 0) {
goto finished;
}
packets = 3;
do
{
int len;
if (packets == 0) {
goto finished;
}
addrlen = sizeof(struct sockaddr_ipx);
len = ipx_recvfrom(sock, &rip, sizeof(rip),0, sr, &addrlen, 1);
if (len < sizeof(rip)) {
packets = packets - 1;
continue;
}
} while (ntohs(rip.operation) != IPX_RIP_RESPONSE);
if (rip.rt[0].network != htonl(network)) {
goto finished;
}
rt_def.rt_flags = RTF_GATEWAY;
st->sipx_network = htonl(network);
sr->sipx_family = st->sipx_family = AF_IPX;
i = 0;
do {
res = ioctl(sock, SIOCADDRT, &rt_def);
i++;
} while ((i < 5) && (res < 0) && (errno == EAGAIN));
finished:
close(sock);
if (res != 0) {
errno = ENETUNREACH;
}
return res;
}
int
ncp_connect(struct ncp_server *server)
ncp_connect_addr(struct ncp_server *server, const struct sockaddr_ipx *target)
{
struct ncp_request_header *h =
(struct ncp_request_header *)&(server->ncp_data);
@@ -263,6 +453,7 @@ ncp_connect(struct ncp_server *server)
int ncp_port, wdog_port;
server->is_connected = NOT_CONNECTED;
server->silent = 1;
ncp_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (ncp_sock == -1) {
@@ -323,6 +514,7 @@ ncp_connect(struct ncp_server *server)
h->type = NCP_ALLOC_SLOT_REQUEST;
server->sequence = 0;
server->addr = *target;
h->sequence = server->sequence;
h->conn_low = 0xff;
h->conn_high = 0xff;
@@ -330,10 +522,17 @@ ncp_connect(struct ncp_server *server)
h->function = 0;
if (do_ncp_call(server, sizeof(*h)) != 0) {
int saved_errno = errno;
close(ncp_sock); close(wdog_sock);
errno = saved_errno;
return -1;
if ( (errno != ENETUNREACH)
|| (ipx_make_reachable(htonl(target->sipx_network)) != 0)
|| (do_ncp_call(server, sizeof(*h)) != 0)) {
int saved_errno = errno;
close(ncp_sock); close(wdog_sock);
errno = saved_errno;
return -1;
}
}
install_wdog(server);
@@ -346,6 +545,107 @@ ncp_connect(struct ncp_server *server)
return 0;
}
static int
ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result)
{
struct sockaddr_ipx addr;
char data[1024];
int sock;
int opt;
int res = -1;
int saved_errno;
int packets;
int len;
struct sap_server_ident *ident;
sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
if (sock==-1) {
return -1;
}
opt=1;
/* Permit broadcast output */
if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST, &opt,sizeof(opt))==-1)
{
goto finished;
}
memset(&addr, 0, sizeof(addr));
addr.sipx_family=AF_IPX;
addr.sipx_network=htonl(0x0);
addr.sipx_port=htons(0x0);
addr.sipx_type=IPX_SAP_PTYPE;
if(bind(sock,(struct sockaddr*)&addr,sizeof(addr))==-1)
{
goto finished;
}
*(unsigned short *)data = htons(IPX_SAP_NEAREST_QUERY);
*(unsigned short *)&(data[2]) = htons(server_type);
memset(&addr, 0, sizeof(addr));
addr.sipx_family=AF_IPX;
addr.sipx_network=htonl(0x0);
ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE);
addr.sipx_port=htons(IPX_SAP_PORT);
addr.sipx_type=IPX_SAP_PTYPE;
if (sendto(sock, data, 4, 0,
(struct sockaddr *)&addr, sizeof(addr)) < 0)
{
goto finished;
}
packets = 5;
do
{
len = ipx_recv(sock, data, 1024, 0, 1);
if (len < 66) {
packets = packets - 1;
continue;
}
} while (ntohs(*((__u16 *)data)) != IPX_SAP_NEAREST_RESPONSE);
ident = (struct sap_server_ident *)(data+2);
result->sipx_family = AF_IPX;
result->sipx_network = ident->server_network;
result->sipx_port = ident->server_port;
ipx_assign_node(result->sipx_node, ident->server_node);
res = 0;
finished:
saved_errno = errno;
close(sock);
errno = saved_errno;
return res;
}
static int
ncp_connect_any(struct ncp_server *server)
{
struct sockaddr_ipx addr;
if (ipx_sap_find_nearest(IPX_SAP_FILE_SERVER, &addr) != 0) {
return -1;
}
return ncp_connect_addr(server, &addr);
}
int
ncp_connect(struct ncp_server *server, const char *name)
{
if (name == NULL) {
return ncp_connect_any(server);
}
return -1;
}
static int
ncp_user_disconnect(struct ncp_server *server)
{
@@ -610,6 +910,35 @@ ncp_get_bindery_object_id(struct ncp_server *server,
return 0;
}
int
ncp_scan_bindery_object(struct ncp_server *server,
__u32 last_id, __u16 object_type, char *search_string,
struct ncp_bindery_object *target)
{
int result;
ncp_init_request_s(server, 55);
ncp_add_dword(server, htonl(last_id));
ncp_add_word(server, htons(object_type));
ncp_add_pstring(server, search_string);
if ((result = ncp_request(server, 23)) != 0) {
ncp_unlock_server(server);
return result;
}
target->object_id = ntohl(ncp_reply_dword(server, 0));
target->object_type = ntohs(ncp_reply_word(server, 4));
memcpy(target->object_name, ncp_reply_data(server, 6),
NCP_BINDERY_NAME_LEN);
target->object_flags = ncp_reply_byte(server, 54);
target->object_security = ncp_reply_byte(server, 55);
target->object_has_prop = ncp_reply_byte(server, 56);
ncp_unlock_server(server);
return 0;
}
int
ncp_read_property_value(struct ncp_server *server,
int object_type, char *object_name,

View File

@@ -6,6 +6,68 @@
#include <linux/ncp_fs.h>
#include <linux/ipx.h>
typedef unsigned long IPXNet;
typedef unsigned short IPXPort;
typedef unsigned char IPXNode[IPX_NODE_LEN];
#define IPX_RIP_PTYPE (0x01)
#define IPX_SAP_PTYPE (0x04)
#define IPX_SAP_PORT (0x0452)
#define IPX_RIP_PORT (0x0453)
#define IPX_SAP_GENERAL_QUERY (0x0001)
#define IPX_SAP_GENERAL_RESPONSE (0x0002)
#define IPX_SAP_NEAREST_QUERY (0x0003)
#define IPX_SAP_NEAREST_RESPONSE (0x0004)
#define IPX_SAP_FILE_SERVER (0x0004)
struct sap_query {
unsigned short query_type; /* net order */
unsigned short server_type; /* net order */
};
struct sap_server_ident {
unsigned short server_type __attribute__ ((packed));
char server_name[48] __attribute__ ((packed));
IPXNet server_network __attribute__ ((packed));
IPXNode server_node __attribute__ ((packed));
IPXPort server_port __attribute__ ((packed));
unsigned short intermediate_network __attribute__ ((packed));
};
#define IPX_RIP_REQUEST (0x1)
#define IPX_RIP_RESPONSE (0x2)
struct ipx_rip_packet {
__u16 operation __attribute__ ((packed));
struct ipx_rt_def {
__u32 network __attribute__ ((packed));
__u16 hops __attribute__ ((packed));
__u16 ticks __attribute__ ((packed));
} rt[1] __attribute__ ((packed));
};
#define IPX_BROADCAST_NODE "\xff\xff\xff\xff\xff\xff"
#define IPX_THIS_NODE "\0\0\0\0\0\0"
#ifndef IPX_NODE_LEN
#define IPX_NODE_LEN (6)
#endif
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);
int
ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]);
void
ipx_assign_node(IPXNode dest, IPXNode src);
enum connect_state {
NOT_CONNECTED = 0,
CONN_MOUNTED,
@@ -43,7 +105,10 @@ int
ncp_connect_mount(struct ncp_server *server, const char *mount_point);
int
ncp_connect(struct ncp_server *server);
ncp_connect_addr(struct ncp_server *server, const struct sockaddr_ipx *target);
int
ncp_connect(struct ncp_server *server, const char *server_name);
int
ncp_disconnect(struct ncp_server *server);
@@ -59,6 +124,10 @@ ncp_get_bindery_object_id(struct ncp_server *server,
int object_type, char *object_name,
struct ncp_bindery_object *target);
int
ncp_scan_bindery_object(struct ncp_server *server,
__u32 last_id, __u16 object_type, char *search_string,
struct ncp_bindery_object *target);
int
ncp_read_property_value(struct ncp_server *server,
int object_type, char *object_name,
int segment, char *prop_name,

View File

@@ -28,15 +28,13 @@ extern pid_t waitpid(pid_t, int *, int);
#include <sys/mount.h>
#include <mntent.h>
#include <linux/ipx.h>
#include <linux/route.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_mount.h>
#include "ipxutil.h"
#include "ncplib_user.h"
#include "ncplib.h"
static char *progname;
@@ -77,105 +75,34 @@ help(void)
"\n");
}
struct sap_query {
unsigned short query_type; /* net order */
unsigned short server_type; /* net order */
};
struct sap_server_ident {
unsigned short server_type __attribute__ ((packed));
char server_name[48] __attribute__ ((packed));
IPXNet server_network __attribute__ ((packed));
IPXNode server_node __attribute__ ((packed));
IPXPort server_port __attribute__ ((packed));
unsigned short intermediate_network __attribute__ ((packed));
};
void
ipx_fprint_node(FILE* file,IPXNode node)
int
ipx_sap_find_server(char *name, int server_type, int timeout,
struct sockaddr_ipx *result)
{
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",ntohl(net));
}
void
ipx_fprint_port(FILE* file,IPXPort port)
{
fprintf(file,"%04X",ntohs(port));
}
void
ipx_fprint_saddr(FILE* file,struct sockaddr_ipx* sipx)
{
ipx_fprint_network(file,sipx->sipx_network);
fprintf(file,":");
ipx_fprint_node(file,sipx->sipx_node);
fprintf(file,":");
ipx_fprint_port(file,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);
}
static int
ipx_make_reachable(__u32 network)
{
struct rtentry rt_def;
/* Router */
struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rt_def.rt_gateway;
/* Target */
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rt_def.rt_dst;
fd_set rd, wr, ex;
struct timeval tv;
struct ipx_rip_packet rip;
struct sockaddr_ipx addr;
int addrlen;
char data[1024];
int sock;
int opt;
int res=-1;
int i;
int res = -1;
int name_len = strlen(name);
fd_set rd, wr, ex;
struct timeval tv;
struct sap_server_ident *ident;
sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
struct ncp_server server;
struct nw_property prop;
struct prop_net_address *n_addr = (struct prop_net_address *)&prop;
if (sock == -1) {
if (name_len > 48) {
return -1;
}
sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
if (sock==-1) {
return -1;
}
opt=1;
/* Permit broadcast output */
if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST, &opt,sizeof(opt))==-1)
@@ -188,7 +115,7 @@ ipx_make_reachable(__u32 network)
addr.sipx_family=AF_IPX;
addr.sipx_network=htonl(0x0);
addr.sipx_port=htons(0x0);
addr.sipx_type=IPX_RIP_PTYPE;
addr.sipx_type=IPX_SAP_PTYPE;
if(bind(sock,(struct sockaddr*)&addr,sizeof(addr))==-1)
{
@@ -196,153 +123,18 @@ ipx_make_reachable(__u32 network)
goto finished;
}
addr.sipx_family = AF_IPX;
addr.sipx_network = htonl(0x0);
addr.sipx_port = htons(IPX_RIP_PORT);
addr.sipx_type = IPX_RIP_PTYPE;
ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE);
rip.operation = htons(IPX_RIP_REQUEST);
rip.rt[0].network = htonl(network);
if (sendto(sock, &rip, sizeof(rip), 0,
(struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("sendto");
goto finished;
}
do
{
FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&ex);
FD_SET(sock, &rd);
tv.tv_sec = 3;
tv.tv_usec = 0;
if (select(sock+1, &rd, &wr, &ex, &tv) == -1)
{
goto finished;
}
if (FD_ISSET(sock, &rd))
{
int len;
addrlen = sizeof(struct sockaddr_ipx);
len = recvfrom(sock, &rip, sizeof(rip), 0,
(struct sockaddr *)sr, &addrlen);
if (len < sizeof(rip))
{
continue;
}
}
else
{
goto finished;
}
} while (ntohs(rip.operation) != IPX_RIP_RESPONSE);
if (rip.rt[0].network != htonl(network)) {
goto finished;
}
rt_def.rt_flags = RTF_GATEWAY;
st->sipx_network = htonl(network);
sr->sipx_family = st->sipx_family = AF_IPX;
i = 0;
do {
res = ioctl(sock, SIOCADDRT, &rt_def);
i++;
} while ((i < 5) && (res < 0) && (errno == EAGAIN));
if (res != 0) {
switch (errno) {
case ENETUNREACH:
fprintf(stderr,
"%s: Router network (%08lX) not reachable.\n",
progname, htonl(sr->sipx_network));
break;
default:
perror("ioctl");
break;
}
goto finished;
}
finished:
close(sock);
return res;
}
int
ipx_sap_find_server(char *name, int server_type, int timeout,
struct sockaddr_ipx *result)
{
struct sockaddr_ipx ipxs;
char data[1024];
int sock;
int opt;
int res = -1;
int name_len = strlen(name);
fd_set rd, wr, ex;
struct timeval tv;
struct sap_server_ident *ident;
struct ncp_server server;
struct nw_property prop;
struct net_address
{
__u32 network __attribute__ ((packed));
__u8 node[6] __attribute__ ((packed));
__u16 port __attribute__ ((packed));
} *n_addr = (struct net_address *)&prop;
if (name_len > 48) {
return -1;
}
sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
if (sock==-1) {
return -1;
}
opt=1;
/* Permit broadcast output */
if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST, &opt,sizeof(opt))==-1)
{
perror("setsockopt");
goto finished;
}
memset(&ipxs, 0, sizeof(ipxs));
ipxs.sipx_family=AF_IPX;
ipxs.sipx_network=htonl(0x0);
ipxs.sipx_port=htons(0x0);
ipxs.sipx_type=IPX_SAP_PTYPE;
if(bind(sock,(struct sockaddr*)&ipxs,sizeof(ipxs))==-1)
{
perror("bind");
goto finished;
}
*(unsigned short *)data = htons(IPX_SAP_NEAREST_QUERY);
*(unsigned short *)&(data[2]) = htons(server_type);
memset(&ipxs, 0, sizeof(ipxs));
ipxs.sipx_family=AF_IPX;
ipxs.sipx_network=htonl(0x0);
ipx_assign_node(ipxs.sipx_node, IPX_BROADCAST_NODE);
ipxs.sipx_port=htons(IPX_SAP_PORT);
ipxs.sipx_type=IPX_SAP_PTYPE;
memset(&addr, 0, sizeof(addr));
addr.sipx_family=AF_IPX;
addr.sipx_network=htonl(0x0);
ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE);
addr.sipx_port=htons(IPX_SAP_PORT);
addr.sipx_type=IPX_SAP_PTYPE;
if (sendto(sock, data, 4, 0,
(struct sockaddr *)&ipxs, sizeof(ipxs)) < 0)
(struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("sendto");
goto finished;
@@ -385,18 +177,13 @@ ipx_sap_find_server(char *name, int server_type, int timeout,
route to the server's internal network. Because this one
request is not very expensive, we always do it. */
server.addr.sipx_family = AF_IPX;
server.addr.sipx_network = ident->server_network;
server.addr.sipx_port = ident->server_port;
ipx_assign_node(server.addr.sipx_node, ident->server_node);
addr.sipx_family = AF_IPX;
addr.sipx_network = ident->server_network;
addr.sipx_port = ident->server_port;
ipx_assign_node(addr.sipx_node, ident->server_node);
if (ncp_connect(&server) != 0)
{
if ( (errno != ENETUNREACH)
|| (ipx_make_reachable(ntohl(server.addr.sipx_network))!=0)
|| (ncp_connect(&server) != 0)) {
goto finished;
}
if (ncp_connect_addr(&server, &addr) != 0) {
goto finished;
}
if (ncp_read_property_value(&server, NCP_BINDERY_FSERVER,
@@ -407,8 +194,7 @@ ipx_sap_find_server(char *name, int server_type, int timeout,
goto finished;
}
if (ncp_disconnect(&server) != 0)
{
if (ncp_disconnect(&server) != 0) {
goto finished;
}
@@ -420,19 +206,8 @@ ipx_sap_find_server(char *name, int server_type, int timeout,
/* Now we connect to the ultimate target, again with a test
for reachability. This time nothing is done except connecting. */
server.addr = *result;
if (ncp_connect(&server) != 0)
{
if ( (errno != ENETUNREACH)
|| (ipx_make_reachable(ntohl(server.addr.sipx_network))!=0)
|| (ncp_connect(&server) != 0)) {
goto finished;
}
}
if (ncp_disconnect(&server) != 0)
{
if ( (ncp_connect_addr(&server, result) != 0)
|| (ncp_disconnect(&server) != 0)) {
goto finished;
}
@@ -444,24 +219,6 @@ ipx_sap_find_server(char *name, int server_type, int timeout,
return res;
}
int
ipx_sscanf_node(char *buf, unsigned char node[6])
{
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 i;
}
for (i=0; i<6; i++) {
node[i] = n[i];
}
return 6;
}
static int
parse_args(int argc, char *argv[], struct ncp_mount_data *data,
int *got_password, int *upcase_password)
@@ -664,7 +421,8 @@ main(int argc, char *argv[])
exit(1);
}
memset(&data, 0, sizeof(struct ncp_mount_data));
memset(&data, 0, sizeof(data));
memset(&serv, 0, sizeof(serv));
memset(hostname, '\0', MAXHOSTNAMELEN+1);
gethostname(hostname, MAXHOSTNAMELEN);
@@ -832,9 +590,6 @@ main(int argc, char *argv[])
if (ncp_login_user(server, data.username, data.password) != 0) {
fprintf(stderr, "login failed\n");
fprintf(stderr,
"should try to type the username and\n"
"password in UPPERCASE.\n");
close(server->mount_fid);
umount(mount_point);
return -1;

View File

@@ -35,8 +35,7 @@ extern pid_t waitpid(pid_t, int *, int);
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_mount.h>
#include "ncplib_user.h"
#include "ipxutil.h"
#include "ncplib.h"
static char *progname;
@@ -49,79 +48,6 @@ str_upper(char *name)
}
}
struct sap_query {
unsigned short query_type; /* net order */
unsigned short server_type; /* net order */
};
struct sap_server_ident {
unsigned short server_type __attribute__ ((packed));
char server_name[48] __attribute__ ((packed));
IPXNet server_network __attribute__ ((packed));
IPXNode server_node __attribute__ ((packed));
IPXPort server_port __attribute__ ((packed));
unsigned short intermediate_network __attribute__ ((packed));
};
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",ntohl(net));
}
void
ipx_fprint_port(FILE* file,IPXPort port)
{
fprintf(file,"%04X",ntohs(port));
}
void
ipx_fprint_saddr(FILE* file,struct sockaddr_ipx* sipx)
{
ipx_fprint_network(file,sipx->sipx_network);
fprintf(file,":");
ipx_fprint_node(file,sipx->sipx_node);
fprintf(file,":");
ipx_fprint_port(file,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);
}
int
ipx_sap_find_server(char *_name, int server_type, int timeout,
struct sockaddr_ipx *result)
@@ -237,25 +163,6 @@ ipx_sap_find_server(char *_name, int server_type, int timeout,
return res;
}
int
ipx_sscanf_node(char *buf, unsigned char node[6])
{
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 i;
}
for (i=0; i<6; i++) {
node[i] = n[i];
}
return 6;
}
void
test_filesearch(struct ncp_server *server)
{
@@ -560,21 +467,21 @@ test_print(struct ncp_server *server)
j.j.TargetServerID = 0xffffffff; /* any server */
memset(&(j.j.TargetExecTime), 0xff, sizeof(j.j.TargetExecTime)); /* at once */
j.j.JobType = 0xffff;
j.j.JobType = htons(0);
strcpy(j.j.JobTextDescription, "Test Job");
memset(&pj, 0, sizeof(pj));
pj.Version = 0;
pj.TabSize = 0;
pj.Copies = 1;
pj.TabSize = 8;
pj.Copies = htons(1);
pj.CtrlFlags = 0;
pj.Lines = 0;
pj.Rows = 0;
strcpy(pj.FormName, "");
strcpy(pj.Banner, "");
strcpy(pj.FnameBanner, "");
strcpy(pj.FnameHeader, "");
pj.Lines = htons(66);
pj.Rows = htons(80);
strcpy(pj.FormName, "test");
strcpy(pj.BannerName, "BannerName");
strcpy(pj.FnameBanner, "BannerFile");
strcpy(pj.FnameHeader, "HeaderName");
strcpy(pj.Path, "");
memcpy(j.j.ClientRecordArea, &pj, sizeof(pj));
@@ -584,7 +491,8 @@ test_print(struct ncp_server *server)
return;
}
if (ncp_write(server, j.file_handle, 0, 5, "hallo", &written) != 0) {
if (ncp_write(server, j.file_handle, 0, 5, "hallo, wie geht's?",
&written) != 0) {
printf("write error\n");
return;
}
@@ -597,29 +505,37 @@ test_print(struct ncp_server *server)
return;
}
void
test_slist(struct ncp_server *server)
{
struct ncp_bindery_object obj;
obj.object_id = 0xffffffff;
while (ncp_scan_bindery_object(server, obj.object_id,
0xffff, "*",
&obj) == 0) {
printf("%s\n", obj.object_name);
}
return;
}
int
main(int argc, char **argv)
{
struct ncp_server serv;
struct ncp_server *server = &serv;
struct sockaddr_ipx addr;
progname = argv[0];
if (argc != 2) {
printf("usage: %s server\n", argv[0]);
exit(1);
}
if (ipx_sap_find_server(argv[1], IPX_SAP_FILE_SERVER,
3, &(serv.addr)) != 0) {
if (ipx_sap_find_server("nw311", IPX_SAP_FILE_SERVER,
3, &addr) != 0) {
printf("could not find server %s\n", argv[1]);
exit(1);
}
if (ncp_connect(server) != 0) {
if (ncp_connect_addr(server, &addr) != 0) {
printf("could not connect\n");
exit(1);
}
@@ -629,7 +545,7 @@ main(int argc, char **argv)
exit(1);
}
getchar();
test_slist(server);
ncp_disconnect(server);

View File

@@ -89,9 +89,8 @@ typedef unsigned char buf32[32];
typedef unsigned char buf16[16];
typedef unsigned char buf8[8];
typedef unsigned char buf4[4];
typedef unsigned char u8;
static u8 encrypttable[256] =
static unsigned char encrypttable[256] =
{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
@@ -142,7 +141,7 @@ shuffle1(buf32 temp, unsigned char *target)
}
void
static void
shuffle(unsigned char *lon, const unsigned char *buf, int buflen,
unsigned char *target)
{
@@ -191,7 +190,7 @@ shuffle(unsigned char *lon, const unsigned char *buf, int buflen,
}
void
static void
nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til)
{
buf32 k;

View File

@@ -1,5 +0,0 @@
void
shuffle(unsigned char *lon, const unsigned char *buf, int buflen,
unsigned char *target);
void
nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til);

77
util/slist.c Normal file
View File

@@ -0,0 +1,77 @@
#include "ncplib.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
void
main(int argc, char *argv[])
{
struct ncp_server server;
struct ncp_bindery_object obj;
int found = 0;
char default_pattern[2] = "*";
char *pattern = default_pattern;
char *p;
if (argc > 2) {
printf("usage: %s [pattern]\n", argv[0]);
exit(1);
}
if (argc == 2) {
pattern = argv[1];
}
for (p = pattern; *p != '\0'; p++) {
*p = toupper(*p);
}
memset(&server, 0, sizeof(server));
if (ncp_connect(&server, NULL) != 0) {
perror("ncp_connect");
exit(1);
}
if (isatty(1)) {
printf("\n%-52s%-10s%-12s\n"
"-----------------------------------------------"
"---------------------------\n",
"Known NetWare File Servers",
"Network",
"Node Address");
}
obj.object_id = 0xffffffff;
while (ncp_scan_bindery_object(&server, obj.object_id,
NCP_BINDERY_FSERVER, pattern,
&obj) == 0) {
struct nw_property prop;
struct prop_net_address *naddr
= (struct prop_net_address *)&prop;
found = 1;
printf("%-52s", obj.object_name);
if (ncp_read_property_value(&server, NCP_BINDERY_FSERVER,
obj.object_name, 1, "NET_ADDRESS",
&prop) == 0) {
ipx_print_network(naddr->network);
printf(" ");
ipx_print_node(naddr->node);
}
printf("\n");
}
if ((found == 0) && (isatty(1))) {
printf("No servers found\n");
}
ncp_disconnect(&server);
}