NetBIOS-NS:网络基本输入/输出系统-名称服务

一、概述

NetBIOS-NS(NetBIOS Name Service)是计算机网络领域中一个重要的协议。它主要负责实现名称的解析和注册,是 NetBIOS 网络的核心。NetBIOS-NS 早期广泛应用于局域网环境中,如今也经常被用于早期的Windows系统中。在现代计算机网络中,NetBIOS-NS 已经逐渐被DNS(Domain Name Service)所取代,但 NetBIOS 仍然有其特殊的应用场合。

二、NetBIOS-NS 的工作原理

NetBIOS-NS 首先通过 UDP 端口 137 监听网络,等待来自其它计算机的 NetBIOS 函数调用。当一个 NetBIOS 函数调用到达时,NetBIOS-NS 首先通过三次广播(Broadcast)的方式查询(Query)网络上所有节点的名称表,以获得使用了该名字的计算机的 IP 地址。如果该名字有多个对应的 IP 地址,则返回所有的 IP 地址。

相反的,如果一个计算机希望把自己的名字注册到网络上,它就会向 NetBIOS-NS 发送一个“名字注册”(Name Registration)请求,NetBIOS-NS 会先查询网络上是否已经有其他计算机的名字相同,如果没有,就向网络上广播一个“名字注册”回复,告诉其它计算机该名字已经被占用并且提供自身的 IP 地址。如果多个计算机请求同一个名字的注册,则只有一个计算机能够注册成功,后来的请求将被忽略。

三、NetBIOS-NS 端口和服务

NetBIOS-NS 端口使用的是 UDP 协议中的 137 端口,每个使用 NetBIOS-NS 服务的计算机都必须注册一个 NetBIOS 名字,并向网络中注册该服务。当其它计算机需要连接到该服务时,就可以通过名称传输(NetBIOS Name Resolution)查询该名字的实际 IP 地址,从而建立服务与调用之间的连接。NetBIOS-NS 还有一个充当 NetBIOS 进程间通信服务(NetBIOS Session Service)的标准 TCP/IP 端口,即 139 端口。该端口主要用于实现 SMB(Server Message Block)和 CIFS(Common Internet File System) 等服务。

四、NetBIOS-NS 的安全问题

由于 NetBIOS-NS 在设计之初并没有考虑安全问题,因此在网络安全方面存在许多问题。例如,NetBIOS-NS 在注册名字时没有进行身份验证,因此能够轻易地进行 DNS Spoofing 或者 ARP Spoofing 攻击,从而实现欺骗性的 DNS 查询结果。为了避免网络中出现此类问题,可采用 IPsec 或 VPN 等技术,加密数据协议,如 SMB、NetBIOS 等,并限制 NetBIOS-NS 在网络中的使用频率。

五、NetBIOS-NS 的代码示例

//NetBIOS注册名字
void nbns_reg_name(unsigned char *name)
{
    unsigned char buff[65536];
    
    memset(buff, 0, sizeof(buff));
    struct nbns_header *nbh = (struct nbns_header *) buff;
    struct nbns_question *nbq = (struct nbns_question *) (buff + sizeof(struct nbns_header));
    struct sockaddr_in sin = { 0 };

    nbh->id = htons(getpid());  //进程 id,随机生成
    nbh->flags = htons(0x0120); //NBNS标志,注册名字

    //问题部分
    qname(nbq->name, name); //注册名字
    nbq->type = htons(NBNS_TYPE_NB); //类型
    nbq->classes = htons(NBNS_CLASS_IN); //类别

    sin.sin_family = AF_INET;
    sin.sin_port = htons(NBNS_PORT);

    int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    bind(s, (struct sockaddr *) &sin, sizeof(struct sockaddr_in));
    sendto(s, buff, sizeof(struct nbns_header) + sizeof(struct nbns_question) + nbq->name_len, 0, &sin, sizeof(sin));
    close(s);
}

