You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Uniflex系统中启用BSD套接字的广播功能?

修复Tektronix 4404(Uniflex系统)NRC套接字实现问题

背景

我正在修复一台1986年生产的Tektronix 4404设备,它运行Uniflex系统,其BSD套接字由Network Research Corporation(NRC)实现,但没有任何官方文档,仅有的头文件里也没有函数声明。

我需要找到net_ioctl()这类套接字控制函数的相关信息,目前遇到的问题是setsockopt()支持SO_REUSEADDR,但未定义SO_BROADCAST。

我已经用strings工具提取了入口点信息,头文件里包含大量套接字内部结构体,看起来必须操作这些内部结构才能实现需求。

基于net/netioc.h的分析

从提供的net/netioc.h文件来看,这套NRC套接字实现使用了一套自定义的el数组结构作为用户态和内核态的交互载体,_el_init()和_elc()是核心入口函数:

核心结构与函数

  • struct el:数据交互的基本单元,包含类型、标志、长度和两个通用字段,用于传递各种套接字操作的参数和数据。
  • _el_init():初始化一个el数组,指定要执行的命令(比如ELC_SETOPT对应套接字选项设置)和标志。
  • _elc():向el数组中添加一个新的el元素,用于传递具体参数(比如选项值、地址等)。

关键命令与选项

  • 要实现类似SO_BROADCAST的功能,可以尝试使用ELC_SETOPT命令(对应setsockopt()的功能),结合协议特定参数来设置广播权限。
  • 以太网层面的广播/混杂模式可以通过ENIOC系列ioctl控制:
    • ENIOCNORMAL:接受广播和目标为本机的数据包
    • ENIOCPROMISC:接受所有未损坏的数据包
    • ENIOCALL:接受所有数据包(包括损坏的)

操作示例(伪代码)

如果要设置套接字的广播选项,可以按以下步骤操作:

// 1. 初始化el数组,指定ELC_SETOPT命令
struct el *el_array;
el_array = el_init(NULL, ELC_SETOPT, 0);

// 2. 添加要设置的选项参数(假设广播选项对应协议特定的P0参数)
el_u(el_array, EL_P0, YOUR_BROADCAST_OPTION_VALUE);

// 3. 调用net_ioctl(需要自己声明函数原型,比如int net_ioctl(int sock, int cmd, struct el *args);)
int ret = net_ioctl(sock_fd, el_ioc(el_array), el_array);

注意事项

  • 由于没有文档,需要通过strings工具找到的入口点,结合ELC_*命令枚举测试不同参数的效果。
  • el_ioc()宏会根据el数组的元素数量生成对应的ioctl命令码,这是和内核交互的关键。

完整net/netioc.h内容

/*  Copyright (C) 3/10/86 by Network Research Corporation
 *  All rights reserved.  No part of this software may be disclosed or distributed in any form or by any means without the prior written consent of Network Research Corporation.
 */
/*  Module: h       File: /nrc/rel/h/s.netioc.h  */
/*  Version 11.2 as of 86/03/10 at 10:31:12  */

#ifndef _NETIOC_
#define _NETIOC_

#ifndef _STD_
#include <net/std.h>
#endif

#define EL_VERSION  0
#define EL_MAX_SIZE 10

#ifndef SOIOCBASE
#define SOIOCBASE   ('s' << 8)
#endif

#ifndef SOIOCGNTTY
#define SOIOCGNTTY  (SOIOCBASE-2)
#define SOIOCSNTTY  (SOIOCBASE-1)
#endif

#ifndef SOIOCATMARK
#define SOIOCATMARK (SOIOCBASE-3)   /* for MSG_OOB */
#endif

#ifndef ENIOCBASE
#define ENIOCBASE   ('e' << 8)
#endif

#ifndef INPIOCBASE
#define INPIOCBASE  ('i' << 8)
#endif

#define INPIOCDOWNLOAD      (INPIOCBASE + 0)
#define INPIOCEXECUTE       (INPIOCBASE + 1)
#define INPIOCINITIALIZE    (INPIOCBASE + 2)
#define INPIOCPROBE     (INPIOCBASE + 3)
#define INPIOCDIDDLE        (INPIOCBASE + 4)

/* Values for raw ethernet ioctls.  These select the action inside
 * the link layer ioctl routine.
 */
#define ENIOCEND    (ENIOCBASE+10)
#define ENIOCNORMAL ENIOCBASE   /* accept broadcast and specific */
#define ENIOCPROMISC    (ENIOCBASE+1)   /* accept all undamaged packets */
#define ENIOCALL    (ENIOCBASE+2)   /* accept ALL packets */
#define ENIOCRESET  (ENIOCBASE+3)

#ifdef  MSDOS
/* Raw socket driver interface ioctls for MSDOS only! */
#define SDIOCBASE   ('o' << 8)

#define SDIOCSTK    SDIOCBASE   /* give pre-sockdrv stack */
#endif  MSDOS

