1 |
|
|
2 |
/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation |
/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation |
3 |
|
|
4 |
Version 1.0 |
Version 1.0 |
32 |
#include "rfcnb-util.h" |
#include "rfcnb-util.h" |
33 |
#include "rfcnb-io.h" |
#include "rfcnb-io.h" |
34 |
|
|
35 |
extern void (*Prot_Print_Routine)(); /* Pointer to protocol print routine */ |
extern void (*Prot_Print_Routine) (); /* Pointer to protocol print routine */ |
36 |
|
|
37 |
/* Convert name and pad to 16 chars as needed */ |
/* Convert name and pad to 16 chars as needed */ |
38 |
|
|
39 |
/* Name 1 is a C string with null termination, name 2 may not be */ |
/* Name 1 is a C string with null termination, name 2 may not be */ |
40 |
|
|
41 |
/* If SysName is true, then put a <00> on end, else space> */ |
/* If SysName is true, then put a <00> on end, else space> */ |
42 |
|
|
43 |
void RFCNB_CvtPad_Name(char *name1, char *name2) |
void RFCNB_CvtPad_Name(char *name1, |
44 |
|
char *name2) |
45 |
|
{ |
46 |
|
char c, c1, c2; |
47 |
|
int i, len; |
48 |
|
|
49 |
{ char c, c1, c2; |
len = strlen(name1); |
|
int i, len; |
|
50 |
|
|
51 |
len = strlen(name1); |
for (i = 0; i < 16; i++) |
52 |
|
{ |
53 |
|
|
54 |
for (i = 0; i < 16; i++) { |
if (i >= len) |
55 |
|
{ |
56 |
|
|
57 |
if (i >= len) { |
c1 = 'C'; |
58 |
|
c2 = 'A'; /* CA is a space */ |
59 |
|
|
60 |
c1 = 'C'; c2 = 'A'; /* CA is a space */ |
} |
61 |
|
else |
62 |
} else { |
{ |
63 |
|
|
64 |
c = name1[i]; |
c = name1[i]; |
65 |
c1 = (char)((int)c/16 + (int)'A'); |
c1 = (char) ((int) c / 16 + (int) 'A'); |
66 |
c2 = (char)((int)c%16 + (int)'A'); |
c2 = (char) ((int) c % 16 + (int) 'A'); |
67 |
} |
} |
68 |
|
|
69 |
name2[i*2] = c1; |
name2[i * 2] = c1; |
70 |
name2[i*2+1] = c2; |
name2[i * 2 + 1] = c2; |
71 |
|
|
72 |
} |
} |
73 |
|
|
74 |
name2[32] = 0; /* Put in the nll ...*/ |
name2[32] = 0; /* Put in the nll ... */ |
75 |
|
|
76 |
} |
} |
77 |
|
|
84 |
|
|
85 |
*/ |
*/ |
86 |
|
|
87 |
void RFCNB_AName_To_NBName(char *AName, char *NBName) |
void RFCNB_AName_To_NBName(char *AName, |
88 |
|
char *NBName) |
89 |
{ char c, c1, c2; |
{ |
90 |
int i; |
char c, c1, c2; |
91 |
|
int i; |
92 |
|
|
93 |
for (i=0; i < 16; i++) { |
for (i = 0; i < 16; i++) |
94 |
|
{ |
95 |
|
|
96 |
c = AName[i]; |
c = AName[i]; |
97 |
|
|
98 |
c1 = (char)((c >> 4) + 'A'); |
c1 = (char) ((c >> 4) + 'A'); |
99 |
c2 = (char)((c & 0xF) + 'A'); |
c2 = (char) ((c & 0xF) + 'A'); |
100 |
|
|
101 |
NBName[i*2] = c1; |
NBName[i * 2] = c1; |
102 |
NBName[i*2+1] = c2; |
NBName[i * 2 + 1] = c2; |
103 |
} |
} |
104 |
|
|
105 |
NBName[32] = 0; /* Put in a null */ |
NBName[32] = 0; /* Put in a null */ |
106 |
|
|
107 |
} |
} |
108 |
|
|
109 |
/* Do the reverse of the above ... */ |
/* Do the reverse of the above ... */ |
110 |
|
|
111 |
void RFCNB_NBName_To_AName(char *NBName, char *AName) |
void RFCNB_NBName_To_AName(char *NBName, |
112 |
|
char *AName) |
113 |
{ char c, c1, c2; |
{ |
114 |
int i; |
char c, c1, c2; |
115 |
|
int i; |
116 |
|
|
117 |
for (i=0; i < 16; i++) { |
for (i = 0; i < 16; i++) |
118 |
|
{ |
119 |
|
|
120 |
c1 = NBName[i*2]; |
c1 = NBName[i * 2]; |
121 |
c2 = NBName[i*2+1]; |
c2 = NBName[i * 2 + 1]; |
122 |
|
|
123 |
c = (char)(((int)c1 - (int)'A') * 16 + ((int)c2 - (int)'A')); |
c = (char) (((int) c1 - (int) 'A') * 16 + ((int) c2 - (int) 'A')); |
124 |
|
|
125 |
AName[i] = c; |
AName[i] = c; |
126 |
|
|
127 |
} |
} |
128 |
|
|
129 |
AName[i] = 0; /* Put a null on the end ... */ |
AName[i] = 0; /* Put a null on the end ... */ |
130 |
|
|
131 |
} |
} |
132 |
|
|
133 |
/* Print a string of bytes in HEX etc */ |
/* Print a string of bytes in HEX etc */ |
134 |
|
|
135 |
void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len) |
void RFCNB_Print_Hex(FILE * fd, |
136 |
|
struct RFCNB_Pkt *pkt, |
137 |
{ char c1, c2, outbuf1[33]; |
int Offset, |
138 |
unsigned char c; |
int Len) |
139 |
int i, j; |
{ |
140 |
struct RFCNB_Pkt *pkt_ptr = pkt; |
char c1, c2, outbuf1[33]; |
141 |
static char Hex_List[17] = "0123456789ABCDEF"; |
unsigned char c; |
142 |
|
int i, j; |
143 |
|
struct RFCNB_Pkt *pkt_ptr = pkt; |
144 |
|
static char Hex_List[17] = "0123456789ABCDEF"; |
145 |
|
|
146 |
j = 0; |
j = 0; |
147 |
|
|
148 |
/* We only want to print as much as sepcified in Len */ |
/* |
149 |
|
* We only want to print as much as sepcified in Len |
150 |
|
*/ |
151 |
|
|
152 |
while (pkt_ptr != NULL) { |
while (pkt_ptr != NULL) |
153 |
|
{ |
154 |
|
|
155 |
for (i = 0; |
for (i = 0; |
156 |
i < ((Len > (pkt_ptr -> len)?pkt_ptr -> len:Len) - Offset); |
i < ((Len > (pkt_ptr->len) ? pkt_ptr->len : Len) - Offset); i++) |
157 |
i++) { |
{ |
158 |
|
|
159 |
c = pkt_ptr -> data[i + Offset]; |
c = pkt_ptr->data[i + Offset]; |
160 |
c1 = Hex_List[c >> 4]; |
c1 = Hex_List[c >> 4]; |
161 |
c2 = Hex_List[c & 0xF]; |
c2 = Hex_List[c & 0xF]; |
162 |
|
|
163 |
outbuf1[j++] = c1; outbuf1[j++] = c2; |
outbuf1[j++] = c1; |
164 |
|
outbuf1[j++] = c2; |
165 |
|
|
166 |
if (j == 32){ /* Print and reset */ |
if (j == 32) |
167 |
outbuf1[j] = 0; |
{ /* Print and reset */ |
168 |
fprintf(fd, " %s\n", outbuf1); |
outbuf1[j] = 0; |
169 |
j = 0; |
fprintf(fd, " %s\n", outbuf1); |
170 |
} |
j = 0; |
171 |
|
} |
172 |
|
|
173 |
} |
} |
174 |
|
|
175 |
Offset = 0; |
Offset = 0; |
176 |
Len = Len - pkt_ptr -> len; /* Reduce amount by this much */ |
Len = Len - pkt_ptr->len; /* Reduce amount by this much */ |
177 |
pkt_ptr = pkt_ptr -> next; |
pkt_ptr = pkt_ptr->next; |
178 |
|
|
179 |
} |
} |
180 |
|
|
181 |
/* Print last lot in the buffer ... */ |
/* |
182 |
|
* Print last lot in the buffer ... |
183 |
|
*/ |
184 |
|
|
185 |
if (j > 0) { |
if (j > 0) |
186 |
|
{ |
187 |
|
|
188 |
outbuf1[j] = 0; |
outbuf1[j] = 0; |
189 |
fprintf(fd, " %s\n", outbuf1); |
fprintf(fd, " %s\n", outbuf1); |
190 |
|
|
191 |
} |
} |
192 |
|
|
193 |
fprintf(fd, "\n"); |
fprintf(fd, "\n"); |
194 |
|
|
195 |
} |
} |
196 |
|
|
197 |
/* Get a packet of size n */ |
/* Get a packet of size n */ |
198 |
|
|
199 |
struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n) |
struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n) |
200 |
|
{ |
201 |
|
RFCNB_Pkt *pkt; |
202 |
|
|
203 |
{ RFCNB_Pkt *pkt; |
if ((pkt = (struct RFCNB_Pkt *) malloc(sizeof(struct RFCNB_Pkt))) == NULL) |
204 |
|
{ |
|
if ((pkt = (struct RFCNB_Pkt *)malloc(sizeof(struct RFCNB_Pkt))) == NULL) { |
|
205 |
|
|
206 |
RFCNB_errno = RFCNBE_NoSpace; |
RFCNB_errno = RFCNBE_NoSpace; |
207 |
RFCNB_saved_errno = errno; |
RFCNB_saved_errno = errno; |
208 |
return(NULL); |
return (NULL); |
209 |
|
|
210 |
} |
} |
211 |
|
|
212 |
pkt -> next = NULL; |
pkt->next = NULL; |
213 |
pkt -> len = n; |
pkt->len = n; |
214 |
|
|
215 |
if (n == 0) return(pkt); |
if (n == 0) |
216 |
|
return (pkt); |
217 |
|
|
218 |
if ((pkt -> data = (char *)malloc(n)) == NULL) { |
if ((pkt->data = (char *) malloc(n)) == NULL) |
219 |
|
{ |
220 |
|
|
221 |
RFCNB_errno = RFCNBE_NoSpace; |
RFCNB_errno = RFCNBE_NoSpace; |
222 |
RFCNB_saved_errno = errno; |
RFCNB_saved_errno = errno; |
223 |
free(pkt); |
free(pkt); |
224 |
return(NULL); |
return (NULL); |
225 |
|
|
226 |
} |
} |
227 |
|
|
228 |
return(pkt); |
return (pkt); |
229 |
|
|
230 |
} |
} |
231 |
|
|
232 |
/* Free up a packet */ |
/* Free up a packet */ |
233 |
|
|
234 |
int RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt) |
int RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt) |
235 |
|
{ |
236 |
|
struct RFCNB_Pkt *pkt_next; |
237 |
|
char *data_ptr; |
238 |
|
|
239 |
{ struct RFCNB_Pkt *pkt_next; char *data_ptr; |
while (pkt != NULL) |
240 |
|
{ |
|
while (pkt != NULL) { |
|
241 |
|
|
242 |
pkt_next = pkt -> next; |
pkt_next = pkt->next; |
243 |
|
|
244 |
data_ptr = pkt -> data; |
data_ptr = pkt->data; |
245 |
|
|
246 |
if (data_ptr != NULL) |
if (data_ptr != NULL) |
247 |
free(data_ptr); |
free(data_ptr); |
248 |
|
|
249 |
free(pkt); |
free(pkt); |
250 |
|
|
251 |
pkt = pkt_next; |
pkt = pkt_next; |
252 |
|
|
253 |
} |
} |
254 |
|
|
255 |
} |
} |
256 |
|
|
257 |
/* Print an RFCNB packet */ |
/* Print an RFCNB packet */ |
258 |
|
|
259 |
void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len) |
void RFCNB_Print_Pkt(FILE * fd, |
260 |
|
char *dirn, |
261 |
{ char lname[17]; |
struct RFCNB_Pkt *pkt, |
262 |
|
int len) |
263 |
|
{ |
264 |
|
char lname[17]; |
265 |
|
|
266 |
/* We assume that the first fragment is the RFCNB Header */ |
/* |
267 |
/* We should loop through the fragments printing them out */ |
* We assume that the first fragment is the RFCNB Header |
268 |
|
*/ |
269 |
|
/* |
270 |
|
* We should loop through the fragments printing them out |
271 |
|
*/ |
272 |
|
|
273 |
fprintf(fd, "RFCNB Pkt %s:", dirn); |
fprintf(fd, "RFCNB Pkt %s:", dirn); |
274 |
|
|
275 |
switch (RFCNB_Pkt_Type(pkt -> data)) { |
switch (RFCNB_Pkt_Type(pkt->data)) |
276 |
|
{ |
277 |
|
|
278 |
case RFCNB_SESSION_MESSAGE: |
case RFCNB_SESSION_MESSAGE: |
279 |
|
|
280 |
fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt -> data)); |
fprintf(fd, "SESSION MESSAGE: Length = %i\n", |
281 |
RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len, |
RFCNB_Pkt_Len(pkt->data)); |
282 |
|
RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len, |
283 |
#ifdef RFCNB_PRINT_DATA |
#ifdef RFCNB_PRINT_DATA |
284 |
RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len); |
RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len); |
285 |
#else |
#else |
286 |
40); |
40); |
287 |
#endif |
#endif |
288 |
|
|
289 |
if (Prot_Print_Routine != 0) { /* Print the rest of the packet */ |
if (Prot_Print_Routine != 0) |
290 |
|
{ /* Print the rest of the packet */ |
291 |
Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, RFCNB_Pkt_Hdr_Len, |
|
292 |
RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len); |
Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, |
293 |
|
RFCNB_Pkt_Hdr_Len, |
294 |
|
RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len); |
295 |
|
|
296 |
} |
} |
297 |
|
|
298 |
break; |
break; |
299 |
|
|
300 |
case RFCNB_SESSION_REQUEST: |
case RFCNB_SESSION_REQUEST: |
301 |
|
|
302 |
fprintf(fd, "SESSION REQUEST: Length = %i\n", |
fprintf(fd, "SESSION REQUEST: Length = %i\n", |
303 |
RFCNB_Pkt_Len(pkt -> data)); |
RFCNB_Pkt_Len(pkt->data)); |
304 |
RFCNB_NBName_To_AName((char *)(pkt -> data + RFCNB_Pkt_Called_Offset), lname); |
RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Called_Offset), |
305 |
fprintf(fd, " Called Name: %s\n", lname); |
lname); |
306 |
RFCNB_NBName_To_AName((char *)(pkt -> data + RFCNB_Pkt_Calling_Offset), lname); |
fprintf(fd, " Called Name: %s\n", lname); |
307 |
fprintf(fd, " Calling Name: %s\n", lname); |
RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Calling_Offset), |
308 |
|
lname); |
309 |
|
fprintf(fd, " Calling Name: %s\n", lname); |
310 |
|
|
311 |
break; |
break; |
312 |
|
|
313 |
case RFCNB_SESSION_ACK: |
case RFCNB_SESSION_ACK: |
314 |
|
|
315 |
fprintf(fd, "RFCNB SESSION ACK: Length = %i\n", |
fprintf(fd, "RFCNB SESSION ACK: Length = %i\n", |
316 |
RFCNB_Pkt_Len(pkt -> data)); |
RFCNB_Pkt_Len(pkt->data)); |
317 |
|
|
318 |
break; |
break; |
319 |
|
|
320 |
case RFCNB_SESSION_REJ: |
case RFCNB_SESSION_REJ: |
321 |
fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n", |
fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n", |
322 |
RFCNB_Pkt_Len(pkt -> data)); |
RFCNB_Pkt_Len(pkt->data)); |
323 |
|
|
324 |
if (RFCNB_Pkt_Len(pkt -> data) < 1) { |
if (RFCNB_Pkt_Len(pkt->data) < 1) |
325 |
fprintf(fd, " Protocol Error, short Reject packet!\n"); |
{ |
326 |
} |
fprintf(fd, " Protocol Error, short Reject packet!\n"); |
327 |
else { |
} |
328 |
fprintf(fd, " Error = %x\n", CVAL(pkt -> data, RFCNB_Pkt_Error_Offset)); |
else |
329 |
} |
{ |
330 |
|
fprintf(fd, " Error = %x\n", |
331 |
|
CVAL(pkt->data, RFCNB_Pkt_Error_Offset)); |
332 |
|
} |
333 |
|
|
334 |
break; |
break; |
335 |
|
|
336 |
case RFCNB_SESSION_RETARGET: |
case RFCNB_SESSION_RETARGET: |
337 |
|
|
338 |
fprintf(fd, "RFCNB SESSION RETARGET: Length = %i\n", |
fprintf(fd, "RFCNB SESSION RETARGET: Length = %i\n", |
339 |
RFCNB_Pkt_Len(pkt -> data)); |
RFCNB_Pkt_Len(pkt->data)); |
340 |
|
|
341 |
/* Print out the IP address etc and the port? */ |
/* |
342 |
|
* Print out the IP address etc and the port? |
343 |
|
*/ |
344 |
|
|
345 |
break; |
break; |
346 |
|
|
347 |
case RFCNB_SESSION_KEEP_ALIVE: |
case RFCNB_SESSION_KEEP_ALIVE: |
348 |
|
|
349 |
fprintf(fd, "RFCNB SESSION KEEP ALIVE: Length = %i\n", |
fprintf(fd, "RFCNB SESSION KEEP ALIVE: Length = %i\n", |
350 |
RFCNB_Pkt_Len(pkt -> data)); |
RFCNB_Pkt_Len(pkt->data)); |
351 |
break; |
break; |
352 |
|
|
353 |
default: |
default: |
354 |
|
|
355 |
break; |
break; |
356 |
} |
} |
357 |
|
|
358 |
} |
} |
359 |
|
|
360 |
/* Resolve a name into an address */ |
/* Resolve a name into an address */ |
361 |
|
|
362 |
int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP) |
int RFCNB_Name_To_IP(char *host, |
363 |
|
struct in_addr *Dest_IP) |
364 |
{ int addr; /* Assumes IP4, 32 bit network addresses */ |
{ |
365 |
struct hostent *hp; |
int addr; /* Assumes IP4, 32 bit network addresses */ |
366 |
|
struct hostent *hp; |
367 |
|
|
368 |
/* Use inet_addr to try to convert the address */ |
/* |
369 |
|
* Use inet_addr to try to convert the address |
370 |
|
*/ |
371 |
|
|
372 |
if ((addr = inet_addr(host)) == INADDR_NONE) { /* Oh well, a good try :-) */ |
if ((addr = inet_addr(host)) == INADDR_NONE) |
373 |
|
{ /* Oh well, a good try :-) */ |
374 |
|
|
375 |
/* Now try a name look up with gethostbyname */ |
/* |
376 |
|
* Now try a name look up with gethostbyname |
377 |
|
*/ |
378 |
|
|
379 |
if ((hp = gethostbyname(host)) == NULL) { /* Not in DNS */ |
if ((hp = gethostbyname(host)) == NULL) |
380 |
|
{ /* Not in DNS */ |
381 |
|
|
382 |
/* Try NetBIOS name lookup, how the hell do we do that? */ |
/* |
383 |
|
* Try NetBIOS name lookup, how the hell do we do that? |
384 |
|
*/ |
385 |
|
|
386 |
RFCNB_errno = RFCNBE_BadName; /* Is this right? */ |
RFCNB_errno = RFCNBE_BadName; /* Is this right? */ |
387 |
RFCNB_saved_errno = errno; |
RFCNB_saved_errno = errno; |
388 |
return(RFCNBE_Bad); |
return (RFCNBE_Bad); |
389 |
|
|
390 |
} |
} |
391 |
else { /* We got a name */ |
else |
392 |
|
{ /* We got a name */ |
393 |
|
|
394 |
memcpy((void *)Dest_IP, (void *)hp -> h_addr_list[0], sizeof(struct in_addr)); |
memcpy((void *) Dest_IP, (void *) hp->h_addr_list[0], |
395 |
|
sizeof(struct in_addr)); |
396 |
|
|
397 |
} |
} |
398 |
} |
} |
399 |
else { /* It was an IP address */ |
else |
400 |
|
{ /* It was an IP address */ |
401 |
|
|
402 |
memcpy((void *)Dest_IP, (void *)&addr, sizeof(struct in_addr)); |
memcpy((void *) Dest_IP, (void *) &addr, sizeof(struct in_addr)); |
403 |
|
|
404 |
} |
} |
405 |
|
|
406 |
return 0; |
return 0; |
407 |
|
|
408 |
} |
} |
409 |
|
|
410 |
/* Disconnect the TCP connection to the server */ |
/* Disconnect the TCP connection to the server */ |
411 |
|
|
412 |
int RFCNB_Close(int socket) |
int RFCNB_Close(int socket) |
|
|
|
413 |
{ |
{ |
414 |
|
|
415 |
close(socket); |
close(socket); |
416 |
|
|
417 |
/* If we want to do error recovery, here is where we put it */ |
/* |
418 |
|
* If we want to do error recovery, here is where we put it |
419 |
|
*/ |
420 |
|
|
421 |
return 0; |
return 0; |
422 |
|
|
423 |
} |
} |
424 |
|
|
425 |
/* Connect to the server specified in the IP address. |
/* Connect to the server specified in the IP address. |
426 |
Not sure how to handle socket options etc. */ |
Not sure how to handle socket options etc. */ |
427 |
|
|
428 |
int RFCNB_IP_Connect(struct in_addr Dest_IP, int port) |
int RFCNB_IP_Connect(struct in_addr Dest_IP, |
429 |
|
int port) |
430 |
{ struct sockaddr_in Socket; |
{ |
431 |
int fd; |
struct sockaddr_in Socket; |
432 |
|
int fd; |
433 |
|
|
434 |
/* Create a socket */ |
/* |
435 |
|
* Create a socket |
436 |
|
*/ |
437 |
|
|
438 |
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { /* Handle the error */ |
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) |
439 |
|
{ /* Handle the error */ |
440 |
|
|
441 |
RFCNB_errno = RFCNBE_BadSocket; |
RFCNB_errno = RFCNBE_BadSocket; |
442 |
RFCNB_saved_errno = errno; |
RFCNB_saved_errno = errno; |
443 |
return(RFCNBE_Bad); |
return (RFCNBE_Bad); |
444 |
} |
} |
445 |
|
|
446 |
bzero((char *)&Socket, sizeof(Socket)); |
bzero((char *) &Socket, sizeof(Socket)); |
447 |
memcpy((char *)&Socket.sin_addr, (char *)&Dest_IP, sizeof(Dest_IP)); |
memcpy((char *) &Socket.sin_addr, (char *) &Dest_IP, sizeof(Dest_IP)); |
448 |
|
|
449 |
Socket.sin_port = htons(port); |
Socket.sin_port = htons(port); |
450 |
Socket.sin_family = PF_INET; |
Socket.sin_family = PF_INET; |
451 |
|
|
452 |
/* Now connect to the destination */ |
/* |
453 |
|
* Now connect to the destination |
454 |
|
*/ |
455 |
|
|
456 |
if (connect(fd, (struct sockaddr *)&Socket, sizeof(Socket)) < 0) { /* Error */ |
if (connect(fd, (struct sockaddr *) &Socket, sizeof(Socket)) < 0) |
457 |
|
{ /* Error */ |
458 |
|
|
459 |
close(fd); |
close(fd); |
460 |
RFCNB_errno = RFCNBE_ConnectFailed; |
RFCNB_errno = RFCNBE_ConnectFailed; |
461 |
RFCNB_saved_errno = errno; |
RFCNB_saved_errno = errno; |
462 |
return(RFCNBE_Bad); |
return (RFCNBE_Bad); |
463 |
} |
} |
464 |
|
|
465 |
return(fd); |
return (fd); |
466 |
|
|
467 |
} |
} |
468 |
|
|
471 |
|
|
472 |
*/ |
*/ |
473 |
|
|
474 |
int RFCNB_Session_Req(struct RFCNB_Con *con, |
int RFCNB_Session_Req(struct RFCNB_Con *con, |
475 |
char *Called_Name, |
char *Called_Name, |
476 |
char *Calling_Name, |
char *Calling_Name, |
477 |
BOOL *redirect, |
BOOL * redirect, |
478 |
struct in_addr *Dest_IP, |
struct in_addr *Dest_IP, |
479 |
int * port) |
int *port) |
480 |
|
{ |
481 |
{ char *sess_pkt; |
char *sess_pkt; |
482 |
|
|
483 |
/* Response packet should be no more than 9 bytes, make 16 jic */ |
/* |
484 |
|
* Response packet should be no more than 9 bytes, make 16 jic |
485 |
|
*/ |
486 |
|
|
487 |
char ln1[16], ln2[16], n1[32], n2[32], resp[16]; |
char ln1[16], ln2[16], n1[32], n2[32], resp[16]; |
488 |
int len; |
int len; |
489 |
struct RFCNB_Pkt *pkt, res_pkt; |
struct RFCNB_Pkt *pkt, res_pkt; |
490 |
|
|
491 |
/* We build and send the session request, then read the response */ |
/* |
492 |
|
* We build and send the session request, then read the response |
493 |
|
*/ |
494 |
|
|
495 |
pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len); |
pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len); |
496 |
|
|
497 |
if (pkt == NULL) { |
if (pkt == NULL) |
498 |
|
{ |
499 |
|
|
500 |
return(RFCNBE_Bad); /* Leave the error that RFCNB_Alloc_Pkt gives) */ |
return (RFCNBE_Bad); /* Leave the error that RFCNB_Alloc_Pkt gives) */ |
501 |
|
|
502 |
} |
} |
503 |
|
|
504 |
sess_pkt = pkt -> data; /* Get pointer to packet proper */ |
sess_pkt = pkt->data; /* Get pointer to packet proper */ |
505 |
|
|
506 |
sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST; |
sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST; |
507 |
RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len-RFCNB_Pkt_Hdr_Len); |
RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len - RFCNB_Pkt_Hdr_Len); |
508 |
sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32; |
sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32; |
509 |
sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32; |
sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32; |
510 |
|
|
511 |
RFCNB_CvtPad_Name(Called_Name, (sess_pkt + RFCNB_Pkt_Called_Offset)); |
RFCNB_CvtPad_Name(Called_Name, (sess_pkt + RFCNB_Pkt_Called_Offset)); |
512 |
RFCNB_CvtPad_Name(Calling_Name, (sess_pkt + RFCNB_Pkt_Calling_Offset)); |
RFCNB_CvtPad_Name(Calling_Name, (sess_pkt + RFCNB_Pkt_Calling_Offset)); |
513 |
|
|
514 |
/* Now send the packet */ |
/* |
515 |
|
* Now send the packet |
516 |
|
*/ |
517 |
|
|
518 |
#ifdef RFCNB_DEBUG |
#ifdef RFCNB_DEBUG |
519 |
|
|
520 |
fprintf(stderr, "Sending packet: "); |
fprintf(stderr, "Sending packet: "); |
521 |
|
|
522 |
#endif |
#endif |
523 |
|
|
524 |
if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) { |
if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) |
525 |
|
{ |
526 |
|
|
527 |
return(RFCNBE_Bad); /* Should be able to write that lot ... */ |
return (RFCNBE_Bad); /* Should be able to write that lot ... */ |
528 |
|
|
529 |
} |
} |
530 |
|
|
531 |
#ifdef RFCNB_DEBUG |
#ifdef RFCNB_DEBUG |
532 |
|
|
533 |
fprintf(stderr, "Getting packet.\n"); |
fprintf(stderr, "Getting packet.\n"); |
534 |
|
|
535 |
#endif |
#endif |
536 |
|
|
537 |
res_pkt.data = resp; |
res_pkt.data = resp; |
538 |
res_pkt.len = sizeof(resp); |
res_pkt.len = sizeof(resp); |
539 |
res_pkt.next = NULL; |
res_pkt.next = NULL; |
|
|
|
|
if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) { |
|
540 |
|
|
541 |
return(RFCNBE_Bad); |
if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) |
542 |
|
{ |
543 |
|
|
544 |
} |
return (RFCNBE_Bad); |
545 |
|
|
546 |
/* Now analyze the packet ... */ |
} |
547 |
|
|
548 |
switch (RFCNB_Pkt_Type(resp)) { |
/* |
549 |
|
* Now analyze the packet ... |
550 |
|
*/ |
551 |
|
|
552 |
case RFCNB_SESSION_REJ: /* Didnt like us ... too bad */ |
switch (RFCNB_Pkt_Type(resp)) |
553 |
|
{ |
554 |
|
|
555 |
/* Why did we get rejected ? */ |
case RFCNB_SESSION_REJ: /* Didnt like us ... too bad */ |
|
|
|
|
switch (CVAL(resp,RFCNB_Pkt_Error_Offset)) { |
|
556 |
|
|
557 |
case 0x80: |
/* |
558 |
RFCNB_errno = RFCNBE_CallRejNLOCN; |
* Why did we get rejected ? |
559 |
break; |
*/ |
|
case 0x81: |
|
|
RFCNB_errno = RFCNBE_CallRejNLFCN; |
|
|
break; |
|
|
case 0x82: |
|
|
RFCNB_errno = RFCNBE_CallRejCNNP; |
|
|
break; |
|
|
case 0x83: |
|
|
RFCNB_errno = RFCNBE_CallRejInfRes; |
|
|
break; |
|
|
case 0x8F: |
|
|
RFCNB_errno = RFCNBE_CallRejUnSpec; |
|
|
break; |
|
|
default: |
|
|
RFCNB_errno = RFCNBE_ProtErr; |
|
|
break; |
|
|
} |
|
560 |
|
|
561 |
return(RFCNBE_Bad); |
switch (CVAL(resp, RFCNB_Pkt_Error_Offset)) |
562 |
break; |
{ |
563 |
|
|
564 |
case RFCNB_SESSION_ACK: /* Got what we wanted ... */ |
case 0x80: |
565 |
|
RFCNB_errno = RFCNBE_CallRejNLOCN; |
566 |
return(0); |
break; |
567 |
break; |
case 0x81: |
568 |
|
RFCNB_errno = RFCNBE_CallRejNLFCN; |
569 |
case RFCNB_SESSION_RETARGET: /* Go elsewhere */ |
break; |
570 |
|
case 0x82: |
571 |
*redirect = TRUE; /* Copy port and ip addr */ |
RFCNB_errno = RFCNBE_CallRejCNNP; |
572 |
|
break; |
573 |
memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr)); |
case 0x83: |
574 |
*port = SVAL(resp, RFCNB_Pkt_Port_Offset); |
RFCNB_errno = RFCNBE_CallRejInfRes; |
575 |
|
break; |
576 |
return(0); |
case 0x8F: |
577 |
break; |
RFCNB_errno = RFCNBE_CallRejUnSpec; |
578 |
|
break; |
579 |
default: /* A protocol error */ |
default: |
580 |
|
RFCNB_errno = RFCNBE_ProtErr; |
581 |
RFCNB_errno = RFCNBE_ProtErr; |
break; |
582 |
return(RFCNBE_Bad); |
} |
|
break; |
|
|
} |
|
|
} |
|
583 |
|
|
584 |
|
return (RFCNBE_Bad); |
585 |
|
break; |
586 |
|
|
587 |
|
case RFCNB_SESSION_ACK: /* Got what we wanted ... */ |
588 |
|
|
589 |
|
return (0); |
590 |
|
break; |
591 |
|
|
592 |
|
case RFCNB_SESSION_RETARGET: /* Go elsewhere */ |
593 |
|
|
594 |
|
*redirect = TRUE; /* Copy port and ip addr */ |
595 |
|
|
596 |
|
memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr)); |
597 |
|
*port = SVAL(resp, RFCNB_Pkt_Port_Offset); |
598 |
|
|
599 |
|
return (0); |
600 |
|
break; |
601 |
|
|
602 |
|
default: /* A protocol error */ |
603 |
|
|
604 |
|
RFCNB_errno = RFCNBE_ProtErr; |
605 |
|
return (RFCNBE_Bad); |
606 |
|
break; |
607 |
|
} |
608 |
|
} |