⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 telnet.c

📁 TELNET实现嵌入式原程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Telnet utility for 'TCP/IP Lean' (c) Iosoft Ltd. 2000

This software is only licensed for distribution with the book 'TCP/IP Lean',
and may only be used for personal experimentation by the purchaser
of that book, on condition that this copyright notice is retained.
For commercial licensing, contact license@iosoft.co.uk

This is experimental software; use it entirely at your own risk. The author
offers no warranties of any kind, including its fitness for purpose. */
/*
** v0.01 JPB 27/1/00
** v0.02 JPB 28/1/00  First steps toward TCP implementation
** v0.03 JPB 31/1/00  Added timeout
** v0.04 JPB 1/2/00   Added duplicate segment handling
** v0.05 JPB 2/2/00   Added TCP upcall, and active close
** v0.06 JPB 3/2/00   Simplified socket closure
** v0.07 JPB 4/2/00   Simplified state machine
** v0.08 JPB 4/2/00   Split upcalls into client & server
** v0.09 JPB 7/2/00   Improved active close
** v0.10 JPB 1/3/00   Fixed 'gate_ip' problem when no gateway specified
**                    Fixed problem with SLIP node matching
** v0.11 JPB 1/3/00   changed command-line interface to include port names
** v0.12 JPB 20/3/00  Added LiteLink and modem support
** v0.13 JPB 23/3/00  Used upcall pointers in TCP.C
** v0.14 JPB 6/4/00   Replaced 'strcmpi' with 'stricmp' for DJGPP compatibility
** v0.15 JPB 21/4/00  Fixed TCP problem receiving FIN + data
** v0.16 JPB 5/5/00   Minor cosmetic improvements to TCP code
** v0.17 JPB 3/7/00   Changed default config file to TCPLEAN.CFG
**                    Revised header for book CD
*/

#define VERSION "0.17"

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <signal.h>
#include <time.h>

#include "ether.h"
#include "netutil.h"
#include "net.h"
#include "ip.h"
#include "tcp.h"

#define CFGFILE     "tcplean.cfg"   /* Default config filename */
#define CFGEXT      ".cfg"          /* Default config extension */
#define MAXNETCFG   40              /* Max length of a net config string */
#define DEFPORT     TELPORT         /* Default port number */

/* Test page for Web server */
#define MYPAGE "HTTP/1.0 200 OK\r\n\r\n\
    <html><body>Test page from telnet server v" VERSION "</body></html>"

GENFRAME genframe;                  /* Frame for network Tx/Rx */
char cfgfile[MAXPATH+5]=CFGFILE;    /* Config filename */
char netcfg[MAXNETCFG+1]="??";      /* Network config string */
extern BYTE bcast[MACLEN];          /* Broadcast Ethernet addr */
NODE  locnode;                      /* My Ethernet and IP addresses */
int breakflag;                      /* Flag to indicate ctrl-break pressed */
char *clientcmd;                    /* Pointer to command-line command */

/* Debug flags */
extern int netdebug;                /* Verbose packet display */
extern int tcpdebug;                /* TCP frame display */
extern int statedebug;              /* TCP state display */

/* Socket storage */
#define NSOCKS 2
TSOCK tsocks[NSOCKS] =              /* Initialise index num and buffer sizes */
{
    {1,{_CBUFFLEN_},{_CBUFFLEN_}}, {2,{_CBUFFLEN_},{_CBUFFLEN_}}
};

/* Telnet options */
BYTE telopts[] =
{
    TEL_IAC, TEL_DO,    TEL_SGA,    /* Do suppress go-ahead */
    TEL_IAC, TEL_WONT,  TEL_ECHO,   /* Won't echo */
    TEL_IAC, TEL_WONT,  TEL_AUTH    /* Won't authenticate */
};

/* Function pointers: upcalls from TCP/IP stack */
extern NODE *(*get_locnode_n)(int n);                   /* Get local node */
extern int (*server_upcall)(TSOCK *ts, CONN_STATE conn);/* TCP server action */
extern int (*client_upcall)(TSOCK *ts, CONN_STATE conn);/* TCP client action */

/* Prototypes */
WORD read_netconfig(char *fname, NODE *np);
NODE *locnode_n(int n);
int server_action(TSOCK *ts, CONN_STATE conn);
int client_action(TSOCK *ts, CONN_STATE conn);
void do_teldisp(TSOCK *ts);
void do_receive(GENFRAME *gfp);
void do_poll(GENFRAME *gfp);
WORD str2service(char *str);
void disp_usage(void);
void break_handler(int sig);

