Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 22663
b: refs/heads/master
c: a64b7b9
h: refs/heads/master
i:
  22661: c5b222b
  22659: 5355e98
  22655: b123095
v: v3
  • Loading branch information
Shaun Pereira authored and David S. Miller committed Mar 22, 2006
1 parent 2187c8a commit 0be0847
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bac37ec8300389d355d41a828b47577c1ec2e4f4
refs/heads/master: a64b7b936dcd926ace745c07c14f45ecfaddb034
26 changes: 26 additions & 0 deletions trunk/include/linux/x25.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#ifndef X25_KERNEL_H
#define X25_KERNEL_H

#include <linux/types.h>

#define SIOCX25GSUBSCRIP (SIOCPROTOPRIVATE + 0)
#define SIOCX25SSUBSCRIP (SIOCPROTOPRIVATE + 1)
#define SIOCX25GFACILITIES (SIOCPROTOPRIVATE + 2)
Expand All @@ -21,6 +23,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.
Expand Down Expand Up @@ -77,6 +81,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


/*
Expand All @@ -98,6 +104,26 @@ 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 {
__u16 delay_cumul;
__u16 delay_target;
__u16 delay_max;
__u8 min_throughput;
__u8 expedited;
__u8 calling_len;
__u8 called_len;
__u8 calling_ae[20];
__u8 called_ae[20];
};

/*
* Call User Data structure.
*/
Expand Down
21 changes: 17 additions & 4 deletions trunk/include/net/x25.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,17 @@ 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 40 /* Max num of semi-octets in AE - OSI Nw */
#define X25_MAX_DTE_FACIL_LEN 21 /* Max length of DTE facility params */

/**
* struct x25_route - x25 routing entry
* @node - entry in x25_list_lock
Expand Down Expand Up @@ -148,6 +156,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 */
};
Expand Down Expand Up @@ -180,9 +189,13 @@ extern void x25_establish_link(struct x25_neigh *);
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 */
Expand Down
45 changes: 44 additions & 1 deletion trunk/net/x25/af_x25.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,13 @@ static int x25_create(struct socket *sock, int protocol)
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;
Expand Down Expand Up @@ -561,6 +568,7 @@ static struct sock *x25_make_new(struct sock *osk)
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;

Expand Down Expand Up @@ -840,6 +848,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
struct x25_sock *makex25;
struct x25_address source_addr, dest_addr;
struct x25_facilities facilities;
struct x25_dte_facilities dte_facilities;
int len, rc;

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

/*
Expand Down Expand Up @@ -907,9 +917,12 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
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 */
Expand Down Expand Up @@ -1316,6 +1329,36 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
break;
}

case SIOCX25GDTEFACILITIES: {
rc = copy_to_user(argp, &x25->dte_facilities,
sizeof(x25->dte_facilities));
if (rc)
rc = -EFAULT;
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,
Expand Down
82 changes: 70 additions & 12 deletions trunk/net/x25/x25_facilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,28 @@
#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,
unsigned long *vc_fac_mask)
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;
unsigned int len = *p++;

*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:
Expand Down Expand Up @@ -74,6 +84,8 @@ int x25_parse_facilities(struct sk_buff *skb,
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",
Expand Down Expand Up @@ -112,11 +124,30 @@ int x25_parse_facilities(struct sk_buff *skb,
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] > X25_MAX_DTE_FACIL_LEN)
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] > X25_MAX_DTE_FACIL_LEN)
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;
p += p[1] + 2;
break;
}
}
Expand All @@ -128,8 +159,8 @@ int x25_parse_facilities(struct sk_buff *skb,
* Create a set of facilities.
*/
int x25_create_facilities(unsigned char *buffer,
struct x25_facilities *facilities,
unsigned long facil_mask)
struct x25_facilities *facilities,
struct x25_dte_facilities *dte_facs, unsigned long facil_mask)
{
unsigned char *p = buffer + 1;
int len;
Expand Down Expand Up @@ -168,6 +199,33 @@ int x25_create_facilities(unsigned char *buffer,
*p++ = facilities->winsize_out ? : facilities->winsize_in;
}

if (facil_mask & (X25_MASK_CALLING_AE|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;

Expand All @@ -180,7 +238,7 @@ int x25_create_facilities(unsigned char *buffer,
* 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;
Expand All @@ -190,7 +248,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
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.
Expand Down
3 changes: 2 additions & 1 deletion trunk/net/x25/x25_in.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
skb_pull(skb,
x25_parse_facilities(skb, &x25->facilities,
&x25->vc_facil_mask));
&x25->dte_facilities,
&x25->vc_facil_mask));
/*
* Copy any Call User Data.
*/
Expand Down
6 changes: 4 additions & 2 deletions trunk/net/x25/x25_subr.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,9 @@ void x25_write_internal(struct sock *sk, int frametype)
dptr = skb_put(skb, len);
memcpy(dptr, addresses, len);
len = x25_create_facilities(facilities,
&x25->facilities,
x25->neighbour->global_facil_mask);
&x25->facilities,
&x25->dte_facilities,
x25->neighbour->global_facil_mask);
dptr = skb_put(skb, len);
memcpy(dptr, facilities, len);
dptr = skb_put(skb, x25->calluserdata.cudlength);
Expand All @@ -206,6 +207,7 @@ void x25_write_internal(struct sock *sk, int frametype)
*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);
Expand Down

0 comments on commit 0be0847

Please sign in to comment.