OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [x25/] [af_x25.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      X.25 Packet Layer release 002
3
 *
4
 *      This is ALPHA test software. This code may break your machine, randomly fail to work with new
5
 *      releases, misbehave and/or generally screw up. It might even work.
6
 *
7
 *      This code REQUIRES 2.1.15 or higher
8
 *
9
 *      This module:
10
 *              This module is free software; you can redistribute it and/or
11
 *              modify it under the terms of the GNU General Public License
12
 *              as published by the Free Software Foundation; either version
13
 *              2 of the License, or (at your option) any later version.
14
 *
15
 *      History
16
 *      X.25 001        Jonathan Naylor Started coding.
17
 *      X.25 002        Jonathan Naylor Centralised disconnect handling.
18
 *                                      New timer architecture.
19
 *      2000-03-11      Henner Eisen    MSG_EOR handling more POSIX compliant.
20
 *      2000-03-22      Daniela Squassoni Allowed disabling/enabling of
21
 *                                        facilities negotiation and increased
22
 *                                        the throughput upper limit.
23
 *      2000-08-27      Arnaldo C. Melo s/suser/capable/ + micro cleanups
24
 *      2000-09-04      Henner Eisen    Set sock->state in x25_accept().
25
 *                                      Fixed x25_output() related skb leakage.
26
 *      2000-10-02      Henner Eisen    Made x25_kick() single threaded per socket.
27
 *      2000-10-27      Henner Eisen    MSG_DONTWAIT for fragment allocation.
28
 *      2000-11-14      Henner Eisen    Closing datalink from NETDEV_GOING_DOWN
29
 */
30
 
31
#include <linux/config.h>
32
#include <linux/module.h>
33
#include <linux/errno.h>
34
#include <linux/types.h>
35
#include <linux/socket.h>
36
#include <linux/in.h>
37
#include <linux/kernel.h>
38
#include <linux/sched.h>
39
#include <linux/timer.h>
40
#include <linux/string.h>
41
#include <linux/sockios.h>
42
#include <linux/net.h>
43
#include <linux/stat.h>
44
#include <linux/inet.h>
45
#include <linux/netdevice.h>
46
#include <linux/if_arp.h>
47
#include <linux/skbuff.h>
48
#include <net/sock.h>
49
#include <asm/segment.h>
50
#include <asm/system.h>
51
#include <asm/uaccess.h>
52
#include <linux/fcntl.h>
53
#include <linux/termios.h>      /* For TIOCINQ/OUTQ */
54
#include <linux/mm.h>
55
#include <linux/interrupt.h>
56
#include <linux/notifier.h>
57
#include <linux/proc_fs.h>
58
#include <linux/init.h>
59
#include <net/x25.h>
60
 
61
int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20;
62
int sysctl_x25_call_request_timeout    = X25_DEFAULT_T21;
63
int sysctl_x25_reset_request_timeout   = X25_DEFAULT_T22;
64
int sysctl_x25_clear_request_timeout   = X25_DEFAULT_T23;
65
int sysctl_x25_ack_holdback_timeout    = X25_DEFAULT_T2;
66
 
67
static struct sock *volatile x25_list /* = NULL initially */;
68
 
69
static struct proto_ops x25_proto_ops;
70
 
71
static x25_address null_x25_address = {"               "};
72
 
73
int x25_addr_ntoa(unsigned char *p, x25_address *called_addr, x25_address *calling_addr)
74
{
75
        int called_len, calling_len;
76
        char *called, *calling;
77
        int i;
78
 
79
        called_len  = (*p >> 0) & 0x0F;
80
        calling_len = (*p >> 4) & 0x0F;
81
 
82
        called  = called_addr->x25_addr;
83
        calling = calling_addr->x25_addr;
84
        p++;
85
 
86
        for (i = 0; i < (called_len + calling_len); i++) {
87
                if (i < called_len) {
88
                        if (i % 2 != 0) {
89
                                *called++ = ((*p >> 0) & 0x0F) + '0';
90
                                p++;
91
                        } else {
92
                                *called++ = ((*p >> 4) & 0x0F) + '0';
93
                        }
94
                } else {
95
                        if (i % 2 != 0) {
96
                                *calling++ = ((*p >> 0) & 0x0F) + '0';
97
                                p++;
98
                        } else {
99
                                *calling++ = ((*p >> 4) & 0x0F) + '0';
100
                        }
101
                }
102
        }
103
 
104
        *called  = '\0';
105
        *calling = '\0';
106
 
107
        return 1 + (called_len + calling_len + 1) / 2;
108
}
109
 
110
int x25_addr_aton(unsigned char *p, x25_address *called_addr, x25_address *calling_addr)
111
{
112
        unsigned int called_len, calling_len;
113
        char *called, *calling;
114
        int i;
115
 
116
        called  = called_addr->x25_addr;
117
        calling = calling_addr->x25_addr;
118
 
119
        called_len  = strlen(called);
120
        calling_len = strlen(calling);
121
 
122
        *p++ = (calling_len << 4) | (called_len << 0);
123
 
124
        for (i = 0; i < (called_len + calling_len); i++) {
125
                if (i < called_len) {
126
                        if (i % 2 != 0) {
127
                                *p |= (*called++ - '0') << 0;
128
                                p++;
129
                        } else {
130
                                *p = 0x00;
131
                                *p |= (*called++ - '0') << 4;
132
                        }
133
                } else {
134
                        if (i % 2 != 0) {
135
                                *p |= (*calling++ - '0') << 0;
136
                                p++;
137
                        } else {
138
                                *p = 0x00;
139
                                *p |= (*calling++ - '0') << 4;
140
                        }
141
                }
142
        }
143
 
144
        return 1 + (called_len + calling_len + 1) / 2;
145
}
146
 
147
/*
148
 *      Socket removal during an interrupt is now safe.
149
 */
150
static void x25_remove_socket(struct sock *sk)
151
{
152
        struct sock *s;
153
        unsigned long flags;
154
 
155
        save_flags(flags);
156
        cli();
157
 
158
        if ((s = x25_list) == sk) {
159
                x25_list = s->next;
160
                restore_flags(flags);
161
                return;
162
        }
163
 
164
        while (s != NULL && s->next != NULL) {
165
                if (s->next == sk) {
166
                        s->next = sk->next;
167
                        restore_flags(flags);
168
                        return;
169
                }
170
 
171
                s = s->next;
172
        }
173
 
174
        restore_flags(flags);
175
}
176
 
177
/*
178
 *      Kill all bound sockets on a dropped device.
179
 */
180
static void x25_kill_by_device(struct net_device *dev)
181
{
182
        struct sock *s;
183
 
184
        for (s = x25_list; s != NULL; s = s->next)
185
                if (s->protinfo.x25->neighbour &&
186
                    s->protinfo.x25->neighbour->dev == dev)
187
                        x25_disconnect(s, ENETUNREACH, 0, 0);
188
}
189
 
190
/*
191
 *      Handle device status changes.
192
 */
193
static int x25_device_event(struct notifier_block *this, unsigned long event, void *ptr)
194
{
195
        struct net_device *dev = (struct net_device *)ptr;
196
        struct x25_neigh *neigh;
197
 
198
        if (dev->type == ARPHRD_X25
199
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
200
         || dev->type == ARPHRD_ETHER
201
#endif
202
         ) {
203
                switch (event) {
204
                        case NETDEV_UP:
205
                                x25_link_device_up(dev);
206
                                break;
207
                        case NETDEV_GOING_DOWN:
208
                                if ((neigh = x25_get_neigh(dev)))
209
                                        x25_terminate_link(neigh);
210
                                break;
211
                        case NETDEV_DOWN:
212
                                x25_kill_by_device(dev);
213
                                x25_route_device_down(dev);
214
                                x25_link_device_down(dev);
215
                                break;
216
                }
217
        }
218
 
219
        return NOTIFY_DONE;
220
}
221
 
222
/*
223
 *      Add a socket to the bound sockets list.
224
 */
225
static void x25_insert_socket(struct sock *sk)
226
{
227
        unsigned long flags;
228
 
229
        save_flags(flags);
230
        cli();
231
 
232
        sk->next = x25_list;
233
        x25_list = sk;
234
 
235
        restore_flags(flags);
236
}
237
 
238
/*
239
 *      Find a socket that wants to accept the Call Request we just
240
 *      received.
241
 */
242
static struct sock *x25_find_listener(x25_address *addr)
243
{
244
        unsigned long flags;
245
        struct sock *s;
246
 
247
        save_flags(flags);
248
        cli();
249
 
250
        for (s = x25_list; s != NULL; s = s->next) {
251
                if ((strcmp(addr->x25_addr, s->protinfo.x25->source_addr.x25_addr) == 0 ||
252
                     strcmp(addr->x25_addr, null_x25_address.x25_addr) == 0) &&
253
                     s->state == TCP_LISTEN) {
254
                        restore_flags(flags);
255
                        return s;
256
                }
257
        }
258
 
259
        restore_flags(flags);
260
        return NULL;
261
}
262
 
263
/*
264
 *      Find a connected X.25 socket given my LCI and neighbour.
265
 */
266
struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *neigh)
267
{
268
        struct sock *s;
269
        unsigned long flags;
270
 
271
        save_flags(flags);
272
        cli();
273
 
274
        for (s = x25_list; s != NULL; s = s->next) {
275
                if (s->protinfo.x25->lci == lci && s->protinfo.x25->neighbour == neigh) {
276
                        restore_flags(flags);
277
                        return s;
278
                }
279
        }
280
 
281
        restore_flags(flags);
282
        return NULL;
283
}
284
 
