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

📄 libnet_link_dlpi.c

📁 tcp数据流重放工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  $Id: libnet_link_dlpi.c,v 1.4 2003/10/17 15:54:35 kkuehl Exp $ * *  libnet *  libnet_dlpi.c - dlpi routines * *  Copyright (c) 1998 - 2003 Mike D. Schiffman <mike@infonexus.com> *  All rights reserved. * * Copyright (c) 1993, 1994, 1995, 1996, 1997 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), * University College London. */#if (HAVE_CONFIG_H)#include "../include/config.h"#endif#include <sys/types.h>#include <sys/time.h>#ifdef HAVE_SYS_BUFMOD_H#include <sys/bufmod.h>#endif#include <sys/dlpi.h>#ifdef HAVE_HPUX9#include <sys/socket.h>#endif#ifdef DL_HP_PPA_ACK_OBS#include <sys/stat.h>#endif#include <sys/stream.h>#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)#include <sys/systeminfo.h>#endif#ifdef HAVE_SYS_DLPI_EXT_H#include <sys/dlpi_ext.h>#endif#ifdef HAVE_HPUX9#include <net/if.h>#endif#include <ctype.h>#ifdef HAVE_HPUX9#include <nlist.h>#include <dlpi_ext.h>#endif#include <errno.h>#include <fcntl.h>#include <memory.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stropts.h>#include <unistd.h>#include "../include/libnet.h"#include "../include/bpf.h"#include "../include/gnuc.h"#ifdef HAVE_OS_PROTO_H#include "../include/os-proto.h"#endif#ifndef DLPI_DEV_PREFIX#define DLPI_DEV_PREFIX "/dev"#endif#define	MAXDLBUF 8192/* Forwards */static int dlattachreq(int, bpf_u_int32, int8_t *);static int dlbindack(int, int8_t *, int8_t *);static int dlbindreq(int, bpf_u_int32, int8_t *);static int dlinfoack(int, int8_t *, int8_t *);static int dlinforeq(int, int8_t *);static int dlokack(int, const int8_t *, int8_t *, int8_t *);static int recv_ack(int, int, const int8_t *, int8_t *, int8_t *);static int send_request(int, int8_t *, int, int8_t *, int8_t *, int);#ifdef HAVE_SYS_BUFMOD_Hstatic int strioctl(int, int, int, int8_t *);#endif#ifdef HAVE_HPUX9static int dlpi_kread(int, off_t, void *, u_int, int8_t *);#endif#ifdef HAVE_DEV_DLPIstatic int get_dlpi_ppa(int, const int8_t *, int, int8_t *);#endif/* XXX Needed by HP-UX (at least) */static bpf_u_int32 ctlbuf[MAXDLBUF];intlibnet_open_link(libnet_t *l){    register int8_t *cp;    int8_t *eos;    register int ppa;    register dl_info_ack_t *infop;    bpf_u_int32 buf[MAXDLBUF];    int8_t dname[100];#ifndef HAVE_DEV_DLPI    int8_t dname2[100];#endif    if (l == NULL)    {         return (-1);    }     /*     *  Determine device and ppa     */    cp = strpbrk(l->device, "0123456789");    if (cp == NULL)    {        sprintf(l->err_buf, "%s missing unit number", l->device);        goto bad;    }    ppa = strtol(cp, &eos, 10);    if (*eos != '\0')    {        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,                "libnet_open_link: %s bad unit number", l->device);        goto bad;    }    if (*(l->device) == '/')    {        memset(&dname, 0, sizeof(dname));        strncpy(dname, l->device, sizeof(dname) - 1);
		dname[sizeof(dname) - 1] = '\0';    }    else    {        sprintf(dname, "%s/%s", DLPI_DEV_PREFIX, l->device);    }#ifdef HAVE_DEV_DLPI    /*     *  Map network device to /dev/dlpi unit     */    cp = "/dev/dlpi";    l->fd = open(cp, O_RDWR);    if (l->fd == -1)    {        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,                "libnet_open_link: %s: %s", cp,                 strerror(errno));        goto bad;    }    /*     *  Map network interface to /dev/dlpi unit     */    ppa = get_dlpi_ppa(l->fd, dname, ppa, l->err_buf);    if (ppa < 0)    {        goto bad;    }#else    /*     *  Try device without unit number     */    strcpy(dname2, dname);    cp = strchr(dname, *cp);    *cp = '\0';    l->fd = open(dname, O_RDWR);    if (l->fd == -1)    {        if (errno != ENOENT)        {            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,                    "libnet_open_link: %s: %s", dname, strerror(errno));            goto bad;        }        /*         *  Try again with unit number         */        l->fd = open(dname2, O_RDWR);        if (l->fd == -1)        {            snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,                    "libnet_open_link: %s: %s", dname2, strerror(errno));            goto bad;        }        cp = dname2;        while (*cp && !isdigit((int)*cp)) cp++;        if (*cp) ppa = atoi(cp);        else        /*         *  XXX Assume unit zero         */        ppa = 0;    }#endif    /*     *  Attach if "style 2" provider     */    if (dlinforeq(l->fd, l->err_buf) < 0 ||            dlinfoack(l->fd, (int8_t *)buf, l->err_buf) < 0)    {        goto bad;    }    infop = &((union DL_primitives *)buf)->info_ack;    if (infop->dl_provider_style == DL_STYLE2 &&            (dlattachreq(l->fd, ppa, l->err_buf)            < 0 || dlokack(l->fd, "attach", (int8_t *)buf, l->err_buf) < 0))    {        goto bad;    }    /*     *  Bind HP-UX 9 and HP-UX 10.20     */#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20) || defined(HAVE_HPUX11) || defined(HAVE_SOLARIS)    if (dlbindreq(l->fd, 0, l->err_buf) < 0 ||            dlbindack(l->fd, (int8_t *)buf, l->err_buf) < 0)    {        goto bad;    }#endif    /*     *  Determine link type     */    if (dlinforeq(l->fd, l->err_buf) < 0 ||            dlinfoack(l->fd, (int8_t *)buf, l->err_buf) < 0)    {        goto bad;    }    infop = &((union DL_primitives *)buf)->info_ack;    switch (infop->dl_mac_type)    {        case DL_CSMACD:        case DL_ETHER:            l->link_type    = DLT_EN10MB;            l->link_offset  = 0xe;            break;        case DL_FDDI:            l->link_type    = DLT_FDDI;            l->link_offset  = 0x15;            break;        case DL_TPR:            l->link_type    = DLT_PRONET;            l->link_offset  = 0x16;            break;        default:            sprintf(l->err_buf, "libnet_open_link(): unknown mac type 0x%lu",                    (u_int32_t) infop->dl_mac_type);            goto bad;    }#ifdef	DLIOCRAW    /*     *  This is a non standard SunOS hack to get the ethernet header.     */    if (strioctl(l->fd, DLIOCRAW, 0, NULL) < 0)    {        sprintf(l->err_buf, "libnet_open_link(): DLIOCRAW: %s", strerror(errno));        goto bad;    }#endif    return (1);bad:    if (l->fd > 0)    {        close(l->fd);      /* this can fail ok */    }    return (-1);}static intsend_request(int fd, int8_t *ptr, int len, int8_t *what, int8_t *ebuf, int flags){    struct strbuf ctl;    ctl.maxlen = 0;    ctl.len = len;    ctl.buf = ptr;    if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0)    {        sprintf(ebuf, "send_request: putmsg \"%s\": %s", what, strerror(errno));        return (-1);    }    return (0);}static intrecv_ack(int fd, int size, const int8_t *what, int8_t *bufp, int8_t *ebuf){    union DL_primitives *dlp;    struct strbuf ctl;    int flags;    ctl.maxlen = MAXDLBUF;    ctl.len = 0;    ctl.buf = bufp;    flags = 0;    if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0)    {        sprintf(ebuf, "recv_ack: %s getmsg: %s", what, strerror(errno));        return (-1);    }    dlp = (union DL_primitives *)ctl.buf;    switch (dlp->dl_primitive)    {        case DL_INFO_ACK:        case DL_PHYS_ADDR_ACK:        case DL_BIND_ACK:        case DL_OK_ACK:#ifdef DL_HP_PPA_ACK        case DL_HP_PPA_ACK:#endif        /*         *  These are OK         */        break;        case DL_ERROR_ACK:            switch (dlp->error_ack.dl_errno)            {                case DL_BADPPA:                    sprintf(ebuf, "recv_ack: %s bad ppa (device unit)", what);                    break;                case DL_SYSERR:                    sprintf(ebuf, "recv_ack: %s: %s",                        what, strerror(dlp->error_ack.dl_unix_errno));                    break;                case DL_UNSUPPORTED:                    sprintf(ebuf,                        "recv_ack: %s: Service not supplied by provider", what);                    break;                default:                    sprintf(ebuf, "recv_ack: %s error 0x%x", what,                        (bpf_u_int32)dlp->error_ack.dl_errno);                    break;            }            return (-1);        default:            sprintf(ebuf, "recv_ack: %s unexpected primitive ack 0x%x ",                what, (bpf_u_int32)dlp->dl_primitive);            return (-1);    }    if (ctl.len < size)    {        sprintf(ebuf, "recv_ack: %s ack too small (%d < %d)",            what, ctl.len, size);        return (-1);    }    return (ctl.len);}static intdlattachreq(int fd, bpf_u_int32 ppa, int8_t *ebuf){    dl_attach_req_t req;    req.dl_primitive = DL_ATTACH_REQ;    req.dl_ppa       = ppa;    return (send_request(fd, (int8_t *)&req, sizeof(req), "attach", ebuf, 0));}

⌨️ 快捷键说明

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