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

Linux Cross Reference
Linux/net/decnet/dn_nsp_out.c

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

  1 
  2 /*
  3  * DECnet       An implementation of the DECnet protocol suite for the LINUX
  4  *              operating system.  DECnet is implemented using the  BSD Socket
  5  *              interface as the means of communication with the user level.
  6  *
  7  *              DECnet Network Services Protocol (Output)
  8  *
  9  * Author:      Eduardo Marcelo Serrat <emserrat@geocities.com>
 10  *
 11  * Changes:
 12  *
 13  *    Steve Whitehouse:  Split into dn_nsp_in.c and dn_nsp_out.c from
 14  *                       original dn_nsp.c.
 15  *    Steve Whitehouse:  Updated to work with my new routing architecture.
 16  *    Steve Whitehouse:  Added changes from Eduardo Serrat's patches.
 17  *    Steve Whitehouse:  Now conninits have the "return" bit set.
 18  *    Steve Whitehouse:  Fixes to check alloc'd skbs are non NULL!
 19  *                       Moved output state machine into one function
 20  *    Steve Whitehouse:  New output state machine
 21  *         Paul Koning:  Connect Confirm message fix.
 22  *      Eduardo Serrat:  Fix to stop dn_nsp_do_disc() sending malformed packets.
 23  */
 24 
 25 /******************************************************************************
 26     (c) 1995-1998 E.M. Serrat           emserrat@geocities.com
 27     
 28     This program is free software; you can redistribute it and/or modify
 29     it under the terms of the GNU General Public License as published by
 30     the Free Software Foundation; either version 2 of the License, or
 31     any later version.
 32 
 33     This program is distributed in the hope that it will be useful,
 34     but WITHOUT ANY WARRANTY; without even the implied warranty of
 35     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 36     GNU General Public License for more details.
 37 *******************************************************************************/
 38 
 39 #include <linux/errno.h>
 40 #include <linux/types.h>
 41 #include <linux/socket.h>
 42 #include <linux/in.h>
 43 #include <linux/kernel.h>
 44 #include <linux/sched.h>
 45 #include <linux/timer.h>
 46 #include <linux/string.h>
 47 #include <linux/sockios.h>
 48 #include <linux/net.h>
 49 #include <linux/netdevice.h>
 50 #include <linux/inet.h>
 51 #include <linux/route.h>
 52 #include <net/sock.h>
 53 #include <asm/segment.h>
 54 #include <asm/system.h>
 55 #include <linux/fcntl.h>
 56 #include <linux/mm.h>
 57 #include <linux/termios.h>      
 58 #include <linux/interrupt.h>
 59 #include <linux/proc_fs.h>
 60 #include <linux/stat.h>
 61 #include <linux/init.h>
 62 #include <linux/poll.h>
 63 #include <linux/if_packet.h>
 64 #include <net/neighbour.h>
 65 #include <net/dst.h>
 66 #include <net/dn_nsp.h>
 67 #include <net/dn_dev.h>
 68 #include <net/dn_route.h>
 69 
 70 
 71 static int nsp_backoff[NSP_MAXRXTSHIFT + 1] = { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
 72 
 73 /*
 74  * If sk == NULL, then we assume that we are supposed to be making
 75  * a routing layer skb. If sk != NULL, then we are supposed to be
 76  * creating an skb for the NSP layer.
 77  *
 78  * The eventual aim is for each socket to have a cached header size
 79  * for its outgoing packets, and to set hdr from this when sk != NULL.
 80  */
 81 struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri)
 82 {
 83         struct sk_buff *skb;
 84         int hdr = 64;
 85 
 86         if ((skb = alloc_skb(size + hdr, pri)) == NULL)
 87                 return NULL;
 88 
 89         skb->protocol = __constant_htons(ETH_P_DNA_RT);
 90         skb->pkt_type = PACKET_OUTGOING;
 91 
 92         if (sk)
 93                 skb_set_owner_w(skb, sk);
 94 
 95         skb_reserve(skb, hdr);
 96 
 97         return skb;
 98 }
 99 
