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

📄 main.c

📁 Vista 核心Rally技术之-LLTD 实现源代码
💻 C
字号:
/*
 * LICENSE NOTICE.
 *
 * Use of the Microsoft Windows Rally Development Kit is covered under
 * the Microsoft Windows Rally Development Kit License Agreement,
 * which is provided within the Microsoft Windows Rally Development
 * Kit or at http://www.microsoft.com/whdc/rally/rallykit.mspx. If you
 * want a license from Microsoft to use the software in the Microsoft
 * Windows Rally Development Kit, you must (1) complete the designated
 * "licensee" information in the Windows Rally Development Kit License
 * Agreement, and (2) sign and return the Agreement AS IS to Microsoft
 * at the address provided in the Agreement.
 */

/*
 * Copyright (c) Microsoft Corporation 2005.  All rights reserved.
 * This software is provided with NO WARRANTY.
 */

//#define CHECKING_PACKING 1

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>

#define	DECLARING_GLOBALS
#include "globals.h"

#include "statemachines.h"
#include "packetio.h"

extern void qos_init(void);

bool_t          isConfTest;

static void
usage(void)
{
    fprintf(stderr, "usage: %s [-d] [-t TRACELEVEL] INTERFACE [WIRELESS-IF]\n"
	    "\tRuns a link-layer topology discovery daemon on INTERFACE (eg eth0)\n"
	    "\t-d : don't background, and log moderate tracing to stdout (debug mode)\n"
	    "\t-t TRACELEVEL : select tracing by adding together:\n"
	    "\t\t0x01 : BAND network load control calculations\n"
	    "\t\t0x02 : packet dump of protocol exchange\n"
	    "\t\t0x04 : Charge mechanism for protection against denial of service\n"
	    "\t\t0x08 : system information TLVs (type-length-value)\n"
	    "\t\t0x10 : State-Machine transitions for smS, smE, and smT\n"
	    "\t\t0x20 : Qos/qWave extensions\n",
	    g_Progname);
    exit(2);
}


static void
init_from_conf_file()
{
    FILE   *conf_file;
    char   *line = NULL;
    #define LINEBUFLEN 256
    char    var[LINEBUFLEN];
    char    val[LINEBUFLEN];
    size_t  len  = 0;
    ssize_t numread;
    int     assigns;
    char    default_icon_path[] = {"/etc/icon.ico"};

    /* Set default values for configuration options */
    /* (avoid strdup() since it doesn't use xmalloc wrapper) */
    g_icon_path = xmalloc(strlen(default_icon_path)+1);
    strcpy(g_icon_path,default_icon_path);

    /* Examine configuration file, if it exists */
    conf_file = fopen("/etc/lld2d.conf", "r");
    if (conf_file == NULL)  return;
    while ((numread = getline(&line, &len, conf_file)) != -1)
    {
        var[0] = val[0] = '\0';
        assigns = sscanf(line, "%s = %s", var, val);

        if (assigns==2)
        {
            /* compare to each of the 2 allowed vars... */
            if (!strcmp(var,"icon")) {
                char *path = NULL;
                char *cur  = NULL;

                path = xmalloc(strlen(val)+6); // always allow enough room for a possible prefix of '/etc/'
                cur = path;

                /* Check for leading '/' and prefix '/etc/' if missing */
                if (val[0] != '/')
                {
                    strcpy(cur,"/etc/"); cur += 5;
                }
                strncpy(cur,val,strlen(val));

                if (g_icon_path) xfree(g_icon_path);	// always use the most recent occurrence
                g_icon_path = path;
                DEBUG({printf("configvar 'g_icon_path' = %s\n", g_icon_path);})
            } else if (!strcmp(var,"jumbo-icon")) {
                char *path = NULL;
                char *cur  = NULL;

                path = xmalloc(strlen(val)+6); // always allow enough room for a possible prefix of '/etc/'
                cur = path;

                /* Check for leading '/' and prefix '/etc/' if missing */
                if (val[0] != '/')
                {
                    strcpy(cur,"/etc/"); cur += 5;
                }
                strncpy(cur,val,strlen(val));

                if (g_jumbo_icon_path) xfree(g_jumbo_icon_path);	// always use the most recent occurrence
                g_jumbo_icon_path = path;
                DEBUG({printf("configvar 'g_jumbo_icon_path' = %s\n", g_jumbo_icon_path);})
            } else {
                warn("line ignored - var does not match a known string\n");
            }
        } else {
            warn("line ignored - var or val was missing or no equals\n");
        }

    }
    if (line!=NULL)  free(line);
    fclose(conf_file);
}

