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