285
/*
286
 *      Find a unique LCI for a given device.
287
 */
288
unsigned int x25_new_lci(struct x25_neigh *neigh)
289
{
290
        unsigned int lci = 1;
291
 
292
        while (x25_find_socket(lci, neigh) != NULL) {
293
                lci++;
294
                if (lci == 4096) return 0;
295
        }
296
 
297
        return lci;
298
}
299
 
300
/*
301
 *      Deferred destroy.
302
 */
303
void x25_destroy_socket(struct sock *);
304
 
305
/*
306
 *      handler for deferred kills.
307
 */
308
static void x25_destroy_timer(unsigned long data)
309
{
310
        x25_destroy_socket((struct sock *)data);
311
}
312
 
313
/*
314
 *      This is called from user mode and the timers. Thus it protects itself against
315
 *      interrupt users but doesn't worry about being called during work.
316
 *      Once it is removed from the queue no interrupt or bottom half will
317
 *      touch it and we are (fairly 8-) ) safe.
318
 */
319
void x25_destroy_socket(struct sock *sk)        /* Not static as it's used by the timer */
320
{
321
        struct sk_buff *skb;
322
        unsigned long flags;
323
 
324
        save_flags(flags);
325
        cli();
326
 
327
        x25_stop_heartbeat(sk);
328
        x25_stop_timer(sk);
329
 
330
        x25_remove_socket(sk);
331
        x25_clear_queues(sk);           /* Flush the queues */
332
 
333
        while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
334
                if (skb->sk != sk) {            /* A pending connection */
335
                        skb->sk->dead = 1;      /* Queue the unaccepted socket for death */
336
                        x25_start_heartbeat(skb->sk);
337
                        skb->sk->protinfo.x25->state = X25_STATE_0;
338
                }
339
 
340
                kfree_skb(skb);
341
        }
342
 
343
        if (atomic_read(&sk->wmem_alloc) != 0 || atomic_read(&sk->rmem_alloc) != 0) {
344
                /* Defer: outstanding buffers */
345
                init_timer(&sk->timer);
346
                sk->timer.expires  = jiffies + 10 * HZ;
347
                sk->timer.function = x25_destroy_timer;
348
                sk->timer.data     = (unsigned long)sk;
349
                add_timer(&sk->timer);
350
        } else {
351
                sk_free(sk);
352
                MOD_DEC_USE_COUNT;
353
        }
354
 
355
        restore_flags(flags);
356
}
357
 
358
/*
359
 *      Handling for system calls applied via the various interfaces to a
360
 *      X.25 socket object.
361
 */
362
 
363
static int x25_setsockopt(struct socket *sock, int level, int optname,
364
        char *optval, int optlen)
365
{
366
        struct sock *sk = sock->sk;
367
        int opt;
368
 
369
        if (level != SOL_X25)
370
                return -ENOPROTOOPT;
371
 
372
        if (optlen < sizeof(int))
373
                return-EINVAL;
374
 
375
        if (get_user(opt, (int *)optval))
376
                return -EFAULT;
377
 
378
        switch (optname) {
379
                case X25_QBITINCL:
380
                        sk->protinfo.x25->qbitincl = opt ? 1 : 0;
381
                        return 0;
382
 
383
                default:
384
                        return -ENOPROTOOPT;
385
        }
386
}
387
 
388
static int x25_getsockopt(struct socket *sock, int level, int optname,
389
        char *optval, int *optlen)
390
{
391
        struct sock *sk = sock->sk;
392
        int val = 0;
393
        int len;
394
 
395
        if (level != SOL_X25)
396
                return -ENOPROTOOPT;
397
 
398
        if (get_user(len, optlen))
399
                return -EFAULT;
400
 
401
        switch (optname) {
402
                case X25_QBITINCL:
403
                        val = sk->protinfo.x25->qbitincl;
404
                        break;
405
 
406
                default:
407
                        return -ENOPROTOOPT;
408
        }
409
 
410
        len = min_t(unsigned int, len, sizeof(int));
411
 
412
        if (len < 0)
413
                return -EINVAL;
414
 
415
        if (put_user(len, optlen))
416
                return -EFAULT;
417
 
418
        return copy_to_user(optval, &val, len) ? -EFAULT : 0;
419
}
420
 
421
static int x25_listen(struct socket *sock, int backlog)
422
{
423
        struct sock *sk = sock->sk;
424
 
425
        if (sk->state != TCP_LISTEN) {
426
                memset(&sk->protinfo.x25->dest_addr, '\0', X25_ADDR_LEN);
427
                sk->max_ack_backlog = backlog;
428
                sk->state           = TCP_LISTEN;
429
                return 0;
430
        }
431
 
432
        return -EOPNOTSUPP;
433
}
434
 
435
static struct sock *x25_alloc_socket(void)
436
{
437
        struct sock *sk;
438
        x25_cb *x25;
439
 
440
        if ((sk = sk_alloc(AF_X25, GFP_ATOMIC, 1)) == NULL)
441
                return NULL;
442
 
443
        if ((x25 = kmalloc(sizeof(*x25), GFP_ATOMIC)) == NULL) {
444
                sk_free(sk);
445
                return NULL;
446
        }
447
 
448
        memset(x25, 0x00, sizeof(*x25));
449
 
450
        x25->sk          = sk;
451
        sk->protinfo.x25 = x25;
452
 
453
        MOD_INC_USE_COUNT;
454
 
455
        sock_init_data(NULL, sk);
456
 
457
        skb_queue_head_init(&x25->ack_queue);
458
        skb_queue_head_init(&x25->fragment_queue);
459
        skb_queue_head_init(&x25->interrupt_in_queue);
460
        skb_queue_head_init(&x25->interrupt_out_queue);
461
 
462
        return sk;
463
}
464
 
465
static int x25_create(struct socket *sock, int protocol)
466
{
467
        struct sock *sk;
468
        x25_cb *x25;
469
 
470
        if (sock->type != SOCK_SEQPACKET || protocol != 0)
471
                return -ESOCKTNOSUPPORT;
472
 
473
        if ((sk = x25_alloc_socket()) == NULL)
474
                return -ENOMEM;
475
 
476
        x25 = sk->protinfo.x25;
477
 
478
        sock_init_data(sock, sk);
479
 
480
        init_timer(&x25->timer);
481
 
482
        sock->ops    = &x25_proto_ops;
483
        sk->protocol = protocol;
484
        sk->backlog_rcv = x25_backlog_rcv;
485
 
486
        x25->t21   = sysctl_x25_call_request_timeout;
487
        x25->t22   = sysctl_x25_reset_request_timeout;
488
        x25->t23   = sysctl_x25_clear_request_timeout;
489
        x25->t2    = sysctl_x25_ack_holdback_timeout;
490
        x25->state = X25_STATE_0;
491
 
492
        x25->facilities.winsize_in  = X25_DEFAULT_WINDOW_SIZE;
493
        x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
494
        x25->facilities.pacsize_in  = X25_DEFAULT_PACKET_SIZE;
495
        x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
496
        x25->facilities.throughput  = X25_DEFAULT_THROUGHPUT;
497
        x25->facilities.reverse     = X25_DEFAULT_REVERSE;
498
 
499
        return 0;
500
}
501
 
502
static struct sock *x25_make_new(struct sock *osk)
503
{
504
        struct sock *sk;
505
        x25_cb *x25;
506
 
507
        if (osk->type != SOCK_SEQPACKET)
508
                return NULL;
509
 
510
        if ((sk = x25_alloc_socket()) == NULL)
511
                return NULL;
512
 
513
        x25 = sk->protinfo.x25;
514
 
515
        sk->type        = osk->type;
516
        sk->socket      = osk->socket;
517
        sk->priority    = osk->priority;
518
        sk->protocol    = osk->protocol;
519
        sk->rcvbuf      = osk->rcvbuf;
520
        sk->sndbuf      = osk->sndbuf;
521
        sk->debug       = osk->debug;
522
        sk->state       = TCP_ESTABLISHED;
523
        sk->sleep       = osk->sleep;
524
        sk->zapped      = osk->zapped;
525
        sk->backlog_rcv = osk->backlog_rcv;
526
 
527
        x25->t21        = osk->protinfo.x25->t21;
528
        x25->t22        = osk->protinfo.x25->t22;
529
        x25->t23        = osk->protinfo.x25->t23;
530
        x25->t2         = osk->protinfo.x25->t2;
531
 
532
        x25->facilities = osk->protinfo.x25->facilities;
533
 
534
        x25->qbitincl   = osk->protinfo.x25->qbitincl;
535
 
536
        init_timer(&x25->timer);
537
 
538
        return sk;
539
}
540
 
541
static int x25_release(struct socket *sock)
542
{
543
        struct sock *sk = sock->sk;
544
 
545
        if (sk == NULL) return 0;
546
 
547
        switch (sk->protinfo.x25->state) {
548
 
549
                case X25_STATE_0:
550
                case X25_STATE_2:
551
                        x25_disconnect(sk, 0, 0, 0);
552
                        x25_destroy_socket(sk);
553
                        break;
554
 
555
                case X25_STATE_1:
556
                case X25_STATE_3:
557
                case X25_STATE_4:
558
                        x25_clear_queues(sk);
559
                        x25_write_internal(sk, X25_CLEAR_REQUEST);
560
                        x25_start_t23timer(sk);
561
                        sk->protinfo.x25->state = X25_STATE_2;
562
                        sk->state               = TCP_CLOSE;
563
                        sk->shutdown           |= SEND_SHUTDOWN;
564
                        sk->state_change(sk);
565
                        sk->dead                = 1;
566
                        sk->destroy             = 1;
567
                        break;
568
 
569
                default:
570
                        break;
571
        }
572
 
573
        sock->sk   = NULL;
574
        sk->socket = NULL;      /* Not used, but we should do this */
575
 
576
        return 0;
577
}
578
 
579
static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
580
{
581
        struct sock *sk = sock->sk;
582
        struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
583
 
584
        if (sk->zapped == 0)
585
                return -EINVAL;
586
 
587
        if (addr_len != sizeof(struct sockaddr_x25))
588
                return -EINVAL;
589
 
590
        if (addr->sx25_family != AF_X25)
591
                return -EINVAL;
592
 
593
        sk->protinfo.x25->source_addr = addr->sx25_addr;
594
 
595
        x25_insert_socket(sk);
596
 
597
        sk->zapped = 0;
598
 
599
        SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
600
 
601
        return 0;
602
}
603
 
604
static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
605
{
606
        struct sock *sk = sock->sk;
607
        struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
608
        struct net_device *dev;
609
 
610
        if (sk->state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
611
                sock->state = SS_CONNECTED;
612
                return 0;        /* Connect completed during a ERESTARTSYS event */
613
        }
614
 
615
        if (sk->state == TCP_CLOSE && sock->state == SS_CONNECTING) {
616
                sock->state = SS_UNCONNECTED;
617
                return -ECONNREFUSED;
618
        }
619
 
620
        if (sk->state == TCP_ESTABLISHED)
621
                return -EISCONN;        /* No reconnect on a seqpacket socket */
622
 
623
        sk->state   = TCP_CLOSE;
624
        sock->state = SS_UNCONNECTED;
625
 
626
        if (addr_len != sizeof(struct sockaddr_x25))
627
                return -EINVAL;
628
 
629
        if (addr->sx25_family != AF_X25)
630
                return -EINVAL;
631
 
632
        if ((dev = x25_get_route(&addr->sx25_addr)) == NULL)
633
                return -ENETUNREACH;
634
 
635
        if ((sk->protinfo.x25->neighbour = x25_get_neigh(dev)) == NULL)
636
                return -ENETUNREACH;
637
 
638
        x25_limit_facilities(&sk->protinfo.x25->facilities,
639
                             sk->protinfo.x25->neighbour);
640
 
641
        if ((sk->protinfo.x25->lci = x25_new_lci(sk->protinfo.x25->neighbour)) == 0)
642
                return -ENETUNREACH;
643
 
644
        if (sk->zapped)         /* Must bind first - autobinding does not work */
645
                return -EINVAL;
646
 
647
        if (strcmp(sk->protinfo.x25->source_addr.x25_addr, null_x25_address.x25_addr) == 0)
648
                memset(&sk->protinfo.x25->source_addr, '\0', X25_ADDR_LEN);
649
 
650
        sk->protinfo.x25->dest_addr = addr->sx25_addr;
651
 
652
        /* Move to connecting socket, start sending Connect Requests */
653
        sock->state   = SS_CONNECTING;
654
        sk->state     = TCP_SYN_SENT;
655
 
656
        sk->protinfo.x25->state = X25_STATE_1;
657
 
658
        x25_write_internal(sk, X25_CALL_REQUEST);
659
 
660
        x25_start_heartbeat(sk);
661
        x25_start_t21timer(sk);
662
 
663
        /* Now the loop */
664
        if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
665
                return -EINPROGRESS;
666
 
667
        cli();  /* To avoid races on the sleep */
668
 
669
        /*
670
         * A Clear Request or timeout or failed routing will go to closed.
671
         */
672
        while (sk->state == TCP_SYN_SENT) {
673
                interruptible_sleep_on(sk->sleep);
674
                if (signal_pending(current)) {
675
                        sti();
676
                        return -ERESTARTSYS;
677
                }
678
        }
679
 
680
        if (sk->state != TCP_ESTABLISHED) {
681
                sti();
682
                sock->state = SS_UNCONNECTED;
683
                return sock_error(sk);  /* Always set at this point */
684
        }
685
 
686
        sock->state = SS_CONNECTED;
687
 
688
        sti();
689
 
690
        return 0;
691
}
692
 
693
static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
694
{
695
        struct sock *sk;
696
        struct sock *newsk;
697
        struct sk_buff *skb;
698
 
699
        if ((sk = sock->sk) == NULL)
700
                return -EINVAL;
701
 
702
        if (sk->type != SOCK_SEQPACKET)
703
                return -EOPNOTSUPP;
704
 
705
        if (sk->state != TCP_LISTEN)
706
                return -EINVAL;
707
 
708
        /*
709
         *      The write queue this time is holding sockets ready to use
710
         *      hooked into the CALL INDICATION we saved
711
         */
712
        do {
713
                cli();
714
                if ((skb = skb_dequeue(&sk->receive_queue)) == NULL) {
715
                        if (flags & O_NONBLOCK) {
716
                                sti();
717
                                return -EWOULDBLOCK;
718
                        }
719
                        interruptible_sleep_on(sk->sleep);
720
                        if (signal_pending(current)) {
721
                                sti();
722
                                return -ERESTARTSYS;
723
                        }
724
                }
725
        } while (skb == NULL);
726
 
727
        newsk = skb->sk;
728
        newsk->pair = NULL;
729
        newsk->socket = newsock;
730
        newsk->sleep = &newsock->wait;
731
        sti();
732
 
733
        /* Now attach up the new socket */
734
        skb->sk = NULL;
735
        kfree_skb(skb);
736
        sk->ack_backlog--;
737
        newsock->sk = newsk;
738
        newsock->state = SS_CONNECTED;
739
 
740
        return 0;
741
}
742
 
743
static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
744
{
745
        struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
746
        struct sock *sk = sock->sk;
747
 
748
        if (peer != 0) {
749
                if (sk->state != TCP_ESTABLISHED)
750
                        return -ENOTCONN;
751
                sx25->sx25_addr   = sk->protinfo.x25->dest_addr;
752
        } else {
753
                sx25->sx25_addr   = sk->protinfo.x25->source_addr;
754
        }
755
 
756
        sx25->sx25_family = AF_X25;
757
        *uaddr_len = sizeof(struct sockaddr_x25);
758
 
759
        return 0;
760
}
761
 
762
int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned int lci)
763
{
764
        struct sock *sk;
765
        struct sock *make;
766
        x25_address source_addr, dest_addr;
767
        struct x25_facilities facilities;
768
        int len;
769
 
770
        /*
771
         *      Remove the LCI and frame type.
772
         */
773
        skb_pull(skb, X25_STD_MIN_LEN);
774
 
775
        /*
776
         *      Extract the X.25 addresses and convert them to ASCII strings,
777
         *      and remove them.
778
         */
779
        skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
780
 
781
        /*
782
         *      Find a listener for the particular address.
783
         */
784
        sk = x25_find_listener(&source_addr);
785
 
786
        /*
787
         *      We can't accept the Call Request.
788
         */
789
        if (sk == NULL || sk->ack_backlog == sk->max_ack_backlog) {
790
                x25_transmit_clear_request(neigh, lci, 0x01);
791
                return 0;
792
        }
793
 
794
        /*
795
         *      Try to reach a compromise on the requested facilities.
796
         */
797
        if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1) {
798
                x25_transmit_clear_request(neigh, lci, 0x01);
799
                return 0;
800
        }
801
 
802
        /*
803
         * current neighbour/link might impose additional limits
804
         * on certain facilties
805
         */
806
 
807
        x25_limit_facilities(&facilities,neigh);
808
 
809
        /*
810
         *      Try to create a new socket.
811
         */
812
        if ((make = x25_make_new(sk)) == NULL) {
813
                x25_transmit_clear_request(neigh, lci, 0x01);
814
                return 0;
815
        }
816
 
817
        /*
818
         *      Remove the facilities, leaving any Call User Data.
819
         */
820
        skb_pull(skb, len);
821
 
822
        skb->sk     = make;
823
        make->state = TCP_ESTABLISHED;
824
 
825
        make->protinfo.x25->lci           = lci;
826
        make->protinfo.x25->dest_addr     = dest_addr;
827
        make->protinfo.x25->source_addr   = source_addr;
828
        make->protinfo.x25->neighbour     = neigh;
829
        make->protinfo.x25->facilities    = facilities;
830
        make->protinfo.x25->vc_facil_mask = sk->protinfo.x25->vc_facil_mask;
831
 
832
        x25_write_internal(make, X25_CALL_ACCEPTED);
833
 
834
        /*
835
         *      Incoming Call User Data.
836
         */
837
        if (skb->len >= 0) {
838
                memcpy(make->protinfo.x25->calluserdata.cuddata, skb->data, skb->len);
839
                make->protinfo.x25->calluserdata.cudlength = skb->len;
840
        }
841
 
842
        make->protinfo.x25->state = X25_STATE_3;
843
 
844
        sk->ack_backlog++;
845
        make->pair = sk;
846
 
847
        x25_insert_socket(make);
848
 
849
        skb_queue_head(&sk->receive_queue, skb);
850
 
851
        x25_start_heartbeat(make);
852
 
853
        if (!sk->dead)
854
                sk->data_ready(sk, skb->len);
855
 
856
        return 1;
857
}
858
 
859
static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
860
{
861
        struct sock *sk = sock->sk;
862
        struct sockaddr_x25 *usx25 = (struct sockaddr_x25 *)msg->msg_name;
863
        int err;
864
        struct sockaddr_x25 sx25;
865
        struct sk_buff *skb;
866
        unsigned char *asmptr;
867
        int size, qbit = 0;
868
 
869
        if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
870
                return -EINVAL;
871
 
872
        /* we currently don't support segmented records at the user interface */
873
        if (!(msg->msg_flags & (MSG_EOR|MSG_OOB)))
874
                return -EINVAL;
875
 
876
        if (sk->zapped)
877
                return -EADDRNOTAVAIL;
878
 
879
        if (sk->shutdown & SEND_SHUTDOWN) {
880
                send_sig(SIGPIPE, current, 0);
881
                return -EPIPE;
882
        }
883
 
884
        if (sk->protinfo.x25->neighbour == NULL)
885
                return -ENETUNREACH;
886
 
887
        if (usx25 != NULL) {
888
                if (msg->msg_namelen < sizeof(sx25))
889
                        return -EINVAL;
890
                sx25 = *usx25;
891
                if (strcmp(sk->protinfo.x25->dest_addr.x25_addr, sx25.sx25_addr.x25_addr) != 0)
892
                        return -EISCONN;
893
                if (sx25.sx25_family != AF_X25)
894
                        return -EINVAL;
895
        } else {
896
                /*
897
                 *      FIXME 1003.1g - if the socket is like this because
898
                 *      it has become closed (not started closed) we ought
899
                 *      to SIGPIPE, EPIPE;
900
                 */
901
                if (sk->state != TCP_ESTABLISHED)
902
                        return -ENOTCONN;
903
 
904
                sx25.sx25_family = AF_X25;
905
                sx25.sx25_addr   = sk->protinfo.x25->dest_addr;
906
        }
907
 
908
        SOCK_DEBUG(sk, "x25_sendmsg: sendto: Addresses built.\n");
909
 
910
        /* Build a packet */
911
        SOCK_DEBUG(sk, "x25_sendmsg: sendto: building packet.\n");
912
 
913
        if ((msg->msg_flags & MSG_OOB) && len > 32)
914
                len = 32;
915
 
916
        size = len + X25_MAX_L2_LEN + X25_EXT_MIN_LEN;
917
 
918
        if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
919
                return err;
920
        X25_SKB_CB(skb)->flags = msg->msg_flags;
921
 
922
        skb_reserve(skb, X25_MAX_L2_LEN + X25_EXT_MIN_LEN);
923
 
924
        /*
925
         *      Put the data on the end
926
         */
927
        SOCK_DEBUG(sk, "x25_sendmsg: Copying user data\n");
928
 
929
        asmptr = skb->h.raw = skb_put(skb, len);
930
 
931
        memcpy_fromiovec(asmptr, msg->msg_iov, len);
932
 
933
        /*
934
         *      If the Q BIT Include socket option is in force, the first
935
         *      byte of the user data is the logical value of the Q Bit.
936
         */
937
        if (sk->protinfo.x25->qbitincl) {
938
                qbit = skb->data[0];
939
                skb_pull(skb, 1);
940
        }
941
 
942
        /*
943
         *      Push down the X.25 header
944
         */
945
        SOCK_DEBUG(sk, "x25_sendmsg: Building X.25 Header.\n");
946
 
947
        if (msg->msg_flags & MSG_OOB) {
948
                if (sk->protinfo.x25->neighbour->extended) {
949
                        asmptr    = skb_push(skb, X25_STD_MIN_LEN);
950
                        *asmptr++ = ((sk->protinfo.x25->lci >> 8) & 0x0F) | X25_GFI_EXTSEQ;
951
                        *asmptr++ = (sk->protinfo.x25->lci >> 0) & 0xFF;
952
                        *asmptr++ = X25_INTERRUPT;
953
                } else {
954
                        asmptr    = skb_push(skb, X25_STD_MIN_LEN);
955
                        *asmptr++ = ((sk->protinfo.x25->lci >> 8) & 0x0F) | X25_GFI_STDSEQ;
956
                        *asmptr++ = (sk->protinfo.x25->lci >> 0) & 0xFF;
957
                        *asmptr++ = X25_INTERRUPT;
958
                }
959
        } else {
960
                if (sk->protinfo.x25->neighbour->extended) {
961
                        /* Build an Extended X.25 header */
962
                        asmptr    = skb_push(skb, X25_EXT_MIN_LEN);
963
                        *asmptr++ = ((sk->protinfo.x25->lci >> 8) & 0x0F) | X25_GFI_EXTSEQ;
964
                        *asmptr++ = (sk->protinfo.x25->lci >> 0) & 0xFF;
965
                        *asmptr++ = X25_DATA;
966
                        *asmptr++ = X25_DATA;
967
                } else {
968
                        /* Build an Standard X.25 header */
969
                        asmptr    = skb_push(skb, X25_STD_MIN_LEN);
970
                        *asmptr++ = ((sk->protinfo.x25->lci >> 8) & 0x0F) | X25_GFI_STDSEQ;
971
                        *asmptr++ = (sk->protinfo.x25->lci >> 0) & 0xFF;
972
                        *asmptr++ = X25_DATA;
973
                }
974
 
975
                if (qbit)
976
                        skb->data[0] |= X25_Q_BIT;
977
        }
978
 
979
        SOCK_DEBUG(sk, "x25_sendmsg: Built header.\n");
980
        SOCK_DEBUG(sk, "x25_sendmsg: Transmitting buffer\n");
981
 
982
        if (sk->state != TCP_ESTABLISHED) {
983
                kfree_skb(skb);
984
                return -ENOTCONN;
985
        }
986
 
987
        if (msg->msg_flags & MSG_OOB) {
988
                skb_queue_tail(&sk->protinfo.x25->interrupt_out_queue, skb);
989
        } else {
990
                len = x25_output(sk, skb);
991
                if(len<0){
992
                        kfree_skb(skb);
993
                } else {
994
                        if(sk->protinfo.x25->qbitincl) len++;
995
                }
996
        }
997
 
998
        /*
999
         * lock_sock() is currently only used to serialize this x25_kick()
1000
         * against input-driven x25_kick() calls. It currently only blocks
1001
         * incoming packets for this socket and does not protect against
1002
         * any other socket state changes and is not called from anywhere
1003
         * else. As x25_kick() cannot block and as long as all socket
1004
         * operations are BKL-wrapped, we don't need take to care about
1005
         * purging the backlog queue in x25_release().
1006
         *
1007
         * Using lock_sock() to protect all socket operations entirely
1008
         * (and making the whole x25 stack SMP aware) unfortunately would
1009
         * require major changes to {send,recv}msg and skb allocation methods.
1010
         * -> 2.5 ;)
1011
         */
1012
        lock_sock(sk);
1013
        x25_kick(sk);
1014
        release_sock(sk);
1015
 
1016
        return len;
1017
}
1018
 
1019
 
1020
static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm)
1021
{
1022
        struct sock *sk = sock->sk;
1023
        struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name;
1024
        int copied, qbit;
1025
        struct sk_buff *skb;
1026
        unsigned char *asmptr;
1027
        int er;
1028
 
1029
        /*
1030
         * This works for seqpacket too. The receiver has ordered the queue for
1031
         * us! We do one quick check first though
1032
         */
1033
        if (sk->state != TCP_ESTABLISHED)
1034
                return -ENOTCONN;
1035
 
1036
        if (flags & MSG_OOB) {
1037
                if (sk->urginline || skb_peek(&sk->protinfo.x25->interrupt_in_queue) == NULL)
1038
                        return -EINVAL;
1039
 
1040
                skb = skb_dequeue(&sk->protinfo.x25->interrupt_in_queue);
1041
 
1042
                skb_pull(skb, X25_STD_MIN_LEN);
1043
 
1044
                /*
1045
                 *      No Q bit information on Interrupt data.
1046
                 */
1047
                if (sk->protinfo.x25->qbitincl) {
1048
                        asmptr  = skb_push(skb, 1);
1049
                        *asmptr = 0x00;
1050
                }
1051
 
1052
                msg->msg_flags |= MSG_OOB;
1053
        } else {
1054
                /* Now we can treat all alike */
1055
                if ((skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &er)) == NULL)
1056
                        return er;
1057
 
1058
                qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT;
1059
 
1060
                skb_pull(skb, (sk->protinfo.x25->neighbour->extended) ? X25_EXT_MIN_LEN : X25_STD_MIN_LEN);
1061
 
1062
                if (sk->protinfo.x25->qbitincl) {
1063
                        asmptr  = skb_push(skb, 1);
1064
                        *asmptr = qbit;
1065
                }
1066
        }
1067
 
1068
        skb->h.raw = skb->data;
1069
 
1070
        copied = skb->len;
1071
 
1072
        if (copied > size) {
1073
                copied = size;
1074
                msg->msg_flags |= MSG_TRUNC;
1075
        }
1076
 
1077
        /* Currently, each datagram always contains a complete record */
1078
        msg->msg_flags |= MSG_EOR;
1079
 
1080
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
1081
 
1082
        if (sx25 != NULL) {
1083
                sx25->sx25_family = AF_X25;
1084
                sx25->sx25_addr   = sk->protinfo.x25->dest_addr;
1085
        }
1086
 
1087
        msg->msg_namelen = sizeof(struct sockaddr_x25);
1088
 
1089
        skb_free_datagram(sk, skb);
1090
        lock_sock(sk);
1091
        x25_check_rbuf(sk);
1092
        release_sock(sk);
1093
 
1094
        return copied;
1095
}
1096
 
1097
 
1098
static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1099
{
1100
        struct sock *sk = sock->sk;
1101
 
1102
        switch (cmd) {
1103
                case TIOCOUTQ: {
1104
                        int amount;
1105
                        amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
1106
                        if (amount < 0)
1107
                                amount = 0;
1108
                        return put_user(amount, (unsigned int *)arg);
1109
                }
1110
 
1111
                case TIOCINQ: {
1112
                        struct sk_buff *skb;
1113
                        int amount = 0;
1114
                        /* These two are safe on a single CPU system as only user tasks fiddle here */
1115
                        if ((skb = skb_peek(&sk->receive_queue)) != NULL)
1116
                                amount = skb->len;
1117
                        return put_user(amount, (unsigned int *)arg);
1118
                }
1119
 
1120
                case SIOCGSTAMP:
1121
                        if (sk != NULL) {
1122
                                if (sk->stamp.tv_sec == 0)
1123
                                        return -ENOENT;
1124
                                return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
1125
                        }
1126
                        return -EINVAL;
1127
 
1128
                case SIOCGIFADDR:
1129
                case SIOCSIFADDR:
1130
                case SIOCGIFDSTADDR:
1131
                case SIOCSIFDSTADDR:
1132
                case SIOCGIFBRDADDR:
1133
                case SIOCSIFBRDADDR:
1134
                case SIOCGIFNETMASK:
1135
                case SIOCSIFNETMASK:
1136
                case SIOCGIFMETRIC:
1137
                case SIOCSIFMETRIC:
1138
                        return -EINVAL;
1139
 
1140
                case SIOCADDRT:
1141
                case SIOCDELRT:
1142
                        if (!capable(CAP_NET_ADMIN)) return -EPERM;
1143
                        return x25_route_ioctl(cmd, (void *)arg);
1144
 
1145
                case SIOCX25GSUBSCRIP:
1146
                        return x25_subscr_ioctl(cmd, (void *)arg);
1147
 
1148
                case SIOCX25SSUBSCRIP:
1149
                        if (!capable(CAP_NET_ADMIN)) return -EPERM;
1150
                        return x25_subscr_ioctl(cmd, (void *)arg);
1151
 
1152
                case SIOCX25GFACILITIES: {
1153
                        struct x25_facilities facilities;
1154
                        facilities = sk->protinfo.x25->facilities;
1155
                        return copy_to_user((void *)arg, &facilities, sizeof(facilities)) ? -EFAULT : 0;
1156
                }
1157
 
1158
                case SIOCX25SFACILITIES: {
1159
                        struct x25_facilities facilities;
1160
                        if (copy_from_user(&facilities, (void *)arg, sizeof(facilities)))
1161
                                return -EFAULT;
1162
                        if (sk->state != TCP_LISTEN && sk->state != TCP_CLOSE)
1163
                                return -EINVAL;
1164
                        if (facilities.pacsize_in < X25_PS16 || facilities.pacsize_in > X25_PS4096)
1165
                                return -EINVAL;
1166
                        if (facilities.pacsize_out < X25_PS16 || facilities.pacsize_out > X25_PS4096)
1167
                                return -EINVAL;
1168
                        if (facilities.winsize_in < 1 || facilities.winsize_in > 127)
1169
                                return -EINVAL;
1170
                        if (facilities.throughput < 0x03 || facilities.throughput > 0xDD)
1171
                                return -EINVAL;
1172
                        if (facilities.reverse != 0 && facilities.reverse != 1)
1173
                                return -EINVAL;
1174
                        sk->protinfo.x25->facilities = facilities;
1175
                        return 0;
1176
                }
1177
 
1178
                case SIOCX25GCALLUSERDATA: {
1179
                        struct x25_calluserdata calluserdata;
1180
                        calluserdata = sk->protinfo.x25->calluserdata;
1181
                        return copy_to_user((void *)arg, &calluserdata, sizeof(calluserdata)) ? -EFAULT : 0;
1182
                }
1183
 
1184
                case SIOCX25SCALLUSERDATA: {
1185
                        struct x25_calluserdata calluserdata;
1186
                        if (copy_from_user(&calluserdata, (void *)arg, sizeof(calluserdata)))
1187
                                return -EFAULT;
1188
                        if (calluserdata.cudlength > X25_MAX_CUD_LEN)
1189
                                return -EINVAL;
1190
                        sk->protinfo.x25->calluserdata = calluserdata;
1191
                        return 0;
1192
                }
1193
 
1194
                case SIOCX25GCAUSEDIAG: {
1195
                        struct x25_causediag causediag;
1196
                        causediag = sk->protinfo.x25->causediag;
1197
                        return copy_to_user((void *)arg, &causediag, sizeof(causediag)) ? -EFAULT : 0;
1198
                }
1199
 
1200
                default:
1201
                        return dev_ioctl(cmd, (void *)arg);
1202
        }
1203
 
1204
        /*NOTREACHED*/
1205
        return 0;
1206
}
1207
 
1208
static int x25_get_info(char *buffer, char **start, off_t offset, int length)
1209
{
1210
        struct sock *s;
1211
        struct net_device *dev;
1212
        const char *devname;
1213
        int len = 0;
1214
        off_t pos = 0;
1215
        off_t begin = 0;
1216
 
1217
        cli();
1218
 
1219
        len += sprintf(buffer, "dest_addr  src_addr   dev   lci st vs vr va   t  t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
1220
 
1221
        for (s = x25_list; s != NULL; s = s->next) {
1222
                if (s->protinfo.x25->neighbour == NULL || (dev = s->protinfo.x25->neighbour->dev) == NULL)
1223
                        devname = "???";
1224
                else
1225
                        devname = s->protinfo.x25->neighbour->dev->name;
1226
 
1227
                len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X  %d  %d  %d  %d %3lu %3lu %3lu %3lu %3lu %5d %5d %ld\n",
1228
                        (s->protinfo.x25->dest_addr.x25_addr[0] == '\0')   ? "*" : s->protinfo.x25->dest_addr.x25_addr,
1229
                        (s->protinfo.x25->source_addr.x25_addr[0] == '\0') ? "*" : s->protinfo.x25->source_addr.x25_addr,
1230
                        devname,
1231
                        s->protinfo.x25->lci & 0x0FFF,
1232
                        s->protinfo.x25->state,
1233
                        s->protinfo.x25->vs,
1234
                        s->protinfo.x25->vr,
1235
                        s->protinfo.x25->va,
1236
                        x25_display_timer(s) / HZ,
1237
                        s->protinfo.x25->t2  / HZ,
1238
                        s->protinfo.x25->t21 / HZ,
1239
                        s->protinfo.x25->t22 / HZ,
1240
                        s->protinfo.x25->t23 / HZ,
1241
                        atomic_read(&s->wmem_alloc),
1242
                        atomic_read(&s->rmem_alloc),
1243
                        s->socket != NULL ? s->socket->inode->i_ino : 0L);
1244
 
1245
                pos = begin + len;
1246
 
1247
                if (pos < offset) {
1248
                        len   = 0;
1249
                        begin = pos;
1250
                }
1251
 
1252
                if (pos > offset + length)
1253
                        break;
1254
        }
1255
 
1256
        sti();
1257
 
1258
        *start = buffer + (offset - begin);
1259
        len   -= (offset - begin);
1260
 
1261
        if (len > length) len = length;
1262
 
1263
        return(len);
1264
}
1265
 
1266
struct net_proto_family x25_family_ops = {
1267
        family:         AF_X25,
1268
        create:         x25_create,
1269
};
1270
 
1271
static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
1272
        family:         AF_X25,
1273
 
1274
        release:        x25_release,
1275
        bind:           x25_bind,
1276
        connect:        x25_connect,
1277
        socketpair:     sock_no_socketpair,
1278
        accept:         x25_accept,
1279
        getname:        x25_getname,
1280
        poll:           datagram_poll,
1281
        ioctl:          x25_ioctl,
1282
        listen:         x25_listen,
1283
        shutdown:       sock_no_shutdown,
1284
        setsockopt:     x25_setsockopt,
1285
        getsockopt:     x25_getsockopt,
1286
        sendmsg:        x25_sendmsg,
1287
        recvmsg:        x25_recvmsg,
1288
        mmap:           sock_no_mmap,
1289
        sendpage:       sock_no_sendpage,
1290
};
1291
 
1292
#include <linux/smp_lock.h>
1293
SOCKOPS_WRAP(x25_proto, AF_X25);
1294
 
1295
 
1296
static struct packet_type x25_packet_type = {
1297
        type:           __constant_htons(ETH_P_X25),
1298
        func:           x25_lapb_receive_frame,
1299
};
1300
 
1301
struct notifier_block x25_dev_notifier = {
1302
        notifier_call:  x25_device_event,
1303
};
1304
 
1305
void x25_kill_by_neigh(struct x25_neigh *neigh)
1306
{
1307
        struct sock *s;
1308
 
1309
        for( s=x25_list; s != NULL; s=s->next){
1310
                if( s->protinfo.x25->neighbour == neigh )
1311
                        x25_disconnect(s, ENETUNREACH, 0, 0);
1312
        }
1313
}
1314
 
1315
static int __init x25_init(void)
1316
{
1317
#ifdef MODULE
1318
        struct net_device *dev;
1319
#endif /* MODULE */
1320
        sock_register(&x25_family_ops);
1321
 
1322
        dev_add_pack(&x25_packet_type);
1323
 
1324
        register_netdevice_notifier(&x25_dev_notifier);
1325
 
1326
        printk(KERN_INFO "X.25 for Linux. Version 0.2 for Linux 2.1.15\n");
1327
 
1328
#ifdef CONFIG_SYSCTL
1329
        x25_register_sysctl();
1330
#endif
1331
 
1332
        proc_net_create("x25", 0, x25_get_info);
1333
        proc_net_create("x25_routes", 0, x25_routes_get_info);
1334
 
1335
#ifdef MODULE
1336
        /*
1337
         *      Register any pre existing devices.
1338
         */
1339
        read_lock(&dev_base_lock);
1340
        for (dev = dev_base; dev != NULL; dev = dev->next) {
1341
                if ((dev->flags & IFF_UP) && (dev->type == ARPHRD_X25
1342
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
1343
                                           || dev->type == ARPHRD_ETHER
1344
#endif
1345
                        ))
1346
                        x25_link_device_up(dev);
1347
        }
1348
        read_unlock(&dev_base_lock);
1349
#endif /* MODULE */
1350
        return 0;
1351
}
1352
module_init(x25_init);
1353
 
1354
 
1355
 
1356
EXPORT_NO_SYMBOLS;
1357
 
1358
MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
1359
MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
1360
MODULE_LICENSE("GPL");
1361
 
1362
static void __exit x25_exit(void)
1363
{
1364
 
1365
        proc_net_remove("x25");
1366
        proc_net_remove("x25_routes");
1367
 
1368
        x25_link_free();
1369
        x25_route_free();
1370
 
1371
#ifdef CONFIG_SYSCTL
1372
        x25_unregister_sysctl();
1373
#endif
1374
 
1375
        unregister_netdevice_notifier(&x25_dev_notifier);
1376
 
1377
        dev_remove_pack(&x25_packet_type);
1378
 
1379
        sock_unregister(AF_X25);
1380
}
1381
module_exit(x25_exit);
1382
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.