Line No. | Rev | Author | Line |
---|---|---|---|
1 | 32 | kaklik | /********************************************************************* |
2 | * |
||
3 | * NetBIOS Name Service (NBNS) Server |
||
4 | * Module for Microchip TCP/IP Stack |
||
5 | * -Responds to NBNS name requests to allow human name assignment |
||
6 | * to the board. i.e. allows nodes on the same IP subnet to use a |
||
7 | * hostname to access the board instead of an IP address. |
||
8 | * -Reference: RFC 1002 |
||
9 | * |
||
10 | ********************************************************************* |
||
11 | * FileName: NBNS.c |
||
12 | * Dependencies: UDP |
||
13 | * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32 |
||
14 | * Compiler: Microchip C32 v1.05 or higher |
||
15 | * Microchip C30 v3.12 or higher |
||
16 | * Microchip C18 v3.30 or higher |
||
17 | * HI-TECH PICC-18 PRO 9.63PL2 or higher |
||
18 | * Company: Microchip Technology, Inc. |
||
19 | * |
||
20 | * Software License Agreement |
||
21 | * |
||
22 | * Copyright (C) 2002-2009 Microchip Technology Inc. All rights |
||
23 | * reserved. |
||
24 | * |
||
25 | * Microchip licenses to you the right to use, modify, copy, and |
||
26 | * distribute: |
||
27 | * (i) the Software when embedded on a Microchip microcontroller or |
||
28 | * digital signal controller product ("Device") which is |
||
29 | * integrated into Licensee's product; or |
||
30 | * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h, |
||
31 | * ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device |
||
32 | * used in conjunction with a Microchip ethernet controller for |
||
33 | * the sole purpose of interfacing with the ethernet controller. |
||
34 | * |
||
35 | * You should refer to the license agreement accompanying this |
||
36 | * Software for additional information regarding your rights and |
||
37 | * obligations. |
||
38 | * |
||
39 | * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT |
||
40 | * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT |
||
41 | * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A |
||
42 | * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
||
43 | * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR |
||
44 | * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF |
||
45 | * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS |
||
46 | * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE |
||
47 | * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER |
||
48 | * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT |
||
49 | * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE. |
||
50 | * |
||
51 | * |
||
52 | * Author Date Comment |
||
53 | *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||
54 | * Howard Schlunder 8/01/06 Original |
||
55 | ********************************************************************/ |
||
56 | #define __NBNS_C |
||
57 | |||
58 | #include "TCPIPConfig.h" |
||
59 | |||
60 | #if defined(STACK_USE_NBNS) |
||
61 | |||
62 | #include "TCPIP Stack/TCPIP.h" |
||
63 | |||
64 | // NetBIOS Name Service port |
||
65 | #define NBNS_PORT (137u) |
||
66 | |||
67 | // NBNS Header structure |
||
68 | typedef struct _NBNS_HEADER |
||
69 | { |
||
70 | WORD_VAL TransactionID; |
||
71 | WORD_VAL Flags; |
||
72 | WORD_VAL Questions; |
||
73 | WORD_VAL Answers; |
||
74 | WORD_VAL AuthoritativeRecords; |
||
75 | WORD_VAL AdditionalRecords; |
||
76 | } NBNS_HEADER; |
||
77 | |||
78 | static void NBNSPutName(BYTE *String); |
||
79 | static void NBNSGetName(BYTE *String); |
||
80 | |||
81 | extern NODE_INFO remoteNode; |
||
82 | |||
83 | |||
84 | /********************************************************************* |
||
85 | * Function: void NBNSTask(void) |
||
86 | * |
||
87 | * PreCondition: None |
||
88 | * |
||
89 | * Input: None |
||
90 | * |
||
91 | * Output: None |
||
92 | * |
||
93 | * Side Effects: None |
||
94 | * |
||
95 | * Overview: Sends responses to NetBIOS name requests |
||
96 | * |
||
97 | * Note: None |
||
98 | ********************************************************************/ |
||
99 | void NBNSTask(void) |
||
100 | { |
||
101 | static UDP_SOCKET MySocket; |
||
102 | BYTE i; |
||
103 | WORD_VAL Type, Class; |
||
104 | NBNS_HEADER NBNSHeader; |
||
105 | BYTE NameString[16]; |
||
106 | static enum |
||
107 | { |
||
108 | NBNS_HOME = 0, |
||
109 | NBNS_OPEN_SOCKET, |
||
110 | NBNS_LISTEN |
||
111 | } smNBNS = NBNS_HOME; |
||
112 | |||
113 | switch(smNBNS) |
||
114 | { |
||
115 | case NBNS_HOME: |
||
116 | smNBNS++; |
||
117 | break; |
||
118 | |||
119 | case NBNS_OPEN_SOCKET: |
||
120 | MySocket = UDPOpen(NBNS_PORT, NULL, NBNS_PORT); |
||
121 | if(MySocket == INVALID_UDP_SOCKET) |
||
122 | break; |
||
123 | |||
124 | smNBNS++; |
||
125 | |||
126 | case NBNS_LISTEN: |
||
127 | if(!UDPIsGetReady(MySocket)) |
||
128 | break; |
||
129 | |||
130 | // Respond only to name requests sent to us from nodes on the same subnet |
||
131 | // This prevents us from sending out the wrong IP address information if |
||
132 | // we haven't gotten a DHCP lease yet. |
||
133 | if((remoteNode.IPAddr.Val & AppConfig.MyMask.Val) != (AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val)) |
||
134 | { |
||
135 | UDPDiscard(); |
||
136 | break; |
||
137 | } |
||
138 | |||
139 | // Retrieve the NBNS header and de-big-endian it |
||
140 | UDPGet(&NBNSHeader.TransactionID.v[1]); |
||
141 | UDPGet(&NBNSHeader.TransactionID.v[0]); |
||
142 | UDPGet(&NBNSHeader.Flags.v[1]); |
||
143 | UDPGet(&NBNSHeader.Flags.v[0]); |
||
144 | UDPGet(&NBNSHeader.Questions.v[1]); |
||
145 | UDPGet(&NBNSHeader.Questions.v[0]); |
||
146 | UDPGet(&NBNSHeader.Answers.v[1]); |
||
147 | UDPGet(&NBNSHeader.Answers.v[0]); |
||
148 | UDPGet(&NBNSHeader.AuthoritativeRecords.v[1]); |
||
149 | UDPGet(&NBNSHeader.AuthoritativeRecords.v[0]); |
||
150 | UDPGet(&NBNSHeader.AdditionalRecords.v[1]); |
||
151 | UDPGet(&NBNSHeader.AdditionalRecords.v[0]); |
||
152 | |||
153 | // Remove all questions |
||
154 | while(NBNSHeader.Questions.Val--) |
||
155 | { |
||
156 | NBNSGetName(NameString); |
||
157 | UDPGet(&i); // <??> Trailing character on string |
||
158 | UDPGet(&Type.v[1]); // Question type |
||
159 | UDPGet(&Type.v[0]); |
||
160 | UDPGet(&Class.v[1]); // Question class |
||
161 | UDPGet(&Class.v[0]); |
||
162 | |||
163 | if(Type.Val == 0x0020u && Class.Val == 0x0001u && memcmp((void*)NameString, (void*)AppConfig.NetBIOSName, sizeof(AppConfig.NetBIOSName)) == 0) |
||
164 | { |
||
165 | while(!UDPIsPutReady(MySocket)); |
||
166 | |||
167 | NBNSHeader.Flags.Val = 0x8400; |
||
168 | |||
169 | UDPPut(NBNSHeader.TransactionID.v[1]); |
||
170 | UDPPut(NBNSHeader.TransactionID.v[0]); |
||
171 | UDPPut(NBNSHeader.Flags.v[1]); |
||
172 | UDPPut(NBNSHeader.Flags.v[0]); |
||
173 | UDPPut(0x00); // 0x0000 Questions |
||
174 | UDPPut(0x00); |
||
175 | UDPPut(0x00); // 0x0001 Answers |
||
176 | UDPPut(0x01); |
||
177 | UDPPut(0x00); // 0x0000 Athoritative records |
||
178 | UDPPut(0x00); |
||
179 | UDPPut(0x00); // 0x0000 Additional records |
||
180 | UDPPut(0x00); |
||
181 | |||
182 | NBNSPutName(AppConfig.NetBIOSName); |
||
183 | UDPPut(0x00); // 0x0020 Type: NetBIOS |
||
184 | UDPPut(0x20); |
||
185 | UDPPut(0x00); // 0x0001 Class: Internet |
||
186 | UDPPut(0x01); |
||
187 | UDPPut(0x00); // 0x00000000 Time To Live |
||
188 | UDPPut(0x00); |
||
189 | UDPPut(0x00); |
||
190 | UDPPut(0x00); |
||
191 | |||
192 | UDPPut(0x00); // 0x0006 Data length |
||
193 | UDPPut(0x06); |
||
194 | UDPPut(0x60); // 0x6000 Flags: H-node, Unique |
||
195 | UDPPut(0x00); |
||
196 | UDPPut(AppConfig.MyIPAddr.v[0]); // Put out IP address |
||
197 | UDPPut(AppConfig.MyIPAddr.v[1]); |
||
198 | UDPPut(AppConfig.MyIPAddr.v[2]); |
||
199 | UDPPut(AppConfig.MyIPAddr.v[3]); |
||
200 | |||
201 | // Change the destination address to the unicast address of the last received packet |
||
202 | memcpy((void*)&UDPSocketInfo[MySocket].remoteNode, (const void*)&remoteNode, sizeof(remoteNode)); |
||
203 | UDPFlush(); |
||
204 | } |
||
205 | |||
206 | } |
||
207 | |||
208 | UDPDiscard(); |
||
209 | |||
210 | break; |
||
211 | } |
||
212 | } |
||
213 | |||
214 | /********************************************************************* |
||
215 | * Function: static void NBNSPutName (BYTE *String) |
||
216 | * |
||
217 | * PreCondition: None |
||
218 | * |
||
219 | * Input: String: The name to transmit |
||
220 | * |
||
221 | * Output: None |
||
222 | * |
||
223 | * Side Effects: None |
||
224 | * |
||
225 | * Overview: Transmits the NetBIOS name across an open UDP |
||
226 | * socket. |
||
227 | * |
||
228 | * Note: None |
||
229 | ********************************************************************/ |
||
230 | static void NBNSPutName(BYTE *String) |
||
231 | { |
||
232 | BYTE i, j; |
||
233 | |||
234 | UDPPut(32); // NetBIOS names are always 32 bytes long (16 decoded bytes) |
||
235 | for(i = 0; i < 16u; i++) |
||
236 | { |
||
237 | j = *String++; |
||
238 | UDPPut((j>>4) + 'A'); |
||
239 | UDPPut((j & 0x0F) + 'A'); |
||
240 | } |
||
241 | |||
242 | UDPPut(0x00); |
||
243 | } |
||
244 | |||
245 | /********************************************************************* |
||
246 | * Function: static void NBNSGetName (BYTE *String) |
||
247 | * |
||
248 | * PreCondition: None |
||
249 | * |
||
250 | * Input: String: Pointer to an array into which |
||
251 | * a received NetBIOS name should be copied. |
||
252 | * |
||
253 | * Output: None |
||
254 | * |
||
255 | * Side Effects: None |
||
256 | * |
||
257 | * Overview: Reads the NetBIOS name from a UDP socket and |
||
258 | * copies it into a user-specified buffer. |
||
259 | * |
||
260 | * Note: None |
||
261 | ********************************************************************/ |
||
262 | static void NBNSGetName(BYTE *String) |
||
263 | { |
||
264 | BYTE i, j, k; |
||
265 | |||
266 | if(String == NULL) |
||
267 | { |
||
268 | UDPGet(&i); |
||
269 | while(i--) |
||
270 | { |
||
271 | UDPGet(&j); |
||
272 | } |
||
273 | } |
||
274 | else |
||
275 | { |
||
276 | UDPGet(&i); |
||
277 | if(i != 32u) |
||
278 | { |
||
279 | *String = 0; |
||
280 | return; |
||
281 | } |
||
282 | while(i--) |
||
283 | { |
||
284 | UDPGet(&j); |
||
285 | j -= 'A'; |
||
286 | k = j<<4; |
||
287 | i--; |
||
288 | UDPGet(&j); |
||
289 | j -= 'A'; |
||
290 | *String++ = k | j; |
||
291 | } |
||
292 | } |
||
293 | } |
||
294 | |||
295 | |||
296 | #endif //#if defined(STACK_USE_NBNS) |
Powered by WebSVN v2.8.3