ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
11 июля
365719 Топик полностью
ig_z (01.11.2012 19:06, просмотров: 206) ответил FDA на Что-то я там таких файлов не нашёл. Можете поделиться своими?
Занимался этим очень давно, деталей не помню уже. Основная задача была поднять mdns + autoip. netbios прикрутил к проекту за полдня, столько же поигрался с ним в корпоративной сети. Рабочая машины находилась в домене, устройство находилось вне домена (не знаю насколько это критично с сетевой точки зрения) и пинговалось по имени ("BRIDGE-TEST") без проблем. Код "портирован" для uIP, компилер ИАР, netbios_name_decoding() удалена для уменьшения размера кода //#include "lwip/opt.h" //#include "lwip/udp.h" //#include "lwip/netif.h" #include <string.h> #include "Trace/dbg_cfg.h" #define DBG_SCOPE NETBIOS_DBG #include "Trace/dbg.h" #include "uip.h" #if UIP_UDP /* don't build if not configured for use in lwipopts.h */ #include "netbios.h" #define PP_NTOHS HTONS #define PP_HTONS HTONS //#define PP_HTONL HTONS /** This is an example implementation of a NetBIOS name server. * It responds to name queries for a configurable name. * Name resolving is not supported. * * Note that the device doesn't broadcast it's own name so can't * detect duplicate names! */ /** NetBIOS name of LWIP device * This must be uppercase until NETBIOS_STRCMP() is defined to a string * comparision function that is case insensitive. * If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME): * (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "") */ #ifndef NETBIOS_LWIP_NAME #define NETBIOS_LWIP_NAME "BRIDGE-TEST" #endif /** Since there's no standard function for case-insensitive string comparision, * we need another define here: * define this to stricmp() for windows or strcasecmp() for linux. * If not defined, comparision is case sensitive and NETBIOS_LWIP_NAME must be * uppercase */ #ifndef NETBIOS_STRCMP #define NETBIOS_STRCMP(str1, str2) strcmp(str1, str2) #endif /** size of a NetBIOS name */ #define NETBIOS_NAME_LEN 16 /** The Time-To-Live for NetBIOS name responds (in seconds) * Default is 300000 seconds (3 days, 11 hours, 20 minutes) */ #define NETBIOS_NAME_TTL 300000 /** NetBIOS header flags */ #define NETB_HFLAG_RESPONSE 0x8000 #define NETB_HFLAG_OPCODE 0x7800 #define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000 #define NETB_HFLAG_AUTHORATIVE 0x0400 #define NETB_HFLAG_TRUNCATED 0x0200 #define NETB_HFLAG_RECURS_DESIRED 0x0100 #define NETB_HFLAG_RECURS_AVAILABLE 0x0080 #define NETB_HFLAG_BROADCAST 0x0010 #define NETB_HFLAG_REPLYCODE 0x0008 #define NETB_HFLAG_REPLYCODE_NOERROR 0x0000 /** NetBIOS name flags */ #define NETB_NFLAG_UNIQUE 0x8000 #define NETB_NFLAG_NODETYPE 0x6000 #define NETB_NFLAG_NODETYPE_HNODE 0x6000 #define NETB_NFLAG_NODETYPE_MNODE 0x4000 #define NETB_NFLAG_NODETYPE_PNODE 0x2000 #define NETB_NFLAG_NODETYPE_BNODE 0x0000 /** NetBIOS message header */ #pragma pack(1) struct netbios_hdr { u16_t trans_id; u16_t flags; u16_t questions; u16_t answerRRs; u16_t authorityRRs; u16_t additionalRRs; }; #pragma pack() /** NetBIOS message name part */ #pragma pack(1) struct netbios_name_hdr { u8_t nametype; u8_t encname[(NETBIOS_NAME_LEN*2)+1]; u16_t type; u16_t cls; u32_t ttl; u16_t datalen; u16_t flags; // ip_addr_p_t uip_ipaddr_t addr; // u8_t addr[4]; }; #pragma pack() /** NetBIOS message */ #pragma pack(1) struct netbios_resp { struct netbios_hdr resp_hdr; struct netbios_name_hdr resp_name; }; #pragma pack() /** NetBIOS Name service recv callback */ //static void netbios_recv()//(void *arg, struct udp_pcb *upcb, struct pbuf *p, /*ip_addr_t*/ uip_ipaddr_t *addr, u16_t port) { /* if packet is valid */ char netbios_name[NETBIOS_NAME_LEN+1]; // struct netbios_hdr* netbios_hdr = (struct netbios_hdr*)p->payload; // struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; struct netbios_hdr* netbios_hdr = (struct netbios_hdr*)uip_appdata; struct netbios_name_hdr* netbios_name_hdr = (struct netbios_name_hdr*)(netbios_hdr+1); /* we only answer if we got a default interface */ // if (netif_default != NULL) // { /* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */ /* if the packet is a NetBIOS name query question */ if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) && ((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) && (netbios_hdr->questions == PP_NTOHS(1))) { DBG_PRINTF(("netbios_recv:: NetBIOS name query question\n")); /* decode the NetBIOS name */ netbios_name_decoding((char*)(netbios_name_hdr->encname), netbios_name); DBG_PRINTF(("netbios_recv:: netbios_name_decoding = %s\n", netbios_name)); /* if the packet is for us */ if (NETBIOS_STRCMP(netbios_name, NETBIOS_LWIP_NAME) == 0) { struct netbios_resp *resp; DBG_PRINTF(("netbios_recv:: netbios_name is OK\n")); // q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM); // if (q != NULL) // { //resp = (struct netbios_resp*)q->payload; resp = (struct netbios_resp*)uip_appdata; /* prepare NetBIOS header response */ resp->resp_hdr.trans_id = netbios_hdr->trans_id; resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | NETB_HFLAG_OPCODE_NAME_QUERY | NETB_HFLAG_AUTHORATIVE | NETB_HFLAG_RECURS_DESIRED); resp->resp_hdr.questions = 0; resp->resp_hdr.answerRRs = PP_HTONS(1); resp->resp_hdr.authorityRRs = 0; resp->resp_hdr.additionalRRs = 0; /* prepare NetBIOS header datas */ //MEMCPY memcpy( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname)); resp->resp_name.nametype = netbios_name_hdr->nametype; resp->resp_name.type = netbios_name_hdr->type; resp->resp_name.cls = netbios_name_hdr->cls; resp->resp_name.ttl = 0xE0930400; //0x00.04.93.E0 = 300,000 PP_HTONL(NETBIOS_NAME_TTL); resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr)); resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE); // ip_addr_copy(resp->resp_name.addr, netif_default->ip_addr); // uip_ipaddr_copy(resp->resp_name.addr,uip_hostaddr); resp->resp_name.addr[0] = uip_hostaddr[0]; resp->resp_name.addr[1] = uip_hostaddr[1]; // resp->resp_name.addr[0] = (u8_t)(uip_hostaddr[0]&0xFF); // resp->resp_name.addr[1] = (u8_t)((uip_hostaddr[0]>>8)&0xFF); // resp->resp_name.addr[2] = (u8_t)(uip_hostaddr[1]&0xFF); // resp->resp_name.addr[3] = (u8_t)((uip_hostaddr[1]>>8)&0xFF); uip_send(uip_appdata, sizeof(struct netbios_resp)); /* send the NetBIOS response */ // udp_sendto(upcb, q, addr, port); /* free the "reference" pbuf */ // pbuf_free(q); } } } void netbios_init(void) { // struct udp_pcb *pcb; // LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN); // pcb = udp_new(); // if (pcb != NULL) // { // we have to be allowed to send broadcast packets! // pcb->so_options |= SOF_BROADCAST; // udp_bind(pcb, IP_ADDR_ANY, NETBIOS_PORT); // udp_recv(pcb, netbios_recv, pcb); // } struct uip_udp_conn *conn; uip_ipaddr_t zeroes_addr = {0x0000,0x0000}; conn = uip_udp_new(&zeroes_addr, 0); DBG_PRINTF(("udp_listen NETBIOS_PORT\n")); if(conn != NULL) { uip_udp_bind(conn, HTONS(NETBIOS_PORT)); } } void netbios_appcall(void) { // if(uip_aborted()) { } // if(uip_timedout()) { } // if(uip_closed()) { } // if(uip_connected()){ } // if(uip_newdata()) // { DBG_PRINTF(("netbios_appcall >>>>>>>>>>>>>>>>>>>>>>>>>>\n")); if (uip_conn->lport == NETBIOS_PORT) { DBG_PRINTF(("netbios_appcall:: uip_conn->lport == NETBIOS_PORT\n")); netbios_recv();//(uip_conn); } // } // if(uip_rexmit()) { } // if(uip_acked()) { } // if(uip_poll()) { } } #endif //#if UIP_UDP