Re: [PATCH] X25: Add ITU-T facilites

From: Andrew Hendry
Date: Tue Oct 18 2005 - 01:11:10 EST


Thanks for the feedback Arnaldo. All points should be fixed.

Adds options for ITU DTE facilities to X.25, called address extension and calling address extension

Signed-off-by: Andrew Hendry <ahendry@xxxxxxxxxxx>

diff -uprN -X dontdiff linux-2.6.13.4-vanilla/include/linux/x25.h linux-2.6.13.4/include/linux/x25.h
--- linux-2.6.13.4-vanilla/include/linux/x25.h 2005-10-11 04:54:29.000000000 +1000
+++ linux-2.6.13.4/include/linux/x25.h 2005-10-17 10:38:22.000000000 +1000
@@ -21,6 +21,8 @@
#define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7)
#define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8)
#define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9)
+#define SIOCX25GDTEFACILITIES (SIOCPROTOPRIVATE + 10)
+#define SIOCX25SDTEFACILITIES (SIOCPROTOPRIVATE + 11)

/*
* Values for {get,set}sockopt.
@@ -77,6 +79,8 @@ struct x25_subscrip_struct {
#define X25_MASK_PACKET_SIZE 0x04
#define X25_MASK_WINDOW_SIZE 0x08

+#define X25_MASK_CALLING_AE 0x10
+#define X25_MASK_CALLED_AE 0x20


/*
@@ -98,6 +102,24 @@ struct x25_facilities {
unsigned int reverse;
};

+/*
+* ITU DTE facilities
+* Only the called and calling address
+* extension are currently implemented.
+* The rest are in place to avoid the struct
+* changing size if someone needs them later
++ */
+struct x25_dte_facilities {
+ unsigned int calling_len, called_len;
+ char calling_ae[20];
+ char called_ae[20];
+ unsigned char min_throughput;
+ unsigned short delay_cumul;
+ unsigned short delay_target;
+ unsigned short delay_max;
+ unsigned char expedited;
+};
+
/*
* Call User Data structure.
*/
diff -uprN -X dontdiff linux-2.6.13.4-vanilla/include/net/x25.h linux-2.6.13.4/include/net/x25.h
--- linux-2.6.13.4-vanilla/include/net/x25.h 2005-10-11 04:54:29.000000000 +1000
+++ linux-2.6.13.4/include/net/x25.h 2005-10-17 17:02:44.000000000 +1000
@@ -101,9 +101,16 @@ enum {
#define X25_FAC_PACKET_SIZE 0x42
#define X25_FAC_WINDOW_SIZE 0x43

-#define X25_MAX_FAC_LEN 20 /* Plenty to spare */
+#define X25_MAX_FAC_LEN 60
#define X25_MAX_CUD_LEN 128

+#define X25_FAC_CALLING_AE 0xCB
+#define X25_FAC_CALLED_AE 0xC9
+
+#define X25_MARKER 0x00
+#define X25_DTE_SERVICES 0x0F
+#define X25_MAX_AE_LEN 32
+
/**
* struct x25_route - x25 routing entry
* @node - entry in x25_list_lock
@@ -148,6 +155,7 @@ struct x25_sock {
struct timer_list timer;
struct x25_causediag causediag;
struct x25_facilities facilities;
+ struct x25_dte_facilities dte_facilities;
struct x25_calluserdata calluserdata;
unsigned long vc_facil_mask; /* inc_call facilities mask */
};
@@ -180,9 +188,9 @@ extern void x25_establish_link(struct x2
extern void x25_terminate_link(struct x25_neigh *);

/* x25_facilities.c */
-extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, unsigned long *);
-extern int x25_create_facilities(unsigned char *, struct x25_facilities *, unsigned long);
-extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *);
+extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, struct x25_dte_facilities *, unsigned long *);
+extern int x25_create_facilities(unsigned char *, struct x25_facilities *, struct x25_dte_facilities *, unsigned long);
+extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *, struct x25_dte_facilities *);
extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *);

/* x25_in.c */
diff -uprN -X dontdiff linux-2.6.13.4-vanilla/net/x25/af_x25.c linux-2.6.13.4/net/x25/af_x25.c
--- linux-2.6.13.4-vanilla/net/x25/af_x25.c 2005-10-11 04:54:29.000000000 +1000
+++ linux-2.6.13.4/net/x25/af_x25.c 2005-10-17 16:49:38.000000000 +1000
@@ -513,6 +513,13 @@ static int x25_create(struct socket *soc
x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
x25->facilities.throughput = X25_DEFAULT_THROUGHPUT;
x25->facilities.reverse = X25_DEFAULT_REVERSE;
+ x25->dte_facilities.calling_len = 0;
+ x25->dte_facilities.called_len = 0;
+ memset(x25->dte_facilities.called_ae, '\0',
+ sizeof(x25->dte_facilities.called_ae));
+ memset(x25->dte_facilities.calling_ae, '\0',
+ sizeof(x25->dte_facilities.calling_ae));
+
rc = 0;
out:
return rc;
@@ -554,6 +561,7 @@ static struct sock *x25_make_new(struct
x25->t2 = ox25->t2;
x25->facilities = ox25->facilities;
x25->qbitincl = ox25->qbitincl;
+ x25->dte_facilities = ox25->dte_facilities;
x25->cudmatchlength = ox25->cudmatchlength;
x25->accptapprv = ox25->accptapprv;

@@ -833,6 +841,7 @@ int x25_rx_call_request(struct sk_buff *
struct x25_sock *makex25;
struct x25_address source_addr, dest_addr;
struct x25_facilities facilities;
+ struct x25_dte_facilities dte_facilities;
int len, rc;

/*
@@ -869,7 +878,8 @@ int x25_rx_call_request(struct sk_buff *
/*
* Try to reach a compromise on the requested facilities.
*/
- if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1)
+ if ((len = x25_negotiate_facilities(skb, sk, &facilities,
+ &dte_facilities)) == -1)
goto out_sock_put;

/*
@@ -900,9 +910,12 @@ int x25_rx_call_request(struct sk_buff *
makex25->source_addr = source_addr;
makex25->neighbour = nb;
makex25->facilities = facilities;
+ makex25->dte_facilities= dte_facilities;
makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
/* ensure no reverse facil on accept */
makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
+ /* ensure no calling address extension on accept */
+ makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE;
makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;

/* Normally all calls are accepted immediatly */
@@ -1309,6 +1322,34 @@ static int x25_ioctl(struct socket *sock
break;
}

+ case SIOCX25GDTEFACILITIES: {
+ rc = copy_to_user(argp, &x25->dte_facilities,
+ sizeof(x25->dte_facilities)) ? -EFAULT : 0;
+ break;
+ }
+
+ case SIOCX25SDTEFACILITIES: {
+ struct x25_dte_facilities dtefacs;
+ rc = -EFAULT;
+ if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
+ break;
+ rc = -EINVAL;
+ if (sk->sk_state != TCP_LISTEN &&
+ sk->sk_state != TCP_CLOSE)
+ break;
+ if (dtefacs.calling_len > X25_MAX_AE_LEN)
+ break;
+ if (dtefacs.calling_ae == NULL)
+ break;
+ if (dtefacs.called_len > X25_MAX_AE_LEN)
+ break;
+ if (dtefacs.called_ae == NULL)
+ break;
+ x25->dte_facilities = dtefacs;
+ rc = 0;
+ break;
+ }
+
case SIOCX25GCALLUSERDATA: {
struct x25_calluserdata cud = x25->calluserdata;
rc = copy_to_user(argp, &cud,
diff -uprN -X dontdiff linux-2.6.13.4-vanilla/net/x25/x25_facilities.c linux-2.6.13.4/net/x25/x25_facilities.c
--- linux-2.6.13.4-vanilla/net/x25/x25_facilities.c 2005-10-11 04:54:29.000000000 +1000
+++ linux-2.6.13.4/net/x25/x25_facilities.c 2005-10-17 15:28:10.000000000 +1000
@@ -28,11 +28,12 @@
#include <net/x25.h>

/*
- * Parse a set of facilities into the facilities structure. Unrecognised
+ * Parse a set of facilities into the facilities structures. Unrecognised
* facilities are written to the debug log file.
*/
int x25_parse_facilities(struct sk_buff *skb,
struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
unsigned long *vc_fac_mask)
{
unsigned char *p = skb->data;
@@ -40,6 +41,16 @@ int x25_parse_facilities(struct sk_buff

*vc_fac_mask = 0;

+ /* The kernel knows which facilities were set on an incoming call
+ * but currently this information is not available to userspace.
+ * Here we give userspace who read incoming call facilities
+ * 0 length to indicate it wasn't set.
+ */
+ dte_facs->calling_len = 0;
+ dte_facs->called_len = 0;
+ memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
+ memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
+
while (len > 0) {
switch (*p & X25_FAC_CLASS_MASK) {
case X25_FAC_CLASS_A:
@@ -74,6 +85,8 @@ int x25_parse_facilities(struct sk_buff
facilities->throughput = p[1];
*vc_fac_mask |= X25_MASK_THROUGHPUT;
break;
+ case X25_MARKER:
+ break;
default:
printk(KERN_DEBUG "X.25: unknown facility "
"%02X, value %02X\n",
@@ -112,9 +125,28 @@ int x25_parse_facilities(struct sk_buff
len -= 4;
break;
case X25_FAC_CLASS_D:
- printk(KERN_DEBUG "X.25: unknown facility %02X, "
- "length %d, values %02X, %02X, %02X, %02X\n",
- p[0], p[1], p[2], p[3], p[4], p[5]);
+ switch (*p) {
+ case X25_FAC_CALLING_AE:
+ if (p[1] > 33)
+ break;
+ dte_facs->calling_len = p[2];
+ memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
+ *vc_fac_mask |= X25_MASK_CALLING_AE;
+ break;
+ case X25_FAC_CALLED_AE:
+ if (p[1] > 33)
+ break;
+ dte_facs->called_len = p[2];
+ memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
+ *vc_fac_mask |= X25_MASK_CALLED_AE;
+ break;
+ default:
+ printk(KERN_DEBUG "X.25: unknown facility %02X,"
+ "length %d, values %02X, %02X, %02X, %02X\n",
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+ break;
+ }
+
len -= p[1] + 2;
p += p[1] + 2;
break;
@@ -129,6 +161,7 @@ int x25_parse_facilities(struct sk_buff
*/
int x25_create_facilities(unsigned char *buffer,
struct x25_facilities *facilities,
+ struct x25_dte_facilities *dte_facs,
unsigned long facil_mask)
{
unsigned char *p = buffer + 1;
@@ -168,6 +201,34 @@ int x25_create_facilities(unsigned char
*p++ = facilities->winsize_out ? : facilities->winsize_in;
}

+ if ((facil_mask & X25_MASK_CALLING_AE) ||
+ (facil_mask & X25_MASK_CALLED_AE)) {
+ *p++ = X25_MARKER;
+ *p++ = X25_DTE_SERVICES;
+ }
+
+ if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) {
+ unsigned bytecount = (dte_facs->calling_len % 2) ?
+ dte_facs->calling_len / 2 + 1 :
+ dte_facs->calling_len / 2;
+ *p++ = X25_FAC_CALLING_AE;
+ *p++ = 1 + bytecount;
+ *p++ = dte_facs->calling_len;
+ memcpy(p, dte_facs->calling_ae, bytecount);
+ p+=bytecount;
+ }
+
+ if (dte_facs->called_len && (facil_mask & X25_MASK_CALLED_AE)) {
+ unsigned bytecount = (dte_facs->called_len % 2) ?
+ dte_facs->called_len / 2 + 1 :
+ dte_facs->called_len / 2;
+ *p++ = X25_FAC_CALLED_AE;
+ *p++ = 1 + bytecount;
+ *p++ = dte_facs->called_len;
+ memcpy(p, dte_facs->called_ae, bytecount);
+ p+=bytecount;
+ }
+
len = p - buffer;
buffer[0] = len - 1;

@@ -180,7 +241,8 @@ int x25_create_facilities(unsigned char
* The only real problem is with reverse charging.
*/
int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
- struct x25_facilities *new)
+ struct x25_facilities *new,
+ struct x25_dte_facilities *dte)
{
struct x25_sock *x25 = x25_sk(sk);
struct x25_facilities *ours = &x25->facilities;
@@ -190,7 +252,7 @@ int x25_negotiate_facilities(struct sk_b
memset(&theirs, 0, sizeof(theirs));
memcpy(new, ours, sizeof(*new));

- len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask);
+ len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);

/*
* They want reverse charging, we won't accept it.
diff -uprN -X dontdiff linux-2.6.13.4-vanilla/net/x25/x25_in.c linux-2.6.13.4/net/x25/x25_in.c
--- linux-2.6.13.4-vanilla/net/x25/x25_in.c 2005-10-11 04:54:29.000000000 +1000
+++ linux-2.6.13.4/net/x25/x25_in.c 2005-10-17 10:38:22.000000000 +1000
@@ -106,6 +106,7 @@ static int x25_state1_machine(struct soc
skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
skb_pull(skb,
x25_parse_facilities(skb, &x25->facilities,
+ &x25->dte_facilities,
&x25->vc_facil_mask));
/*
* Copy any Call User Data.
diff -uprN -X dontdiff linux-2.6.13.4-vanilla/net/x25/x25_subr.c linux-2.6.13.4/net/x25/x25_subr.c
--- linux-2.6.13.4-vanilla/net/x25/x25_subr.c 2005-10-11 04:54:29.000000000 +1000
+++ linux-2.6.13.4/net/x25/x25_subr.c 2005-10-17 10:38:22.000000000 +1000
@@ -191,6 +191,7 @@ void x25_write_internal(struct sock *sk,
memcpy(dptr, addresses, len);
len = x25_create_facilities(facilities,
&x25->facilities,
+ &x25->dte_facilities,
x25->neighbour->global_facil_mask);
dptr = skb_put(skb, len);
memcpy(dptr, facilities, len);
@@ -206,6 +207,7 @@ void x25_write_internal(struct sock *sk,
*dptr++ = 0x00; /* Address lengths */
len = x25_create_facilities(facilities,
&x25->facilities,
+ &x25->dte_facilities,
x25->vc_facil_mask);
dptr = skb_put(skb, len);
memcpy(dptr, facilities, len);
Binary files linux-2.6.13.4-vanilla/scripts/genksyms/genksyms and linux-2.6.13.4/scripts/genksyms/genksyms differ




On Mon, 2005-10-17 at 12:28, Arnaldo Carvalho de Melo wrote:
> Em Mon, Oct 17, 2005 at 11:47:46AM +1000, Andrew Hendry escreveu:
> > Non line wrapped version..
> > Adds options for ITU DTE facilities to x.25, called address extension and
> > calling address extension.
> >
> > Signed-off-by: Andrew Hendry <ahendry@xxxxxxxxxxx>
>
> Some comments below, please fix them and I'll queue it up in my net-2.6.15
> git tree if Henner hasn't any problems with this, but I don't remember him
> being active maintaining X.25 for quite a while :-)
>
> Ah, and please post networking patches to the netdev@xxxxxxxxxxxxxxx in
> the future.
>
> Thanks,
>
> - Arnaldo
>
> > diff -uprN -X dontdiff linux-2.6.13.4-vanilla/include/linux/x25.h linux-2.6.13.4/include/linux/x25.h
> > --- linux-2.6.13.4-vanilla/include/linux/x25.h 2005-09-17 11:02:12.000000000 +1000
> > +++ linux-2.6.13.4/include/linux/x25.h 2005-09-26 13:44:39.000000000 +1000
> > @@ -21,6 +21,8 @@
> > #define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7)
> > #define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8)
> > #define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9)
> > +#define SIOCX25GDTEFACILITIES (SIOCPROTOPRIVATE + 10)
> > +#define SIOCX25SDTEFACILITIES (SIOCPROTOPRIVATE + 11)
> >
> > /*
> > * Values for {get,set}sockopt.
> > @@ -77,6 +79,8 @@ struct x25_subscrip_struct {
> > #define X25_MASK_PACKET_SIZE 0x04
> > #define X25_MASK_WINDOW_SIZE 0x08
> >
> > +#define X25_MASK_CALLING_AE 0x10
> > +#define X25_MASK_CALLED_AE 0x20
> >
> >
> > /*
> > @@ -98,6 +102,24 @@ struct x25_facilities {
> > unsigned int reverse;
> > };
> >
> > +/*
> > +* ITU DTE facilities
> > +* Only the called and calling address
> > +* extension are currently implemented.
> > +* The rest are in place to avoid the struct
> > +* changing size if someone needs them later
> > ++ */
> > +struct x25_dte_facilities {
> > + unsigned int calling_len, called_len;
> > + char calling_ae[20];
> > + char called_ae[20];
> > + unsigned char min_throughput;
> > + unsigned short delay_cumul;
> > + unsigned short delay_target;
> > + unsigned short delay_max;
> > + unsigned char expedited;
> > +};
> > +
> > /*
> > * Call User Data structure.
> > */
> > diff -uprN -X dontdiff linux-2.6.13.4-vanilla/include/net/x25.h linux-2.6.13.4/include/net/x25.h
> > --- linux-2.6.13.4-vanilla/include/net/x25.h 2005-09-17 11:02:12.000000000 +1000
> > +++ linux-2.6.13.4/include/net/x25.h 2005-09-26 13:44:39.000000000 +1000
> > @@ -101,9 +101,19 @@ enum {
> > #define X25_FAC_PACKET_SIZE 0x42
> > #define X25_FAC_WINDOW_SIZE 0x43
> >
> > -#define X25_MAX_FAC_LEN 20 /* Plenty to spare */
> > +#define X25_MAX_FAC_LEN 60
>
> X25_MAX_FAC_LEN defined here and...
>
> > #define X25_MAX_CUD_LEN 128
> >
> > +#define X25_FAC_CALLING_AE 0xCB
> > +#define X25_FAC_CALLED_AE 0xC9
> > +
> > +#define X25_MAX_FAC_LEN 60
>
> ...here
>
> > +#define X25_MARKER 0x00
> > +#define X25_DTE_SERVICES 0x0F
> > +#define X25_MAX_AE_LEN 32
> > +
> > +
> > /**
> > * struct x25_route - x25 routing entry
> > * @node - entry in x25_list_lock
> > @@ -148,6 +158,7 @@ struct x25_sock {
> > struct timer_list timer;
> > struct x25_causediag causediag;
> > struct x25_facilities facilities;
> > + struct x25_dte_facilities dte_facilities;
> > struct x25_calluserdata calluserdata;
> > unsigned long vc_facil_mask; /* inc_call facilities mask */
> > };
> > @@ -180,9 +191,9 @@ extern void x25_establish_link(struct x2
> > extern void x25_terminate_link(struct x25_neigh *);
> >
> > /* x25_facilities.c */
> > -extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, unsigned long *);
> > -extern int x25_create_facilities(unsigned char *, struct x25_facilities *, unsigned long);
> > -extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *);
> > +extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, struct x25_dte_facilities *, unsigned long *);
> > +extern int x25_create_facilities(unsigned char *, struct x25_facilities *, struct x25_dte_facilities *, unsigned long);
> > +extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *, struct x25_dte_facilities *);
> > extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *);
> >
> > /* x25_in.c */
> > diff -uprN -X dontdiff linux-2.6.13.4-vanilla/net/x25/af_x25.c linux-2.6.13.4/net/x25/af_x25.c
> > --- linux-2.6.13.4-vanilla/net/x25/af_x25.c 2005-09-17 11:02:12.000000000 +1000
> > +++ linux-2.6.13.4/net/x25/af_x25.c 2005-09-26 13:52:55.000000000 +1000
> > @@ -513,6 +513,11 @@ static int x25_create(struct socket *soc
> > x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
> > x25->facilities.throughput = X25_DEFAULT_THROUGHPUT;
> > x25->facilities.reverse = X25_DEFAULT_REVERSE;
> > + x25->dte_facilities.calling_len = 0;
> > + x25->dte_facilities.called_len = 0;
> > + memset(x25->dte_facilities.called_ae,'\0',X25_MAX_AE_LEN);
> > + memset(x25->dte_facilities.calling_ae,'\0',X25_MAX_AE_LEN);
>
> spaces after commas please, and called_ae and calling_ae are 20 bytes,
> X25_MAX_AE_LEN is 32, I suggest you use
> sizeof(x25->dte_facilities.called_ae) instead of X25_MAX_AE_LEN
>
> > rc = 0;
> > out:
> > return rc;
> > @@ -554,6 +559,7 @@ static struct sock *x25_make_new(struct
> > x25->t2 = ox25->t2;
> > x25->facilities = ox25->facilities;
> > x25->qbitincl = ox25->qbitincl;
> > + x25->dte_facilities = ox25->dte_facilities;
> > x25->cudmatchlength = ox25->cudmatchlength;
> > x25->accptapprv = ox25->accptapprv;
> >
> > @@ -833,6 +839,7 @@ int x25_rx_call_request(struct sk_buff *
> > struct x25_sock *makex25;
> > struct x25_address source_addr, dest_addr;
> > struct x25_facilities facilities;
> > + struct x25_dte_facilities dte_facilities;
> > int len, rc;
> >
> > /*
> > @@ -869,7 +876,8 @@ int x25_rx_call_request(struct sk_buff *
> > /*
> > * Try to reach a compromise on the requested facilities.
> > */
> > - if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1)
> > + if ((len = x25_negotiate_facilities(skb, sk, &facilities,
> > + &dte_facilities)) == -1)
> > goto out_sock_put;
> >
> > /*
> > @@ -900,9 +908,12 @@ int x25_rx_call_request(struct sk_buff *
> > makex25->source_addr = source_addr;
> > makex25->neighbour = nb;
> > makex25->facilities = facilities;
> > + makex25->dte_facilities= dte_facilities;
> > makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
> > /* ensure no reverse facil on accept */
> > makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
> > + /* ensure no calling address extension on accept */
> > + makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE;
> > makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;
> >
> > /* Normally all calls are accepted immediatly */
> > @@ -1309,6 +1320,35 @@ static int x25_ioctl(struct socket *sock
> > break;
> > }
> >
> > + case SIOCX25GDTEFACILITIES: {
> > + struct x25_dte_facilities dtefacs = x25->dte_facilities;
> > + rc = copy_to_user(argp, &dtefacs,
> > + sizeof(dtefacs)) ? -EFAULT :0;
>
> why not:
>
> copy_to_user(argp, x25->dte_facilities, sizeof(*x25->dte_facilities))
>
> avoiding the extra struct copy to the stack?
>
> > + break;
> > + }
> > + case SIOCX25SDTEFACILITIES: {
> > + struct x25_dte_facilities dtefacs;
> > + rc = -EFAULT;
> > + if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
> > + break;
> > + rc = -EINVAL;
> > + if (sk->sk_state != TCP_LISTEN &&
> > + sk->sk_state != TCP_CLOSE)
> > + break;
> > + if (dtefacs.calling_len > X25_MAX_AE_LEN)
> > + break;
> > + if (dtefacs.calling_ae == NULL)
> > + break;
> > + if (dtefacs.called_len > X25_MAX_AE_LEN)
> > + break;
> > + if (dtefacs.called_ae == NULL)
> > + break;
> > + x25->dte_facilities = dtefacs;
> > + rc = 0;
> > + break;
> > + }
> > +
> > case SIOCX25GCALLUSERDATA: {
> > struct x25_calluserdata cud = x25->calluserdata;
> > rc = copy_to_user(argp, &cud,
> > diff -uprN -X dontdiff linux-2.6.13.4-vanilla/net/x25/x25_facilities.c linux-2.6.13.4/net/x25/x25_facilities.c
> > --- linux-2.6.13.4-vanilla/net/x25/x25_facilities.c 2005-09-17 11:02:12.000000000 +1000
> > +++ linux-2.6.13.4/net/x25/x25_facilities.c 2005-09-26 13:44:39.000000000 +1000
> > @@ -28,11 +28,12 @@
> > #include <net/x25.h>
> >
> > /*
> > - * Parse a set of facilities into the facilities structure. Unrecognised
> > + * Parse a set of facilities into the facilities structures. Unrecognised
> > * facilities are written to the debug log file.
> > */
> > int x25_parse_facilities(struct sk_buff *skb,
> > struct x25_facilities *facilities,
> > + struct x25_dte_facilities *dte_facs,
> > unsigned long *vc_fac_mask)
> > {
> > unsigned char *p = skb->data;
> > @@ -40,6 +41,16 @@ int x25_parse_facilities(struct sk_buff
> >
> > *vc_fac_mask = 0;
> >
> > + /* The kernel knows which facilities were set on an incoming call
> > + * but currently its not available to userspace.
> > + * Here we give userspace who read incoming call facilities
> > + * 0 length to indicate it wasn't set.
> > + */
> > + dte_facs->calling_len = 0;
> > + dte_facs->called_len = 0;
> > + memset(dte_facs->called_ae,'\0',X25_MAX_AE_LEN);
> > + memset(dte_facs->calling_ae,'\0',X25_MAX_AE_LEN);
>
> Ditto, 20 versus 32
>
> > while (len > 0) {
> > switch (*p & X25_FAC_CLASS_MASK) {
> > case X25_FAC_CLASS_A:
> > @@ -74,6 +85,8 @@ int x25_parse_facilities(struct sk_buff
> > facilities->throughput = p[1];
> > *vc_fac_mask |= X25_MASK_THROUGHPUT;
> > break;
> > + case X25_MARKER:
> > + break;
> > default:
> > printk(KERN_DEBUG "X.25: unknown facility "
> > "%02X, value %02X\n",
> > @@ -112,9 +125,28 @@ int x25_parse_facilities(struct sk_buff
> > len -= 4;
> > break;
> > case X25_FAC_CLASS_D:
> > - printk(KERN_DEBUG "X.25: unknown facility %02X, "
> > - "length %d, values %02X, %02X, %02X, %02X\n",
> > - p[0], p[1], p[2], p[3], p[4], p[5]);
> > + switch (*p) {
> > + case X25_FAC_CALLING_AE:
> > + if (p[1] > 33)
> > + break;
> > + dte_facs->calling_len = p[2];
> > + memcpy(dte_facs->calling_ae,&p[3],p[1]-1);
> > + *vc_fac_mask |= X25_MASK_CALLING_AE;
> > + break;
> > + case X25_FAC_CALLED_AE:
> > + if (p[1] > 33)
> > + break;
> > + dte_facs->called_len = p[2];
> > + memcpy(dte_facs->called_ae,&p[3],p[1]-1);
> > + *vc_fac_mask |= X25_MASK_CALLED_AE;
> > + break;
> > + default:
> > + printk(KERN_DEBUG "X.25: unknown facility %02X,"
> > + "length %d, values %02X, %02X, %02X, %02X\n",
> > + p[0], p[1], p[2], p[3], p[4], p[5]);
> > + break;
> > + }
> > +
> > len -= p[1] + 2;
> > p += p[1] + 2;
> > break;
> > @@ -129,6 +161,7 @@ int x25_parse_facilities(struct sk_buff
> > */
> > int x25_create_facilities(unsigned char *buffer,
> > struct x25_facilities *facilities,
> > + struct x25_dte_facilities *dte_facs,
> > unsigned long facil_mask)
> > {
> > unsigned char *p = buffer + 1;
> > @@ -168,6 +201,32 @@ int x25_create_facilities(unsigned char
> > *p++ = facilities->winsize_out ? : facilities->winsize_in;
> > }
> >
> > + if ((facil_mask & X25_MASK_CALLING_AE) ||
> > + (facil_mask & X25_MASK_CALLED_AE)) {
> > + *p++ = X25_MARKER;
> > + *p++ = X25_DTE_SERVICES;
> > + }
> > +
> > + if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) {
> > + unsigned bytecount = (dte_facs->calling_len % 2) ?
> > + dte_facs->calling_len/2+1 : dte_facs->calling_len/2;
>
> Spaces after operators such as '/' please
>
> > + *p++ = X25_FAC_CALLING_AE;
> > + *p++ = 1 + bytecount;
> > + *p++ = dte_facs->calling_len;
> > + memcpy(p,dte_facs->calling_ae,bytecount);
> > + p+=bytecount;
> > + }
>
> Ditto
>
> > + if (dte_facs->called_len && (facil_mask & X25_MASK_CALLED_AE)) {
> > + unsigned bytecount = (dte_facs->called_len % 2) ?
> > + dte_facs->called_len/2+1 : dte_facs->called_len/2;
> > + *p++ = X25_FAC_CALLED_AE;
> > + *p++ = 1 + bytecount;
> > + *p++ = dte_facs->called_len;
> > + memcpy(p,dte_facs->called_ae,bytecount);
> > + p+=bytecount;
> > + }
> > +
> > len = p - buffer;
> > buffer[0] = len - 1;
> >
> > @@ -180,7 +239,8 @@ int x25_create_facilities(unsigned char
> > * The only real problem is with reverse charging.
> > */
> > int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
> > - struct x25_facilities *new)
> > + struct x25_facilities *new,
> > + struct x25_dte_facilities *dte)
> > {
> > struct x25_sock *x25 = x25_sk(sk);
> > struct x25_facilities *ours = &x25->facilities;
> > @@ -190,7 +250,7 @@ int x25_negotiate_facilities(struct sk_b
> > memset(&theirs, 0, sizeof(theirs));
> > memcpy(new, ours, sizeof(*new));
> >
> > - len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask);
> > + len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
> >
> > /*
> > * They want reverse charging, we won't accept it.
> > diff -uprN -X dontdiff linux-2.6.13.4-vanilla/net/x25/x25_in.c linux-2.6.13.4/net/x25/x25_in.c
> > --- linux-2.6.13.4-vanilla/net/x25/x25_in.c 2005-09-17 11:02:12.000000000 +1000
> > +++ linux-2.6.13.4/net/x25/x25_in.c 2005-09-26 13:44:39.000000000 +1000
> > @@ -106,6 +106,7 @@ static int x25_state1_machine(struct soc
> > skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
> > skb_pull(skb,
> > x25_parse_facilities(skb, &x25->facilities,
> > + &x25->dte_facilities,
> > &x25->vc_facil_mask));
> > /*
> > * Copy any Call User Data.
> > diff -uprN -X dontdiff linux-2.6.13.4-vanilla/net/x25/x25_subr.c linux-2.6.13.4/net/x25/x25_subr.c
> > --- linux-2.6.13.4-vanilla/net/x25/x25_subr.c 2005-09-17 11:02:12.000000000 +1000
> > +++ linux-2.6.13.4/net/x25/x25_subr.c 2005-09-26 13:44:39.000000000 +1000
> > @@ -191,6 +191,7 @@ void x25_write_internal(struct sock *sk,
> > memcpy(dptr, addresses, len);
> > len = x25_create_facilities(facilities,
> > &x25->facilities,
> > + &x25->dte_facilities,
> > x25->neighbour->global_facil_mask);
> > dptr = skb_put(skb, len);
> > memcpy(dptr, facilities, len);
> > @@ -206,6 +207,7 @@ void x25_write_internal(struct sock *sk,
> > *dptr++ = 0x00; /* Address lengths */
> > len = x25_create_facilities(facilities,
> > &x25->facilities,
> > + &x25->dte_facilities,
> > x25->vc_facil_mask);
> > dptr = skb_put(skb, len);
> > memcpy(dptr, facilities, len);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/