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