100 /*
101  * Wrapper for the above, for allocs of data skbs. We try and get the
102  * whole size thats been asked for (plus 11 bytes of header). If this
103  * fails, then we try for any size over 16 bytes for SOCK_STREAMS.
104  */
105 struct sk_buff *dn_alloc_send_skb(struct sock *sk, int *size, int noblock, int *err)
106 {
107         int space;
108         int len;
109         struct sk_buff *skb = NULL;
110 
111         *err = 0;
112 
113         while(skb == NULL) {
114                 if (signal_pending(current)) {
115                         *err = ERESTARTSYS;
116                         break;
117                 }
118 
119                 if (sk->shutdown & SEND_SHUTDOWN) {
120                         *err = EINVAL;
121                         break;
122                 }
123 
124                 if (sk->err)
125                         break;
126 
127                 len = *size + 11;
128                 space = sk->sndbuf - atomic_read(&sk->wmem_alloc);
129 
130                 if (space < len) {
131                         if ((sk->socket->type == SOCK_STREAM) && (space >= (16 + 11)))
132                                 len = space;
133                 }
134 
135                 if (space < len) {
136                         set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
137                         if (noblock) {
138                                 *err = EWOULDBLOCK;
139                                 break;
140                         }
141 
142                         clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
143                         SOCK_SLEEP_PRE(sk)
144 
145                         if ((sk->sndbuf - atomic_read(&sk->wmem_alloc)) < len)
146                                 schedule();
147 
148                         SOCK_SLEEP_POST(sk)
149                         continue;
150                 }
151 
152                 if ((skb = dn_alloc_skb(sk, len, sk->allocation)) == NULL)
153                         continue;
154 
155                 *size = len - 11;
156         }
157 
158         return skb;
159 }
160 
161 /*
162  * Calculate persist timer based upon the smoothed round
163  * trip time and the variance. Backoff according to the
164  * nsp_backoff[] array.
165  */
166 unsigned long dn_nsp_persist(struct sock *sk)
167 {
168         struct dn_scp *scp = &sk->protinfo.dn;
169 
170         unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1;
171 
172         t *= nsp_backoff[scp->nsp_rxtshift];
173 
174         if (t < HZ) t = HZ;
175         if (t > (600*HZ)) t = (600*HZ);
176 
177         if (scp->nsp_rxtshift < NSP_MAXRXTSHIFT)
178                 scp->nsp_rxtshift++;
179 
180         /* printk(KERN_DEBUG "rxtshift %lu, t=%lu\n", scp->nsp_rxtshift, t); */
181 
182         return t;
183 }
184 
185 /*
186  * This is called each time we get an estimate for the rtt
187  * on the link.
188  */
189 static void dn_nsp_rtt(struct sock *sk, long rtt)
190 {
191         struct dn_scp *scp = &sk->protinfo.dn;
192         long srtt = (long)scp->nsp_srtt;
193         long rttvar = (long)scp->nsp_rttvar;
194         long delta;
195 
196         /*
197          * If the jiffies clock flips over in the middle of timestamp
198          * gathering this value might turn out negative, so we make sure
199          * that is it always positive here.
200          */
201         if (rtt < 0) 
202                 rtt = -rtt;
203         /*
204          * Add new rtt to smoothed average
205          */
206         delta = ((rtt << 3) - srtt);
207         srtt += (delta >> 3);
208         if (srtt >= 1) 
209                 scp->nsp_srtt = (unsigned long)srtt;
210         else
211                 scp->nsp_srtt = 1;
212 
213         /*
214          * Add new rtt varience to smoothed varience
215          */
216         delta >>= 1;
217         rttvar += ((((delta>0)?(delta):(-delta)) - rttvar) >> 2);
218         if (rttvar >= 1) 
219                 scp->nsp_rttvar = (unsigned long)rttvar;
220         else
221                 scp->nsp_rttvar = 1;
222 
223         /* printk(KERN_DEBUG "srtt=%lu rttvar=%lu\n", scp->nsp_srtt, scp->nsp_rttvar); */
224 }
225 
226 /*
227  * Walk the queues, otherdata/linkservice first. Send as many
228  * frames as the window allows, increment send counts on all
229  * skbs which are sent. Reduce the window if we are retransmitting
230  * frames.
231  */
232 void dn_nsp_output(struct sock *sk)
233 {
234         struct dn_scp *scp = &sk->protinfo.dn;
235         unsigned long win = scp->snd_window;
236         struct sk_buff *skb, *skb2, *list;
237         struct dn_skb_cb *cb;
238         int reduce_win = 0;
239 
240         /* printk(KERN_DEBUG "dn_nsp_output: ping\n"); */
241 
242         /*
243          * First we check for otherdata/linkservice messages
244          */
245         skb = scp->other_xmit_queue.next;
246         list = (struct sk_buff *)&scp->other_xmit_queue;
247         while(win && (skb != list)) {
248                 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
249                         cb = (struct dn_skb_cb *)skb;
250                         if (cb->xmit_count > 0)
251                                 reduce_win = 1;
252                         else
253                                 cb->stamp = jiffies;
254                         cb->xmit_count++;
255                         skb2->sk = sk;
256                         dn_nsp_send(skb2);
257                 }
258                 skb = skb->next;
259                 win--;
260         }
261 
262         /*
263          * If we may not send any data, we don't.
264          * Should this apply to otherdata as well ? - SJW
265          */
266         if (scp->flowrem_sw != DN_SEND)
267                 goto recalc_window;
268 
269         skb = scp->data_xmit_queue.next;
270         list = (struct sk_buff *)&scp->data_xmit_queue;
271         while(win && (skb != list)) {
272                 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
273                         cb = (struct dn_skb_cb *)skb;
274                         if (cb->xmit_count > 0)
275                                 reduce_win = 1;
276                         else
277                                 cb->stamp = jiffies;
278                         cb->xmit_count++;
279                         skb2->sk = sk;
280                         dn_nsp_send(skb2);
281                 }
282                 skb = skb->next;
283                 win--;
284         }
285 
286         /*
287          * If we've sent any frame more than once, we cut the
288          * send window size in half. There is always a minimum
289          * window size of one available.
290          */
291 recalc_window:
292         if (reduce_win) {
293                 /* printk(KERN_DEBUG "Window reduction %ld\n", scp->snd_window); */
294                 scp->snd_window >>= 1;
295                 if (scp->snd_window < NSP_MIN_WINDOW)
296                         scp->snd_window = NSP_MIN_WINDOW;
297         }
298 }
299 
300 int dn_nsp_xmit_timeout(struct sock *sk)
301 {
302         struct dn_scp *scp = &sk->protinfo.dn;
303 
304         dn_nsp_output(sk);
305 
306         if (skb_queue_len(&scp->data_xmit_queue) || skb_queue_len(&scp->other_xmit_queue))
307                 scp->persist = dn_nsp_persist(sk);
308 
309         return 0;
310 }
311 
312 void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int oth)
313 {
314         struct dn_scp *scp = &sk->protinfo.dn;
315         struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
316         unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1;
317         struct sk_buff *skb2;
318 
319         if (t < HZ) t = HZ;
320         /*
321          * Slow start: If we have been idle for more than
322          * one RTT, then reset window to min size.
323          */
324         if ((jiffies - scp->stamp) > t)
325                 scp->snd_window = NSP_MIN_WINDOW;
326 
327         /* printk(KERN_DEBUG "Window: %lu\n", scp->snd_window); */
328 
329         cb->xmit_count = 0;
330 
331         if (oth)
332                 skb_queue_tail(&scp->other_xmit_queue, skb);
333         else
334                 skb_queue_tail(&scp->data_xmit_queue, skb);
335 
336         if (scp->flowrem_sw != DN_SEND)
337                 return;
338 
339         if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
340                 cb->stamp = jiffies;
341                 cb->xmit_count++;
342                 skb2->sk = sk;
343                 dn_nsp_send(skb2);
344         }
345 }
346 
347 int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum)
348 {
349         struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
350         struct dn_scp *scp = &sk->protinfo.dn;
351         struct sk_buff *skb2, *list, *ack = NULL;
352         int wakeup = 0;
353         unsigned long reftime = cb->stamp;
354         unsigned long pkttime;
355         unsigned short xmit_count;
356         unsigned short segnum;
357 
358         skb2 = q->next;
359         list = (struct sk_buff *)q;
360         while(list != skb2) {
361                 struct dn_skb_cb *cb2 = (struct dn_skb_cb *)skb2->cb;
362 
363                 if (before_or_equal(cb2->segnum, acknum))
364                         ack = skb2;
365 
366                 /* printk(KERN_DEBUG "ack: %s %04x %04x\n", ack ? "ACK" : "SKIP", (int)cb2->segnum, (int)acknum); */
367 
368                 skb2 = skb2->next;
369 
370                 if (ack == NULL)
371                         continue;
372 
373                 /* printk(KERN_DEBUG "check_xmit_queue: %04x, %d\n", acknum, cb2->xmit_count); */
374 
375                 wakeup = 1;
376                 pkttime = cb2->stamp;
377                 xmit_count = cb2->xmit_count;
378                 segnum = cb2->segnum;
379                 skb_unlink(ack);
380                 kfree_skb(ack);
381                 ack = NULL;
382                 if (xmit_count == 1) {
383                         if (equal(segnum, acknum)) 
384                                 dn_nsp_rtt(sk, (long)(pkttime - reftime));
385 
386                         if (scp->snd_window < NSP_MAX_WINDOW)
387                                 scp->snd_window++;
388                 }
389         }
390 
391 #if 0 /* Turned off due to possible interference in socket shutdown */
392         if ((skb_queue_len(&scp->data_xmit_queue) == 0) &&
393             (skb_queue_len(&scp->other_xmit_queue) == 0))
394                 scp->persist = 0;
395 #endif
396 
397         return wakeup;
398 }
399 
400 void dn_nsp_send_data_ack(struct sock *sk)
401 {
402         struct sk_buff *skb = NULL;
403         struct  nsp_data_ack_msg *msg;
404 
405         if ((skb = dn_alloc_skb(sk, 200, GFP_ATOMIC)) == NULL)
406                 return;
407         
408         msg = (struct nsp_data_ack_msg *)skb_put(skb,sizeof(*msg));
409 
410         msg->msgflg  = 0x04;                    /* data ack message     */
411         msg->dstaddr = sk->protinfo.dn.addrrem;
412         msg->srcaddr = sk->protinfo.dn.addrloc;
413         msg->acknum  = dn_htons((sk->protinfo.dn.numdat_rcv & 0x0FFF) | 0x8000);
414 
415         sk->protinfo.dn.ackxmt_dat = sk->protinfo.dn.numdat_rcv;
416 
417         dn_nsp_send(skb);
418 }
419 
420 void dn_nsp_send_oth_ack(struct sock *sk)
421 {
422         struct sk_buff *skb = NULL;
423         struct  nsp_data_ack_msg *msg;
424 
425         if ((skb = dn_alloc_skb(sk, 200, GFP_ATOMIC)) == NULL)
426                 return;
427         
428         msg = (struct nsp_data_ack_msg *)skb_put(skb,sizeof(*msg));
429 
430         msg->msgflg = 0x14;     /* oth ack message      */
431         msg->dstaddr = sk->protinfo.dn.addrrem;
432         msg->srcaddr = sk->protinfo.dn.addrloc;
433         msg->acknum  = dn_htons((sk->protinfo.dn.numoth_rcv & 0x0FFF) | 0x8000);
434 
435         sk->protinfo.dn.ackxmt_oth = sk->protinfo.dn.numoth_rcv;
436 
437         dn_nsp_send(skb);
438 }
439 
440 
441 void dn_send_conn_ack (struct sock *sk)
442 {
443         struct dn_scp *scp = &sk->protinfo.dn;
444         struct sk_buff *skb = NULL;
445         struct nsp_conn_ack_msg *msg;
446 
447         if ((skb = dn_alloc_skb(sk, 3, sk->allocation)) == NULL)
448                 return;
449 
450         msg = (struct nsp_conn_ack_msg *)skb_put(skb, 3);
451         msg->msgflg = 0x24;                   
452         msg->dstaddr = scp->addrrem;
453 
454         dn_nsp_send(skb);       
455 }
456 
457 void dn_nsp_delayed_ack(struct sock *sk)
458 {
459         struct dn_scp *scp = &sk->protinfo.dn;
460 
461         if (scp->ackxmt_oth != scp->numoth_rcv)
462                 dn_nsp_send_oth_ack(sk);
463 
464         if (scp->ackxmt_dat != scp->numdat_rcv)
465                 dn_nsp_send_data_ack(sk);
466 }
467 
468 static int dn_nsp_retrans_conn_conf(struct sock *sk)
469 {
470         struct dn_scp *scp = &sk->protinfo.dn;
471 
472         if (scp->state == DN_CC)
473                 dn_send_conn_conf(sk, GFP_ATOMIC);
474 
475         return 0;
476 }
477 
478 void dn_send_conn_conf(struct sock *sk, int gfp)
479 {
480         struct dn_scp *scp = &sk->protinfo.dn;
481         struct sk_buff *skb = NULL;
482         struct nsp_conn_init_msg *msg;
483         unsigned char len = scp->conndata_out.opt_optl;
484 
485         if ((skb = dn_alloc_skb(sk, 50 + scp->conndata_out.opt_optl, gfp)) == NULL)
486                 return;
487 
488         msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg));
489         msg->msgflg = 0x28;                   
490         msg->dstaddr = scp->addrrem;
491         msg->srcaddr = scp->addrloc;
492         msg->services = 0x01;
493         msg->info = 0x03;
494         msg->segsize = dn_htons(0x05B3);
495 
496         *skb_put(skb,1) = len;
497 
498         if (len > 0) 
499                 memcpy(skb_put(skb, len), scp->conndata_out.opt_data, len);
500         
501 
502         dn_nsp_send(skb);
503 
504         scp->persist = dn_nsp_persist(sk);
505         scp->persist_fxn = dn_nsp_retrans_conn_conf;
506 }
507 
508 
509 static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, 
510                         unsigned short reason, int gfp, struct dst_entry *dst,
511                         int ddl, unsigned char *dd, __u16 rem, __u16 loc)
512 {
513         struct sk_buff *skb = NULL;
514         int size = 7 + ddl + ((msgflg == NSP_DISCINIT) ? 1 : 0);
515         unsigned char *msg;
516 
517         if ((dst == NULL) || (rem == 0)) {
518                 if (net_ratelimit())
519                         printk(KERN_DEBUG "DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n", (unsigned)rem, dst);
520                 return;
521         }
522 
523         if ((skb = dn_alloc_skb(sk, size, gfp)) == NULL)
524                 return;
525 
526         msg = skb_put(skb, size);
527         *msg++ = msgflg;
528         *(__u16 *)msg = rem;
529         msg += 2;
530         *(__u16 *)msg = loc;
531         msg += 2;
532         *(__u16 *)msg = dn_htons(reason);
533         msg += 2;
534         if (msgflg == NSP_DISCINIT)
535                 *msg++ = ddl;
536 
537         if (ddl) {
538                 memcpy(msg, dd, ddl);
539         }
540 
541         /*
542          * This doesn't go via the dn_nsp_send() fucntion since we need
543          * to be able to send disc packets out which have no socket
544          * associations.
545          */
546         skb->dst = dst_clone(dst);
547         skb->dst->output(skb);
548 }
549 
550 
551 void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg, 
552                         unsigned short reason, int gfp)
553 {
554         struct dn_scp *scp = &sk->protinfo.dn;
555         int ddl = 0;
556 
557         if (msgflg == NSP_DISCINIT)
558                 ddl = scp->discdata_out.opt_optl;
559 
560         if (reason == 0)
561                 reason = scp->discdata_out.opt_status;
562 
563         dn_nsp_do_disc(sk, msgflg, reason, gfp, sk->dst_cache, ddl, 
564                 scp->discdata_out.opt_data, scp->addrrem, scp->addrloc);
565 }
566 
567 
568 void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg, 
569                         unsigned short reason)
570 {
571         struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
572         int ddl = 0;
573         int gfp = GFP_ATOMIC;
574 
575         dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb->dst, ddl, 
576                         NULL, cb->src_port, cb->dst_port);
577 }
578 
579 
580 void dn_nsp_send_lnk(struct sock *sk, unsigned short flgs)
581 {
582         struct dn_scp *scp = &sk->protinfo.dn;
583         struct sk_buff *skb = NULL;
584         struct nsp_data_seg_msg *msg;
585         struct nsp_data_opt_msg *msg1;
586         struct dn_skb_cb *cb;
587 
588         if ((skb = dn_alloc_skb(sk, 80, GFP_ATOMIC)) == NULL)
589                 return;
590 
591         cb = (struct dn_skb_cb *)skb->cb;       
592         msg = (struct nsp_data_seg_msg *)skb_put(skb, sizeof(*msg));
593         msg->msgflg = 0x10;                     /* Link svc message     */
594         msg->dstaddr = scp->addrrem;
595         msg->srcaddr = scp->addrloc;
596 
597         msg1 = (struct nsp_data_opt_msg *)skb_put(skb, sizeof(*msg1));
598         msg1->acknum = dn_htons((scp->ackxmt_oth & 0x0FFF) | 0x8000);
599         msg1->segnum = dn_htons(cb->segnum = (scp->numoth++ & 0x0FFF));
600         msg1->lsflgs = flgs;
601 
602         dn_nsp_queue_xmit(sk, skb, 1);
603 
604         scp->persist = dn_nsp_persist(sk);
605         scp->persist_fxn = dn_nsp_xmit_timeout;
606 
607 }
608 
609 static int dn_nsp_retrans_conninit(struct sock *sk)
610 {
611         struct dn_scp *scp = &sk->protinfo.dn;
612 
613         if (scp->state == DN_CI)
614                 dn_nsp_send_conninit(sk, NSP_RCI);
615 
616         return 0;
617 }
618 
619 void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg)
620 {
621         struct dn_scp *scp = &sk->protinfo.dn;
622         struct sk_buff *skb = NULL;
623         struct nsp_conn_init_msg *msg;
624         unsigned char aux;
625         unsigned char menuver;
626         struct dn_skb_cb *cb;
627         unsigned char type = 1;
628 
629         if ((skb = dn_alloc_skb(sk, 200, (msgflg == NSP_CI) ? sk->allocation : GFP_ATOMIC)) == NULL)
630                 return;
631 
632         cb  = (struct dn_skb_cb *)skb->cb;
633         msg = (struct nsp_conn_init_msg *)skb_put(skb,sizeof(*msg));
634 
635         msg->msgflg     = msgflg;
636         msg->dstaddr    = 0x0000;               /* Remote Node will assign it*/
637 
638         msg->srcaddr    = sk->protinfo.dn.addrloc;
639         msg->services   = 1 | NSP_FC_NONE;      /* Requested flow control    */
640         msg->info       = 0x03;                 /* Version Number            */ 
641         msg->segsize    = dn_htons(1459);       /* Max segment size          */ 
642 
643         if (scp->peer.sdn_objnum)
644                 type = 0;
645 
646         skb_put(skb, dn_sockaddr2username(&scp->peer, skb->tail, type));
647         skb_put(skb, dn_sockaddr2username(&scp->addr, skb->tail, 2));
648 
649         menuver = DN_MENUVER_ACC | DN_MENUVER_USR;
650         if (scp->peer.sdn_flags & SDF_PROXY)
651                 menuver |= DN_MENUVER_PRX;
652         if (scp->peer.sdn_flags & SDF_UICPROXY)
653                 menuver |= DN_MENUVER_UIC;
654 
655         *skb_put(skb, 1) = menuver;     /* Menu Version         */
656         
657         aux = scp->accessdata.acc_userl;
658         *skb_put(skb, 1) = aux;
659         if (aux > 0)
660         memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux);
661 
662         aux = scp->accessdata.acc_passl;
663         *skb_put(skb, 1) = aux;
664         if (aux > 0)
665         memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux);
666 
667         aux = scp->accessdata.acc_accl;
668         *skb_put(skb, 1) = aux;
669         if (aux > 0)
670         memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux);
671 
672         aux = scp->conndata_out.opt_optl;
673         *skb_put(skb, 1) = aux;
674         if (aux > 0)
675         memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux);
676 
677         sk->protinfo.dn.persist = dn_nsp_persist(sk);
678         sk->protinfo.dn.persist_fxn = dn_nsp_retrans_conninit;
679 
680         cb->rt_flags = DN_RT_F_RQR;
681 
682         dn_nsp_send(skb);       
683 }
684 
685 

~ [ 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.