//-----------------------------------------------------------------------------------------------------------//
int
main(int argc, char **argv)
{
    char  *p;
    int    c;
    bool_t opt_debug = FALSE;
    int    opt_trace = 0;

    /* set program name to last component of filename */
    p = strrchr(argv[0], '/');
    if (p)
	g_Progname = p+1;
    else
	g_Progname = argv[0];

    /* set a module flag if this is the confidence test */
    isConfTest = (strstr(g_Progname,"conftest") != NULL ? TRUE : FALSE);

    /* parse arguments */
    while ((c=getopt(argc, argv, "dt:")) != -1)
    {
	switch (c)
	{
	case 'd':
	    opt_debug = TRUE;
	    break;

	case 't':
	    opt_trace = atoi(optarg);
	    if (opt_trace == 0)
	    {
		fprintf(stderr, "%s: -t TRACELEVEL: parse error in \"%s\"\n",
			g_Progname, optarg);
		usage();
	    }
	    break;

	default:
	    if (isConfTest)
            {
                opt_debug = TRUE;
                opt_trace = TRC_PACKET + TRC_STATE;
            } else {
                usage();
            }
	    break;
	}
    }

    if (isConfTest)
    {
        if (optind >= argc)
        {
            g_interface = strstr(g_Progname,"x86") != NULL ? "eth0" : "br0";
            g_wl_interface = strstr(g_Progname,"x86") != NULL ? "eth0" : "eth1";
            printf("%s: no interface-name argument; '%s' assumed.\n", g_Progname, g_interface);
        } else {
            g_interface = strdup(argv[optind]);
            if ((optind+1) >= argc)
            {
                g_wl_interface = g_interface;
            } else {
                g_wl_interface = strdup(argv[optind+1]);
            }
        }
    } else {
        if (optind >= argc)
        {
            fprintf(stderr, "%s: error: missing INTERFACE name argument\n", g_Progname);
            usage();
        } else {
            g_interface = strdup(argv[optind]);
            if ((optind+1) >= argc)
            {
                g_wl_interface = g_interface;
            } else {
                g_wl_interface = strdup(argv[optind+1]);
            }
        }
    }

#ifdef CHECKING_PACKING
    printf("etherHdr: " FMT_SIZET "   baseHdr: " FMT_SIZET "    discoverHdr: " \
            FMT_SIZET "    helloHdr: " FMT_SIZET "    qltlvHdr: " FMT_SIZET "\n",
            sizeof(topo_ether_header_t),sizeof(topo_base_header_t),sizeof(topo_discover_header_t),
            sizeof(topo_hello_header_t),sizeof(topo_qltlv_header_t));
    assert(sizeof(topo_ether_header_t) == 14);
    assert(sizeof(topo_base_header_t) == 18);
    assert(sizeof(topo_discover_header_t) == 4);
    assert(sizeof(topo_hello_header_t) == 14);
    assert(sizeof(topo_qltlv_header_t) == 4);
    puts("Passed struct-packing checks!");
#endif

    /* initialise remaining process state */
    g_trace_flags = opt_trace;
    memset(&g_hwaddr,0,sizeof(etheraddr_t));

    g_smE_state = smE_Quiescent;
    g_smT_state = smT_Quiescent;

    memset (g_sessions,0,MAX_NUM_SESSIONS*sizeof(g_sessions[0]));

    memset(&g_band,0,sizeof(band_t));		/* BAND algorthm's state */
    g_osl = osl_init();				/* initialise OS-glue Layer */
    memset(g_rxbuf,0,(size_t)RXBUFSZ);
    memset(g_emitbuf,0,(size_t)RXBUFSZ);
    memset(g_txbuf,0,(size_t)TXBUFSZ);
    memset(g_re_txbuf,0,(size_t)TXBUFSZ);
    g_sees = seeslist_new(NUM_SEES);
    g_rcvd_pkt_len = 0;
    g_rtxseqnum = 0;
    g_re_tx_len = 0;
    g_generation = 0;
    g_sequencenum = 0;
    g_opcode = Opcode_INVALID;
    g_ctc_packets = 0;
    g_ctc_bytes = 0;

#if CAN_FOPEN_IN_SELECT_LOOP
    /* then we don't need a global to keep the stream open all the time...*/
#else
    g_procnetdev = fopen("/proc/net/dev","r");
    if (g_procnetdev<0)
        die("fopen of /proc/net/dev failed\n");
#endif

    /* Initialize the timers (inactivity timers are init'd when session is created) */
    g_block_timer = g_charge_timer = g_emit_timer = g_hello_timer = NULL;

    /* initialize things from the parameter file, /etc/lld2d.conf
     * currently, v1.0, this only involves LTLV pointers... */

    init_from_conf_file();

    event_init();
    qos_init();

    osl_interface_open(g_osl, g_interface, NULL);
    osl_get_hwaddr(g_osl, &g_hwaddr);

    IF_DEBUG
        printf("%s: listening at address: " ETHERADDR_FMT "\n",
	    g_Progname, ETHERADDR_PRINT(&g_hwaddr));
    END_DEBUG
    if (!opt_debug)
    {
        DEBUG({printf("%s: Using syslog\n", g_Progname);})
        util_use_syslog();
        DEBUG({printf("%s: Daemonizing...\n", g_Progname);})
        osl_become_daemon(g_osl);
    }
    DEBUG({printf("%s: listening on interface %s\n", g_Progname, g_interface);})

    osl_write_pidfile(g_osl);

    osl_drop_privs(g_osl);

    /* add IO handlers & run main event loop forever */
    event_mainloop();

    return 0;
}

⌨️ 快捷键说明

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