home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / pksnd102.zip / PKTSEND.C < prev    next >
C/C++ Source or Header  |  1997-01-06  |  22KB  |  603 lines

  1. /*  PKTSEND.C
  2.  
  3.     Author:        Patrick Whittle
  4.     Date:          November 4, 1994
  5.     Revisions:     February 24, 1995
  6.            January 6, 1997
  7.  
  8.     Purpose:       Provide interface to network packet driver.
  9.  
  10.     The accompanying file 8086.H must be included for a successful
  11.     compile.  Two key functions used in PKTSEND for communicating with a
  12.     packet driver are drvrchk(), and sendpkt().  These are both found in
  13.     the file 8086.H.
  14.  
  15.     To implement driver calls such as Get Address (function 06h), or Get
  16.     Driver Info (function 01h, subfunction FFh), a C function is available
  17.     in the public domain by Phil Karn.  This function, access_type(), can
  18.     be found in the file PKTDRVR.C.  Following is an example for using my
  19.     function with access_type():
  20.  
  21.     if (intno = drvrchk())
  22.         handle = access_type(intno,if_class,if_type,if_number,
  23.                 type,typelen,receiver);
  24.  
  25.     Once this completes successfully, PKTSEND.COM will be registered with
  26.     the packet driver, and may begin using its internal functions.  Note
  27.     that the function sendpkt() used in this program is available without
  28.     first calling access_type.
  29.  
  30. */
  31. #include <stdio.h>
  32. #include <conio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <ctype.h>
  36. #include <dos.h>
  37. #include "8086.h"
  38.  
  39. #define TRUE          -1
  40. #define FALSE          0
  41. #define BELL           7
  42. #define ESCAPE         27
  43.  
  44. /* Global variables are next */
  45.  
  46. int pane = 10;
  47.  
  48. /* Function prototypes are next */
  49. void sendframe(int times, char *data, char ieee[], int intno);
  50. int  validkey(int *code, char addr[], char *data);
  51. void newfield(char *data);
  52. void menu(char ary[]);
  53. void fldset(char disp[], int pos);
  54. void reset(void);
  55. void leave(int *code);
  56.  
  57. int main(void) {
  58.  
  59.     int intno, keystr = 0, extended = 0, col;
  60.     char *txt = "A network packet driver was ";  /* found, or not found? */
  61.  
  62.     char ieee[14] = {0x08,0x0A,0x21,0x36,0x2C,0x98,0x0B,
  63.              0x81,0x26,0x37,0xAE,0x71,0x08,0x00}, *pkt;
  64.  
  65.     intno = drvrchk(); /* Function returns currently hooked interrupt in
  66.               intno if it exists, or FALSE condition otherwise */
  67.     if (intno) {
  68.         clrscr();
  69.     printf("Packet Send Utility, Copyright (C) Patrick Whittle 1995-1997\n");
  70.     sleep(5);     /* wait 5 seconds */
  71.     menu(ieee);    /* pass initial network address to menu function */
  72.     gotoxy(19, 2);
  73.     cprintf("%sfound at 0x%X.", txt, intno);
  74.  
  75.     /* allocate memory for packet string */
  76.     pkt = (char *) calloc(104, sizeof(char)); // 90 bytes for packet, 14 for header
  77.     pkt = (char *) memcpy(pkt, ieee, 14);
  78.  
  79.     pkt += 14;  /* Point to end of ieee address.  This pointer is passed
  80.                between sendframe() and main function for the purpose
  81.                of concatination of address, and data. */
  82.  
  83.     textbackground(LIGHTGREEN);  /* defined in CONIO.H */
  84.     window(32, 11, 48, 11);      /* dimension of destination field */
  85.  
  86.     while (keystr != ESCAPE) {   /* escape key will break loop */
  87.         keystr = getch();
  88.         if (!keystr)
  89.         extended = getch();  /* i.e. F1-F10, arrow keys, etc. */
  90.  
  91.         if (extended) {
  92.         switch (extended) {
  93.             case 'K':                               /* left arrow */
  94.                         gotoxy(wherex()-1, wherey());
  95.                         if (pane == 10 || pane == 20) {
  96.                             col = wherex();
  97.                             if (col==3||col==6||col==9||col==12||col==15)
  98.                                 gotoxy(col-1, wherey());
  99.                         }
  100.                         break;
  101.                     case 'M':                              /* right arrow */
  102.                         gotoxy(wherex()+1, wherey());
  103.                         if (pane == 10 || pane == 20) {
  104.                             col = wherex();
  105.                             if (col==3||col==6||col==9||col==12||col==15)
  106.                                 gotoxy(col+1, wherey());
  107.                         }
  108.                         break;
  109.                     case 'H':                                    /* up */
  110.  
  111.                         break;
  112.                     case 'P':                                    /* down */
  113.  
  114.                         break;
  115.                     case ';':                                    /* F1 */
  116.                         sendframe(1, pkt, ieee, intno);
  117.                         break;
  118.                     case '<':                                    /* F2 */
  119.                         sendframe(10, pkt, ieee, intno);
  120.                         break;
  121.                     case '=':                                    /* F3 */
  122.                         sendframe(100, pkt, ieee, intno);
  123.                         break;
  124.                 }
  125.                 extended = 0;   /* reset for next iteration */
  126.             }
  127.             else  /* else, normal keystroke */
  128.             {
  129.                 if (!validkey(&keystr, ieee, pkt))
  130.                     cprintf("%c", BELL);          /* Invalid key */
  131.                 else
  132.                 {
  133.                     if (keystr == ESCAPE)   /* Does the user want to exit? */
  134.                         leave(&keystr);
  135.                     else                /* Does not want to exit! */
  136.                     {
  137.                         col = wherex();
  138.                         if ((col == 3)||(col == 6)||(col == 9)||(col == 12)||(col == 15)) {
  139.  
  140.                             /* The "pane" variable will hold a value
  141.                                indicating the current field that is active
  142.                                to accept user input. Delimeters in the
  143.                                source and destination fields (colons) must
  144.                                by recognized with the code below.           */
  145.  
  146.                             if (pane == 10 || pane == 20)
  147.                                 gotoxy(col+1, wherey());
  148.                         }
  149.                     }
  150.                 }
  151.             }
  152.         }
  153.         reset();            /* restore default DOS window and colours */
  154.     }
  155.     else
  156.         printf("%sNOT found.\n", txt);  /* ftp packet driver wasn't found. */
  157.  
  158.     return(0);
  159. }
  160. /***************************************************************************
  161. Function  : sendframe
  162. Parameters:
  163. Returns   : nothing
  164.  
  165. ***************************************************************************/
  166. void sendframe(int times, char *data, char ieee[], int intno) {
  167.  
  168.     int i;
  169.     data -= 14;  // Point back to start.  See the line "pkt += 14" in main()
  170.     data = (char *) memcpy(data, ieee, 14);
  171.  
  172.     _setcursortype(_NOCURSOR);
  173.     textbackground(BLUE);
  174.     window(2, 3, 79, 23);
  175.     gotoxy(32, 20);
  176.  
  177.     for (i = 1; i <= times; i++) {
  178.         if (sendpkt(data, 104, intno)) {
  179.             gotoxy(22, 20);
  180.             clreol();
  181.             cprintf("Packet sent successfully %d time(s).", i);
  182.         }
  183.         else {
  184.             cprintf("Send was not successful.");
  185.             i = times;
  186.         }
  187.     }
  188.     data += 14;                     /* Start accepting data again */
  189.     textbackground(LIGHTGREEN);
  190.  
  191.     window(32, 11, 48, 11);
  192.     _setcursortype(_NORMALCURSOR);
  193.     _wscroll = 0;                   /* scrolling disabled */
  194.     pane = 10;                      /* a global variable */
  195. }
  196. /***************************************************************************
  197. Function  : validkey
  198. Parameters:
  199. Returns   : TRUE or FALSE condition
  200.  
  201. ***************************************************************************/
  202. int validkey(int *code, char addr[], char *data) {
  203.  
  204.     int temp, temp2, c, extended = 0, offset, flag = TRUE;
  205.     static int row, col = 0, nibble = 1;
  206.     char i, *ptr, save;
  207.  
  208.     switch (*code) {
  209.         case 9:                                 /* tab */
  210.             newfield(data);
  211.             break;
  212.         case 13:                                /* carriage return */
  213.             newfield(data);
  214.             break;
  215.         case ESCAPE:                            /* escape */
  216.  
  217.             break;
  218.         default:                                /* case else */
  219.             if (pane >= 10 && pane <= 30) {
  220.                 if (*code >=97 && *code <=102)
  221.                     *code -= 32;                /* change to upper case */
  222.  
  223.                 /* Is key pressed 0-9, A-F? */
  224.                 if ((*code >= 48 && *code <=57)||(*code >= 65 && *code <= 70)) {
  225.                     i = wherex();
  226.                     cprintf("%c", *code);
  227.  
  228.                     /* Next, adjust for colons that delimit each byte. These
  229.                        are displayed as part of the addresses for source and
  230.                        destination. */
  231.  
  232.                     if (i == 2) {
  233.                         nibble = FALSE;
  234.                         i = 1;
  235.                     }
  236.                     if (pane == 10 || pane == 20) { /* only adjust source
  237.                                                          and dest fields */
  238.                         if (i == 4 || i == 5) {
  239.                             if (i == 5) nibble = FALSE;
  240.                             i = 2;
  241.                         }
  242.                         if (i == 7 || i == 8) {
  243.                             if (i == 8) nibble = FALSE;
  244.                             i = 3;
  245.                         }
  246.                         if (i == 10|| i == 11) {
  247.                             if (i == 11) nibble = FALSE;
  248.                             i = 4;
  249.                         }
  250.                         if (i == 13|| i == 14) {
  251.                             if (i == 14) nibble = FALSE;
  252.                             i = 5;
  253.                         }
  254.                         if (i == 16|| i == 17) {
  255.                             if (i == 17) nibble = FALSE;
  256.                             i = 6;
  257.                         }
  258.                     }
  259.                     else {                    /* Adjust the "type" field */
  260.                         if (i == 2 || i == 4)
  261.                             nibble = FALSE;
  262.                         if (i == 3 || i == 4)
  263.                             i = 2;
  264.                     }
  265.                     /* Next, ASCII character 48 (zero) is converted to 0x00
  266.                        else A-F characters are converted to 0x0A, 0x0B, etc. */
  267.  
  268.                     if (*code >= 48 && *code <=57)
  269.                         *code -= 48;
  270.                     else
  271.                         *code -= 55;   /* ASCII character "A" for example is
  272.                                           65 in decimal.  Subtracting 55 from
  273.                                           it produces 0A in hex */
  274.                     ptr = (char *)addr;
  275.  
  276.                     switch(pane) {
  277.                         case 20:     ptr += 6;     break;
  278.                         case 30:     ptr += 12;    break;
  279.                     }
  280.                     ptr += --i;
  281.  
  282.                     if (nibble == 1) {
  283.                         save = *ptr;
  284.                         if (save >= 0x10 || save < 0) {
  285.                             temp = (int)save;
  286.                             temp2 = temp;
  287.                             temp2 = temp2 << 4;
  288.  
  289.                             temp = temp >> 4;
  290.                             temp = temp << 8;
  291.                             temp2 -= temp;
  292.                             temp2 = temp2 >> 4;
  293.                             save  = (char)temp2;
  294.                         }
  295.                         strncpy(ptr, (const char *)code, 1);
  296.                         *ptr = *ptr << 4;
  297.                         *ptr += save;
  298.                         nibble = FALSE;
  299.                     }
  300.                     else {
  301.                         save = *ptr;
  302.                         strncpy(ptr, (const char *)code, 1);
  303.                         save = save >> 4;
  304.                         save = save << 4;
  305.                         *ptr += save;
  306.                         nibble = 1;
  307.                     }
  308.                 }
  309.                 else
  310.                     flag = FALSE;  /* else, key was not 0-9, A-F */
  311.             }
  312.             else {             /* else, pane is 40 (i.e. the data window) */
  313.                 col = wherex();
  314.                 ungetch(*code); /* Force key just pressed back onto the keyboard */
  315.  
  316.                 for (i = 0; i <= 80; i++) {
  317.                     c = getch();
  318.                     if (!c)
  319.                         extended = getch();
  320.  
  321.                     if (extended)
  322.                         extended = 0;
  323.                     else {
  324.                         switch(c) {
  325.                             case 8:                      /* backspace */
  326.                                 i-=2;
  327.                                 gotoxy(wherex() - 1, wherey());
  328.                                 cprintf(" ");
  329.                                 gotoxy(wherex() - 1, wherey());
  330.                                 break;
  331.                             case 9:                      /* tab */
  332.  
  333.                                 break;
  334.                             case 13:
  335.                                 data[i] = '\0';      /* Terminate string */
  336.                                 i = 81;
  337.                                 newfield(data);
  338.                             case ESCAPE:
  339.  
  340.                                 break;
  341.                             default:
  342.                                 col = wherex();
  343.                                 row = wherey();
  344.  
  345.                                 if (c == 32)
  346.                                     offset = i;
  347.  
  348.                                 /* next, perform word wrap */
  349.                                 if (col == 29 && row != 3) {
  350.                                     if (offset < i) {
  351.                                         gotoxy(((offset + 1)-(i-28)), row);
  352.                                         clreol();
  353.                                         data[i] = '\0';
  354.                                         (char *)temp = data;
  355.                                         data += (offset + 1);
  356.                                         cprintf("\r\n%s", data);
  357.                                         data = (char *)temp;
  358.                                     }
  359.                                 }
  360.                                 if (col == 29 && row == 3) {
  361.                                     _wscroll = 0;  /* disable scrolling */
  362.                                     ungetch(13);   /* cause "for" exit */
  363.                                 }
  364.                                 data[i] = c;
  365.                                 cprintf("%c", c);
  366.  
  367.                         }     /* End of case structure */
  368.  
  369.                     }
  370.  
  371.                 }  /* Bottom of for loop */
  372.             }
  373.             break;            /* the end of default, or "case else" */
  374.     }
  375.     return(flag);
  376. }
  377. /***************************************************************************
  378. Function  : newfield
  379. Parameters:
  380. Returns   : Changes current field, "toggling" each call
  381.  
  382. ***************************************************************************/
  383. void newfield(char *data) {
  384.  
  385.     int i;
  386.     pane += 10;           /* pane changed from static to global Feb. 24 */
  387.     _wscroll = 0;         /* defined in CONIO.H */
  388.  
  389.     switch(pane) {
  390.         case 10:       window(32, 11, 48, 11);  /* select desination */
  391.                        break;
  392.         case 20:       window(32, 12, 48, 12);  /* select source */
  393.                        break;
  394.         case 30:       window(32, 14, 35, 14);  /* select type */
  395.                        break;
  396.         case 40:       window(32, 16, 60, 18);  /* select packet window */
  397.                        clrscr();
  398.                        _wscroll = 1;
  399.                        pane = 0;
  400.                        for (i = 0; i < 90; i++)
  401.                            data[i] = '\0';
  402.     }
  403. }
  404. /***************************************************************************
  405. Function  : menu
  406. Parameters: ethernet address to be printed
  407. Returns   : nothing
  408.  
  409. ***************************************************************************/
  410. void menu(char ary[]) {
  411.  
  412.     int coord, i;
  413.  
  414.     _setcursortype(_NOCURSOR);
  415.     textcolor(BLACK);           /* reverse the colours (black on white) */
  416.     textbackground(WHITE);
  417.     _wscroll = 0;          /* Do not scroll when maximum row is reached */
  418.  
  419.     /* Draw bars on top & bottom */
  420.     for (coord = 1; coord <= 80; coord++) {
  421.         gotoxy(coord, 1);
  422.         cprintf("%c", 32);
  423.         gotoxy(coord, 25);
  424.         cprintf("%c", 32);
  425.     }
  426.     gotoxy(30, 1);
  427.     cprintf("Packet Send Utility");
  428.     gotoxy(4, 25);
  429.     cprintf("F1=Send  %c  F2=10 Frames  %c  F3=100 Frames", 179, 179);
  430.  
  431.     window(1, 2, 80, 24);
  432.     textcolor(LIGHTGRAY);
  433.     textbackground(BLUE);
  434.     clrscr();               /* clear based on most recent call to window() */
  435.  
  436.     /* Draw horozontal lines on top and bottom of window */
  437.     for (coord = 2; coord < 80; coord++) {
  438.         gotoxy(coord, 1);
  439.         cprintf("%c", 196);
  440.         gotoxy(coord, 23);
  441.         cprintf("%c", 196);
  442.     }
  443.     /* Place corners of box */
  444.     gotoxy(1, 1);
  445.     cprintf("%c", 218);
  446.     gotoxy(80, 1);
  447.     cprintf("%c", 191);
  448.     gotoxy(1, 23);
  449.     cprintf("%c", 192);
  450.     gotoxy(80, 23);
  451.     cprintf("%c", 217);
  452.  
  453.     /* Draw left and right verticle lines */
  454.     for (coord = 2; coord < 23; coord++) {
  455.         gotoxy(1, coord);
  456.         cprintf("%c", 179);
  457.         gotoxy(80, coord);
  458.         cprintf("%c", 179);
  459.     }
  460.     textcolor(DARKGRAY);
  461.     textbackground(LIGHTGRAY);
  462.     /****************** Draw inner box ******************/
  463.  
  464.     /* Draw horozontal lines on top and bottom of inner window */
  465.     for (coord = 13; coord < 68; coord++) {
  466.         gotoxy(coord, 5);
  467.         cprintf("%c", 205);
  468.         gotoxy(coord, 19);
  469.         cprintf("%c", 205);
  470.     }
  471.     /* Place corners of inner box */
  472.     gotoxy(12, 5);                     /* row 5 to 19, col 12 to 68 */
  473.     cprintf("%c", 201);
  474.     gotoxy(68, 5);
  475.     cprintf("%c", 187);
  476.     gotoxy(12, 19);
  477.     cprintf("%c", 200);
  478.     gotoxy(68, 19);
  479.     cprintf("%c", 188);
  480.  
  481.     /* Draw left and right verticle lines for inner box */
  482.     for (coord = 6; coord < 19; coord++) {
  483.         gotoxy(12, coord);
  484.         cprintf("%c", 186);
  485.         gotoxy(68, coord);
  486.         cprintf("%c", 186);
  487.     }
  488.     textcolor(YELLOW);
  489.     window(13, 7, 67, 19);
  490.     clrscr();               /* clear based on most recent call to window() */
  491.     gotoxy(13, 2);
  492.     cprintf("Enter the Packet Frame to Send:");
  493.     textcolor(BLUE);
  494.     gotoxy(6, 5);
  495.     cprintf("Destination:");
  496.     gotoxy(11, 6);
  497.     cprintf("Source:");
  498.     gotoxy(13, 8);
  499.     cprintf("Type:");
  500.     gotoxy(13, 10);
  501.     cprintf("Data:");
  502.     textcolor(WHITE);
  503.     textbackground(LIGHTGREEN);
  504.     window(32, 11, 48, 11);     /* Destination window */
  505.     clrscr();
  506.     fldset(ary, 0);             /* Print 1 hex byte as two ASCII characters */
  507.  
  508.     window(32, 12, 48, 12);     /* Source window */
  509.     clrscr();
  510.     fldset(ary, 6);             /* offset 6 into "ary" array */
  511.  
  512.     window(32, 14, 35, 14);     /* Type window */
  513.     clrscr();
  514.  
  515.     for (i = 12; i < 14; i++)
  516.         cprintf("%02X", ary[i]);    /* Print in hexadecimal */
  517.  
  518.     window(32, 16, 61, 18);         /* Packet window */
  519.     textcolor(YELLOW);
  520.     clrscr();
  521.  
  522.     for (coord = 1; coord <= 3; coord++) {
  523.         gotoxy(30, coord);
  524.         cprintf("%c", 174);         /* print "«" to right of window. */
  525.     }
  526.     window(32, 16, 60, 18);
  527.     textcolor(WHITE);
  528.     clrscr();
  529.     window(2, 3, 79, 23);
  530.     textbackground(BLUE);
  531.     _setcursortype(_NORMALCURSOR);
  532. }
  533. /***************************************************************************
  534. Function  : fldset
  535. Parameters: This function is only used by menu()
  536. Returns   : nothing
  537.  
  538. ***************************************************************************/
  539. void fldset(char disp[], int pos) {
  540.  
  541.     int i, j, limit, delimit;
  542.     limit = pos + 6;
  543.     delimit = (limit - 1);
  544.  
  545.     for (i = pos; i < limit; i++) {
  546.         j = abs(disp[i]);
  547.         if (disp[i] < 0)
  548.             j = (128 + (128-j));   /* adjust large numbers */
  549.  
  550.         if (i < delimit)
  551.             cprintf("%02X:", j);
  552.         else
  553.             cprintf("%02X", j);
  554.     }
  555. }
  556. /***************************************************************************
  557. Function  : reset
  558. Parameters:
  559. Returns   : nothing
  560.  
  561. ***************************************************************************/
  562. void reset(void) {
  563.  
  564.     window(1, 1, 80, 25);
  565.     textcolor(LIGHTGRAY);
  566.     textbackground(BLACK);
  567.     _setcursortype(_NORMALCURSOR);
  568.     clrscr();
  569. }
  570. /***************************************************************************
  571. Function  : leave
  572. Parameters: a keystroke from user
  573. Returns   : nothing
  574.  
  575. ***************************************************************************/
  576. void leave(int *code) {
  577.  
  578.     struct text_info ti;    /* defined in CONIO.H */
  579.     int resp;
  580.  
  581.     gettextinfo(&ti);
  582.  
  583.     _setcursortype(_NOCURSOR);
  584.     window(2, 3, 79, 23);
  585.     gotoxy(22, 20);
  586.     textbackground(BLUE);
  587.     clreol();
  588.     gotoxy(31, 20);
  589.     cprintf("Do you wish to exit?");
  590.  
  591.     resp = getch();
  592.  
  593.     if (toupper(resp) != 'Y')
  594.         *code = 0;             /* change users key press to null */
  595.  
  596.     gotoxy(31, 20);
  597.     clreol();                  /* Remove prompt just displayed */
  598.  
  599.     window(ti.winleft, ti.wintop, ti.winright, ti.winbottom);
  600.     gotoxy(ti.curx, ti.cury);
  601.     textbackground(LIGHTGREEN);
  602.     _setcursortype(_NORMALCURSOR);
  603. }