aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/x25_facilities.c
diff options
context:
space:
mode:
authorShaun Pereira <spereira@tusc.com.au>2006-03-22 03:01:31 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-22 03:01:31 -0500
commita64b7b936dcd926ace745c07c14f45ecfaddb034 (patch)
tree734b65e3c7c1862b05ef65e0ffbd584d7b86d537 /net/x25/x25_facilities.c
parentbac37ec8300389d355d41a828b47577c1ec2e4f4 (diff)
[X25]: allow ITU-T DTE facilities for x25
Allows use of the optional user facility to insert ITU-T (http://www.itu.int/ITU-T/) specified DTE facilities in call set-up x25 packets. This feature is optional; no facilities will be added if the ioctl is not used, and call setup packet remains the same as before. If the ioctls provided by the patch are used, then a facility marker will be added to the x25 packet header so that the called dte address extension facility can be differentiated from other types of facilities (as described in the ITU-T X.25 recommendation) that are also allowed in the x25 packet header. Facility markers are made up of two octets, and may be present in the x25 packet headers of call-request, incoming call, call accepted, clear request, and clear indication packets. The first of the two octets represents the facility code field and is set to zero by this patch. The second octet of the marker represents the facility parameter field and is set to 0x0F because the marker will be inserted before ITU-T type DTE facilities. Since according to ITU-T X.25 Recommendation X.25(10/96)- 7.1 "All networks will support the facility markers with a facility parameter field set to all ones or to 00001111", therefore this patch should work with all x.25 networks. While there are many ITU-T DTE facilities, this patch implements only the called and calling address extension, with placeholders in the x25_dte_facilities structure for the rest of the facilities. Testing: This patch was tested using a cisco xot router connected on its serial ports to an X.25 network, and on its lan ports to a host running an xotd daemon. It is also possible to test this patch using an xotd daemon and an x25tap patch, where the xotd daemons work back-to-back without actually using an x.25 network. See www.fyonne.net for details on how to do this. Signed-off-by: Shaun Pereira <spereira@tusc.com.au> Acked-by: Andrew Hendry <ahendry@tusc.com.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/x25/x25_facilities.c')
-rw-r--r--net/x25/x25_facilities.c82
1 files changed, 70 insertions, 12 deletions
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index 54278b962f4c..9f42b9c9de37 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -28,18 +28,28 @@
28#include <net/x25.h> 28#include <net/x25.h>
29 29
30/* 30/*
31 * Parse a set of facilities into the facilities structure. Unrecognised 31 * Parse a set of facilities into the facilities structures. Unrecognised
32 * facilities are written to the debug log file. 32 * facilities are written to the debug log file.
33 */ 33 */
34int x25_parse_facilities(struct sk_buff *skb, 34int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
35 struct x25_facilities *facilities, 35 struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
36 unsigned long *vc_fac_mask)
37{ 36{
38 unsigned char *p = skb->data; 37 unsigned char *p = skb->data;
39 unsigned int len = *p++; 38 unsigned int len = *p++;
40 39
41 *vc_fac_mask = 0; 40 *vc_fac_mask = 0;
42 41
42 /*
43 * The kernel knows which facilities were set on an incoming call but
44 * currently this information is not available to userspace. Here we
45 * give userspace who read incoming call facilities 0 length to indicate
46 * it wasn't set.
47 */
48 dte_facs->calling_len = 0;
49 dte_facs->called_len = 0;
50 memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
51 memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
52
43 while (len > 0) { 53 while (len > 0) {
44 switch (*p & X25_FAC_CLASS_MASK) { 54 switch (*p & X25_FAC_CLASS_MASK) {
45 case X25_FAC_CLASS_A: 55 case X25_FAC_CLASS_A:
@@ -74,6 +84,8 @@ int x25_parse_facilities(struct sk_buff *skb,
74 facilities->throughput = p[1]; 84 facilities->throughput = p[1];
75 *vc_fac_mask |= X25_MASK_THROUGHPUT; 85 *vc_fac_mask |= X25_MASK_THROUGHPUT;
76 break; 86 break;
87 case X25_MARKER:
88 break;
77 default: 89 default:
78 printk(KERN_DEBUG "X.25: unknown facility " 90 printk(KERN_DEBUG "X.25: unknown facility "
79 "%02X, value %02X\n", 91 "%02X, value %02X\n",
@@ -112,11 +124,30 @@ int x25_parse_facilities(struct sk_buff *skb,
112 len -= 4; 124 len -= 4;
113 break; 125 break;
114 case X25_FAC_CLASS_D: 126 case X25_FAC_CLASS_D:
115 printk(KERN_DEBUG "X.25: unknown facility %02X, " 127 switch (*p) {
116 "length %d, values %02X, %02X, %02X, %02X\n", 128 case X25_FAC_CALLING_AE:
117 p[0], p[1], p[2], p[3], p[4], p[5]); 129 if (p[1] > X25_MAX_DTE_FACIL_LEN)
130 break;
131 dte_facs->calling_len = p[2];
132 memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
133 *vc_fac_mask |= X25_MASK_CALLING_AE;
134 break;
135 case X25_FAC_CALLED_AE:
136 if (p[1] > X25_MAX_DTE_FACIL_LEN)
137 break;
138 dte_facs->called_len = p[2];
139 memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
140 *vc_fac_mask |= X25_MASK_CALLED_AE;
141 break;
142 default:
143 printk(KERN_DEBUG "X.25: unknown facility %02X,"
144 "length %d, values %02X, %02X, "
145 "%02X, %02X\n",
146 p[0], p[1], p[2], p[3], p[4], p[5]);
147 break;
148 }
118 len -= p[1] + 2; 149 len -= p[1] + 2;
119 p += p[1] + 2; 150 p += p[1] + 2;
120 break; 151 break;
121 } 152 }
122 } 153 }
@@ -128,8 +159,8 @@ int x25_parse_facilities(struct sk_buff *skb,
128 * Create a set of facilities. 159 * Create a set of facilities.
129 */ 160 */
130int x25_create_facilities(unsigned char *buffer, 161int x25_create_facilities(unsigned char *buffer,
131 struct x25_facilities *facilities, 162 struct x25_facilities *facilities,
132 unsigned long facil_mask) 163 struct x25_dte_facilities *dte_facs, unsigned long facil_mask)
133{ 164{
134 unsigned char *p = buffer + 1; 165 unsigned char *p = buffer + 1;
135 int len; 166 int len;
@@ -168,6 +199,33 @@ int x25_create_facilities(unsigned char *buffer,
168 *p++ = facilities->winsize_out ? : facilities->winsize_in; 199 *p++ = facilities->winsize_out ? : facilities->winsize_in;
169 } 200 }
170 201
202 if (facil_mask & (X25_MASK_CALLING_AE|X25_MASK_CALLED_AE)) {
203 *p++ = X25_MARKER;
204 *p++ = X25_DTE_SERVICES;
205 }
206
207 if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) {
208 unsigned bytecount = (dte_facs->calling_len % 2) ?
209 dte_facs->calling_len / 2 + 1 :
210 dte_facs->calling_len / 2;
211 *p++ = X25_FAC_CALLING_AE;
212 *p++ = 1 + bytecount;
213 *p++ = dte_facs->calling_len;
214 memcpy(p, dte_facs->calling_ae, bytecount);
215 p += bytecount;
216 }
217
218 if (dte_facs->called_len && (facil_mask & X25_MASK_CALLED_AE)) {
219 unsigned bytecount = (dte_facs->called_len % 2) ?
220 dte_facs->called_len / 2 + 1 :
221 dte_facs->called_len / 2;
222 *p++ = X25_FAC_CALLED_AE;
223 *p++ = 1 + bytecount;
224 *p++ = dte_facs->called_len;
225 memcpy(p, dte_facs->called_ae, bytecount);
226 p+=bytecount;
227 }
228
171 len = p - buffer; 229 len = p - buffer;
172 buffer[0] = len - 1; 230 buffer[0] = len - 1;
173 231
@@ -180,7 +238,7 @@ int x25_create_facilities(unsigned char *buffer,
180 * The only real problem is with reverse charging. 238 * The only real problem is with reverse charging.
181 */ 239 */
182int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, 240int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
183 struct x25_facilities *new) 241 struct x25_facilities *new, struct x25_dte_facilities *dte)
184{ 242{
185 struct x25_sock *x25 = x25_sk(sk); 243 struct x25_sock *x25 = x25_sk(sk);
186 struct x25_facilities *ours = &x25->facilities; 244 struct x25_facilities *ours = &x25->facilities;
@@ -190,7 +248,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
190 memset(&theirs, 0, sizeof(theirs)); 248 memset(&theirs, 0, sizeof(theirs));
191 memcpy(new, ours, sizeof(*new)); 249 memcpy(new, ours, sizeof(*new));
192 250
193 len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask); 251 len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
194 252
195 /* 253 /*
196 * They want reverse charging, we won't accept it. 254 * They want reverse charging, we won't accept it.