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