📄 netbios.cpp
字号:
#include "netbios.h"NetBios::NetBios(){ packetlen=sizeof(*outip)+sizeof(*outudp)+sizeof(NetbiosNS)-2; answerOffset=sizeof(*outip)+sizeof(*outudp)+sizeof(NetbiosNS)-2; NsOffset=packetlen-sizeof(NetbiosNS)+2; udpOffset=sizeof(*outip); nameOffset=answerOffset+7; outip=NULL; sndsock=-1; recvsock=-1;}NetBios::~NetBios(){ if(sndsock!=-1) close(sndsock); if(recvsock!=-1) close(recvsock); if(outip!=NULL) free(outip);}int NetBios::setupDestAdd(char *ipasc,uint16_t MyID){ to.sin_addr.s_addr=inet_addr(ipasc); outip->ip_dst=to.sin_addr; NS->transactionID=htons(MyID); return 0; }int NetBios::initNetbios(){ struct protoent *pe; u_short on=1,off=0; char cp[]="udp"; outip = (struct ip *)malloc((unsigned)packetlen); if ( NULL == outip ) { printf("allocate memory error\n"); return -1; } memset((char *)outip, 0, packetlen); memset(&from, 0, sizeof(from)); from.sin_family = AF_INET; from.sin_addr.s_addr = INADDR_ANY; wherefrom=(struct sockaddr*)&from; memset(&to, 0, sizeof(to)); to.sin_family = AF_INET; to.sin_port=htons(NETBIOSNS); to.sin_addr.s_addr=inet_addr("192.168.0.1"); whereto=(struct sockaddr*)&to; outip->ip_v = IPVERSION; outip->ip_ttl=64; outip->ip_src = from.sin_addr; outip->ip_dst = to.sin_addr; // 这里的代码处理 little_endian 和 big-endian 两种情况 outip->ip_len = htons(packetlen); outip->ip_off = htons(off); outp = (u_char *)(outip + 1); outip->ip_hl = (outp - (u_char *)outip) >> 2; outip->ip_p = IPPROTO_UDP; outudp = (struct udphdr *)outp; outudp->source = htons(SPORT); outudp->dest=htons(NETBIOSNS); outudp->len = htons((u_short)(packetlen - (sizeof(*outip)))); NS = (struct NetbiosNS *)(outudp + 1); NS->transactionID=htons(tid); NS->flags=FLAGS; NS->questions=htons(QUESTIONS); NS->answerRRs=ANSWER; NS->autherityRRs=AUTHERITY; NS->additionalRRs=ADDITIONAL; NS->query.type=htons(NBSTA); NS->query.myclass=inet; NS->query.type1=htons(TYPE1); NS->query.type2=htons(TYPE2); memset(NS->query.name,'A',29); NS->query.name[29]=0; // 创建发送 SOCKET sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sndsock < 0) { printf("send socket: %s\tcreate error\n", strerror(errno)); // 特别注意内存释放问题, 防止内存泄漏 ! free(outip); return -1; } if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packetlen, sizeof(packetlen)) < 0) { printf("SO_SNDBUF: %s\n", strerror(errno)); // 特别注意内存释放问题, 防止内存泄漏 ! free(outip); return -1; } if (setsockopt(sndsock, IPPROTO_IP, 3, (char *)&on, sizeof(on)) < 0) { printf("IP_HDRINCL: %s\n", strerror(errno)); // 特别注意内存释放问题, 防止内存泄漏 ! free(outip); return -1; } pe = getprotobyname(cp); if ( NULL == pe ) { printf("unknown protocol %s\n", cp); // 特别注意内存释放问题, 防止内存泄漏 ! free(outip); return -1; } recvsock = socket(AF_INET, SOCK_RAW, pe->p_proto); if ( recvsock < 0) { printf("Error in function main\n"); // 特别注意内存释放问题, 防止内存泄漏 ! free(outip); return -1; } return 0;}int NetBios::sendNetbios(){ if(sendto(sndsock, (char *)outip, packetlen, 0, whereto, sizeof(*whereto))!=-1) return 0; else { printf("error send udp\n"); return -1; }}int NetBios::waitNetbiosEcho(){ fd_set fds; int cc = 0; int fromlen = sizeof(*wherefrom); struct timeval wait; FD_ZERO(&fds); FD_SET(recvsock, &fds); wait.tv_sec = 0; wait.tv_usec =5000; from.sin_port=htons(SPORT); if (select(recvsock + 1, &fds, NULL, NULL, &wait) > 0) cc = recvfrom(recvsock,recvbuf, MAXLEN, 0,wherefrom, (socklen_t*)&fromlen); /* printf("************************************\n"); for(int i=0;i<cc;i++) { printf("%02x ",recvbuf[i]); if((i+1)%16==0)printf("\n"); } printf("\n"); */ if(!cc) { // printf("receive error\n"); nameNumber=-1; return -1; } if(cc<=packetlen) { // printf("too short\n"); nameNumber= -1; return -1; } NS_data=(struct NetbiosNS*)(recvbuf+NsOffset); if((!NS_data->flags&(0x8000))) {// printf("self send packet\n"); nameNumber=-1; return -1; } tid=ntohs(NS_data->transactionID); // printf("tid=%04X\n",tid); answer=(struct answer*)(recvbuf+ answerOffset); nameNumber=answer->number; return answer->number;}char *NetBios::getUserName(){ char *userName; userName=NULL; for(int i=0;i<nameNumber;i++) { myname=(struct name*)(recvbuf+nameOffset+i*18); if(myname->type==0&&!(myname->nameflag&(0x8000))) { myname->nbname[14]=0; userName=myname->nbname; break; } } return userName;}char *NetBios::getGroupName(){ char *groupName; groupName=NULL; for(int i=0;i<nameNumber;i++) { myname=(struct name*)(recvbuf+nameOffset+i*18); if(myname->type==0&&myname->nameflag&(0x8000)) { myname->nbname[14]=0; groupName=myname->nbname; break; } } return groupName;}u_char *NetBios::getMac(){ return (u_char *)(recvbuf+nameOffset+nameNumber*18);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -