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