int main(int argc, char *argv[])
{
    int args=0, err=0, client=0, fail, n;
    char *p, temps[18], k=0, c;
    WORD dtype;
    GENFRAME *gfp;
    LWORD mstimer;
    TSOCK *ts;
    NODE rem;

    printf("TELNET v" VERSION "\n");            /* Sign on */
    get_locnode_n = locnode_n;                  /* Set upcall ptrs to funcs */
    server_upcall = server_action;
    client_upcall = client_action;
    signal(SIGINT, break_handler);              /* Trap ctrl-C */
    ts = &tsocks[0];                            /* Pointer to client socket */
    memset(&rem, 0, sizeof(rem));               /* Preset remote port number */
    rem.port = DEFPORT;
    while (argc > ++args)                       /* Process command-line args */
    {
        if ((c=argv[args][0])=='-' || c=='/')
        {
            switch (toupper(argv[args][1]))
            {
            case 'C':                           /* -C: config filename */
                strncpy(cfgfile, argv[++args], MAXPATH);
                if ((p=strrchr(cfgfile, '.'))==0 || !isalpha(*(p+1)))
                    strcat(cfgfile, CFGEXT);
                break;
            case 'S':                           /* -S: display TCP states */
                statedebug = 1;
                break;
            case 'T':                           /* -T: display TCP segments */
                tcpdebug = 1;
                break;
            case 'V':                           /* -V: verbose packet display */
                netdebug |= 1;
                break;
            case 'X':                           /* -X: hex packet display */
                netdebug |= 2;
                break;
            default:
                err = 1;
            }
        }
        else if (client==0 && isdigit(c))       /* If client mode.. */
        {
            rem.ip = atoip(argv[args]);         /* Get destination IP address */
            client++;
        }                                       /* ..then port num/name */
        else if (client==1 && (rem.port=str2service(argv[args]))!=0)
            client++;
        else if (client == 2)
        {
            clientcmd = argv[args];             /* ..then command string */
            client++;
        }

    }
    if (err || rem.port==0)                     /* Prompt user if error */
        disp_usage();
    else if (!(dtype=read_netconfig(cfgfile, &locnode)))
        printf("Invalid configuration '%s'\n", cfgfile);
    else
    {
        rem.dtype = genframe.g.dtype = dtype;   /* Set frame driver type */
        gfp = &genframe;                        /* Get pointer to frame */
        printf("IP %s", ipstr(locnode.ip, temps));
        printf(" mask %s", ipstr(locnode.mask, temps));
        if (locnode.gate)
            printf(" gate %s", ipstr(locnode.gate, temps));
        if (dtype & DTYPE_ETHER)
            printf(" Ethernet %s", ethstr(locnode.mac, temps));
        if (client && !on_subnet(rem.ip, &locnode) && !locnode.gate)
            printf("\nWARNING: no gateway specified!");
        printf("\nPress ESC or ctrl-C to exit\n\n");
        if (client)                             /* If client, open socket */
            open_tcp(ts, gfp, &locnode, &rem);
        while (!breakflag && k!=0x1b)           /* Main loop.. */
        {
            do_receive(gfp);                    /* Receive frames */
            do_poll(gfp);                       /* Poll net drivers */
            if (client)
            {
                do_teldisp(ts);                 /* Telnet client display */
                if (!ts->state)                 /* If closed */
                    breakflag = 1;              /* ..exit from main loop */
                else if (k)                     /* If key pressed.. */
                    buff_in(&ts->txb, (BYTE *)&k, 1);
                k = 0;                          /* ..send it */
            }
            if (kbhit())                        /* Get keypress */
                k = getch();
        }                                       /* Close connection */
        if (k)
            printf("Closing...\n");
        mstimeout(&mstimer, 0);                 /* Refresh timer */
        do
        {                                       /* Loop until conns closed */
            for (n=fail=0; n<NSOCKS; n++)
                fail += !close_tcp(&tsocks[n]);
            do_receive(gfp);
            do_poll(gfp);                       /* ..or timeout */
        } while (!mstimeout(&mstimer, 1000) && fail);
        if (fail)                               /* If still open.. */
        {
            printf("Resetting connections\n");
            for (n=0; n<NSOCKS; n++)            /* ..send reset */
                reset_tcp(&tsocks[n], gfp);
            while (!mstimeout(&mstimer, 1000))
            {                                   /* ..and wait until sent */
                do_receive(gfp);
                do_poll(gfp);
            }
        }
        close_net(dtype);                       /* Shut down net driver */
    }
    return(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -