~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/x25/x25_facilities.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      X.25 Packet Layer release 002
  3  *
  4  *      This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  5  *      releases, misbehave and/or generally screw up. It might even work. 
  6  *
  7  *      This code REQUIRES 2.1.15 or higher
  8  *
  9  *      This module:
 10  *              This module is free software; you can redistribute it and/or
 11  *              modify it under the terms of the GNU General Public License
 12  *              as published by the Free Software Foundation; either version
 13  *              2 of the License, or (at your option) any later version.
 14  *
 15  *      History
 16  *      X.25 001        Split from x25_subr.c
 17  *      mar/20/00       Daniela Squassoni Disabling/enabling of facilities 
 18  *                                        negotiation.
 19  */
 20 
 21 #include <linux/config.h>
 22 #if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
 23 #include <linux/errno.h>
 24 #include <linux/types.h>
 25 #include <linux/socket.h>
 26 #include <linux/in.h>
 27 #include <linux/kernel.h>
 28 #include <linux/sched.h>
 29 #include <linux/timer.h>
 30 #include <linux/string.h>
 31 #include <linux/sockios.h>
 32 #include <linux/net.h>
 33 #include <linux/inet.h>
 34 #include <linux/netdevice.h>
 35 #include <linux/skbuff.h>
 36 #include <net/sock.h>
 37 #include <asm/segment.h>
 38 #include <asm/system.h>
 39 #include <linux/fcntl.h>
 40 #include <linux/mm.h>
 41 #include <linux/interrupt.h>
 42 #include <net/x25.h>
 43 
 44 /*
 45  *      Parse a set of facilities into the facilities structure. Unrecognised
 46  *      facilities are written to the debug log file.
 47  */
 48 int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, unsigned long *vc_fac_mask)
 49 {
 50         unsigned int len;
 51         unsigned char *p = skb->data;
 52 
 53         len = *p++;
 54         *vc_fac_mask = 0;
 55 
 56         while (len > 0) {
 57                 switch (*p & X25_FAC_CLASS_MASK) {
 58                         case X25_FAC_CLASS_A:
 59                                 switch (*p) {
 60                                         case X25_FAC_REVERSE:
 61                                                 facilities->reverse = (p[1] & 0x01);
 62                                                 *vc_fac_mask |= X25_MASK_REVERSE;
 63                                                 break;
 64                                         case X25_FAC_THROUGHPUT:
 65                                                 facilities->throughput = p[1];
 66                                                 *vc_fac_mask |= X25_MASK_THROUGHPUT;
 67                                                 break;
 68                                         default:
 69                                                 printk(KERN_DEBUG "X.25: unknown facility %02X, value %02X\n", p[0], p[1]);
 70                                                 break;
 71                                 }
 72                                 p   += 2;
 73                                 len -= 2;
 74                                 break;
 75 
 76                         case X25_FAC_CLASS_B:
 77                                 switch (*p) {
 78                                         case X25_FAC_PACKET_SIZE:
 79                                                 facilities->pacsize_in  = p[1];
 80                                                 facilities->pacsize_out = p[2];
 81                                                 *vc_fac_mask |= X25_MASK_PACKET_SIZE;
 82                                                 break;
 83                                         case X25_FAC_WINDOW_SIZE:
 84                                                 facilities->winsize_in  = p[1];
 85                                                 facilities->winsize_out = p[2];
 86                                                 *vc_fac_mask |= X25_MASK_WINDOW_SIZE;
 87                                                 break;
 88                                         default:
 89                                                 printk(KERN_DEBUG "X.25: unknown facility %02X, values %02X, %02X\n", p[0], p[1], p[2]);
 90                                                 break;
 91                                 }
 92                                 p   += 3;
 93                                 len -= 3;
 94                                 break;
 95 
 96                         case X25_FAC_CLASS_C:
 97                                 printk(KERN_DEBUG "X.25: unknown facility %02X, values %02X, %02X, %02X\n", p[0], p[1], p[2], p[3]);
 98                                 p   += 4;
 99                                 len -= 4;
100                                 break;
101 
102                         case X25_FAC_CLASS_D:
103                                 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]);
104                                 p   += p[1] + 2;
105                                 len -= p[1] + 2;
106                                 break;
107                 }
108         }
109 
110         return p - skb->data;
111 }
112 
113 /*
114  *      Create a set of facilities.
115  */
116 int x25_create_facilities(unsigned char *buffer, struct x25_facilities *facilities, unsigned long facil_mask)
117 {
118         unsigned char *p = buffer + 1;
119         int len;
120 
121         if (facil_mask == 0) {
122                 buffer [0] = 0; /* length of the facilities field in call_req or call_accept packets */
123                 len = 1; /* 1 byte for the length field */
124                 return len;
125         }
126 
127         if ((facilities->reverse != 0) && (facil_mask & X25_MASK_REVERSE)) {
128                 *p++ = X25_FAC_REVERSE;
129                 *p++ = (facilities->reverse) ? 0x01 : 0x00;
130         }
131 
132         if ((facilities->throughput != 0) && (facil_mask & X25_MASK_THROUGHPUT)) {
133                 *p++ = X25_FAC_THROUGHPUT;
134                 *p++ = facilities->throughput;
135         }
136 
137         if ((facilities->pacsize_in != 0 || facilities->pacsize_out != 0) && (facil_mask & X25_MASK_PACKET_SIZE)) {
138                 *p++ = X25_FAC_PACKET_SIZE;
139                 *p++ = (facilities->pacsize_in  == 0) ? facilities->pacsize_out : facilities->pacsize_in;
140                 *p++ = (facilities->pacsize_out == 0) ? facilities->pacsize_in  : facilities->pacsize_out;
141         }
142 
143         if ((facilities->winsize_in != 0 || facilities->winsize_out != 0) && (facil_mask & X25_MASK_WINDOW_SIZE)) {
144                 *p++ = X25_FAC_WINDOW_SIZE;
145                 *p++ = (facilities->winsize_in  == 0) ? facilities->winsize_out : facilities->winsize_in;
146                 *p++ = (facilities->winsize_out == 0) ? facilities->winsize_in  : facilities->winsize_out;
147         }
148 
149         len       = p - buffer;
150         buffer[0] = len - 1;
151 
152         return len;
153 }
154 
155 /*
156  *      Try to reach a compromise on a set of facilities.
157  *
158  *      The only real problem is with reverse charging.
159  */
160 int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, struct x25_facilities *new)
161 {
162         struct x25_facilities *ours;
163         struct x25_facilities theirs;
164         int len;
165 
166         memset(&theirs, 0x00, sizeof(struct x25_facilities));
167 
168         ours = &sk->protinfo.x25->facilities;
169 
170         *new = *ours;
171 
172         len = x25_parse_facilities(skb, &theirs, &sk->protinfo.x25->vc_facil_mask);
173 
174         /*
175          *      They want reverse charging, we won't accept it.
176          */
177         if (theirs.reverse != 0 && ours->reverse == 0) {
178                 SOCK_DEBUG(sk, "X.25: rejecting reverse charging request");
179                 return -1;
180         }
181 
182         new->reverse = theirs.reverse;
183 
184         if (theirs.throughput != 0) {
185                 if (theirs.throughput < ours->throughput) {
186                         SOCK_DEBUG(sk, "X.25: throughput negotiated down");
187                         new->throughput = theirs.throughput;
188                 }
189         }
190 
191         if (theirs.pacsize_in != 0 && theirs.pacsize_out != 0) {
192                 if (theirs.pacsize_in < ours->pacsize_in) {
193                         SOCK_DEBUG(sk, "X.25: packet size inwards negotiated down");
194                         new->pacsize_in = theirs.pacsize_in;
195                 }
196                 if (theirs.pacsize_out < ours->pacsize_out) {
197                         SOCK_DEBUG(sk, "X.25: packet size outwards negotiated down");
198                         new->pacsize_out = theirs.pacsize_out;
199                 }
200         }
201 
202         if (theirs.winsize_in != 0 && theirs.winsize_out != 0) {
203                 if (theirs.winsize_in < ours->winsize_in) {
204                         SOCK_DEBUG(sk, "X.25: window size inwards negotiated down");
205                         new->winsize_in = theirs.winsize_in;
206                 }
207                 if (theirs.winsize_out < ours->winsize_out) {
208                         SOCK_DEBUG(sk, "X.25: window size outwards negotiated down");
209                         new->winsize_out = theirs.winsize_out;
210                 }
211         }
212 
213         return len;
214 }
215 
216 /*
217  *      Limit values of certain facilities according to the capability of the 
218  *      currently attached x25 link.
219  */
220 void x25_limit_facilities(struct x25_facilities *facilities,
221                           struct x25_neigh *neighbour)
222 {
223 
224         if( ! neighbour->extended ){
225                 if( facilities->winsize_in  > 7 ){
226                         printk(KERN_DEBUG "X.25: incoming winsize limited to 7\n");
227                         facilities->winsize_in = 7;
228                 }
229                 if( facilities->winsize_out > 7 ){
230                         facilities->winsize_out = 7;
231                         printk( KERN_DEBUG "X.25: outgoing winsize limited to 7\n");
232                 }
233         }
234 }
235 
236 #endif
237 
238 
239 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.