//NetBIOS查询名字
int nbns_query_name(unsigned char *name, char *addr)
{
    unsigned char buff[65536];
    struct sockaddr_in sin;
    struct timeval tv;
    
    memset(buff, 0, sizeof(buff));
    struct nbns_header *nbh = (struct nbns_header *) buff;
    struct nbns_question *nbq = (struct nbns_question *) (buff + sizeof(struct nbns_header));

    nbh->id = htons(getpid()); //进程 id,随机生成
    nbh->flags = htons(0x0100); //NBNS标志,查询名字

    //问题部分
    qname(nbq->name, name); //查询名字
    nbq->type = htons(NBNS_TYPE_NB); //类型
    nbq->classes = htons(NBNS_CLASS_IN); //类别

    sin.sin_family = AF_INET;
    sin.sin_port = htons(NBNS_PORT);
    sin.sin_addr.s_addr = htonl(INADDR_BROADCAST);

    int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    setsockopt(s, SOL_SOCKET, SO_BROADCAST, &sin, sizeof(sin));
    sendto(s, buff, sizeof(struct nbns_header) + sizeof(struct nbns_question) + nbq->name_len, 0, &sin, sizeof(sin));

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(s, &fds);

    tv.tv_sec = 1;
    tv.tv_usec = 0;
    select(s + 1, &fds, NULL, NULL, &tv);
    if (FD_ISSET(s, &fds))
    {
        struct sockaddr_in client;
        socklen_t len = sizeof(client);
        unsigned int buflen = recvfrom(s, buff, sizeof(buff), 0, (struct sockaddr *) &client, &len);

        struct nbns_answer *nba = (struct nbns_answer *) (buff + sizeof(struct nbns_header) + sizeof(struct nbns_question));

        struct sockaddr_in *sinaddr = (struct sockaddr_in *) &nba->resource[nba->ans][6];

        memcpy(addr, inet_ntoa(sinaddr->sin_addr), strlen(inet_ntoa(sinaddr->sin_addr)) + 1);

        close(s);
        return 1;
    }
    close(s);
    return 0;
}

原创文章,作者:VMXTM,如若转载,请注明出处:https://www.506064.com/n/330278.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
VMXTMVMXTM
上一篇 2025-01-16 15:46
下一篇 2025-01-16 15:46

相关推荐

  • Deepin系统分区设置教程

    本教程将会详细介绍Deepin系统如何进行分区设置,分享多种方式让您了解如何规划您的硬盘。 一、分区的基本知识 在进行Deepin系统分区设置之前,我们需要了解一些基本分区概念。 …

    编程 2025-04-29
  • 如何在树莓派上安装Windows 7系统?

    随着树莓派的普及,许多用户想在树莓派上安装Windows 7操作系统。 一、准备工作 在开始之前,需要准备以下材料: 1.树莓派4B一台; 2.一张8GB以上的SD卡; 3.下载并…

    编程 2025-04-29
  • Java任务下发回滚系统的设计与实现

    本文将介绍一个Java任务下发回滚系统的设计与实现。该系统可以用于执行复杂的任务,包括可回滚的任务,及时恢复任务失败前的状态。系统使用Java语言进行开发,可以支持多种类型的任务。…

    编程 2025-04-29
  • Python基本索引用法介绍

    Python基本索引是指通过下标来获取列表、元组、字符串等数据类型中的元素。下面将从多个方面对Python基本索引进行详细的阐述。 一、列表(List)的基本索引 列表是Pytho…

    编程 2025-04-29
  • Python基本数字类型

    本文将介绍Python中基本数字类型,包括整型、布尔型、浮点型、复数型,并提供相应的代码示例以便读者更好的理解。 一、整型 整型即整数类型,Python中的整型没有大小限制,所以可…

    编程 2025-04-29
  • Python函数名称相同参数不同:多态

    Python是一门面向对象的编程语言,它强烈支持多态性 一、什么是多态多态是面向对象三大特性中的一种,它指的是:相同的函数名称可以有不同的实现方式。也就是说,不同的对象调用同名方法…

    编程 2025-04-29
  • 使用Netzob进行网络协议分析

    Netzob是一款开源的网络协议分析工具。它提供了一套完整的协议分析框架,可以支持多种数据格式的解析和可视化,方便用户对协议数据进行分析和定制。本文将从多个方面对Netzob进行详…

    编程 2025-04-29
  • Python基本统计量计算

    本文将从多个方面详细介绍Python中基本统计量计算的方法。 一、均值 均值是一组数据的平均值,也就是将所有数据相加后再除以数据个数。 在Python中,可以使用numpy库中的m…

    编程 2025-04-29
  • Python程序的三种基本控制结构

    控制结构是编程语言中非常重要的一部分,它们指导着程序如何在不同的情况下执行相应的指令。Python作为一种高级编程语言,也拥有三种基本的控制结构:顺序结构、选择结构和循环结构。 一…

    编程 2025-04-29
  • 分销系统开发搭建

    本文主要介绍如何搭建一套完整的分销系统,从需求分析、技术选型、开发、部署等方面进行说明。 一、需求分析 在进行分销系统的开发之前,我们首先需要对系统进行需求分析。一般来说,分销系统…

    编程 2025-04-29

发表回复

登录后才能评论