home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
pktsend.zip
/
PKTSEND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-24
|
22KB
|
598 lines
/* PKTSEND.C
Author: Patrick Whittle
Date: November 4, 1994
Revisions: February 24, 1995
Purpose: Provide interface to network packet driver.
The accompanying file 8086.H must be included for a successful
compile. Two key functions used in PKTSEND for communicating with a
packet driver are drvrchk(), and sendpkt(). These are both found in
the file 8086.H.
To implement certain driver calls such as Get Address (function 06h),
or Get Driver Info (function 01h, subfunction FFh), a C function
is available in the public domain by Phil Karn. This function,
access_type(), can be found in the file PKTDRVR.C. Following is
an example for using my functions with this Public Domain function:
if (intno = drvrchk())
handle = access_type(intno,if_class,if_type,if_number,
type,typelen,receiver);
Once this completes successfully, PKTSEND.EXE will be registered with
the packet driver, and may begin using its internal functions. Note
that the function sendpkt() used in this program is available without
first calling access_type.
*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "8086.h"
#define TRUE -1
#define FALSE 0
#define BELL 7
#define ESCAPE 27
/* Global variables are next */
int pane = 10; /* made global Feb. 24 to correct problem with field changes */
/* Function prototypes are next */
void sendframe(int times, char *data, char ieee[], int intno);
int validkey(int *code, char addr[], char *data);
void newfield(char *data);
void menu(char ary[]);
void fldset(char disp[], int pos);
void reset(void);
void leave(int *code);
int main(void) {
int intno, keystr = 0, extended = 0, col;
char *txt = "A network packet driver was "; /* found, or not found? */
char ieee[14] = {0x08,0x0A,0x21,0x36,0x2C,0x98,0x0B,
0x81,0x26,0x37,0xAE,0x71,0x08,0x00}, *pkt;
intno = drvrchk(); /* Function returns currently hooked interrupt in
intno if it exists, or FALSE condition otherwise */
if (intno) {
menu(ieee); /* pass initial network address to menu function */
gotoxy(19, 2);
cprintf("%sfound at 0x%X.", txt, intno);
/* allocate memory for packet string */
pkt = (char *) calloc(104, sizeof(char)); // 90 bytes for packet, 14 for header
pkt = (char *) memcpy(pkt, ieee, 14);
pkt += 14; /* Point to end of ieee address. This pointer is passed
between sendframe() and main function for the purpose
of concatination of address, and data. */
textbackground(LIGHTGREEN); /* defined in CONIO.H */
window(32, 11, 48, 11); /* dimension of destination field */
while (keystr != ESCAPE) { /* escape key will break loop */
keystr = getch();
if (!keystr)
extended = getch(); /* i.e. F1-F10, arrow keys, etc. */
if (extended) {
switch (extended) {
case 'K': /* left arrow */
gotoxy(wherex()-1, wherey());
if (pane == 10 || pane == 20) {
col = wherex();
if (col==3||col==6||col==9||col==12||col==15)
gotoxy(col-1, wherey());
}
break;
case 'M': /* right arrow */
gotoxy(wherex()+1, wherey());
if (pane == 10 || pane == 20) {
col = wherex();
if (col==3||col==6||col==9||col==12||col==15)
gotoxy(col+1, wherey());
}
break;
case 'H': /* up */
break;
case 'P': /* down */
break;
case ';': /* F1 */
sendframe(1, pkt, ieee, intno);
break;
case '<': /* F2 */
sendframe(10, pkt, ieee, intno);
break;
case '=': /* F3 */
sendframe(100, pkt, ieee, intno);
break;
}
extended = 0; /* reset for next iteration */
}
else /* else, normal keystroke */
{
if (!validkey(&keystr, ieee, pkt))
cprintf("%c", BELL); /* Invalid key */
else
{
if (keystr == ESCAPE) /* Does the user want to exit? */
leave(&keystr);
else /* Does not want to exit! */
{
col = wherex();
if ((col == 3)||(col == 6)||(col == 9)||(col == 12)||(col == 15)) {
/* The "pane" variable will hold a value
indicating the current field that is active
to accept user input. Delimeters in the
source and destination fields (colons) must
by recognized with the code below. */
if (pane == 10 || pane == 20)
gotoxy(col+1, wherey());
}
}
}
}
}
reset(); /* restore default DOS window and colours */
}
else
printf("%sNOT found.\n", txt); /* ftp packet driver wasn't found. */
return(0);
}
/***************************************************************************
Function : sendframe
Parameters:
Returns : nothing
***************************************************************************/
void sendframe(int times, char *data, char ieee[], int intno) {
int i;
data -= 14; // Point back to start. See the line "pkt += 14" in main()
data = (char *) memcpy(data, ieee, 14);
_setcursortype(_NOCURSOR);
textbackground(BLUE);
window(2, 3, 79, 23);
gotoxy(32, 20);
for (i = 1; i <= times; i++) {
if (sendpkt(data, 104, intno)) {
gotoxy(22, 20);
clreol();
cprintf("Packet sent successfully %d time(s).", i);
}
else {
cprintf("Send was not successful.");
i = times;
}
}
data += 14; /* Start accepting data again */
textbackground(LIGHTGREEN);
window(32, 11, 48, 11);
_setcursortype(_NORMALCURSOR);
_wscroll = 0; /* scrolling disabled */
pane = 10; /* a global variable */
}
/***************************************************************************
Function : validkey
Parameters:
Returns : TRUE or FALSE condition
***************************************************************************/
int validkey(int *code, char addr[], char *data) {
int temp, temp2, c, extended = 0, offset, flag = TRUE;
static int row, col = 0, nibble = 1;
char i, *ptr, save;
switch (*code) {
case 9: /* tab */
newfield(data);
break;
case 13: /* carriage return */
newfield(data);
break;
case ESCAPE: /* escape */
break;
default: /* case else */
if (pane >= 10 && pane <= 30) {
if (*code >=97 && *code <=102)
*code -= 32; /* change to upper case */
/* Is key pressed 0-9, A-F? */
if ((*code >= 48 && *code <=57)||(*code >= 65 && *code <= 70)) {
i = wherex();
cprintf("%c", *code);
/* Next, adjust for colons that delimit each byte. These
are displayed as part of the addresses for source and
destination. */
if (i == 2) {
nibble = FALSE;
i = 1;
}
if (pane == 10 || pane == 20) { /* only adjust source
and dest fields */
if (i == 4 || i == 5) {
if (i == 5) nibble = FALSE;
i = 2;
}
if (i == 7 || i == 8) {
if (i == 8) nibble = FALSE;
i = 3;
}
if (i == 10|| i == 11) {
if (i == 11) nibble = FALSE;
i = 4;
}
if (i == 13|| i == 14) {
if (i == 14) nibble = FALSE;
i = 5;
}
if (i == 16|| i == 17) {
if (i == 17) nibble = FALSE;
i = 6;
}
}
else { /* Adjust the "type" field */
if (i == 2 || i == 4)
nibble = FALSE;
if (i == 3 || i == 4)
i = 2;
}
/* Next, ASCII character 48 (zero) is converted to 0x00
else A-F characters are converted to 0x0A, 0x0B, etc. */
if (*code >= 48 && *code <=57)
*code -= 48;
else
*code -= 55; /* ASCII character "A" for example is
65 in decimal. Subtracting 55 from
it produces 0A in hex */
ptr = (char *)addr;
switch(pane) {
case 20: ptr += 6; break;
case 30: ptr += 12; break;
}
ptr += --i;
if (nibble == 1) {
save = *ptr;
if (save >= 0x10 || save < 0) {
temp = (int)save;
temp2 = temp;
temp2 = temp2 << 4;
temp = temp >> 4;
temp = temp << 8;
temp2 -= temp;
temp2 = temp2 >> 4;
save = (char)temp2;
}
strncpy(ptr, (const char *)code, 1);
*ptr = *ptr << 4;
*ptr += save;
nibble = FALSE;
}
else {
save = *ptr;
strncpy(ptr, (const char *)code, 1);
save = save >> 4;
save = save << 4;
*ptr += save;
nibble = 1;
}
}
else
flag = FALSE; /* else, key was not 0-9, A-F */
}
else { /* else, pane is 40 (i.e. the data window) */
col = wherex();
ungetch(*code); /* Force key just pressed back onto the keyboard */
for (i = 0; i <= 80; i++) {
c = getch();
if (!c)
extended = getch();
if (extended)
extended = 0;
else {
switch(c) {
case 8: /* backspace */
i-=2;
gotoxy(wherex() - 1, wherey());
cprintf(" ");
gotoxy(wherex() - 1, wherey());
break;
case 9: /* tab */
break;
case 13:
data[i] = '\0'; /* Terminate string */
i = 81;
newfield(data);
case ESCAPE:
break;
default:
col = wherex();
row = wherey();
if (c == 32)
offset = i;
/* next, perform word wrap */
if (col == 29 && row != 3) {
if (offset < i) {
gotoxy(((offset + 1)-(i-28)), row);
clreol();
data[i] = '\0';
(char *)temp = data;
data += (offset + 1);
cprintf("\r\n%s", data);
data = (char *)temp;
}
}
if (col == 29 && row == 3) {
_wscroll = 0; /* disable scrolling */
ungetch(13); /* cause "for" exit */
}
data[i] = c;
cprintf("%c", c);
} /* End of case structure */
}
} /* Bottom of for loop */
}
break; /* the end of default, or "case else" */
}
return(flag);
}
/***************************************************************************
Function : newfield
Parameters:
Returns : Changes current field, "toggling" each call
***************************************************************************/
void newfield(char *data) {
int i;
pane += 10; /* pane changed from static to global Feb. 24 */
_wscroll = 0; /* defined in CONIO.H */
switch(pane) {
case 10: window(32, 11, 48, 11); /* select desination */
break;
case 20: window(32, 12, 48, 12); /* select source */
break;
case 30: window(32, 14, 35, 14); /* select type */
break;
case 40: window(32, 16, 60, 18); /* select packet window */
clrscr();
_wscroll = 1;
pane = 0;
for (i = 0; i < 90; i++)
data[i] = '\0';
}
}
/***************************************************************************
Function : menu
Parameters: ethernet address to be printed
Returns : nothing
***************************************************************************/
void menu(char ary[]) {
int coord, i;
_setcursortype(_NOCURSOR);
textcolor(BLACK); /* reverse the colours (black on white) */
textbackground(WHITE);
_wscroll = 0; /* Do not scroll when maximum row is reached */
/* Draw bars on top & bottom */
for (coord = 1; coord <= 80; coord++) {
gotoxy(coord, 1);
cprintf("%c", 32);
gotoxy(coord, 25);
cprintf("%c", 32);
}
gotoxy(30, 1);
cprintf("Packet Send Utility");
gotoxy(4, 25);
cprintf("F1=Send %c F2=10 Frames %c F3=100 Frames", 179, 179);
window(1, 2, 80, 24);
textcolor(LIGHTGRAY);
textbackground(BLUE);
clrscr(); /* clear based on most recent call to window() */
/* Draw horozontal lines on top and bottom of window */
for (coord = 2; coord < 80; coord++) {
gotoxy(coord, 1);
cprintf("%c", 196);
gotoxy(coord, 23);
cprintf("%c", 196);
}
/* Place corners of box */
gotoxy(1, 1);
cprintf("%c", 218);
gotoxy(80, 1);
cprintf("%c", 191);
gotoxy(1, 23);
cprintf("%c", 192);
gotoxy(80, 23);
cprintf("%c", 217);
/* Draw left and right verticle lines */
for (coord = 2; coord < 23; coord++) {
gotoxy(1, coord);
cprintf("%c", 179);
gotoxy(80, coord);
cprintf("%c", 179);
}
textcolor(DARKGRAY);
textbackground(LIGHTGRAY);
/****************** Draw inner box ******************/
/* Draw horozontal lines on top and bottom of inner window */
for (coord = 13; coord < 68; coord++) {
gotoxy(coord, 5);
cprintf("%c", 205);
gotoxy(coord, 19);
cprintf("%c", 205);
}
/* Place corners of inner box */
gotoxy(12, 5); /* row 5 to 19, col 12 to 68 */
cprintf("%c", 201);
gotoxy(68, 5);
cprintf("%c", 187);
gotoxy(12, 19);
cprintf("%c", 200);
gotoxy(68, 19);
cprintf("%c", 188);
/* Draw left and right verticle lines for inner box */
for (coord = 6; coord < 19; coord++) {
gotoxy(12, coord);
cprintf("%c", 186);
gotoxy(68, coord);
cprintf("%c", 186);
}
textcolor(YELLOW);
window(13, 7, 67, 19);
clrscr(); /* clear based on most recent call to window() */
gotoxy(13, 2);
cprintf("Enter the Packet Frame to Send:");
textcolor(BLUE);
gotoxy(6, 5);
cprintf("Destination:");
gotoxy(11, 6);
cprintf("Source:");
gotoxy(13, 8);
cprintf("Type:");
gotoxy(13, 10);
cprintf("Data:");
textcolor(WHITE);
textbackground(LIGHTGREEN);
window(32, 11, 48, 11); /* Destination window */
clrscr();
fldset(ary, 0); /* Print 1 hex byte as two ASCII characters */
window(32, 12, 48, 12); /* Source window */
clrscr();
fldset(ary, 6); /* offset 6 into "ary" array */
window(32, 14, 35, 14); /* Type window */
clrscr();
for (i = 12; i < 14; i++)
cprintf("%02X", ary[i]); /* Print in hexadecimal */
window(32, 16, 61, 18); /* Packet window */
textcolor(YELLOW);
clrscr();
for (coord = 1; coord <= 3; coord++) {
gotoxy(30, coord);
cprintf("%c", 174); /* print "«" to right of window. */
}
window(32, 16, 60, 18);
textcolor(WHITE);
clrscr();
window(2, 3, 79, 23);
textbackground(BLUE);
_setcursortype(_NORMALCURSOR);
}
/***************************************************************************
Function : fldset
Parameters: This function is only used by menu()
Returns : nothing
***************************************************************************/
void fldset(char disp[], int pos) {
int i, j, limit, delimit;
limit = pos + 6;
delimit = (limit - 1);
for (i = pos; i < limit; i++) {
j = abs(disp[i]);
if (disp[i] < 0)
j = (128 + (128-j)); /* adjust large numbers */
if (i < delimit)
cprintf("%02X:", j);
else
cprintf("%02X", j);
}
}
/***************************************************************************
Function : reset
Parameters:
Returns : nothing
***************************************************************************/
void reset(void) {
window(1, 1, 80, 25);
textcolor(LIGHTGRAY);
textbackground(BLACK);
_setcursortype(_NORMALCURSOR);
clrscr();
}
/***************************************************************************
Function : leave
Parameters: a keystroke from user
Returns : nothing
***************************************************************************/
void leave(int *code) {
struct text_info ti; /* defined in CONIO.H */
int resp;
gettextinfo(&ti);
_setcursortype(_NOCURSOR);
window(2, 3, 79, 23);
gotoxy(22, 20);
textbackground(BLUE);
clreol();
gotoxy(31, 20);
cprintf("Do you wish to exit?");
resp = getch();
if (toupper(resp) != 'Y')
*code = 0; /* change users key press to null */
gotoxy(31, 20);
clreol(); /* Remove prompt just displayed */
window(ti.winleft, ti.wintop, ti.winright, ti.winbottom);
gotoxy(ti.curx, ti.cury);
textbackground(LIGHTGREEN);
_setcursortype(_NORMALCURSOR);
}