Rename sprintf -> ksprintf
[dfdiff.git] / sys / netproto / atm / spans / spans_cls.c
blob5cc9f1bfabacdd6f94ddca0db8e18b0086e9a151
1 /*
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/spans/spans_cls.c,v 1.6 1999/08/28 00:48:49 peter Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/spans/spans_cls.c,v 1.8 2006/12/20 18:14:43 dillon Exp $
31 * SPANS Signalling Manager
32 * ---------------------------
34 * SPANS Connectionless Datagram Service (CLS) module
38 #include <netproto/atm/kern_include.h>
40 #include <netproto/atm/ipatm/ipatm_var.h>
41 #include <netproto/atm/ipatm/ipatm_serv.h>
42 #include "spans_xdr.h"
43 #include "spans_var.h"
44 #include "spans_cls.h"
47 * Global variables
49 int spanscls_print = 0;
51 struct spanscls *spanscls_head = NULL;
53 struct spans_addr spans_bcastaddr = {
54 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
57 struct spanscls_hdr spanscls_hdr = {
58 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* dst */
59 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* src */
60 0x00, 0x00, 0,
61 0xaa, 0xaa, 0x03, { 0x00, 0x00, 0x00 }, 0 /* LLC SNAP */
66 * Local functions
68 static int spanscls_ipact (struct ip_nif *);
69 static int spanscls_ipdact (struct ip_nif *);
70 static int spanscls_bcast_output (struct ip_nif *, KBuffer *);
71 static void spanscls_cpcs_data (void *, KBuffer *);
72 static void spanscls_connected (void *);
73 static void spanscls_cleared (void *, struct t_atm_cause *);
74 static caddr_t spanscls_getname (void *);
75 static void spanscls_pdu_print (struct spanscls *, KBuffer *,
76 char *);
79 * Local variables
81 static struct sp_info spanscls_pool = {
82 "spans cls pool", /* si_name */
83 sizeof(struct spanscls), /* si_blksiz */
84 2, /* si_blkcnt */
85 100 /* si_maxallow */
88 static struct ip_serv spanscls_ipserv = {
89 spanscls_ipact,
90 spanscls_ipdact,
91 spansarp_ioctl,
92 NULL,
93 spansarp_svcout,
94 spansarp_svcin,
95 spansarp_svcactive,
96 spansarp_vcclose,
97 spanscls_bcast_output,
99 {ATM_AAL5, ATM_ENC_NULL},
100 {ATM_AAL3_4, ATM_ENC_NULL}
104 static u_char spanscls_bridged[] = {
105 0x00, 0x00, 0x00, 0x00,
106 0xaa, 0xaa, 0x03, 0x00, 0x80, 0xc2 /* LLC SNAP */
109 static Atm_endpoint spanscls_endpt = {
110 NULL,
111 ENDPT_SPANS_CLS,
112 NULL,
113 spanscls_getname,
114 spanscls_connected,
115 spanscls_cleared,
116 NULL,
117 NULL,
118 NULL,
119 NULL,
120 spanscls_cpcs_data,
121 NULL,
122 NULL,
123 NULL,
124 NULL
127 static Atm_attributes spanscls_attr = {
128 NULL, /* nif */
129 CMAPI_CPCS, /* api */
130 0, /* api_init */
131 0, /* headin */
132 0, /* headout */
133 { /* aal */
134 T_ATM_PRESENT,
135 ATM_AAL3_4
137 { /* traffic */
138 T_ATM_PRESENT,
141 T_ATM_ABSENT,
143 T_ATM_ABSENT,
144 T_ATM_ABSENT,
145 T_ATM_ABSENT,
146 T_ATM_ABSENT,
147 T_NO
150 T_ATM_ABSENT,
152 T_ATM_ABSENT,
153 T_ATM_ABSENT,
154 T_ATM_ABSENT,
155 T_ATM_ABSENT,
156 T_NO
158 T_YES
161 { /* bearer */
162 T_ATM_PRESENT,
164 T_ATM_CLASS_X,
165 T_ATM_NULL,
166 T_ATM_NULL,
167 T_NO,
168 T_ATM_1_TO_1
171 { /* bhli */
172 T_ATM_ABSENT
174 { /* blli */
175 T_ATM_ABSENT,
176 T_ATM_ABSENT
178 { /* llc */
179 T_ATM_ABSENT
181 { /* called */
182 T_ATM_PRESENT,
184 { /* calling */
185 T_ATM_ABSENT
187 { /* qos */
188 T_ATM_PRESENT,
190 T_ATM_NETWORK_CODING,
192 T_ATM_QOS_CLASS_0,
195 T_ATM_QOS_CLASS_0
199 { /* transit */
200 T_ATM_ABSENT
202 { /* cause */
203 T_ATM_ABSENT
207 static struct t_atm_cause spanscls_cause = {
208 T_ATM_ITU_CODING,
209 T_ATM_LOC_USER,
210 T_ATM_CAUSE_UNSPECIFIED_NORMAL,
211 {0, 0, 0, 0}
216 * Process module loading
218 * Called whenever the spans module is initializing.
220 * Arguments:
221 * none
223 * Returns:
224 * 0 initialization successful
225 * errno initialization failed - reason indicated
229 spanscls_start(void)
231 int err;
234 * Fill in union fields
236 spanscls_attr.aal.v.aal4.forward_max_SDU_size = ATM_NIF_MTU;
237 spanscls_attr.aal.v.aal4.backward_max_SDU_size = ATM_NIF_MTU;
238 spanscls_attr.aal.v.aal4.SSCS_type = T_ATM_NULL;
239 spanscls_attr.aal.v.aal4.mid_low = 0;
240 spanscls_attr.aal.v.aal4.mid_high = 1023;
243 * Register our endpoint
245 err = atm_endpoint_register(&spanscls_endpt);
247 return (err);
252 * Process module unloading notification
254 * Called whenever the spans module is about to be unloaded. All signalling
255 * instances will have been previously detached. All spanscls resources
256 * must be freed now.
258 * Arguments:
259 * none
261 * Returns:
262 * none
265 void
266 spanscls_stop(void)
268 crit_enter();
271 * Tell ARP to stop
273 spansarp_stop();
276 * Nothing should be left here...
278 if (spanscls_head) {
279 panic("spanscls_stop: bad state");
281 crit_exit();
284 * De-register ourselves
286 atm_endpoint_deregister(&spanscls_endpt);
289 * Free our storage pools
291 atm_release_pool(&spanscls_pool);
296 * Process signalling interface attach
298 * This function is called whenever a physical interface has been attached
299 * to spans. We will open the CLS PVC and await further events.
301 * Called from a critical section.
303 * Arguments:
304 * spp pointer to spans signalling protocol instance
306 * Returns:
307 * 0 attach successful
308 * errno attach failed - reason indicated
312 spanscls_attach(struct spans *spp)
314 struct spanscls *clp;
315 Atm_addr_pvc *pvcp;
316 int err;
319 * Get a new cls control block
321 clp = (struct spanscls *)atm_allocate(&spanscls_pool);
322 if (clp == NULL)
323 return (ENOMEM);
326 * Initialize some stuff
328 clp->cls_state = CLS_CLOSED;
329 clp->cls_spans = spp;
330 spp->sp_ipserv = &spanscls_ipserv;
333 * Fill out connection attributes
335 spanscls_attr.nif = spp->sp_pif->pif_nif;
336 spanscls_attr.traffic.v.forward.PCR_all_traffic = spp->sp_pif->pif_pcr;
337 spanscls_attr.traffic.v.backward.PCR_all_traffic = spp->sp_pif->pif_pcr;
338 spanscls_attr.called.addr.address_format = T_ATM_PVC_ADDR;
339 spanscls_attr.called.addr.address_length = sizeof(Atm_addr_pvc);
340 pvcp = (Atm_addr_pvc *)spanscls_attr.called.addr.address;
341 ATM_PVC_SET_VPI(pvcp, SPANS_CLS_VPI);
342 ATM_PVC_SET_VCI(pvcp, SPANS_CLS_VCI);
343 spanscls_attr.called.subaddr.address_format = T_ATM_ABSENT;
344 spanscls_attr.called.subaddr.address_length = 0;
347 * Create SPANS Connectionless Service (CLS) PVC
349 err = atm_cm_connect(&spanscls_endpt, clp, &spanscls_attr,
350 &clp->cls_conn);
351 if (err) {
352 atm_free((caddr_t)clp);
353 return (err);
357 * Set new state and link instance
359 clp->cls_state = CLS_OPEN;
360 LINK2TAIL(clp, struct spanscls, spanscls_head, cls_next);
361 spp->sp_cls = clp;
363 return (0);
368 * Process signalling interface detach
370 * This function is called whenever a physical interface has been detached
371 * from spans. We will close the CLS PVC and clean up everything.
373 * Called from a critical section.
375 * Arguments:
376 * spp pointer to spans signalling protocol instance
378 * Returns:
379 * none
382 void
383 spanscls_detach(struct spans *spp)
385 struct spanscls *clp;
388 * Get our control block
390 clp = spp->sp_cls;
391 if (clp == NULL)
392 return;
395 * Just checking up on things...
397 if (clp->cls_ipnif)
398 panic("spanscls_detach: IP interface still active");
401 * Close CLS PVC
403 spanscls_closevc(clp, &spanscls_cause);
406 * Sever links and free server block, if possible
408 clp->cls_spans = NULL;
409 spp->sp_cls = NULL;
410 if (clp->cls_state == CLS_CLOSED) {
411 UNLINK(clp, struct spanscls, spanscls_head, cls_next);
412 atm_free((caddr_t)clp);
418 * Process IP Network Interface Activation
420 * Called whenever an IP network interface becomes active.
422 * Called from a critical section.
424 * Arguments:
425 * inp pointer to IP network interface
427 * Returns:
428 * 0 command successful
429 * errno command failed - reason indicated
432 static int
433 spanscls_ipact(struct ip_nif *inp)
435 struct spans *spp;
436 struct spanscls *clp;
439 * Get corresponding cls instance
441 spp = (struct spans *)inp->inf_nif->nif_pif->pif_siginst;
442 if ((spp == NULL) || ((clp = spp->sp_cls) == NULL))
443 return (ENXIO);
446 * Make sure it's not already activated
448 if (clp->cls_ipnif)
449 return (EEXIST);
452 * Set two-way links with IP world
454 clp->cls_ipnif = inp;
455 inp->inf_isintf = (caddr_t)clp;
458 * Tell arp about new interface
460 spansarp_ipact(clp);
462 return (0);
467 * Process IP Network Interface Deactivation
469 * Called whenever an IP network interface becomes inactive.
471 * Called from a critical section.
473 * Arguments:
474 * inp pointer to IP network interface
476 * Returns:
477 * 0 command successful
478 * errno command failed - reason indicated
481 static int
482 spanscls_ipdact(struct ip_nif *inp)
484 struct spanscls *clp;
487 * Get cls instance and make sure it's been activated
489 clp = (struct spanscls *)inp->inf_isintf;
490 if ((clp == NULL) || (clp->cls_ipnif == NULL))
491 return (ENXIO);
494 * Let arp know about this
496 spansarp_ipdact(clp);
499 * Clear IP interface pointer
501 clp->cls_ipnif = NULL;
502 return (0);
507 * Output IP Broadcast Packet
509 * Called whenever an IP broadcast packet is sent to this interface.
511 * Arguments:
512 * inp pointer to IP network interface
513 * m pointer to packet buffer chain
515 * Returns:
516 * 0 packet sent successfully
517 * errno send failed - reason indicated
520 static int
521 spanscls_bcast_output(struct ip_nif *inp, KBuffer *m)
523 struct spans *spp;
524 struct spanscls *clp;
525 struct spanscls_hdr *chp;
526 int err, space;
529 * Get cls instance and make sure it's been activated
531 clp = (struct spanscls *)inp->inf_isintf;
532 if ((clp == NULL) || (clp->cls_ipnif == NULL)) {
533 KB_FREEALL(m);
534 return (ENETDOWN);
538 * Make sure that we know our addresses
540 spp = clp->cls_spans;
541 if (spp->sp_addr.address_format != T_ATM_SPANS_ADDR) {
542 KB_FREEALL(m);
543 return (ENETDOWN);
547 * See if there's room to add CLS header to front of packet.
549 KB_HEADROOM(m, space);
550 if (space < sizeof(struct spanscls_hdr)) {
551 KBuffer *n;
554 * We have to allocate another buffer and tack it
555 * onto the front of the packet
557 KB_ALLOCPKT(n, sizeof(struct spanscls_hdr),
558 KB_F_NOWAIT, KB_T_HEADER);
559 if (n == 0) {
560 KB_FREEALL(m);
561 return (ENOBUFS);
563 KB_TAILALIGN(n, sizeof(struct spanscls_hdr));
564 KB_LINKHEAD(n, m);
565 m = n;
566 } else {
568 * Header fits, just adjust buffer controls
570 KB_HEADADJ(m, sizeof(struct spanscls_hdr));
574 * Now, build the CLS header
576 KB_DATASTART(m, chp, struct spanscls_hdr *);
577 spans_addr_copy(&spans_bcastaddr, &chp->ch_dst);
578 spans_addr_copy(spp->sp_addr.address, &chp->ch_src);
579 *(u_int *)&chp->ch_proto = *(u_int *)&spanscls_hdr.ch_proto;
580 *(u_int *)&chp->ch_dsap = *(u_int *)&spanscls_hdr.ch_dsap;
581 *(u_short *)&chp->ch_oui[1] = *(u_short *)&spanscls_hdr.ch_oui[1];
582 chp->ch_pid = htons(ETHERTYPE_IP);
584 #ifdef DIAGNOSTIC
585 if (spanscls_print)
586 spanscls_pdu_print(clp, m, "output");
587 #endif
590 * Finally, send the pdu via the CLS service
592 err = atm_cm_cpcs_data(clp->cls_conn, m);
593 if (err) {
594 KB_FREEALL(m);
595 return (ENOBUFS);
598 return (0);
603 * Process VCC Input Data
605 * All input packets received from CLS VCC lower layers are processed here.
607 * Arguments:
608 * tok connection token (pointer to CLS VCC control block)
609 * m pointer to input packet buffer chain
611 * Returns:
612 * none
615 static void
616 spanscls_cpcs_data(void *tok, KBuffer *m)
618 struct spanscls *clp = tok;
619 struct spans *spp = clp->cls_spans;
620 struct spanscls_hdr *chp;
621 struct ip_nif *inp;
624 * Make sure we're ready
626 if ((clp->cls_state != CLS_OPEN) || (spp->sp_state != SPANS_ACTIVE)) {
627 KB_FREEALL(m);
628 return;
631 #ifdef DIAGNOSTIC
632 if (spanscls_print)
633 spanscls_pdu_print(clp, m, "input");
634 #endif
637 * Get CLS header into buffer
639 if (KB_LEN(m) < sizeof(struct spanscls_hdr)) {
640 KB_PULLUP(m, sizeof(struct spanscls_hdr), m);
641 if (m == 0)
642 return;
644 KB_DATASTART(m, chp, struct spanscls_hdr *);
647 * Verify packet information
649 if ((*(u_int *)&chp->ch_proto != *(u_int *)&spanscls_hdr.ch_proto) ||
650 (*(u_int *)&chp->ch_dsap != *(u_int *)&spanscls_hdr.ch_dsap) ||
651 (*(u_short *)&chp->ch_oui[1] !=
652 *(u_short *)&spanscls_hdr.ch_oui[1])) {
655 * Check for bridged PDU
657 if (bcmp((char *)&chp->ch_proto, (char *)spanscls_bridged,
658 sizeof(spanscls_bridged))) {
659 log(LOG_ERR, "spanscls_input: bad format\n");
660 #ifdef DIAGNOSTIC
661 spanscls_pdu_print(clp, m, "input error");
662 #endif
665 KB_FREEALL(m);
666 return;
670 * Make sure packet is for us
672 if (spans_addr_cmp(&chp->ch_dst, spp->sp_addr.address) &&
673 spans_addr_cmp(&chp->ch_dst, &spans_bcastaddr)) {
674 KB_FREEALL(m);
675 return;
679 * Do protocol processing
681 switch (ntohs(chp->ch_pid)) {
683 case ETHERTYPE_IP:
685 * Drop CLS header
687 KB_HEADADJ(m, -sizeof(struct spanscls_hdr));
688 KB_PLENADJ(m, -sizeof(struct spanscls_hdr));
691 * Packet is ready for input to IP
693 if ((inp = clp->cls_ipnif) != NULL)
694 (*inp->inf_ipinput)(inp, m);
695 else
696 KB_FREEALL(m);
697 break;
699 case ETHERTYPE_ARP:
700 spansarp_input(clp, m);
701 break;
703 default:
704 log(LOG_ERR, "spanscls_input: unknown protocol 0x%x\n",
705 chp->ch_pid);
706 KB_FREEALL(m);
707 return;
713 * Close a SPANS CLS VCC
715 * This function will close a SPANS CLS VCC.
717 * Arguments:
718 * clp pointer to CLS instance
719 * cause pointer to cause code
721 * Returns:
722 * none
725 void
726 spanscls_closevc(struct spanscls *clp, struct t_atm_cause *cause)
728 int err;
731 * Close VCC
733 if (clp->cls_conn) {
734 err = atm_cm_release(clp->cls_conn, cause);
735 if (err) {
736 log(LOG_ERR, "spanscls_closevc: release err=%d\n", err);
738 clp->cls_conn = NULL;
741 clp->cls_state = CLS_CLOSED;
746 * Process CLS VCC Connected Notification
748 * Arguments:
749 * toku user's connection token (spanscls protocol block)
751 * Returns:
752 * none
755 static void
756 spanscls_connected(void *toku)
759 * We should never get one of these
761 log(LOG_ERR, "spanscls: unexpected connected event\n");
766 * Process CLS VCC Cleared Notification
768 * Arguments:
769 * toku user's connection token (spanscls protocol block)
770 * cause pointer to cause code
772 * Returns:
773 * none
776 static void
777 spanscls_cleared(void *toku, struct t_atm_cause *cause)
779 struct spanscls *clp = (struct spanscls *)toku;
782 * CLS VCC has been closed, so clean up our side
784 clp->cls_conn = NULL;
785 spanscls_closevc(clp, cause);
790 * Get Connection's Application/Owner Name
792 * Arguments:
793 * tok spanscls connection token
795 * Returns:
796 * addr pointer to string containing our name
799 static caddr_t
800 spanscls_getname(void *tok)
802 return ("SPANSCLS");
807 * Print a SPANS CLS PDU
809 * Arguments:
810 * clp pointer to cls instance
811 * m pointer to pdu buffer chain
812 * msg pointer to message string
814 * Returns:
815 * none
818 static void
819 spanscls_pdu_print(struct spanscls *clp, KBuffer *m, char *msg)
821 char buf[128];
823 ksnprintf(buf, sizeof(buf), "spanscls %s:\n", msg);
824 atm_pdu_print(m, buf);