📄 ndis3api.c
字号:
/* (c) Copyright Daniel D. Lanciani 1998-2003. All rights reserved. */
#include <windows.h>
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned long u_long;
static HANDLE _ndis3vh = (HANDLE)-1;
static char copyright[] = "Copyright Daniel Lanciani 1998-2003";
#define BAD_HANDLE 1
#define NO_CLASS 2
#define NO_TYPE 3
#define NO_NUMBER 4
#define BAD_TYPE 5
#define NO_MULTICAST 6
#define CANT_TERMINATE 7
#define BAD_MODE 8
#define NO_SPACE 9
#define TYPE_INUSE 10
#define BAD_COMMAND 11
#define CANT_SEND 12
#define CANT_SET 13
#define BAD_ADDRESS 14
#define CANT_RESET 15
#define WOULD_BLOCK 200
#define CANCELED 201
#define INTERRUPTED 202
#define RECV_FLAG_NOBLOCK 1 /* don't block */
#define RECV_FLAG_PEEK 2 /* leave the packet on the queue */
#define RECV_FLAG_INTERRUPTIBLE 4 /* allow system interupts */
#define ACCESS_FLAG_TUNNEL 0x8000 /* receive packets sent by MSTCP */
#define ACCESS_FLAG_ASMSTCP 0x4000 /* receive packets as if for MSTCP */
/*
Generic function to call ndis3pkt's DeviceIoControl entry.
*/
static long
nd_call(arg0)
{
long res[1];
int os;
*res = -1;
DeviceIoControl(_ndis3vh, 200, &arg0, 7 * sizeof(long),
res, sizeof(res), &os, 0);
return(*res);
}
/*
Open device and return non-zero if ndis3pkt is available.
*/
nd_loaded()
{
if(_ndis3vh == (HANDLE)-1)
_ndis3vh = CreateFile(L"NDX1:", 0, 0,
NULL, OPEN_EXISTING, 0, NULL);
if(_ndis3vh == (HANDLE)-1)
return(0);
return(1);
}
/*
Return class and Windows name of a given unit.
*/
nd_driver_info(unit, class, name)
int *class;
char *name;
{
return(nd_call(1, unit, class, name, (int *)0));
}
/*
Allocate handle for type. At most qlen packets will be
queued on this handle for later nd_recv().
*/
nd_access_type(unit, handle, type, typelen, qlen)
int *handle;
char *type;
{
return(nd_call(2, unit, handle, type, typelen, qlen));
}
/*
Free handle.
*/
nd_release_type(unit, handle)
{
return(nd_call(3, unit, handle));
}
/*
Send complete frame of len bytes at data.
*/
nd_send_pkt(unit, data, len)
char *data;
{
return(nd_call(4, unit, data, len));
}
/*
Shut down driver.
*/
nd_terminate(unit)
{
return(nd_call(5, unit));
}
/*
Copy MAC address of unit to buf. Size should be at least 6.
*/
nd_get_address(unit, size, buf)
char *buf;
{
return(nd_call(6, unit, size, buf));
}
/*
Set receiver mode.
*/
nd_set_rcv_mode(unit, handle, mode)
{
return(nd_call(20, unit, handle, mode));
}
/*
Get receiver mode.
*/
nd_get_rcv_mode(unit, handle, mode)
int *mode;
{
return(nd_call(21, unit, handle, mode));
}
/*
Read up to *cnt bytes of packet from handle into buf. If flags
includes RECV_FLAG_NOBLOCK then nd_recv will not sleep and the
return code will be WOULD_BLOCK if no packets are immediately
available. If flags includes RECV_FLAG_PEEK then the returned
packet will not be removed from the queue. The number of bytes
copied is returned in *cnt.
*/
nd_recv(unit, handle, buf, cnt, flags)
char *buf;
int *cnt;
{
return(nd_call(200, unit, handle, buf, cnt, flags));
}
/*
Cancel all blocking nd_recv()s associated with handle. They
will return the CANCELED error code.
*/
nd_cancel_recv(unit, handle)
{
return(nd_call(201, unit, handle));
}
/*
Indicate a packet to MSTCP just as if it had been received on
the physical interface. Len is the total length and hlen is
the part of the packet that corresponds to the MAC header, e.g.,
14 for Ethernet.
*/
nd_send_to_tcp(unit, data, len, hlen)
char *data;
{
return(nd_call(210, unit, data, len, hlen));
}
/*
Same as nd_send_pkt, but for purposes of tcp/ip multiplexing the
packet is treated as if it had originated from the MSTCP stack.
*/
nd_send_as_tcp(unit, data, len)
char *data;
{
return(nd_call(211, unit, data, len));
}
struct subinfo {
u_short flags;
u_short proto;
u_long addr;
u_char link[12];
};
#define SUB_WANUP 0x0001
#define SUB_IPGOOD 0x0002
nd_get_subinfo(unit, si)
struct subinfo *si;
{
return(nd_call(212, unit, si));
}
struct ndis3conf {
long major;
long minor;
long nnd;
long nms;
long mmatch;
long nhand;
long ntcptab;
long nbq;
long nsq;
long psize;
/* begin alterable */
long brd_rif0;
long brd_rif1;
long alwayssched;
long tcpmux;
long mstcpmux;
long ignorelocalbroadcast;
long warnmuxfull;
/* end alterable */
long ndis_init_step;
long ndis_init_status;
long nsub;
long reserved[20];
};
struct tcpent {
u_long fhost;
u_long lhost;
u_short fport;
u_short lport;
long vm;
long flags;
} tc[100];
nd_get_my_bindings(buf)
char *buf;
{
return(nd_call(300, 0, buf));
}
nd_get_mstcp_bindings(buf)
char *buf;
{
return(nd_call(301, 0, buf));
}
nd_get_conf(np)
struct ndis3conf *np;
{
return(nd_call(302, 0, np));
}
nd_set_conf(np)
struct ndis3conf *np;
{
return(nd_call(303, 0, np));
}
nd_get_tcpent(tp, cnt)
struct tcpent *tp;
int *cnt;
{
return(nd_call(304, 0, tp, cnt));
}
nd_add_my_binding(device)
char *device;
{
return(nd_call(305, 0, device));
}
/*
Return in *func the 32-bit address of a ring0-callable API entry point
within ndis3pkt. This address cannot be used from ring3; it must passed
down to a ring0 driver. The function is called with C calling convention:
void entry(unsigned long *args, unsigned long *res, unsigned long vm)
where args and res are as in nd_call() and vm is the current virtual machine
(or process for NT).
This interface is experimental and may be replaced.
*/
nd_get_ring0_entry(func)
long *func;
{
return(nd_call(400, 0, func));
}
/*
Below are several sample programs that use the Win32 API. Define MONITOR
to build a basic sniffer. Define WIN32_INTERMEDIATE to build a
pass-through intermediate driver filter. Define NDISINFO to build the
ndisinfo.exe program.
*/
/*#define MONITOR*/
/*#define WIN32_INTERMEDIATE*/
#define NDISINFO
#include <stdio.h>
#ifdef MONITOR
main(argc, argv)
char **argv;
{
register int i;
int m, h, unit = 2;
unsigned char buf[1514];
if(!nd_loaded()) {
fprintf(stderr, "Ndis3pkt not loaded\n");
exit(1);
}
if(argc > 1) {
printf("cancel_recv = %d\n", nd_cancel_recv(0, atoi(argv[1])));
exit(0);
}
printf("driver_info = %d\n", nd_driver_info(unit, &m, buf));
printf("class = %d, Windowsname = %s\n", m, buf);
printf("get_address = %d\n", nd_get_address(unit, 6, buf+6));
printf("address = ");
for(i = 0; i < 6; i++) {
printf("%02x", buf[i+6] & 0xff);
if(i == 5)
printf("\n");
else
printf(":");
}
printf("get_rcv_mode = %d\n", nd_get_rcv_mode(unit, -1, &m));
printf("mode = %d\n", m);
printf("access_type = %d\n", nd_access_type(unit, &h, "", 0, 1));
printf("handle = %d\n", h);
printf("set_rcv_mode = %d\n", nd_set_rcv_mode(unit, h, 6));
for(i = 0; i < 6; i++)
buf[i] = 0xff;
for(i = 12; i < 100; i++)
buf[i] = i;
printf("send = %d\n", nd_send_pkt(unit, buf, sizeof(buf)));
/*while(!kbhit()) {*/
m = sizeof(buf);
printf("recv = %d\n", nd_recv(unit, h, buf, &m, 0));
printf("size recv = %d\n", m);
printf("data: ");
for(i = 0; i < 20; i++)
printf("%02x ", buf[i]);
printf("\n");
/*}*/
printf("set_rcv_mode = %d\n", nd_set_rcv_mode(unit, h, 3));
printf("release_type = %d\n", nd_release_type(unit, h));
}
#endif
#ifdef WIN32_INTERMEDIATE
int h2, unit = 2;
/*
Second thread copies frames from the network to MSTCP without change
*/
DWORD WINAPI
copyit(void *p)
{
int m;
unsigned char buf[2048];
while(1) {
m = sizeof(buf);
if(nd_recv(unit, h2, buf, &m, 0)) /* read from network */
break;
nd_send_to_tcp(unit, buf, m, 14); /* write to MSTCP */
}
return(0);
}
main(argc, argv)
char **argv;
{
register int i;
int m, h, cnt = 100;
unsigned char buf[2048];
if(!nd_loaded()) {
fprintf(stderr, "Ndis3pkt not loaded\n");
exit(1);
}
printf("driver_info = %d\n", nd_driver_info(unit, &m, buf));
printf("class = %d, Windowsname = %s\n", m, buf);
printf("get_address = %d\n", nd_get_address(unit, 6, buf));
printf("address = ");
for(i = 0; i < 6; i++) {
printf("%02x", buf[i] & 0xff);
if(i == 5)
printf("\n");
else
printf(":");
}
printf("access_type = %d\n", nd_access_type(unit, &h, "",
ACCESS_FLAG_TUNNEL, 16));
printf("handle = %d\n", h);
printf("access_type2 = %d\n", nd_access_type(unit, &h2, "",
ACCESS_FLAG_ASMSTCP, 16));
printf("handle2 = %d\n", h2);
CreateThread(NULL, 0, copyit, 0, 0, NULL);
while(cnt--) {
m = sizeof(buf);
nd_recv(unit, h, buf, &m, 0); /* read from MSTCP */
printf("size sent = %d\n", m);
printf("Packet sent by MSTCP: ");
for(i = 0; i < 20; i++)
printf("%02x ", buf[i]);
printf("\n");
nd_send_as_tcp(unit, buf, m); /* send frame to network */
}
printf("release_type = %d\n", nd_release_type(unit, h));
printf("release_type2 = %d\n", nd_release_type(unit, h2));
}
#endif
#ifdef NDISINFO
xntohs(s)
{
return(((s >> 8) & 0xff) | ((s << 8) & 0xff00));
}
xntohl(l)
{
return((xntohs(l) << 16) | xntohs(l >> 16));
}
main(argc, argv)
char **argv;
{
register int i;
register char *p;
u_char *q;
int j;
static unsigned char buf[2048];
static struct subinfo sb;
static struct ndis3conf nc;
if(!nd_loaded()) {
fprintf(stderr, "Ndis3pkt not loaded\n");
exit(1);
}
if(argc < 2)
goto dobindings;
if(i = nd_get_conf(&nc)) {
fprintf(stderr, "Unable to read configuration (%d)\n", i);
exit(1);
}
printf("Version %ld.%ld\n", nc.major, nc.minor);
printf("max adapters = %ld, max mstcp bindings = %ld\n", nc.nnd,nc.nms);
printf("max match = %ld, max handles = %ld\n", nc.mmatch, nc.nhand);
printf("tcp mux tab size = %ld\n", nc.ntcptab);
printf("global q size = %ld, handle q size = %ld\n", nc.nbq, nc.nsq);
printf("max packet size = %ld\n", nc.psize);
printf("rif0 = %lx, rif1 = %lx\n", nc.brd_rif0, nc.brd_rif1);
printf("alwayssched = %ld\n", nc.alwayssched);
printf("tcpmux = %ld, mstcpmux = %ld\n", nc.tcpmux, nc.mstcpmux);
printf("ignorelocalbroadcast = %ld, warnmuxfull = %ld\n",
nc.ignorelocalbroadcast, nc.warnmuxfull);
printf("ndis_init_step = %ld, ndis_init_status = %lx\n",
nc.ndis_init_step, nc.ndis_init_status);
printf("max sub units = %d\n", nc.nsub);
printf("\n");
j = 100;
if(i = nd_get_tcpent(tc, &j)) {
fprintf(stderr, "Unable to read tcpmux table (%d)\n", i);
exit(1);
}
printf("VM Local Foreign Flags\n");
for(i = 0; i < j; i++)
printf("%08lx %08lx:%05u %08lx:%05u %08lx\n", tc[i].vm,
xntohl(tc[i].lhost), xntohs(tc[i].lport),
xntohl(tc[i].fhost), xntohs(tc[i].fport),
tc[i].flags);
printf("\n");
dobindings:
if(i = nd_get_my_bindings(buf)) {
fprintf(stderr, "Unable to read bindings (%d)\n", i);
exit(1);
}
printf("Available devices:\n");
for(i = 0, p = buf; *p; p += strlen(p) + 1, i++) {
printf("%d %s\n", i, p);
if(argc < 2)
continue;
for(j = 0; j < nc.nsub; j++) {
if(nd_get_subinfo(i | (j << 16), &sb))
continue;
if(!(sb.flags&SUB_WANUP))
continue;
printf(" subunit %d protocol %x", j, sb.proto);
if(!(sb.flags&SUB_IPGOOD)) {
printf("\n");
continue;
}
q = (u_char *)&sb.addr;
printf(" IP %d.%d.%d.%d\n", q[0], q[1], q[2], q[3]);
}
}
if(!nd_get_mstcp_bindings(buf) && *buf) {
printf("\nKnown MSTCP bindings:\n");
for(p = buf; *p; p += strlen(p) + 1)
printf("%s\n", p);
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -