This source file includes following definitions.
- smb_data_callback
- smb_catch_keepalive
- smb_dont_catch_keepalive
- smb_receive_raw
- smb_receive
- smb_receive_trans2
- server_sock
- smb_release
- smb_connect
- smb_request
- smb_trans2_request
- smb_request_read_raw
- smb_request_write_raw
1
2
3
4
5
6
7
8 #include <linux/module.h>
9
10 #include <linux/sched.h>
11 #include <linux/smb_fs.h>
12 #include <linux/errno.h>
13 #include <linux/socket.h>
14 #include <linux/fcntl.h>
15 #include <linux/stat.h>
16 #include <asm/segment.h>
17 #include <linux/in.h>
18 #include <linux/net.h>
19 #include <linux/mm.h>
20 #include <linux/netdevice.h>
21 #include <net/ip.h>
22
23 #include <linux/smb.h>
24 #include <linux/smbno.h>
25
26
27 #define _S(nr) (1<<((nr)-1))
28
29 static void
30 smb_data_callback(struct sock *sk,int len)
31 {
32 struct socket *sock = sk->socket;
33
34 if(!sk->dead)
35 {
36 unsigned char peek_buf[4];
37 int result;
38 unsigned short fs;
39
40 fs = get_fs();
41 set_fs(get_ds());
42
43 result = sock->ops->recvfrom(sock, (void *)peek_buf, 1, 1,
44 MSG_PEEK, NULL, NULL);
45
46 while ((result != -EAGAIN) && (peek_buf[0] == 0x85)) {
47
48
49 result = sock->ops->recvfrom(sock, (void *)peek_buf,
50 4, 1, 0, NULL, NULL);
51
52 DDPRINTK("smb_data_callback:"
53 " got SESSION KEEP ALIVE\n");
54
55 if (result == -EAGAIN)
56 break;
57
58 result = sock->ops->recvfrom(sock, (void *)peek_buf,
59 1, 1, MSG_PEEK,
60 NULL, NULL);
61
62 }
63
64 set_fs(fs);
65
66 if (result != -EAGAIN) {
67 wake_up_interruptible(sk->sleep);
68 }
69 }
70 }
71
72 int
73 smb_catch_keepalive(struct smb_server *server)
74 {
75 struct file *file;
76 struct inode *inode;
77 struct socket *sock;
78 struct sock *sk;
79
80 if ( (server == NULL)
81 || ((file = server->sock_file) == NULL)
82 || ((inode = file->f_inode) == NULL)
83 || (!S_ISSOCK(inode->i_mode))) {
84
85 printk("smb_catch_keepalive: did not get valid server!\n");
86 server->data_ready = NULL;
87 return -EINVAL;
88 }
89
90 sock = &(inode->u.socket_i);
91
92 if (sock->type != SOCK_STREAM) {
93 printk("smb_catch_keepalive: did not get SOCK_STREAM\n");
94 server->data_ready = NULL;
95 return -EINVAL;
96 }
97
98 sk = (struct sock *)(sock->data);
99
100 if (sk == NULL) {
101 printk("smb_catch_keepalive: sk == NULL");
102 server->data_ready = NULL;
103 return -EINVAL;
104 }
105
106 DDPRINTK("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n",
107 (unsigned int)(sk->data_ready),
108 (unsigned int)(server->data_ready));
109
110 if (sk->data_ready == smb_data_callback) {
111 printk("smb_catch_keepalive: already done\n");
112 return -EINVAL;
113 }
114
115 server->data_ready = sk->data_ready;
116 sk->data_ready = smb_data_callback;
117 return 0;
118 }
119
120 int
121 smb_dont_catch_keepalive(struct smb_server *server)
122 {
123 struct file *file;
124 struct inode *inode;
125 struct socket *sock;
126 struct sock *sk;
127
128 if ( (server == NULL)
129 || ((file = server->sock_file) == NULL)
130 || ((inode = file->f_inode) == NULL)
131 || (!S_ISSOCK(inode->i_mode))) {
132
133 printk("smb_dont_catch_keepalive: "
134 "did not get valid server!\n");
135 return -EINVAL;
136 }
137
138 sock = &(inode->u.socket_i);
139
140 if (sock->type != SOCK_STREAM) {
141 printk("smb_dont_catch_keepalive: did not get SOCK_STREAM\n");
142 return -EINVAL;
143 }
144
145 sk = (struct sock *)(sock->data);
146
147 if (sk == NULL) {
148 printk("smb_dont_catch_keepalive: sk == NULL");
149 return -EINVAL;
150 }
151
152 if (server->data_ready == NULL) {
153 printk("smb_dont_catch_keepalive: "
154 "server->data_ready == NULL\n");
155 return -EINVAL;
156 }
157
158 if (sk->data_ready != smb_data_callback) {
159 printk("smb_dont_catch_keepalive: "
160 "sk->data_callback != smb_data_callback\n");
161 return -EINVAL;
162 }
163
164 DDPRINTK("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
165 (unsigned int)(sk->data_ready),
166 (unsigned int)(server->data_ready));
167
168 sk->data_ready = server->data_ready;
169 server->data_ready = NULL;
170 return 0;
171 }
172
173
174
175
176
177
178 static int
179 smb_receive_raw(struct socket *sock, unsigned char *target,
180 int max_raw_length, int want_header)
181 {
182 int len, result;
183 int already_read;
184 unsigned char peek_buf[4];
185 unsigned short fs;
186
187
188
189 re_recv:
190
191 fs = get_fs();
192 set_fs(get_ds());
193 result = sock->ops->recvfrom(sock, (void *)peek_buf, 4, 0,
194 0, NULL, NULL);
195 set_fs(fs);
196
197 if (result < 0) {
198 DPRINTK("smb_receive_raw: recv error = %d\n", -result);
199 return result;
200 }
201
202 if (result < 4) {
203 DPRINTK("smb_receive_raw: got less than 4 bytes\n");
204 return -EIO;
205 }
206
207 switch (peek_buf[0]) {
208
209 case 0x00:
210 case 0x82:
211 break;
212
213 case 0x85:
214 DPRINTK("smb_receive_raw: Got SESSION KEEP ALIVE\n");
215 goto re_recv;
216
217 default:
218 printk("smb_receive_raw: Invalid packet\n");
219 return -EIO;
220 }
221
222
223 len = smb_len(peek_buf);
224 if (len > max_raw_length) {
225 printk("smb_receive_raw: Received length (%d) > max_xmit (%d)!\n",
226 len, max_raw_length);
227 return -EIO;
228 }
229
230 if (want_header != 0) {
231 memcpy_tofs(target, peek_buf, 4);
232 target += 4;
233 }
234
235 already_read = 0;
236
237 while (already_read < len) {
238
239 result = sock->ops->
240 recvfrom(sock,
241 (void *)(target+already_read),
242 len - already_read, 0, 0,
243 NULL, NULL);
244
245 if (result < 0) {
246 printk("smb_receive_raw: recvfrom error = %d\n",
247 -result);
248 return result;
249 }
250
251 already_read += result;
252 }
253 return already_read;
254 }
255
256
257
258
259
260 static int
261 smb_receive(struct smb_server *server, struct socket *sock)
262 {
263 int result;
264
265 result = smb_receive_raw(sock, server->packet,
266 server->max_xmit - 4,
267
268 1);
269
270 if (result < 0) {
271 printk("smb_receive: receive error: %d\n", result);
272 return result;
273 }
274
275 server->rcls = *((unsigned char *)(server->packet+9));
276 server->err = *((unsigned short *)(server->packet+11));
277
278 if (server->rcls != 0) {
279 DPRINTK("smb_receive: rcls=%d, err=%d\n",
280 server->rcls, server->err);
281 }
282
283 return result;
284 }
285
286
287
288
289
290 static int
291 smb_receive_trans2(struct smb_server *server, struct socket *sock,
292 int *data_len, int *param_len,
293 char **data, char **param)
294 {
295 int total_data=0;
296 int total_param=0;
297 int result;
298 unsigned char *inbuf = server->packet;
299
300 *data_len = *param_len = 0;
301
302 DDPRINTK("smb_receive_trans2: enter\n");
303
304 if ((result = smb_receive(server, sock)) < 0) {
305 return result;
306 }
307
308 if (server->rcls != 0) {
309 return result;
310 }
311
312
313 total_data = WVAL(inbuf,smb_tdrcnt);
314 total_param = WVAL(inbuf,smb_tprcnt);
315
316 if ( (total_data > TRANS2_MAX_TRANSFER)
317 || (total_param > TRANS2_MAX_TRANSFER)) {
318 printk("smb_receive_trans2: data/param too long\n");
319 return -EIO;
320 }
321
322
323 if ((*data = smb_kmalloc(total_data, GFP_KERNEL)) == NULL) {
324 printk("smb_receive_trans2: could not alloc data area\n");
325 return -ENOMEM;
326 }
327
328 if ((*param = smb_kmalloc(total_param, GFP_KERNEL)) == NULL) {
329 printk("smb_receive_trans2: could not alloc param area\n");
330 smb_kfree_s(*data, total_data);
331 return -ENOMEM;
332 }
333
334 DDPRINTK("smb_rec_trans2: total_data/param: %d/%d\n",
335 total_data, total_param);
336
337 while (1)
338 {
339 if (WVAL(inbuf,smb_prdisp)+WVAL(inbuf, smb_prcnt)
340 > total_param) {
341 printk("smb_receive_trans2: invalid parameters\n");
342 result = -EIO;
343 goto fail;
344 }
345 memcpy(*param + WVAL(inbuf,smb_prdisp),
346 smb_base(inbuf) + WVAL(inbuf,smb_proff),
347 WVAL(inbuf,smb_prcnt));
348 *param_len += WVAL(inbuf,smb_prcnt);
349
350
351 if (WVAL(inbuf,smb_drdisp)+WVAL(inbuf, smb_drcnt)>total_data) {
352 printk("smb_receive_trans2: invalid data block\n");
353 result = -EIO;
354 goto fail;
355 }
356 memcpy(*data + WVAL(inbuf,smb_drdisp),
357 smb_base(inbuf) + WVAL(inbuf,smb_droff),
358 WVAL(inbuf,smb_drcnt));
359 *data_len += WVAL(inbuf,smb_drcnt);
360
361 DDPRINTK("smb_rec_trans2: drcnt/prcnt: %d/%d\n",
362 WVAL(inbuf, smb_drcnt), WVAL(inbuf, smb_prcnt));
363
364
365
366 if ( (WVAL(inbuf,smb_tdrcnt) > total_data)
367 || (WVAL(inbuf,smb_tprcnt) > total_param)) {
368 printk("smb_receive_trans2: data/params grew!\n");
369 result = -EIO;
370 goto fail;
371 }
372
373 total_data = WVAL(inbuf,smb_tdrcnt);
374 total_param = WVAL(inbuf,smb_tprcnt);
375
376 if (total_data <= *data_len && total_param <= *param_len)
377 break;
378
379 if ((result = smb_receive(server, sock)) < 0) {
380 goto fail;
381 }
382 if (server->rcls != 0) {
383 result = -EIO;
384 goto fail;
385 }
386 }
387
388 DDPRINTK("smb_receive_trans2: normal exit\n");
389
390 return 0;
391
392 fail:
393 DPRINTK("smb_receive_trans2: failed exit\n");
394
395 smb_kfree_s(*param, 0); *param = NULL;
396 smb_kfree_s(*data, 0); *data = NULL;
397 return result;
398 }
399
400 static inline struct socket *
401 server_sock(struct smb_server *server)
402 {
403 struct file *file;
404 struct inode *inode;
405
406 if (server == NULL)
407 return NULL;
408 if ((file = server->sock_file) == NULL)
409 return NULL;
410 if ((inode = file->f_inode) == NULL)
411 return NULL;
412 return &(inode->u.socket_i);
413 }
414
415 int
416 smb_release(struct smb_server *server)
417 {
418 struct socket *sock = server_sock(server);
419 int result;
420
421 if (sock == NULL)
422 return -EINVAL;
423
424 result = sock->ops->release(sock, NULL);
425 DPRINTK("smb_release: sock->ops->release = %d\n", result);
426
427
428
429
430 sock->state = SS_UNCONNECTED;
431
432 result = sock->ops->create(sock, 0);
433 DPRINTK("smb_release: sock->ops->create = %d\n", result);
434 return result;
435 }
436
437 int
438 smb_connect(struct smb_server *server)
439 {
440 struct socket *sock = server_sock(server);
441 if (sock == NULL)
442 return -EINVAL;
443 if (sock->state != SS_UNCONNECTED) {
444 DPRINTK("smb_connect: socket is not unconnected: %d\n",
445 sock->state);
446 }
447 return sock->ops->connect(sock, (struct sockaddr *)&(server->m.addr),
448 sizeof(struct sockaddr_in), 0);
449 }
450
451
452
453
454
455
456
457 int
458 smb_request(struct smb_server *server)
459 {
460 unsigned long old_mask;
461 unsigned short fs;
462
463 int len, result, result2;
464
465 struct socket *sock = server_sock(server);
466 unsigned char *buffer = (server == NULL) ? NULL : server->packet;
467
468 if ((sock == NULL) || (buffer == NULL)) {
469 printk("smb_request: Bad server!\n");
470 return -EBADF;
471 }
472
473 if (server->state != CONN_VALID)
474 return -EIO;
475
476 if ((result = smb_dont_catch_keepalive(server)) != 0) {
477 server->state = CONN_INVALID;
478 smb_invalidate_all_inodes(server);
479 return result;
480 }
481
482 len = smb_len(buffer) + 4;
483
484 DDPRINTK("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
485
486 old_mask = current->blocked;
487 current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
488 fs = get_fs();
489 set_fs(get_ds());
490
491 result = sock->ops->send(sock, (void *)buffer, len, 0, 0);
492 if (result < 0) {
493 printk("smb_request: send error = %d\n", result);
494 }
495 else {
496 result = smb_receive(server, sock);
497 }
498
499
500 current->signal &= ~_S(SIGPIPE);
501
502 current->blocked = old_mask;
503 set_fs(fs);
504
505 if ((result2 = smb_catch_keepalive(server)) < 0) {
506 result = result2;
507 }
508
509 if (result < 0) {
510 server->state = CONN_INVALID;
511 smb_invalidate_all_inodes(server);
512 }
513
514 DDPRINTK("smb_request: result = %d\n", result);
515
516 return result;
517 }
518
519
520
521
522
523 int
524 smb_trans2_request(struct smb_server *server,
525 int *data_len, int *param_len,
526 char **data, char **param)
527 {
528 unsigned long old_mask;
529 unsigned short fs;
530
531 int len, result, result2;
532
533 struct socket *sock = server_sock(server);
534 unsigned char *buffer = (server == NULL) ? NULL : server->packet;
535
536 if ((sock == NULL) || (buffer == NULL)) {
537 printk("smb_trans2_request: Bad server!\n");
538 return -EBADF;
539 }
540
541 if (server->state != CONN_VALID)
542 return -EIO;
543
544 if ((result = smb_dont_catch_keepalive(server)) != 0) {
545 server->state = CONN_INVALID;
546 smb_invalidate_all_inodes(server);
547 return result;
548 }
549
550 len = smb_len(buffer) + 4;
551
552 old_mask = current->blocked;
553 current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
554 fs = get_fs();
555 set_fs(get_ds());
556
557 DDPRINTK("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
558
559 result = sock->ops->send(sock, (void *)buffer, len, 0, 0);
560 if (result < 0) {
561 printk("smb_trans2_request: send error = %d\n", result);
562 }
563 else {
564 result = smb_receive_trans2(server, sock,
565 data_len, param_len,
566 data, param);
567 }
568
569
570 current->signal &= ~_S(SIGPIPE);
571
572 current->blocked = old_mask;
573 set_fs(fs);
574
575 if ((result2 = smb_catch_keepalive(server)) < 0) {
576 result = result2;
577 }
578
579 if (result < 0) {
580 server->state = CONN_INVALID;
581 smb_invalidate_all_inodes(server);
582 }
583
584 DDPRINTK("smb_trans2_request: result = %d\n", result);
585
586 return result;
587 }
588
589
590 int
591 smb_request_read_raw(struct smb_server *server,
592 unsigned char *target, int max_len)
593 {
594 unsigned long old_mask;
595 int len, result, result2;
596 unsigned short fs;
597
598
599 struct socket *sock = server_sock(server);
600 unsigned char *buffer = (server == NULL) ? NULL : server->packet;
601
602 if ((sock == NULL) || (buffer == NULL)) {
603 printk("smb_request_read_raw: Bad server!\n");
604 return -EBADF;
605 }
606
607 if (server->state != CONN_VALID)
608 return -EIO;
609
610 if ((result = smb_dont_catch_keepalive(server)) != 0) {
611 server->state = CONN_INVALID;
612 smb_invalidate_all_inodes(server);
613 return result;
614 }
615
616 len = smb_len(buffer) + 4;
617
618 old_mask = current->blocked;
619 current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
620 fs = get_fs();
621 set_fs(get_ds());
622
623 DPRINTK("smb_request_read_raw: len = %d cmd = 0x%X\n",
624 len, buffer[8]);
625 DPRINTK("smb_request_read_raw: target=%X, max_len=%d\n",
626 (unsigned int)target, max_len);
627 DPRINTK("smb_request_read_raw: buffer=%X, sock=%X\n",
628 (unsigned int)buffer, (unsigned int)sock);
629
630 result = sock->ops->send(sock, (void *)buffer, len, 0, 0);
631
632 DPRINTK("smb_request_read_raw: send returned %d\n", result);
633
634 set_fs(fs);
635
636 if (result < 0) {
637 printk("smb_request_read_raw: send error = %d\n", result);
638 }
639 else {
640 result = smb_receive_raw(sock, target, max_len, 0);
641 }
642
643
644 current->signal &= ~_S(SIGPIPE);
645 current->blocked = old_mask;
646
647 if ((result2 = smb_catch_keepalive(server)) < 0) {
648 result = result2;
649 }
650
651 if (result < 0) {
652 server->state = CONN_INVALID;
653 smb_invalidate_all_inodes(server);
654 }
655
656 DPRINTK("smb_request_read_raw: result = %d\n", result);
657
658 return result;
659 }
660
661
662
663
664 int
665 smb_request_write_raw(struct smb_server *server,
666 unsigned const char *source, int length)
667 {
668 unsigned long old_mask;
669 int result, result2;
670 unsigned short fs;
671
672 byte nb_header[4];
673
674 struct socket *sock = server_sock(server);
675 unsigned char *buffer = (server == NULL) ? NULL : server->packet;
676
677 if ((sock == NULL) || (buffer == NULL)) {
678 printk("smb_request_write_raw: Bad server!\n");
679 return -EBADF;
680 }
681
682 if (server->state != CONN_VALID)
683 return -EIO;
684
685 if ((result = smb_dont_catch_keepalive(server)) != 0) {
686 server->state = CONN_INVALID;
687 smb_invalidate_all_inodes(server);
688 return result;
689 }
690
691 old_mask = current->blocked;
692 current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
693 fs = get_fs();
694 set_fs(get_ds());
695
696 smb_encode_smb_length(nb_header, length);
697
698 result = sock->ops->send(sock, (void *)nb_header, 4, 0, 0);
699
700 if (result == 4) {
701 set_fs(fs);
702 result = sock->ops->send(sock, (void *)source, length, 0, 0);
703 set_fs(get_ds());
704 } else {
705 result = -EIO;
706 }
707
708 DPRINTK("smb_request_write_raw: send returned %d\n", result);
709
710 if (result == length) {
711 result = smb_receive(server, sock);
712 } else {
713 result = -EIO;
714 }
715
716
717 current->signal &= ~_S(SIGPIPE);
718 current->blocked = old_mask;
719 set_fs(fs);
720
721 if ((result2 = smb_catch_keepalive(server)) < 0) {
722 result = result2;
723 }
724
725 if (result < 0) {
726 server->state = CONN_INVALID;
727 smb_invalidate_all_inodes(server);
728 }
729
730 if (result > 0) {
731 result = length;
732 }
733
734 DPRINTK("smb_request_write_raw: result = %d\n", result);
735
736 return result;
737 }
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754