aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/af_x25.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-05-06 21:29:25 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-05-06 21:29:25 -0400
commit1ed31d6db90d51010545921e59d369d2f92b7ac2 (patch)
tree358a0b346bc8135cd5e53700eb44308b1a7c8c5b /net/x25/af_x25.c
parentceba1abcb00b0ef0b1efcd715285f6e05523edef (diff)
parent722154e4cacf015161efe60009ae9be23d492296 (diff)
Merge commit 'origin/master' into next
Diffstat (limited to 'net/x25/af_x25.c')
-rw-r--r--net/x25/af_x25.c68
1 files changed, 63 insertions, 5 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index e56f711baccc..36e84e13c6aa 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -83,6 +83,41 @@ struct compat_x25_subscrip_struct {
83}; 83};
84#endif 84#endif
85 85
86
87int x25_parse_address_block(struct sk_buff *skb,
88 struct x25_address *called_addr,
89 struct x25_address *calling_addr)
90{
91 unsigned char len;
92 int needed;
93 int rc;
94
95 if (skb->len < 1) {
96 /* packet has no address block */
97 rc = 0;
98 goto empty;
99 }
100
101 len = *skb->data;
102 needed = 1 + (len >> 4) + (len & 0x0f);
103
104 if (skb->len < needed) {
105 /* packet is too short to hold the addresses it claims
106 to hold */
107 rc = -1;
108 goto empty;
109 }
110
111 return x25_addr_ntoa(skb->data, called_addr, calling_addr);
112
113empty:
114 *called_addr->x25_addr = 0;
115 *calling_addr->x25_addr = 0;
116
117 return rc;
118}
119
120
86int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, 121int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
87 struct x25_address *calling_addr) 122 struct x25_address *calling_addr)
88{ 123{
@@ -367,6 +402,7 @@ static void __x25_destroy_socket(struct sock *sk)
367 /* 402 /*
368 * Queue the unaccepted socket for death 403 * Queue the unaccepted socket for death
369 */ 404 */
405 skb->sk->sk_state = TCP_LISTEN;
370 sock_set_flag(skb->sk, SOCK_DEAD); 406 sock_set_flag(skb->sk, SOCK_DEAD);
371 x25_start_heartbeat(skb->sk); 407 x25_start_heartbeat(skb->sk);
372 x25_sk(skb->sk)->state = X25_STATE_0; 408 x25_sk(skb->sk)->state = X25_STATE_0;
@@ -554,7 +590,8 @@ static int x25_create(struct net *net, struct socket *sock, int protocol,
554 x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE; 590 x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
555 x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE; 591 x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE;
556 x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; 592 x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
557 x25->facilities.throughput = X25_DEFAULT_THROUGHPUT; 593 x25->facilities.throughput = 0; /* by default don't negotiate
594 throughput */
558 x25->facilities.reverse = X25_DEFAULT_REVERSE; 595 x25->facilities.reverse = X25_DEFAULT_REVERSE;
559 x25->dte_facilities.calling_len = 0; 596 x25->dte_facilities.calling_len = 0;
560 x25->dte_facilities.called_len = 0; 597 x25->dte_facilities.called_len = 0;
@@ -922,16 +959,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
922 /* 959 /*
923 * Extract the X.25 addresses and convert them to ASCII strings, 960 * Extract the X.25 addresses and convert them to ASCII strings,
924 * and remove them. 961 * and remove them.
962 *
963 * Address block is mandatory in call request packets
925 */ 964 */
926 addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr); 965 addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
966 if (addr_len <= 0)
967 goto out_clear_request;
927 skb_pull(skb, addr_len); 968 skb_pull(skb, addr_len);
928 969
929 /* 970 /*
930 * Get the length of the facilities, skip past them for the moment 971 * Get the length of the facilities, skip past them for the moment
931 * get the call user data because this is needed to determine 972 * get the call user data because this is needed to determine
932 * the correct listener 973 * the correct listener
974 *
975 * Facilities length is mandatory in call request packets
933 */ 976 */
977 if (skb->len < 1)
978 goto out_clear_request;
934 len = skb->data[0] + 1; 979 len = skb->data[0] + 1;
980 if (skb->len < len)
981 goto out_clear_request;
935 skb_pull(skb,len); 982 skb_pull(skb,len);
936 983
937 /* 984 /*
@@ -1415,9 +1462,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1415 if (facilities.winsize_in < 1 || 1462 if (facilities.winsize_in < 1 ||
1416 facilities.winsize_in > 127) 1463 facilities.winsize_in > 127)
1417 break; 1464 break;
1418 if (facilities.throughput < 0x03 || 1465 if (facilities.throughput) {
1419 facilities.throughput > 0xDD) 1466 int out = facilities.throughput & 0xf0;
1420 break; 1467 int in = facilities.throughput & 0x0f;
1468 if (!out)
1469 facilities.throughput |=
1470 X25_DEFAULT_THROUGHPUT << 4;
1471 else if (out < 0x30 || out > 0xD0)
1472 break;
1473 if (!in)
1474 facilities.throughput |=
1475 X25_DEFAULT_THROUGHPUT;
1476 else if (in < 0x03 || in > 0x0D)
1477 break;
1478 }
1421 if (facilities.reverse && 1479 if (facilities.reverse &&
1422 (facilities.reverse & 0x81) != 0x81) 1480 (facilities.reverse & 0x81) != 0x81)
1423 break; 1481 break;