mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +00:00
netbiosns: check question type before generating an answer
This commit is contained in:
parent
f65911a84b
commit
b1fe8cf4b8
@ -77,6 +77,10 @@
|
|||||||
#define NETB_HFLAG_REPLYCODE 0x0008U
|
#define NETB_HFLAG_REPLYCODE 0x0008U
|
||||||
#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U
|
#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U
|
||||||
|
|
||||||
|
/* NetBIOS question types */
|
||||||
|
#define NETB_QTYPE_NB 0x0020U
|
||||||
|
#define NETB_QTYPE_NBSTAT 0x0021U
|
||||||
|
|
||||||
/** NetBIOS name flags */
|
/** NetBIOS name flags */
|
||||||
#define NETB_NFLAG_UNIQUE 0x8000U
|
#define NETB_NFLAG_UNIQUE 0x8000U
|
||||||
#define NETB_NFLAG_NODETYPE 0x6000U
|
#define NETB_NFLAG_NODETYPE 0x6000U
|
||||||
@ -348,90 +352,97 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
|
|||||||
(netbios_hdr->questions == PP_NTOHS(1))) {
|
(netbios_hdr->questions == PP_NTOHS(1))) {
|
||||||
/* decode the NetBIOS name */
|
/* decode the NetBIOS name */
|
||||||
netbiosns_name_decode((char *)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));
|
netbiosns_name_decode((char *)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));
|
||||||
/* if the packet is for us */
|
/* check the request type */
|
||||||
if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) {
|
if (netbios_name_hdr->type == PP_HTONS(NETB_QTYPE_NB)) {
|
||||||
struct pbuf *q;
|
/* if the packet is for us */
|
||||||
struct netbios_resp *resp;
|
if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) {
|
||||||
|
struct pbuf *q;
|
||||||
|
struct netbios_resp *resp;
|
||||||
|
|
||||||
q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM);
|
q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM);
|
||||||
if (q != NULL) {
|
if (q != NULL) {
|
||||||
resp = (struct netbios_resp *)q->payload;
|
resp = (struct netbios_resp *)q->payload;
|
||||||
|
|
||||||
/* prepare NetBIOS header response */
|
/* prepare NetBIOS header response */
|
||||||
resp->resp_hdr.trans_id = netbios_hdr->trans_id;
|
resp->resp_hdr.trans_id = netbios_hdr->trans_id;
|
||||||
resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE |
|
resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE |
|
||||||
NETB_HFLAG_OPCODE_NAME_QUERY |
|
NETB_HFLAG_OPCODE_NAME_QUERY |
|
||||||
NETB_HFLAG_AUTHORATIVE |
|
NETB_HFLAG_AUTHORATIVE |
|
||||||
NETB_HFLAG_RECURS_DESIRED);
|
NETB_HFLAG_RECURS_DESIRED);
|
||||||
resp->resp_hdr.questions = 0;
|
resp->resp_hdr.questions = 0;
|
||||||
resp->resp_hdr.answerRRs = PP_HTONS(1);
|
resp->resp_hdr.answerRRs = PP_HTONS(1);
|
||||||
resp->resp_hdr.authorityRRs = 0;
|
resp->resp_hdr.authorityRRs = 0;
|
||||||
resp->resp_hdr.additionalRRs = 0;
|
resp->resp_hdr.additionalRRs = 0;
|
||||||
|
|
||||||
/* prepare NetBIOS header datas */
|
/* prepare NetBIOS header datas */
|
||||||
MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname));
|
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.nametype = netbios_name_hdr->nametype;
|
||||||
resp->resp_name.type = netbios_name_hdr->type;
|
resp->resp_name.type = netbios_name_hdr->type;
|
||||||
resp->resp_name.cls = netbios_name_hdr->cls;
|
resp->resp_name.cls = netbios_name_hdr->cls;
|
||||||
resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL);
|
resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL);
|
||||||
resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags) + sizeof(resp->resp_name.addr));
|
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);
|
resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE);
|
||||||
ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default));
|
ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default));
|
||||||
|
|
||||||
/* send the NetBIOS response */
|
/* send the NetBIOS response */
|
||||||
udp_sendto(upcb, q, addr, port);
|
udp_sendto(upcb, q, addr, port);
|
||||||
|
|
||||||
/* free the "reference" pbuf */
|
/* free the "reference" pbuf */
|
||||||
pbuf_free(q);
|
pbuf_free(q);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if LWIP_NETBIOS_RESPOND_NAME_QUERY
|
#if LWIP_NETBIOS_RESPOND_NAME_QUERY
|
||||||
} else if (!lwip_strnicmp(netbios_name, "*", sizeof(NETBIOS_LOCAL_NAME))) {
|
} else if (netbios_name_hdr->type == PP_HTONS(NETB_QTYPE_NBSTAT)) {
|
||||||
/* general query - ask for our IP address */
|
/* if the packet is for us or general query */
|
||||||
struct pbuf *q;
|
if (!lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) ||
|
||||||
struct netbios_answer *resp;
|
!lwip_strnicmp(netbios_name, "*", sizeof(NETBIOS_LOCAL_NAME))) {
|
||||||
|
/* general query - ask for our IP address */
|
||||||
|
struct pbuf *q;
|
||||||
|
struct netbios_answer *resp;
|
||||||
|
|
||||||
q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_answer), PBUF_RAM);
|
q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_answer), PBUF_RAM);
|
||||||
if (q != NULL) {
|
if (q != NULL) {
|
||||||
/* buffer to which a response is compiled */
|
/* buffer to which a response is compiled */
|
||||||
resp = (struct netbios_answer *) q->payload;
|
resp = (struct netbios_answer *) q->payload;
|
||||||
|
|
||||||
/* Init response to zero, especially the statistics fields */
|
/* Init response to zero, especially the statistics fields */
|
||||||
memset(resp, 0, sizeof(*resp));
|
memset(resp, 0, sizeof(*resp));
|
||||||
|
|
||||||
/* copy the query to the response ID */
|
/* copy the query to the response ID */
|
||||||
resp->answer_hdr.trans_id = netbios_hdr->trans_id;
|
resp->answer_hdr.trans_id = netbios_hdr->trans_id;
|
||||||
/* acknowledgment of termination */
|
/* acknowledgment of termination */
|
||||||
resp->answer_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | NETB_HFLAG_OPCODE_NAME_QUERY | NETB_HFLAG_AUTHORATIVE);
|
resp->answer_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | NETB_HFLAG_OPCODE_NAME_QUERY | NETB_HFLAG_AUTHORATIVE);
|
||||||
/* resp->answer_hdr.questions = PP_HTONS(0); done by memset() */
|
/* resp->answer_hdr.questions = PP_HTONS(0); done by memset() */
|
||||||
/* serial number of the answer */
|
/* serial number of the answer */
|
||||||
resp->answer_hdr.answerRRs = PP_HTONS(1);
|
resp->answer_hdr.answerRRs = PP_HTONS(1);
|
||||||
/* resp->answer_hdr.authorityRRs = PP_HTONS(0); done by memset() */
|
/* resp->answer_hdr.authorityRRs = PP_HTONS(0); done by memset() */
|
||||||
/* resp->answer_hdr.additionalRRs = PP_HTONS(0); done by memset() */
|
/* resp->answer_hdr.additionalRRs = PP_HTONS(0); done by memset() */
|
||||||
/* we will copy the length of the station name */
|
/* we will copy the length of the station name */
|
||||||
resp->name_size = netbios_name_hdr->nametype;
|
resp->name_size = netbios_name_hdr->nametype;
|
||||||
/* we will copy the queried name */
|
/* we will copy the queried name */
|
||||||
MEMCPY(resp->query_name, netbios_name_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1);
|
MEMCPY(resp->query_name, netbios_name_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1);
|
||||||
/* NBSTAT */
|
/* NBSTAT */
|
||||||
resp->packet_type = PP_HTONS(0x21);
|
resp->packet_type = PP_HTONS(0x21);
|
||||||
/* Internet name */
|
/* Internet name */
|
||||||
resp->cls = PP_HTONS(1);
|
resp->cls = PP_HTONS(1);
|
||||||
/* resp->ttl = PP_HTONL(0); done by memset() */
|
/* resp->ttl = PP_HTONL(0); done by memset() */
|
||||||
resp->data_length = PP_HTONS(sizeof(struct netbios_answer) - offsetof(struct netbios_answer, number_of_names));
|
resp->data_length = PP_HTONS(sizeof(struct netbios_answer) - offsetof(struct netbios_answer, number_of_names));
|
||||||
resp->number_of_names = 1;
|
resp->number_of_names = 1;
|
||||||
|
|
||||||
/* make windows see us as workstation, not as a server */
|
/* make windows see us as workstation, not as a server */
|
||||||
memset(resp->answer_name, 0x20, NETBIOS_NAME_LEN - 1);
|
memset(resp->answer_name, 0x20, NETBIOS_NAME_LEN - 1);
|
||||||
/* strlen is checked to be < NETBIOS_NAME_LEN during initialization */
|
/* strlen is checked to be < NETBIOS_NAME_LEN during initialization */
|
||||||
MEMCPY(resp->answer_name, NETBIOS_LOCAL_NAME, strlen(NETBIOS_LOCAL_NAME));
|
MEMCPY(resp->answer_name, NETBIOS_LOCAL_NAME, strlen(NETBIOS_LOCAL_NAME));
|
||||||
|
|
||||||
/* b-node, unique, active */
|
/* b-node, unique, active */
|
||||||
resp->answer_name_flags = PP_HTONS(NETB_NFLAG_NAME_IS_ACTIVE);
|
resp->answer_name_flags = PP_HTONS(NETB_NFLAG_NAME_IS_ACTIVE);
|
||||||
|
|
||||||
/* Set responder netif MAC address */
|
/* Set responder netif MAC address */
|
||||||
SMEMCPY(resp->unit_id, ip_current_input_netif()->hwaddr, sizeof(resp->unit_id));
|
SMEMCPY(resp->unit_id, ip_current_input_netif()->hwaddr, sizeof(resp->unit_id));
|
||||||
|
|
||||||
udp_sendto(upcb, q, addr, port);
|
udp_sendto(upcb, q, addr, port);
|
||||||
pbuf_free(q);
|
pbuf_free(q);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* LWIP_NETBIOS_RESPOND_NAME_QUERY */
|
#endif /* LWIP_NETBIOS_RESPOND_NAME_QUERY */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user