/* Defined values for el.el_u2.i field of el array header */
#define ELC_ACCEPT  0   /* accept a new connection */
#define ELC_ADDR    1   /* give back the current net address */
#define ELC_ASYNC   2   /* set/reset the socket as async */
#define ELC_ATTACH  3   /* attach to a protocol */
#define ELC_BETIMER 4   /* assume the timeout chores */
#define ELC_BIND    5   /* bind to a network address */
#define ELC_BLOCKING    6   /* turn off/on blocking */
#define ELC_CONNECT 7   /* actively seek connection */
#define ELC_DEBUG   8   /* network debugging entrypoint */
#define ELC_DIDDLE  9   /* peek/poke kernel variables */
#define ELC_EBDEV   10  /* external block device attach */
#define ELC_GETOPT  11  /* get protocol options now current */
#define ELC_INDEX   12  /* give/get the socket index */
#define ELC_LISTEN  13  /* listen for connection requests */
#define ELC_NEXTSOCKET  14  /* give me the next available socket index */
#define ELC_PAIR    15  /* activate the socketpair() code */
#define ELC_PEERADDR    16  /* deliver up the peer address */
#define ELC_RECV    17  /* recv a packet */
#define ELC_SEND    18  /* send a packet */
#define ELC_SETOPT  19  /* set protocol specific options */
#define ELC_SHUTDOWN    20  /* disallow read/write on socket */
#define ELC_SREAD   21  /* read data (used in VMS) */
#define ELC_SWRITE  22  /* write data (used in VMS) */
#define ELC_NSELECT 23  /* select available io on multiple sockets */
#define ELC_PIOCTL  24  /* protocol specific ioctl */
#define ELC_REJECT  25  /* reject a connection request */

#define EL_HEADER   (0x4000 | EL_VERSION)
#define EL_NOOP     0
#define EL_PROTOCOL 1   /* as in XNS_DGRAM */
#define EL_FAMILY   2   /* as in XNS, DARPA etc */
#define EL_INDEX    3   /* request/give a socket index */
#define EL_A_LEN    4   /* where to place the address length */
#define EL_D_LEN    5   /* where to place the data length */
#define EL_DATA     6   /* where's the beef? */
#define EL_DEST     7   /* destination network address */
#define EL_SRC      8   /* src network address */
#define EL_FLAGS    9   /* as in MSG_OOB MSG_PEEK etc. */
#define EL_TYPE     10  /* type field, interpreted by protocol */
#define EL_P0       11  /* protocol specific param 0 */
#define EL_P1       12  /* protocol specific param 1 */
#define EL_P2       13  /* protocol specific param 2 */
#define EL_P3       14  /* protocol specific param 3 */
#define EL_P4       15  /* protocol specific param 4 */
#define EL_PHDR     16  /* protocol header */
#define EL_PHLEN    17  /* protocol header length */

/* Flags for el.el_flags, musn't overlap common flag area (see <flags.h>) */
#define F_EL_STRUCTURED 0x1 /* structured data (32 bits) */
#define F_EL_IN     0x2 /* incoming (user ==> kernel) data element */
#define F_EL_OUT    0x4 /* outgoing (kernel ==> user) data element */
#define F_EL_KERNEL 0x8 /* element is in kernel space */
#define F_EL_ALLOC  0x10    /* element is in heap space -- must be freed */
#define F_EL_PROCESS    0x20    /* some additional processing to do */
#define F_EL_PPROCESS   0x40    /* don't free, more processing to do */
#define F_EL_MPRE_ALLOC 0x80    /* m structure is pre-allocate */

#define F_EL_KRESERVED  F_EL_KERNEL /* el flags reserved for kernel use */

/* if the size of el changes fix el_cnt()!! */
typedef struct el {
    u16 el_type;
    u16 el_flags;
    u32 el_len;
    u32 el_u1;
    u32 el_u2;
} el;

import  el  * _elc(), * _el_init();

/* How many used. Expects size of an el to be 32 bytes */
#define el_cnt(elp1)    (((int)((char *)elp1[0].el_u1 - (char *)(elp1))) >> 4)

/* the next one available */
#define el_end(elp1)    ((el *)(elp1)->el_u1)

/* the last valid one */
#define el_last(elp1)   (((el *)elp1->el_u1) - 1)

/* size in bytes*/
#define el_size(elp1)   (int)((char *)(elp1)[0].el_u1 - (char *)(elp1))

#define el_ioc(elp) ((SOIOCBASE-1)+el_cnt(elp))
#define el_u(elp, type, u1) \
    _elc(elp, type, (u32)sizeof(u32), (u16)F_EL_STRUCTURED)->el_u1 = (u32)(u1)

#ifdef  KERNEL

#define el_init(elp, cmnd, flags) \
    _el_init(elp,(u32)(cmnd),(u16)flags| F_EL_KERNEL)
#ifndef kcanonptr
#define kcanonptr(p)    ((u32)p)
#endif
#define el_ucp(elp, type, p, size, f) \
    _elc(elp, type, (u32)(size), (u16)(f))->el_u1=((u32)p)
#define el_cp(elp, type, p, size, f) \
    _elc(elp, type, (u32)(size), (u16)(f)|(u16)F_EL_KERNEL)->el_u1=(kcanonptr(p))
#define el_up(elp, type, p, f) \
    _elc(elp, type, (u32)sizeof(u32), (u16)(f)|(u16)(F_EL_STRUCTURED|F_EL_KERNEL))->el_u1=(kcanonptr(p))
#define el_xin(elp,kdest,c) ((elp[0].el_len==c)?el_in(elp,kdest,c):EINVAL)
#define el_xout(elp,udest,c)    ((elp[0].el_len==c)?el_out(elp,udest,c):EINVAL)
#else   KERNEL
#define el_init(elp, cmnd, flags)   _el_init(elp, (u32)(cmnd), (u16)flags)
#ifndef canonptr
#define canonptr(p) ((u32)p)
#endif
#define el_cp(elp, type, p, size, f) \
    _elc(elp, type, (u32)(size), (u16)(f))->el_u1=(canonptr(p))
#define el_up(elp, type, p, f) \
    _elc(elp, type, (u32)sizeof(u32), (u16)(f)|(u16)F_EL_STRUCTURED)->el_u1=(canonptr(p))
#endif  KERNEL

#endif  _NETIOC_

/*
 *  @(#)netioc.h    11.2 (NRC)
 */

内容的提问来源于stack exchange,提问作者Elektraglide

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:00:55