head 1.36; access; symbols netbsd-10-0-RELEASE:1.36 netbsd-10-0-RC6:1.36 netbsd-10-0-RC5:1.36 netbsd-10-0-RC4:1.36 netbsd-10-0-RC3:1.36 netbsd-10-0-RC2:1.36 thorpej-ifq:1.36.0.34 thorpej-ifq-base:1.36 thorpej-altq-separation:1.36.0.32 thorpej-altq-separation-base:1.36 netbsd-10-0-RC1:1.36 netbsd-10:1.36.0.30 netbsd-10-base:1.36 bouyer-sunxi-drm:1.36.0.28 bouyer-sunxi-drm-base:1.36 netbsd-9-3-RELEASE:1.36 thorpej-i2c-spi-conf2:1.36.0.26 thorpej-i2c-spi-conf2-base:1.36 thorpej-futex2:1.36.0.24 thorpej-futex2-base:1.36 thorpej-cfargs2:1.36.0.22 thorpej-cfargs2-base:1.36 cjep_sun2x-base1:1.36 cjep_sun2x:1.36.0.20 cjep_sun2x-base:1.36 cjep_staticlib_x-base1:1.36 netbsd-9-2-RELEASE:1.36 cjep_staticlib_x:1.36.0.18 cjep_staticlib_x-base:1.36 thorpej-i2c-spi-conf:1.36.0.16 thorpej-i2c-spi-conf-base:1.36 thorpej-cfargs:1.36.0.14 thorpej-cfargs-base:1.36 thorpej-futex:1.36.0.12 thorpej-futex-base:1.36 netbsd-9-1-RELEASE:1.36 bouyer-xenpvh-base2:1.36 phil-wifi-20200421:1.36 bouyer-xenpvh-base1:1.36 phil-wifi-20200411:1.36 bouyer-xenpvh:1.36.0.10 bouyer-xenpvh-base:1.36 is-mlppp:1.36.0.8 is-mlppp-base:1.36 phil-wifi-20200406:1.36 netbsd-8-2-RELEASE:1.35.10.1 ad-namecache-base3:1.36 netbsd-9-0-RELEASE:1.36 netbsd-9-0-RC2:1.36 ad-namecache-base2:1.36 ad-namecache-base1:1.36 ad-namecache:1.36.0.6 ad-namecache-base:1.36 netbsd-9-0-RC1:1.36 phil-wifi-20191119:1.36 netbsd-9:1.36.0.4 netbsd-9-base:1.36 phil-wifi-20190609:1.36 netbsd-8-1-RELEASE:1.35.10.1 netbsd-8-1-RC1:1.35.10.1 isaki-audio2:1.36.0.2 isaki-audio2-base:1.36 pgoyette-compat-merge-20190127:1.35 pgoyette-compat-20190127:1.35 pgoyette-compat-20190118:1.35 pgoyette-compat-1226:1.35 pgoyette-compat-1126:1.35 pgoyette-compat-1020:1.35 pgoyette-compat-0930:1.35 pgoyette-compat-0906:1.35 netbsd-7-2-RELEASE:1.31 pgoyette-compat-0728:1.35 netbsd-8-0-RELEASE:1.35 phil-wifi:1.35.0.18 phil-wifi-base:1.35 pgoyette-compat-0625:1.35 netbsd-8-0-RC2:1.35 pgoyette-compat-0521:1.35 pgoyette-compat-0502:1.35 pgoyette-compat-0422:1.35 netbsd-8-0-RC1:1.35 pgoyette-compat-0415:1.35 pgoyette-compat-0407:1.35 pgoyette-compat-0330:1.35 pgoyette-compat-0322:1.35 pgoyette-compat-0315:1.35 netbsd-7-1-2-RELEASE:1.31 pgoyette-compat:1.35.0.16 pgoyette-compat-base:1.35 netbsd-7-1-1-RELEASE:1.31 tls-maxphys-base-20171202:1.35 matt-nb8-mediatek:1.35.0.14 matt-nb8-mediatek-base:1.35 nick-nhusb-base-20170825:1.35 perseant-stdc-iso10646:1.35.0.12 perseant-stdc-iso10646-base:1.35 netbsd-8:1.35.0.10 netbsd-8-base:1.35 prg-localcount2-base3:1.35 prg-localcount2-base2:1.35 prg-localcount2-base1:1.35 prg-localcount2:1.35.0.8 prg-localcount2-base:1.35 pgoyette-localcount-20170426:1.35 bouyer-socketcan-base1:1.35 jdolecek-ncq:1.35.0.6 jdolecek-ncq-base:1.35 pgoyette-localcount-20170320:1.35 netbsd-7-1:1.31.0.10 netbsd-7-1-RELEASE:1.31 netbsd-7-1-RC2:1.31 nick-nhusb-base-20170204:1.35 netbsd-7-nhusb-base-20170116:1.31 bouyer-socketcan:1.35.0.4 bouyer-socketcan-base:1.35 pgoyette-localcount-20170107:1.35 netbsd-7-1-RC1:1.31 nick-nhusb-base-20161204:1.35 pgoyette-localcount-20161104:1.35 netbsd-7-0-2-RELEASE:1.31 nick-nhusb-base-20161004:1.35 localcount-20160914:1.35 netbsd-7-nhusb:1.31.0.8 netbsd-7-nhusb-base:1.31 pgoyette-localcount-20160806:1.35 pgoyette-localcount-20160726:1.35 pgoyette-localcount:1.35.0.2 pgoyette-localcount-base:1.35 nick-nhusb-base-20160907:1.35 nick-nhusb-base-20160529:1.35 netbsd-7-0-1-RELEASE:1.31 nick-nhusb-base-20160422:1.35 nick-nhusb-base-20160319:1.35 nick-nhusb-base-20151226:1.35 netbsd-7-0:1.31.0.6 netbsd-7-0-RELEASE:1.31 nick-nhusb-base-20150921:1.35 netbsd-7-0-RC3:1.31 netbsd-7-0-RC2:1.31 netbsd-7-0-RC1:1.31 nick-nhusb-base-20150606:1.35 nick-nhusb-base-20150406:1.32 nick-nhusb:1.31.0.4 nick-nhusb-base:1.31 netbsd-5-2-3-RELEASE:1.9 netbsd-5-1-5-RELEASE:1.9 netbsd-6-0-6-RELEASE:1.9 netbsd-6-1-5-RELEASE:1.9 netbsd-7:1.31.0.2 netbsd-7-base:1.31 yamt-pagecache-base9:1.10 yamt-pagecache-tag8:1.9 netbsd-6-1-4-RELEASE:1.9 netbsd-6-0-5-RELEASE:1.9 tls-earlyentropy:1.10.0.2 tls-earlyentropy-base:1.31 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.10 riastradh-drm2-base3:1.10 netbsd-6-1-3-RELEASE:1.9 netbsd-6-0-4-RELEASE:1.9 netbsd-5-2-2-RELEASE:1.9 netbsd-5-1-4-RELEASE:1.9 netbsd-6-1-2-RELEASE:1.9 netbsd-6-0-3-RELEASE:1.9 netbsd-5-2-1-RELEASE:1.9 netbsd-5-1-3-RELEASE:1.9 rmind-smpnet-nbase:1.11 netbsd-6-1-1-RELEASE:1.9 riastradh-drm2-base2:1.9 riastradh-drm2-base1:1.9 riastradh-drm2:1.9.0.52 riastradh-drm2-base:1.9 rmind-smpnet:1.9.0.44 rmind-smpnet-base:1.11 netbsd-6-1:1.9.0.50 netbsd-6-0-2-RELEASE:1.9 netbsd-6-1-RELEASE:1.9 khorben-n900:1.9.0.48 netbsd-6-1-RC4:1.9 netbsd-6-1-RC3:1.9 agc-symver:1.9.0.46 agc-symver-base:1.9 netbsd-6-1-RC2:1.9 netbsd-6-1-RC1:1.9 yamt-pagecache-base8:1.9 netbsd-5-2:1.9.0.42 netbsd-6-0-1-RELEASE:1.9 yamt-pagecache-base7:1.9 netbsd-5-2-RELEASE:1.9 netbsd-5-2-RC1:1.9 matt-nb6-plus-nbase:1.9 yamt-pagecache-base6:1.9 netbsd-6-0:1.9.0.40 netbsd-6-0-RELEASE:1.9 netbsd-6-0-RC2:1.9 tls-maxphys:1.9.0.38 tls-maxphys-base:1.31 matt-nb6-plus:1.9.0.36 matt-nb6-plus-base:1.9 netbsd-6-0-RC1:1.9 jmcneill-usbmp-base10:1.9 yamt-pagecache-base5:1.9 jmcneill-usbmp-base9:1.9 yamt-pagecache-base4:1.9 jmcneill-usbmp-base8:1.9 jmcneill-usbmp-base7:1.9 jmcneill-usbmp-base6:1.9 jmcneill-usbmp-base5:1.9 jmcneill-usbmp-base4:1.9 jmcneill-usbmp-base3:1.9 jmcneill-usbmp-pre-base2:1.9 jmcneill-usbmp-base2:1.9 netbsd-6:1.9.0.34 netbsd-6-base:1.9 netbsd-5-1-2-RELEASE:1.9 netbsd-5-1-1-RELEASE:1.9 jmcneill-usbmp:1.9.0.32 jmcneill-usbmp-base:1.9 jmcneill-audiomp3:1.9.0.30 jmcneill-audiomp3-base:1.9 yamt-pagecache-base3:1.9 yamt-pagecache-base2:1.9 yamt-pagecache:1.9.0.28 yamt-pagecache-base:1.9 rmind-uvmplock-nbase:1.9 cherry-xenmp:1.9.0.26 cherry-xenmp-base:1.9 bouyer-quota2-nbase:1.9 bouyer-quota2:1.9.0.24 bouyer-quota2-base:1.9 jruoho-x86intr:1.9.0.22 jruoho-x86intr-base:1.9 matt-mips64-premerge-20101231:1.9 matt-nb5-mips64-premerge-20101231:1.9 matt-nb5-pq3:1.9.0.20 matt-nb5-pq3-base:1.9 netbsd-5-1:1.9.0.18 netbsd-5-1-RELEASE:1.9 uebayasi-xip-base4:1.9 uebayasi-xip-base3:1.9 yamt-nfs-mp-base11:1.9 netbsd-5-1-RC4:1.9 matt-nb5-mips64-k15:1.9 uebayasi-xip-base2:1.9 yamt-nfs-mp-base10:1.9 netbsd-5-1-RC3:1.9 netbsd-5-1-RC2:1.9 uebayasi-xip-base1:1.9 netbsd-5-1-RC1:1.9 rmind-uvmplock:1.9.0.16 rmind-uvmplock-base:1.9 yamt-nfs-mp-base9:1.9 uebayasi-xip:1.9.0.14 uebayasi-xip-base:1.9 netbsd-5-0-2-RELEASE:1.9 matt-nb5-mips64-premerge-20091211:1.9 matt-premerge-20091211:1.9 yamt-nfs-mp-base8:1.9 matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.9 matt-nb4-mips64-k7-u2a-k9b:1.9 matt-nb5-mips64-u1-k1-k5:1.9 yamt-nfs-mp-base7:1.9 matt-nb5-mips64:1.9.0.12 netbsd-5-0-1-RELEASE:1.9 jymxensuspend-base:1.9 yamt-nfs-mp-base6:1.9 yamt-nfs-mp-base5:1.9 yamt-nfs-mp-base4:1.9 jym-xensuspend-nbase:1.9 yamt-nfs-mp-base3:1.9 nick-hppapmap-base4:1.9 nick-hppapmap-base3:1.9 netbsd-5-0:1.9.0.10 netbsd-5-0-RELEASE:1.9 netbsd-5-0-RC4:1.9 netbsd-5-0-RC3:1.9 nick-hppapmap-base2:1.9 netbsd-5-0-RC2:1.9 jym-xensuspend:1.9.0.8 jym-xensuspend-base:1.9 netbsd-5-0-RC1:1.9 haad-dm-base2:1.9 haad-nbase2:1.9 ad-audiomp2:1.9.0.6 ad-audiomp2-base:1.9 netbsd-5:1.9.0.4 netbsd-5-base:1.9 nick-hppapmap:1.9.0.2 nick-hppapmap-base:1.9 matt-mips64-base2:1.9 matt-mips64:1.7.0.32 haad-dm-base1:1.9 wrstuden-revivesa-base-4:1.9 netbsd-4-0-1-RELEASE:1.3.2.1 wrstuden-revivesa-base-3:1.9 wrstuden-revivesa-base-2:1.9 wrstuden-fixsa-newbase:1.3.2.1 nick-csl-alignment-base5:1.7 haad-dm:1.8.0.8 haad-dm-base:1.9 wrstuden-revivesa-base-1:1.8 simonb-wapbl-nbase:1.8 yamt-pf42-base4:1.8 simonb-wapbl:1.8.0.6 simonb-wapbl-base:1.8 yamt-pf42-base3:1.8 hpcarm-cleanup-nbase:1.8 yamt-pf42-baseX:1.7 yamt-pf42-base2:1.8 yamt-nfs-mp-base2:1.8 wrstuden-revivesa:1.8.0.4 wrstuden-revivesa-base:1.8 yamt-nfs-mp:1.8.0.2 yamt-nfs-mp-base:1.8 yamt-pf42:1.7.0.30 yamt-pf42-base:1.7 ad-socklock-base1:1.7 yamt-lazymbuf-base15:1.7 yamt-lazymbuf-base14:1.7 keiichi-mipv6-nbase:1.7 mjf-devfs2:1.7.0.28 mjf-devfs2-base:1.9 nick-net80211-sync:1.7.0.26 nick-net80211-sync-base:1.7 keiichi-mipv6:1.7.0.24 keiichi-mipv6-base:1.7 bouyer-xeni386-merge1:1.7 matt-armv6-prevmlocking:1.7 wrstuden-fixsa-base-1:1.3.2.1 vmlocking2-base3:1.7 netbsd-4-0:1.3.2.1.0.4 netbsd-4-0-RELEASE:1.3.2.1 bouyer-xeni386-nbase:1.7 yamt-kmem-base3:1.7 cube-autoconf:1.7.0.22 cube-autoconf-base:1.7 yamt-kmem-base2:1.7 bouyer-xeni386:1.7.0.20 bouyer-xeni386-base:1.7 yamt-kmem:1.7.0.18 yamt-kmem-base:1.7 vmlocking2-base2:1.7 reinoud-bufcleanup-nbase:1.7 vmlocking2:1.7.0.16 vmlocking2-base1:1.7 netbsd-4-0-RC5:1.3.2.1 matt-nb4-arm:1.3.2.1.0.2 matt-nb4-arm-base:1.3.2.1 matt-armv6-nbase:1.7 jmcneill-base:1.7 netbsd-4-0-RC4:1.3.2.1 mjf-devfs:1.7.0.14 mjf-devfs-base:1.7 bouyer-xenamd64-base2:1.7 vmlocking-nbase:1.7 yamt-x86pmap-base4:1.7 bouyer-xenamd64:1.7.0.12 bouyer-xenamd64-base:1.7 netbsd-4-0-RC3:1.3.2.1 yamt-x86pmap-base3:1.7 yamt-x86pmap-base2:1.7 netbsd-4-0-RC2:1.3.2.1 yamt-x86pmap:1.7.0.10 yamt-x86pmap-base:1.7 netbsd-4-0-RC1:1.3.2.1 matt-armv6:1.7.0.8 matt-armv6-base:1.7 matt-mips64-base:1.7 jmcneill-pm:1.7.0.6 jmcneill-pm-base:1.7 hpcarm-cleanup:1.7.0.4 hpcarm-cleanup-base:1.7 nick-csl-alignment:1.7.0.2 nick-csl-alignment-base:1.7 yamt-idlelwp-base8:1.7 wrstuden-fixsa:1.3.0.8 wrstuden-fixsa-base:1.3.2.1 thorpej-atomic:1.6.0.2 thorpej-atomic-base:1.6 reinoud-bufcleanup:1.4.0.6 reinoud-bufcleanup-base:1.7 mjf-ufs-trans:1.4.0.4 mjf-ufs-trans-base:1.7 vmlocking:1.4.0.2 vmlocking-base:1.7 ad-audiomp:1.3.0.6 ad-audiomp-base:1.3 yamt-idlelwp:1.3.0.4 post-newlock2-merge:1.3 newlock2-nbase:1.3 yamt-splraiseipl-base5:1.3 yamt-splraiseipl-base4:1.3 yamt-splraiseipl-base3:1.3 abandoned-netbsd-4-base:1.1 abandoned-netbsd-4:1.1.0.10 yamt-splraiseipl-base2:1.2 yamt-splraiseipl:1.1.0.16 yamt-splraiseipl-base:1.1 yamt-pdpolicy-base9:1.1 rpaulo-netinet-merge-pcb-base:1.1 rpaulo-netinet-merge-pcb:1.1.0.14 newlock2:1.1.0.12 newlock2-base:1.3 yamt-pdpolicy-base8:1.1 yamt-pdpolicy-base7:1.1 netbsd-4:1.3.0.2 netbsd-4-base:1.3 gdamore-uart:1.1.0.8 yamt-pdpolicy:1.1.0.6 yamt-pdpolicy-base6:1.1 chap-midi-base:1.1 chap-midi:1.1.0.4 yamt-lazymbuf:1.1.0.2 chap-midi-nbase:1.1; locks; strict; comment @ * @; 1.36 date 2019.01.28.12.53.01; author martin; state Exp; branches; next 1.35; commitid SZqeryRNo4Yh8y9B; 1.35 date 2015.05.02.17.18.03; author rtr; state Exp; branches 1.35.10.1 1.35.18.1; next 1.34; commitid hv2KL4NOsCwhxTjy; 1.34 date 2015.04.26.21.40.49; author rtr; state Exp; branches; next 1.33; commitid mq8S3StXainOa9jy; 1.33 date 2015.04.24.22.32.37; author rtr; state Exp; branches; next 1.32; commitid 0j6avA1NaqYbxTiy; 1.32 date 2015.04.03.20.01.07; author rtr; state Exp; branches; next 1.31; commitid EgdLeu39IiXGmbgy; 1.31 date 2014.08.09.05.33.01; author rtr; state Exp; branches 1.31.2.1 1.31.4.1 1.31.6.1 1.31.10.1; next 1.30; commitid HVMneWUkQESvbELx; 1.30 date 2014.08.08.03.05.45; author rtr; state Exp; branches; next 1.29; commitid 8NeMKMtKugA9pvLx; 1.29 date 2014.08.05.07.55.31; author rtr; state Exp; branches; next 1.28; commitid EyuFMH7eaCHt69Lx; 1.28 date 2014.08.05.05.24.26; author rtr; state Exp; branches; next 1.27; commitid rCGGHCBfnXt6g8Lx; 1.27 date 2014.07.31.03.39.35; author rtr; state Exp; branches; next 1.26; commitid 8risrLdDyvQGQtKx; 1.26 date 2014.07.30.10.04.26; author rtr; state Exp; branches; next 1.25; commitid wecR9bnggHUK0oKx; 1.25 date 2014.07.24.15.12.03; author rtr; state Exp; branches; next 1.24; commitid FqfZrLaT60wYTDJx; 1.24 date 2014.07.23.13.17.18; author rtr; state Exp; branches; next 1.23; commitid jpDIfnvwu0yLivJx; 1.23 date 2014.07.09.14.41.42; author rtr; state Exp; branches; next 1.22; commitid NzQuS2E9B50MdIHx; 1.22 date 2014.07.09.04.54.03; author rtr; state Exp; branches; next 1.21; commitid lxAEoci2TpEaYEHx; 1.21 date 2014.07.07.17.13.56; author rtr; state Exp; branches; next 1.20; commitid QLv3f0q4aA6D7tHx; 1.20 date 2014.07.07.15.13.21; author rtr; state Exp; branches; next 1.19; commitid DcGtb6jpwJ41ssHx; 1.19 date 2014.07.07.07.09.58; author rtr; state Exp; branches; next 1.18; commitid j0pAL7b9uj6HMpHx; 1.18 date 2014.07.06.03.33.33; author rtr; state Exp; branches; next 1.17; commitid Axex7k9b20ezCgHx; 1.17 date 2014.07.01.05.49.18; author rtr; state Exp; branches; next 1.16; commitid shRuuxzC6KhQwDGx; 1.16 date 2014.06.22.08.10.18; author rtr; state Exp; branches; next 1.15; commitid Jd2RTP8bE5ynBuFx; 1.15 date 2014.05.20.19.04.00; author rmind; state Exp; branches; next 1.14; commitid fPeXsPamKx89hjBx; 1.14 date 2014.05.20.18.25.54; author rmind; state Exp; branches; next 1.13; commitid iUG1PXVDoOtq4jBx; 1.13 date 2014.05.19.03.18.57; author rmind; state Exp; branches; next 1.12; commitid K4Di49Esniy756Bx; 1.12 date 2014.05.19.02.51.24; author rmind; state Exp; branches; next 1.11; commitid 9u0WtQcwaTaPV5Bx; 1.11 date 2014.05.18.14.46.16; author rmind; state Exp; branches; next 1.10; commitid vElNFHEJ7uqPU1Bx; 1.10 date 2013.08.29.17.49.21; author rmind; state Exp; branches 1.10.2.1; next 1.9; commitid InHRczMY24nQln3x; 1.9 date 2008.08.06.15.01.24; author plunky; state Exp; branches 1.9.28.1 1.9.38.1 1.9.44.1; next 1.8; 1.8 date 2008.04.24.11.38.37; author ad; state Exp; branches 1.8.2.1 1.8.4.1 1.8.8.1; next 1.7; 1.7 date 2007.04.21.06.15.23; author plunky; state Exp; branches 1.7.28.1 1.7.30.1; next 1.6; 1.6 date 2007.03.31.18.17.13; author plunky; state Exp; branches; next 1.5; 1.5 date 2007.03.30.20.47.03; author plunky; state Exp; branches; next 1.4; 1.4 date 2007.03.05.19.11.54; author plunky; state Exp; branches 1.4.2.1 1.4.4.1; next 1.3; 1.3 date 2006.11.16.01.33.45; author christos; state Exp; branches 1.3.2.1 1.3.4.1 1.3.8.1; next 1.2; 1.2 date 2006.10.12.01.32.37; author christos; state Exp; branches; next 1.1; 1.1 date 2006.06.19.15.44.45; author gdamore; state Exp; branches 1.1.2.1 1.1.4.1 1.1.6.1 1.1.8.1 1.1.12.1 1.1.14.1 1.1.16.1; next ; 1.35.10.1 date 2019.01.29.07.04.09; author msaitoh; state Exp; branches; next ; commitid HtVEXelzThIuaE9B; 1.35.18.1 date 2019.06.10.22.09.47; author christos; state Exp; branches; next ; commitid jtc8rnCzWiEEHGqB; 1.31.2.1 date 2019.01.29.07.57.00; author msaitoh; state Exp; branches; next ; commitid TzSuP0SFXWyNsE9B; 1.31.4.1 date 2015.04.06.15.18.22; author skrll; state Exp; branches; next 1.31.4.2; commitid pz01Zhy7RP6iGxgy; 1.31.4.2 date 2015.06.06.14.40.25; author skrll; state Exp; branches; next ; commitid O6LVO5i6UulOvnoy; 1.31.6.1 date 2019.01.29.08.09.00; author msaitoh; state Exp; branches; next ; commitid 3qJbt0j58HrRwE9B; 1.31.10.1 date 2019.01.29.08.12.17; author msaitoh; state Exp; branches; next ; commitid BSFGbEDnwzX5yE9B; 1.10.2.1 date 2014.08.10.06.56.23; author tls; state Exp; branches; next ; commitid Q3VWPxpfW0ywCMLx; 1.9.28.1 date 2014.05.22.11.41.09; author yamt; state Exp; branches; next ; commitid VUUXuyNWnt3AKwBx; 1.9.38.1 date 2014.08.20.00.04.35; author tls; state Exp; branches; next 1.9.38.2; commitid jTnpym9Qu0o4R1Nx; 1.9.38.2 date 2017.12.03.11.39.03; author jdolecek; state Exp; branches; next ; commitid XcIYRZTAh1LmerhA; 1.9.44.1 date 2013.08.28.15.21.48; author rmind; state Exp; branches; next 1.9.44.2; commitid 6VTytZQcOxQfze3x; 1.9.44.2 date 2014.05.18.17.46.13; author rmind; state Exp; branches; next ; commitid mL5ZYSzpqK6QS2Bx; 1.8.2.1 date 2009.05.04.08.14.17; author yamt; state Exp; branches; next ; 1.8.4.1 date 2008.09.18.04.37.00; author wrstuden; state Exp; branches; next ; 1.8.8.1 date 2008.10.19.22.17.45; author haad; state Exp; branches; next ; 1.7.28.1 date 2008.06.02.13.24.23; author mjf; state Exp; branches; next 1.7.28.2; 1.7.28.2 date 2008.09.28.10.40.57; author mjf; state Exp; branches; next ; 1.7.30.1 date 2008.05.18.12.35.28; author yamt; state Exp; branches; next ; 1.4.2.1 date 2007.04.10.13.26.48; author ad; state Exp; branches; next 1.4.2.2; 1.4.2.2 date 2007.06.08.14.17.41; author ad; state Exp; branches; next ; 1.4.4.1 date 2007.07.11.20.11.13; author mjf; state Exp; branches; next ; 1.3.2.1 date 2007.07.19.16.04.18; author liamjfoy; state Exp; branches; next ; 1.3.4.1 date 2007.03.12.05.59.34; author rmind; state Exp; branches; next 1.3.4.2; 1.3.4.2 date 2007.04.15.16.03.59; author yamt; state Exp; branches; next 1.3.4.3; 1.3.4.3 date 2007.05.07.10.55.56; author yamt; state Exp; branches; next ; 1.3.8.1 date 2007.09.03.07.05.11; author wrstuden; state Exp; branches; next ; 1.1.2.1 date 2006.06.19.15.44.45; author yamt; state dead; branches; next 1.1.2.2; 1.1.2.2 date 2006.06.21.15.10.51; author yamt; state Exp; branches; next 1.1.2.3; 1.1.2.3 date 2006.12.30.20.50.32; author yamt; state Exp; branches; next 1.1.2.4; 1.1.2.4 date 2007.09.03.14.42.42; author yamt; state Exp; branches; next ; 1.1.4.1 date 2006.06.19.15.44.45; author chap; state dead; branches; next 1.1.4.2; 1.1.4.2 date 2006.06.22.03.39.50; author chap; state Exp; branches; next ; 1.1.6.1 date 2006.06.19.15.44.45; author yamt; state dead; branches; next 1.1.6.2; 1.1.6.2 date 2006.06.26.12.53.57; author yamt; state Exp; branches; next ; 1.1.8.1 date 2006.06.19.15.44.45; author gdamore; state dead; branches; next 1.1.8.2; 1.1.8.2 date 2006.07.13.17.49.58; author gdamore; state Exp; branches; next ; 1.1.12.1 date 2006.11.18.21.39.36; author ad; state Exp; branches; next ; 1.1.14.1 date 2006.06.19.15.44.45; author rpaulo; state dead; branches; next 1.1.14.2; 1.1.14.2 date 2006.09.09.02.58.39; author rpaulo; state Exp; branches; next ; 1.1.16.1 date 2006.10.22.06.07.28; author yamt; state Exp; branches; next 1.1.16.2; 1.1.16.2 date 2006.12.10.07.19.06; author yamt; state Exp; branches; next ; desc @@ 1.36 log @Fix memory leaks pointed out by Ilja Van Sprundel: all sendoob() functions are expted to free both passed mbuf chains. @ text @/* $NetBSD: l2cap_socket.c,v 1.35 2015/05/02 17:18:03 rtr Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. * Copyright (c) 2006 Itronix Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of Itronix Inc. may not be used to endorse * or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.35 2015/05/02 17:18:03 rtr Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG #define PRUREQUESTS #define PRCOREQUESTS #endif #include #include #include #include #include #include #include #include #include #include #include /* * L2CAP Sockets * * SOCK_SEQPACKET - normal L2CAP connection * * SOCK_DGRAM - connectionless L2CAP - XXX not yet */ static void l2cap_connecting(void *); static void l2cap_connected(void *); static void l2cap_disconnected(void *, int); static void *l2cap_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); static void l2cap_complete(void *, int); static void l2cap_linkmode(void *, int); static void l2cap_input(void *, struct mbuf *); static const struct btproto l2cap_proto = { l2cap_connecting, l2cap_connected, l2cap_disconnected, l2cap_newconn, l2cap_complete, l2cap_linkmode, l2cap_input, }; /* sysctl variables */ int l2cap_sendspace = 4096; int l2cap_recvspace = 4096; static int l2cap_attach(struct socket *so, int proto) { int error; KASSERT(so->so_pcb == NULL); if (so->so_lock == NULL) { mutex_obj_hold(bt_lock); so->so_lock = bt_lock; solock(so); } KASSERT(solocked(so)); /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ error = soreserve(so, l2cap_sendspace, l2cap_recvspace); if (error) return error; return l2cap_attach_pcb((struct l2cap_channel **)&so->so_pcb, &l2cap_proto, so); } static void l2cap_detach(struct socket *so) { KASSERT(so->so_pcb != NULL); l2cap_detach_pcb((struct l2cap_channel **)&so->so_pcb); KASSERT(so->so_pcb == NULL); } static int l2cap_accept(struct socket *so, struct sockaddr *nam) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; return l2cap_peeraddr_pcb(pcb, (struct sockaddr_bt *)nam); } static int l2cap_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind_pcb(pcb, sa); } static int l2cap_listen(struct socket *so, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; return l2cap_listen_pcb(pcb); } static int l2cap_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(so); return l2cap_connect_pcb(pcb, sa); } static int l2cap_connect2(struct socket *so, struct socket *so2) { KASSERT(solocked(so)); if (so->so_pcb == NULL) return EINVAL; return EOPNOTSUPP; } static int l2cap_disconnect(struct socket *so) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; soisdisconnecting(so); return l2cap_disconnect_pcb(pcb, so->so_linger); } static int l2cap_shutdown(struct socket *so) { KASSERT(solocked(so)); socantsendmore(so); return 0; } static int l2cap_abort(struct socket *so) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; l2cap_disconnect_pcb(pcb, 0); soisdisconnected(so); l2cap_detach(so); return 0; } static int l2cap_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) { return EPASSTHROUGH; } static int l2cap_stat(struct socket *so, struct stat *ub) { KASSERT(solocked(so)); return 0; } static int l2cap_peeraddr(struct socket *so, struct sockaddr *nam) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); KASSERT(pcb != NULL); KASSERT(nam != NULL); return l2cap_peeraddr_pcb(pcb, (struct sockaddr_bt *)nam); } static int l2cap_sockaddr(struct socket *so, struct sockaddr *nam) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); KASSERT(pcb != NULL); KASSERT(nam != NULL); return l2cap_sockaddr_pcb(pcb, (struct sockaddr_bt *)nam); } static int l2cap_rcvd(struct socket *so, int flags, struct lwp *l) { KASSERT(solocked(so)); return EOPNOTSUPP; } static int l2cap_recvoob(struct socket *so, struct mbuf *m, int flags) { KASSERT(solocked(so)); return EOPNOTSUPP; } static int l2cap_send(struct socket *so, struct mbuf *m, struct sockaddr *nam, struct mbuf *control, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct mbuf *m0; int error = 0; KASSERT(solocked(so)); KASSERT(m != NULL); if (control) m_freem(control); if (pcb == NULL) { error = EINVAL; goto release; } if (m->m_pkthdr.len == 0) goto release; if (m->m_pkthdr.len > pcb->lc_omtu) { error = EMSGSIZE; goto release; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { error = ENOMEM; goto release; } sbappendrecord(&so->so_snd, m); return l2cap_send_pcb(pcb, m0); release: if (m) m_freem(m); return error; } static int l2cap_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); m_freem(m); m_freem(control); return EOPNOTSUPP; } static int l2cap_purgeif(struct socket *so, struct ifnet *ifp) { return EOPNOTSUPP; } /* * l2cap_ctloutput(req, socket, sockopt) * * Apply configuration commands to channel. This corresponds to * "Reconfigure Channel Request" in the L2CAP specification. */ int l2cap_ctloutput(int req, struct socket *so, struct sockopt *sopt) { struct l2cap_channel *pcb = so->so_pcb; int err = 0; DPRINTFN(2, "%s\n", prcorequests[req]); if (pcb == NULL) return EINVAL; if (sopt->sopt_level != BTPROTO_L2CAP) return ENOPROTOOPT; switch(req) { case PRCO_GETOPT: err = l2cap_getopt(pcb, sopt); break; case PRCO_SETOPT: err = l2cap_setopt(pcb, sopt); break; default: err = ENOPROTOOPT; break; } return err; } /********************************************************************** * * L2CAP Protocol socket callbacks * */ static void l2cap_connecting(void *arg) { struct socket *so = arg; DPRINTF("Connecting\n"); soisconnecting(so); } static void l2cap_connected(void *arg) { struct socket *so = arg; DPRINTF("Connected\n"); soisconnected(so); } static void l2cap_disconnected(void *arg, int err) { struct socket *so = arg; DPRINTF("Disconnected (%d)\n", err); so->so_error = err; soisdisconnected(so); } static void * l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) { struct socket *so = arg; DPRINTF("New Connection\n"); so = sonewconn(so, false); if (so == NULL) return NULL; soisconnecting(so); return so->so_pcb; } static void l2cap_complete(void *arg, int count) { struct socket *so = arg; while (count-- > 0) sbdroprecord(&so->so_snd); sowwakeup(so); } static void l2cap_linkmode(void *arg, int new) { struct socket *so = arg; struct sockopt sopt; int mode; DPRINTF("auth %s, encrypt %s, secure %s\n", (new & L2CAP_LM_AUTH ? "on" : "off"), (new & L2CAP_LM_ENCRYPT ? "on" : "off"), (new & L2CAP_LM_SECURE ? "on" : "off")); sockopt_init(&sopt, BTPROTO_L2CAP, SO_L2CAP_LM, 0); (void)l2cap_getopt(so->so_pcb, &sopt); (void)sockopt_getint(&sopt, &mode); sockopt_destroy(&sopt); if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH)) || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT)) || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))) l2cap_disconnect_pcb(so->so_pcb, 0); } static void l2cap_input(void *arg, struct mbuf *m) { struct socket *so = arg; if (m->m_pkthdr.len > sbspace(&so->so_rcv)) { printf("%s: packet (%d bytes) dropped (socket buffer full)\n", __func__, m->m_pkthdr.len); m_freem(m); return; } DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len); sbappendrecord(&so->so_rcv, m); sorwakeup(so); } PR_WRAP_USRREQS(l2cap) #define l2cap_attach l2cap_attach_wrapper #define l2cap_detach l2cap_detach_wrapper #define l2cap_accept l2cap_accept_wrapper #define l2cap_bind l2cap_bind_wrapper #define l2cap_listen l2cap_listen_wrapper #define l2cap_connect l2cap_connect_wrapper #define l2cap_connect2 l2cap_connect2_wrapper #define l2cap_disconnect l2cap_disconnect_wrapper #define l2cap_shutdown l2cap_shutdown_wrapper #define l2cap_abort l2cap_abort_wrapper #define l2cap_ioctl l2cap_ioctl_wrapper #define l2cap_stat l2cap_stat_wrapper #define l2cap_peeraddr l2cap_peeraddr_wrapper #define l2cap_sockaddr l2cap_sockaddr_wrapper #define l2cap_rcvd l2cap_rcvd_wrapper #define l2cap_recvoob l2cap_recvoob_wrapper #define l2cap_send l2cap_send_wrapper #define l2cap_sendoob l2cap_sendoob_wrapper #define l2cap_purgeif l2cap_purgeif_wrapper const struct pr_usrreqs l2cap_usrreqs = { .pr_attach = l2cap_attach, .pr_detach = l2cap_detach, .pr_accept = l2cap_accept, .pr_bind = l2cap_bind, .pr_listen = l2cap_listen, .pr_connect = l2cap_connect, .pr_connect2 = l2cap_connect2, .pr_disconnect = l2cap_disconnect, .pr_shutdown = l2cap_shutdown, .pr_abort = l2cap_abort, .pr_ioctl = l2cap_ioctl, .pr_stat = l2cap_stat, .pr_peeraddr = l2cap_peeraddr, .pr_sockaddr = l2cap_sockaddr, .pr_rcvd = l2cap_rcvd, .pr_recvoob = l2cap_recvoob, .pr_send = l2cap_send, .pr_sendoob = l2cap_sendoob, .pr_purgeif = l2cap_purgeif, }; @ 1.35 log @make connect syscall use sockaddr_big and modify pr_{send,connect} nam parameter type from buf * to sockaddr *. final commit for parameter type changes to protocol user requests * bump kernel version to 7.99.15 for parameter type changes to pr_{send,connect} @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.34 2015/04/26 21:40:49 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.34 2015/04/26 21:40:49 rtr Exp $"); d341 2 a342 4 if (m) m_freem(m); if (control) m_freem(control); @ 1.35.18.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.36 2019/01/28 12:53:01 martin Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.36 2019/01/28 12:53:01 martin Exp $"); d341 4 a344 2 m_freem(m); m_freem(control); @ 1.35.10.1 log @Pull up following revision(s) (requested by martin in ticket #1175): sys/net/link_proto.c 1.37 sys/netatalk/ddp_usrreq.c 1.72 sys/netbt/hci_socket.c 1.46 sys/netbt/l2cap_socket.c 1.36 sys/netbt/rfcomm_socket.c 1.38 sys/netbt/sco_socket.c 1.38 sys/netinet/sctp_usrreq.c 1.14 sys/netinet/tcp_usrreq.c 1.223 sys/netinet6/raw_ip6.c 1.173 sys/netinet6/sctp6_usrreq.c 1.17 sys/netinet6/udp6_usrreq.c 1.146 sys/netmpls/mpls_proto.c 1.32 sys/netnatm/natm.c patch Fix memory leaks pointed out by Ilja Van Sprundel: all sendoob() functions are expted to free both passed mbuf chains. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.35 2015/05/02 17:18:03 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.35 2015/05/02 17:18:03 rtr Exp $"); d341 4 a344 2 m_freem(m); m_freem(control); @ 1.34 log @remove pr_generic from struct pr_usrreqs and all implementations of pr_generic in protocols. bump to 7.99.13 approved by rmind@@ @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.33 2015/04/24 22:32:37 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.33 2015/04/24 22:32:37 rtr Exp $"); d168 1 a168 1 l2cap_connect(struct socket *so, struct mbuf *nam, struct lwp *l) d171 1 a171 1 struct sockaddr_bt *sa; a178 1 sa = mtod(nam, struct sockaddr_bt *); d294 1 a294 1 l2cap_send(struct socket *so, struct mbuf *m, struct mbuf *nam, @ 1.33 log @make accept, getsockname and getpeername syscalls use sockaddr_big and modify pr_{accept,sockname,peername} nam parameter type from mbuf * to sockaddr *. * retained use of mbuftypes[MT_SONAME] for now. * bump to netbsd version 7.99.12 for parameter type change. patch posted to tech-net@@ 2015/04/19 @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.32 2015/04/03 20:01:07 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.32 2015/04/03 20:01:07 rtr Exp $"); a357 64 * User Request. * up is socket * m is optional mbuf chain containing message * ctl is either * optional mbuf chain containing socket options * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ static int l2cap_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct l2cap_channel *pcb = up->so_pcb; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); KASSERT(req != PRU_ATTACH); KASSERT(req != PRU_DETACH); KASSERT(req != PRU_ACCEPT); KASSERT(req != PRU_BIND); KASSERT(req != PRU_LISTEN); KASSERT(req != PRU_CONNECT); KASSERT(req != PRU_CONNECT2); KASSERT(req != PRU_DISCONNECT); KASSERT(req != PRU_SHUTDOWN); KASSERT(req != PRU_ABORT); KASSERT(req != PRU_CONTROL); KASSERT(req != PRU_SENSE); KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVD); KASSERT(req != PRU_RCVOOB); KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); KASSERT(req != PRU_PURGEIF); if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; } /* a517 1 #define l2cap_usrreq l2cap_usrreq_wrapper a538 1 .pr_generic = l2cap_usrreq, @ 1.32 log @* change pr_bind to accept struct sockaddr * instead of struct mbuf * * update protocol bind implementations to use/expect sockaddr * instead of mbuf * * introduce sockaddr_big struct for storage of addr data passed via sys_bind; sockaddr_big is of sufficient size and alignment to accommodate all addr data sizes received. * modify sys_bind to allocate sockaddr_big instead of using an mbuf. * bump kernel version to 7.99.9 for change to pr_bind() parameter type. Patch posted to tech-net@@ http://mail-index.netbsd.org/tech-net/2015/03/15/msg005004.html The choice to use a new structure sockaddr_big has been retained since changing sockaddr_storage size would lead to unnecessary ABI change. The use of the new structure does not preclude future work that increases the size of sockaddr_storage and at that time sockaddr_big may be trivially replaced. Tested by mrg@@ and myself, discussed with rmind@@, posted to tech-net@@ @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $"); d120 1 a120 1 l2cap_accept(struct socket *so, struct mbuf *nam) a122 1 struct sockaddr_bt *sa; d130 1 a130 3 sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr_pcb(pcb, sa); d255 1 a255 1 l2cap_peeraddr(struct socket *so, struct mbuf *nam) a257 1 struct sockaddr_bt *sa; d263 1 a263 3 sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr_pcb(pcb, sa); d267 1 a267 1 l2cap_sockaddr(struct socket *so, struct mbuf *nam) a269 1 struct sockaddr_bt *sa; d275 1 a275 3 sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr_pcb(pcb, sa); @ 1.31 log @split PRU_CONNECT2 & PRU_PURGEIF function out of pr_generic() usrreq switches and put into separate functions - always KASSERT(solocked(so)) even if not implemented (for PRU_CONNECT2 only) - replace calls to pr_generic() with req = PRU_CONNECT2 with calls to pr_connect2() - replace calls to pr_generic() with req = PRU_PURGEIF with calls to pr_purgeif() put common code from unp_connect2() (used by unp_connect() into unp_connect1() and call out to it when needed patch only briefly reviewed by rmind@@ @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.30 2014/08/08 03:05:45 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.30 2014/08/08 03:05:45 rtr Exp $"); d137 1 a137 1 l2cap_bind(struct socket *so, struct mbuf *nam, struct lwp *l) d140 1 a140 1 struct sockaddr_bt *sa; a147 1 sa = mtod(nam, struct sockaddr_bt *); @ 1.31.10.1 log @Pull up following revision(s) (requested by martin in ticket #1676): sys/net/link_proto.c 1.37 sys/netatalk/ddp_usrreq.c 1.72 sys/netbt/hci_socket.c 1.46 sys/netbt/l2cap_socket.c 1.36 sys/netbt/rfcomm_socket.c 1.38 sys/netbt/sco_socket.c 1.38 sys/netinet/tcp_usrreq.c 1.223 via patch sys/netinet6/raw_ip6.c 1.173 sys/netinet6/udp6_usrreq.c 1.146 sys/netmpls/mpls_proto.c 1.32 sys/netnatm/natm.c patch Fix memory leaks pointed out by Ilja Van Sprundel: all sendoob() functions are expted to free both passed mbuf chains. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $"); d352 4 a355 2 m_freem(m); m_freem(control); @ 1.31.6.1 log @Pull up following revision(s) (requested by martin in ticket #1676): sys/net/link_proto.c 1.37 sys/netatalk/ddp_usrreq.c 1.72 sys/netbt/hci_socket.c 1.46 sys/netbt/l2cap_socket.c 1.36 sys/netbt/rfcomm_socket.c 1.38 sys/netbt/sco_socket.c 1.38 sys/netinet/tcp_usrreq.c 1.223 via patch sys/netinet6/raw_ip6.c 1.173 sys/netinet6/udp6_usrreq.c 1.146 sys/netmpls/mpls_proto.c 1.32 sys/netnatm/natm.c patch Fix memory leaks pointed out by Ilja Van Sprundel: all sendoob() functions are expted to free both passed mbuf chains. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $"); d352 4 a355 2 m_freem(m); m_freem(control); @ 1.31.2.1 log @Pull up following revision(s) (requested by martin in ticket #1676): sys/net/link_proto.c 1.37 sys/netatalk/ddp_usrreq.c 1.72 sys/netbt/hci_socket.c 1.46 sys/netbt/l2cap_socket.c 1.36 sys/netbt/rfcomm_socket.c 1.38 sys/netbt/sco_socket.c 1.38 sys/netinet/tcp_usrreq.c 1.223 via patch sys/netinet6/raw_ip6.c 1.173 sys/netinet6/udp6_usrreq.c 1.146 sys/netmpls/mpls_proto.c 1.32 sys/netnatm/natm.c patch Fix memory leaks pointed out by Ilja Van Sprundel: all sendoob() functions are expted to free both passed mbuf chains. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $"); d352 4 a355 2 m_freem(m); m_freem(control); @ 1.31.4.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.32 2015/04/03 20:01:07 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.32 2015/04/03 20:01:07 rtr Exp $"); d137 1 a137 1 l2cap_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) d140 1 a140 1 struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; d148 1 @ 1.31.4.2 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.31.4.1 2015/04/06 15:18:22 skrll Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.31.4.1 2015/04/06 15:18:22 skrll Exp $"); d120 1 a120 1 l2cap_accept(struct socket *so, struct sockaddr *nam) d123 1 d131 3 a133 1 return l2cap_peeraddr_pcb(pcb, (struct sockaddr_bt *)nam); d171 1 a171 1 l2cap_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) d174 1 a174 1 struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; d182 1 d258 1 a258 1 l2cap_peeraddr(struct socket *so, struct sockaddr *nam) d261 1 d267 3 a269 1 return l2cap_peeraddr_pcb(pcb, (struct sockaddr_bt *)nam); d273 1 a273 1 l2cap_sockaddr(struct socket *so, struct sockaddr *nam) d276 1 d282 3 a284 1 return l2cap_sockaddr_pcb(pcb, (struct sockaddr_bt *)nam); d304 1 a304 1 l2cap_send(struct socket *so, struct mbuf *m, struct sockaddr *nam, d367 64 d591 1 d613 1 @ 1.30 log @split PRU_RCVD function out of pr_generic() usrreq switches and put into separate functions - always KASSERT(solocked(so)) even if not implemented - replace calls to pr_generic() with req = PRU_RCVD with calls to pr_rcvd() @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.29 2014/08/05 07:55:31 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.29 2014/08/05 07:55:31 rtr Exp $"); d195 11 d360 7 a372 1 * optional interface pointer PRU_PURGEIF d392 1 d404 1 a404 5 switch (req) { case PRU_PURGEIF: return EOPNOTSUPP; } a411 1 case PRU_CONNECT2: d579 1 d591 1 d601 1 d613 1 @ 1.29 log @split PRU_SEND function out of pr_generic() usrreq switches and put into separate functions xxx_send(struct socket *, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *) - always KASSERT(solocked(so)) even if not implemented - replace calls to pr_generic() with req = PRU_SEND with calls to pr_send() rename existing functions that operate on PCB for consistency (and to free up their names for xxx_send() PRUs - l2cap_send() -> l2cap_send_pcb() - sco_send() -> sco_send_pcb() - rfcomm_send() -> rfcomm_send_pcb() patch reviewed by rmind @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.28 2014/08/05 05:24:26 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.28 2014/08/05 05:24:26 rtr Exp $"); d278 8 a352 3 * nam is either * optional mbuf chain containing an address * message flags (PRU_RCVD) d382 1 a397 3 case PRU_RCVD: return EOPNOTSUPP; /* (no release) */ d573 1 d593 1 @ 1.28 log @revert the removal of struct lwp * parameter from bind, listen and connect user requests. this should resolve the issue relating to nfs client hangs presented recently by wiz on current-users@@ @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.27 2014/07/31 03:39:35 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.27 2014/07/31 03:39:35 rtr Exp $"); d286 43 a360 1 struct mbuf *m0; d378 1 a391 22 case PRU_SEND: KASSERT(m != NULL); if (m->m_pkthdr.len == 0) break; if (m->m_pkthdr.len > pcb->lc_omtu) { err = EMSGSIZE; break; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { err = ENOMEM; break; } if (ctl) /* no use for that */ m_freem(ctl); sbappendrecord(&up->so_snd, m); return l2cap_send(pcb, m0); d571 1 d590 1 @ 1.27 log @split PRU_DISCONNECT, PRU_SHUTDOWN and PRU_ABORT function out of pr_generic() usrreq switches and put into separate functions xxx_disconnect(struct socket *) xxx_shutdown(struct socket *) xxx_abort(struct socket *) - always KASSERT(solocked(so)) even if not implemented - replace calls to pr_generic() with req = PRU_{DISCONNECT,SHUTDOWN,ABORT} with calls to pr_{disconnect,shutdown,abort}() respectively rename existing internal functions used to implement above functionality to permit use of the names for xxx_{disconnect,shutdown,abort}(). - {l2cap,sco,rfcomm}_disconnect() -> {l2cap,sco,rfcomm}_disconnect_pcb() - {unp,rip,tcp}_disconnect() -> {unp,rip,tcp}_disconnect1() - unp_shutdown() -> unp_shutdown1() patch reviewed by rmind @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.26 2014/07/30 10:04:26 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.26 2014/07/30 10:04:26 rtr Exp $"); d137 1 a137 1 l2cap_bind(struct socket *so, struct mbuf *nam) d159 1 a159 1 l2cap_listen(struct socket *so) d172 1 a172 1 l2cap_connect(struct socket *so, struct mbuf *nam) @ 1.26 log @split PRU_CONNECT function out of pr_generic() usrreq switches and put into seaparate functions xxx_listen(struct socket *, struct mbuf *) - always KASSERT(solocked(so)) and KASSERT(nam != NULL) - replace calls to pr_generic() with req = PRU_CONNECT with pr_connect() - rename existin {l2cap,sco,rfcomm}_connect() to {l2cap,sco,rfcomm}_connect_pcb() respectively to permit naming consistency with other protocols functions. - drop struct lwp * parameter from unp_connect() and at_pcbconnect() and use curlwp instead where appropriate. patch reviewed by rmind @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.25 2014/07/24 15:12:03 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.25 2014/07/24 15:12:03 rtr Exp $"); d195 39 d328 3 a348 14 case PRU_DISCONNECT: soisdisconnecting(up); return l2cap_disconnect(pcb, up->so_linger); case PRU_ABORT: l2cap_disconnect(pcb, 0); soisdisconnected(up); l2cap_detach(up); return 0; case PRU_SHUTDOWN: socantsendmore(up); break; d513 1 a513 1 l2cap_disconnect(so->so_pcb, 0); d542 3 d560 3 @ 1.25 log @split PRU_BIND and PRU_LISTEN function out of pr_generic() usrreq switches and put into separate functions xxx_bind(struct socket *, struct mbuf *) xxx_listen(struct socket *) - always KASSERT(solocked(so)) even if not implemented - replace calls to pr_generic() with req = PRU_BIND with call to pr_bind() - replace calls to pr_generic() with req = PRU_LISTEN with call to pr_listen() - drop struct lwp * parameter from at_pcbsetaddr(), in_pcbbind() and unp_bind() and always use curlwp. rename existing functions that operate on PCB for consistency (and to free up their names for xxx_{bind,listen}() PRUs - l2cap_{bind,listen}() -> l2cap_{bind,listen}_pcb() - sco_{bind,listen}() -> sco_{bind,listen}_pcb() - rfcomm_{bind,listen}() -> rfcomm_{bind,listen}_pcb() patch reviewed by rmind welcome to netbsd 6.99.48 @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.24 2014/07/23 13:17:18 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.24 2014/07/23 13:17:18 rtr Exp $"); d172 23 a278 1 struct sockaddr_bt *sa; d288 1 a316 13 case PRU_CONNECT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return l2cap_connect(pcb, sa); d513 1 d528 1 @ 1.24 log @split PRU_SENDOOB and PRU_RCVOOB function out of pr_generic() usrreq switches and put into separate functions xxx_sendoob(struct socket *, struct mbuf *, struct mbuf *) xxx_recvoob(struct socket *, struct mbuf *, int) - always KASSERT(solocked(so)) even if request is not implemented - replace calls to pr_generic() with req = PRU_{SEND,RCV}OOB with calls to pr_{send,recv}oob() respectively. there is still some tweaking of m_freem(m) and m_freem(control) to come for consistency. not performed with this commit for clarity. reviewed by rmind @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.23 2014/07/09 14:41:42 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.23 2014/07/09 14:41:42 rtr Exp $"); d137 35 d264 2 a293 12 case PRU_BIND: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind(pcb, sa); a335 3 case PRU_LISTEN: return l2cap_listen(pcb); d501 2 d515 2 @ 1.23 log @* split PRU_ACCEPT function out of pr_generic() usrreq switches and put into a separate function xxx_accept(struct socket *, struct mbuf *) note: future cleanup will take place to remove struct mbuf parameter type and replace it with a more appropriate type. patch reviewed by rmind @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.22 2014/07/09 04:54:03 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.22 2014/07/09 04:54:03 rtr Exp $"); d180 21 d233 2 a308 1 case PRU_RCVOOB: a314 1 case PRU_SENDOOB: d483 2 d495 2 @ 1.22 log @* split PRU_PEERADDR and PRU_SOCKADDR function out of pr_generic() usrreq switches and put into separate functions xxx_{peer,sock}addr(struct socket *, struct mbuf *). - KASSERT(solocked(so)) always in new functions even if request is not implemented - KASSERT(pcb != NULL) and KASSERT(nam) if the request is implemented and not for tcp. * for tcp roll #ifdef KPROF and #ifdef DEBUG code from tcp_usrreq() into easier to cut & paste functions tcp_debug_capture() and tcp_debug_trace() - functions provided by rmind - remaining use of PRU_{PEER,SOCK}ADDR #define to be removed in a future commit. * rename netbt functions to permit consistency of pru function names (as has been done with other requests already split out). - l2cap_{peer,sock}addr() -> l2cap_{peer,sock}_addr_pcb() - rfcomm_{peer,sock}addr() -> rfcomm_{peer,sock}_addr_pcb() - sco_{peer,sock}addr() -> sco_{peer,sock}_addr_pcb() * split/refactor do_sys_getsockname(lwp, fd, which, nam) into two functions do_sys_get{peer,sock}name(fd, nam). - move PRU_PEERADDR handling into do_sys_getpeername() from do_sys_getsockname() - have svr4_stream directly call do_sys_get{sock,peer}name() respectively instead of providing `which' & fix a DPRINTF string that incorrectly wrote "getpeername" when it meant "getsockname" - fix sys_getpeername() and sys_getsockname() to call do_sys_get{sock,peer}name() without `which' and `lwp' & adjust comments - bump kernel version for removal of lwp & which parameters from do_sys_getsockname() note: future cleanup to remove struct mbuf * abuse in xxx_{peer,sock}name() still to come, not done in this commit since it is easier to do post split. patch reviewed by rmind welcome to 6.99.47 @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.21 2014/07/07 17:13:56 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.21 2014/07/07 17:13:56 rtr Exp $"); d120 17 d207 1 a291 6 case PRU_ACCEPT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr_pcb(pcb, sa); d457 1 d467 1 @ 1.21 log @* sprinkle KASSERT(solocked(so)); in all pr_stat() functions. * fix remaining inconsistent struct socket parameter names. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.20 2014/07/07 15:13:21 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.20 2014/07/07 15:13:21 rtr Exp $"); d133 30 d192 2 a240 12 case PRU_PEERADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr(pcb, sa); d278 1 a278 1 return l2cap_peeraddr(pcb, sa); d447 2 d456 2 @ 1.20 log @backout change that made pr_stat return EOPNOTSUPP for protocols that were not filling in struct stat. decision made after further discussion with rmind and investigation of how other operating systems behave. soo_stat() is doing just enough to be able to call what gets returned valid and thus justifys a return of success. additional review will be done to determine of the pr_stat functions that were already returning EOPNOTSUPP can be considered successful with what soo_stat() is doing. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.19 2014/07/07 07:09:58 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.19 2014/07/07 07:09:58 rtr Exp $"); d120 1 a120 1 l2cap_ioctl(struct socket *up, u_long cmd, void *nam, struct ifnet *ifp) d128 2 @ 1.19 log @* have pr_stat return EOPNOTSUPP consistently for all protocols that do not fill in struct stat instead of returning success. * in pr_stat remove all checks for non-NULL so->so_pcb except where the pcb is actually used (i.e. cases where we don't return EOPNOTSUPP). proposed on tech-net@@ @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.18 2014/07/06 03:33:33 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.18 2014/07/06 03:33:33 rtr Exp $"); d128 1 a128 1 return EOPNOTSUPP; @ 1.18 log @* split PRU_SENSE functionality out of xxx_usrreq() switches and place into separate xxx_stat(struct socket *, struct stat *) functions. * replace calls using pr_generic with req == PRU_SENSE with pr_stat(). further change will follow that cleans up the pattern used to extract the pcb and test for its presence. reviewed by rmind @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.17 2014/07/01 05:49:18 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.17 2014/07/01 05:49:18 rtr Exp $"); d128 1 a128 6 struct l2cap_channel *pcb = so->so_pcb; if (pcb == NULL) return EINVAL; return 0; @ 1.17 log @fix parameter types in pr_ioctl, called xx_control() functions and remove abuse of pointer to struct mbuf type. param2 changed to u_long type and uses parameter name 'cmd' (ioctl command) param3 changed to void * type and uses parameter name 'data' param4 changed to struct ifnet * and uses parameter name 'ifp' param5 has been removed (formerly struct lwp *) and uses of 'l' have been replaced with curlwp from curproc(9). callers have had (now unnecessary) casts to struct mbuf * removed, called code has had (now unnecessary) casts to u_long, void * and struct ifnet * respectively removed. reviewed by rmind@@ @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.16 2014/06/22 08:10:18 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.16 2014/06/22 08:10:18 rtr Exp $"); d125 11 d164 1 a249 3 case PRU_SENSE: return 0; /* (no release) */ d429 1 d436 1 @ 1.16 log @* split PRU_CONTROL functionality out of xxx_userreq() switches and place into separate xxx_ioctl() functions. * place KASSERT(req != PRU_CONTROL) inside xxx_userreq() as it is now inappropriate for req = PRU_CONTROL in xxx_userreq(). * replace calls to pr_generic() with req = PRU_CONTROL with pr_ioctl(). * remove & fixup references to PRU_CONTROL xxx_userreq() function comments. * fix various comments references for xxx_userreq() that mentioned PRU_CONTROL as xxx_userreq() no longer handles the request. a further change will follow to fix parameter and naming inconsistencies retained from original code. Reviewed by rmind@@ @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.15 2014/05/20 19:04:00 rmind Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.15 2014/05/20 19:04:00 rmind Exp $"); d120 1 a120 2 l2cap_ioctl(struct socket *up, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) @ 1.15 log @Adjust PR_WRAP_USRREQS() to include the attach/detach functions. We still need the kernel-lock for some corner cases. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.14 2014/05/20 18:25:54 rmind Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.14 2014/05/20 18:25:54 rmind Exp $"); d119 7 d129 1 a129 3 * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) a131 1 * ioctl data (PRU_CONTROL) d135 1 a135 1 * optional interface pointer (PRU_CONTROL, PRU_PURGEIF) d153 1 a155 3 case PRU_CONTROL: return EPASSTHROUGH; d420 1 d426 1 @ 1.14 log @netbt: rename some attach/detach functions to have _pcb suffix, so we could use standard attach/detach naming for pr_usrreq functions. No functional change. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.13 2014/05/19 03:18:57 rmind Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.13 2014/05/19 03:18:57 rmind Exp $"); d414 1 a414 1 PR_WRAP_USRREQ(l2cap_usrreq) d416 2 a417 2 //#define l2cap_attach l2cap_attach_wrapper //#define l2cap_detach l2cap_detach_wrapper @ 1.13 log @l2cap_detach1: fix gcc warning for non-DIAGNOSTIC case. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.12 2014/05/19 02:51:24 rmind Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.12 2014/05/19 02:51:24 rmind Exp $"); d86 1 a86 1 l2cap_attach1(struct socket *so, int proto) d107 1 a107 1 return l2cap_attach((struct l2cap_channel **)&so->so_pcb, d112 1 a112 1 l2cap_detach1(struct socket *so) d115 1 a115 1 l2cap_detach((struct l2cap_channel **)&so->so_pcb); d171 1 a171 1 l2cap_detach1(up); d416 2 d421 2 a422 2 .pr_attach = l2cap_attach1, .pr_detach = l2cap_detach1, @ 1.12 log @- Split off PRU_ATTACH and PRU_DETACH logic into separate functions. - Replace malloc with kmem and eliminate M_PCB while here. - Sprinkle more asserts. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.11 2014/05/18 14:46:16 rmind Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.11 2014/05/18 14:46:16 rmind Exp $"); d114 1 a114 3 struct l2cap_channel *pcb = so->so_pcb; KASSERT(pcb != NULL); @ 1.11 log @Add struct pr_usrreqs with a pr_generic function and prepare for the dismantling of pr_usrreq in the protocols; no functional change intended. PRU_ATTACH/PRU_DETACH changes will follow soon. Bump for struct protosw. Welcome to 6.99.62! @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.10 2013/08/29 17:49:21 rmind Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.10 2013/08/29 17:49:21 rmind Exp $"); d85 36 a129 1 * optionally protocol number (PRU_ATTACH) d149 2 a157 20 case PRU_ATTACH: if (up->so_lock == NULL) { mutex_obj_hold(bt_lock); up->so_lock = bt_lock; solock(up); } KASSERT(solocked(up)); if (pcb != NULL) return EINVAL; /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ err = soreserve(up, l2cap_sendspace, l2cap_recvspace); if (err) return err; return l2cap_attach((struct l2cap_channel **)&up->so_pcb, &l2cap_proto, up); d173 2 a174 3 /* fall through to */ case PRU_DETACH: return l2cap_detach((struct l2cap_channel **)&up->so_pcb); d421 2 @ 1.10 log @Remove SS_ISCONFIRMING, it is unused and TP4 will not come back. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $"); d104 1 a104 1 int d399 8 @ 1.10.2.1 log @Rebase. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.31 2014/08/09 05:33:01 rtr Exp $"); a84 282 static int l2cap_attach(struct socket *so, int proto) { int error; KASSERT(so->so_pcb == NULL); if (so->so_lock == NULL) { mutex_obj_hold(bt_lock); so->so_lock = bt_lock; solock(so); } KASSERT(solocked(so)); /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ error = soreserve(so, l2cap_sendspace, l2cap_recvspace); if (error) return error; return l2cap_attach_pcb((struct l2cap_channel **)&so->so_pcb, &l2cap_proto, so); } static void l2cap_detach(struct socket *so) { KASSERT(so->so_pcb != NULL); l2cap_detach_pcb((struct l2cap_channel **)&so->so_pcb); KASSERT(so->so_pcb == NULL); } static int l2cap_accept(struct socket *so, struct mbuf *nam) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr_pcb(pcb, sa); } static int l2cap_bind(struct socket *so, struct mbuf *nam, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind_pcb(pcb, sa); } static int l2cap_listen(struct socket *so, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; return l2cap_listen_pcb(pcb); } static int l2cap_connect(struct socket *so, struct mbuf *nam, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(so); return l2cap_connect_pcb(pcb, sa); } static int l2cap_connect2(struct socket *so, struct socket *so2) { KASSERT(solocked(so)); if (so->so_pcb == NULL) return EINVAL; return EOPNOTSUPP; } static int l2cap_disconnect(struct socket *so) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; soisdisconnecting(so); return l2cap_disconnect_pcb(pcb, so->so_linger); } static int l2cap_shutdown(struct socket *so) { KASSERT(solocked(so)); socantsendmore(so); return 0; } static int l2cap_abort(struct socket *so) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; l2cap_disconnect_pcb(pcb, 0); soisdisconnected(so); l2cap_detach(so); return 0; } static int l2cap_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) { return EPASSTHROUGH; } static int l2cap_stat(struct socket *so, struct stat *ub) { KASSERT(solocked(so)); return 0; } static int l2cap_peeraddr(struct socket *so, struct mbuf *nam) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(pcb != NULL); KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr_pcb(pcb, sa); } static int l2cap_sockaddr(struct socket *so, struct mbuf *nam) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(pcb != NULL); KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr_pcb(pcb, sa); } static int l2cap_rcvd(struct socket *so, int flags, struct lwp *l) { KASSERT(solocked(so)); return EOPNOTSUPP; } static int l2cap_recvoob(struct socket *so, struct mbuf *m, int flags) { KASSERT(solocked(so)); return EOPNOTSUPP; } static int l2cap_send(struct socket *so, struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct mbuf *m0; int error = 0; KASSERT(solocked(so)); KASSERT(m != NULL); if (control) m_freem(control); if (pcb == NULL) { error = EINVAL; goto release; } if (m->m_pkthdr.len == 0) goto release; if (m->m_pkthdr.len > pcb->lc_omtu) { error = EMSGSIZE; goto release; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { error = ENOMEM; goto release; } sbappendrecord(&so->so_snd, m); return l2cap_send_pcb(pcb, m0); release: if (m) m_freem(m); return error; } static int l2cap_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); if (m) m_freem(m); if (control) m_freem(control); return EOPNOTSUPP; } static int l2cap_purgeif(struct socket *so, struct ifnet *ifp) { return EOPNOTSUPP; } d88 8 a95 1 * m is optional mbuf chain containing message d98 1 d104 1 a104 1 static int d109 2 d114 28 a141 19 KASSERT(req != PRU_ATTACH); KASSERT(req != PRU_DETACH); KASSERT(req != PRU_ACCEPT); KASSERT(req != PRU_BIND); KASSERT(req != PRU_LISTEN); KASSERT(req != PRU_CONNECT); KASSERT(req != PRU_CONNECT2); KASSERT(req != PRU_DISCONNECT); KASSERT(req != PRU_SHUTDOWN); KASSERT(req != PRU_ABORT); KASSERT(req != PRU_CONTROL); KASSERT(req != PRU_SENSE); KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVD); KASSERT(req != PRU_RCVOOB); KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); KASSERT(req != PRU_PURGEIF); d149 92 d379 1 a379 1 l2cap_disconnect_pcb(so->so_pcb, 0); a398 46 PR_WRAP_USRREQS(l2cap) #define l2cap_attach l2cap_attach_wrapper #define l2cap_detach l2cap_detach_wrapper #define l2cap_accept l2cap_accept_wrapper #define l2cap_bind l2cap_bind_wrapper #define l2cap_listen l2cap_listen_wrapper #define l2cap_connect l2cap_connect_wrapper #define l2cap_connect2 l2cap_connect2_wrapper #define l2cap_disconnect l2cap_disconnect_wrapper #define l2cap_shutdown l2cap_shutdown_wrapper #define l2cap_abort l2cap_abort_wrapper #define l2cap_ioctl l2cap_ioctl_wrapper #define l2cap_stat l2cap_stat_wrapper #define l2cap_peeraddr l2cap_peeraddr_wrapper #define l2cap_sockaddr l2cap_sockaddr_wrapper #define l2cap_rcvd l2cap_rcvd_wrapper #define l2cap_recvoob l2cap_recvoob_wrapper #define l2cap_send l2cap_send_wrapper #define l2cap_sendoob l2cap_sendoob_wrapper #define l2cap_purgeif l2cap_purgeif_wrapper #define l2cap_usrreq l2cap_usrreq_wrapper const struct pr_usrreqs l2cap_usrreqs = { .pr_attach = l2cap_attach, .pr_detach = l2cap_detach, .pr_accept = l2cap_accept, .pr_bind = l2cap_bind, .pr_listen = l2cap_listen, .pr_connect = l2cap_connect, .pr_connect2 = l2cap_connect2, .pr_disconnect = l2cap_disconnect, .pr_shutdown = l2cap_shutdown, .pr_abort = l2cap_abort, .pr_ioctl = l2cap_ioctl, .pr_stat = l2cap_stat, .pr_peeraddr = l2cap_peeraddr, .pr_sockaddr = l2cap_sockaddr, .pr_rcvd = l2cap_rcvd, .pr_recvoob = l2cap_recvoob, .pr_send = l2cap_send, .pr_sendoob = l2cap_sendoob, .pr_purgeif = l2cap_purgeif, .pr_generic = l2cap_usrreq, }; @ 1.9 log @Convert socket options code to use a sockopt structure instead of laying everything into an mbuf. approved by core @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.8 2008/04/24 11:38:37 ad Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.8 2008/04/24 11:38:37 ad Exp $"); d339 1 a339 1 so = sonewconn(so, 0); @ 1.9.38.1 log @Rebase to HEAD as of a few days ago. @ text @d1 1 a1 1 /* $NetBSD$ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD$"); a84 282 static int l2cap_attach(struct socket *so, int proto) { int error; KASSERT(so->so_pcb == NULL); if (so->so_lock == NULL) { mutex_obj_hold(bt_lock); so->so_lock = bt_lock; solock(so); } KASSERT(solocked(so)); /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ error = soreserve(so, l2cap_sendspace, l2cap_recvspace); if (error) return error; return l2cap_attach_pcb((struct l2cap_channel **)&so->so_pcb, &l2cap_proto, so); } static void l2cap_detach(struct socket *so) { KASSERT(so->so_pcb != NULL); l2cap_detach_pcb((struct l2cap_channel **)&so->so_pcb); KASSERT(so->so_pcb == NULL); } static int l2cap_accept(struct socket *so, struct mbuf *nam) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr_pcb(pcb, sa); } static int l2cap_bind(struct socket *so, struct mbuf *nam, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind_pcb(pcb, sa); } static int l2cap_listen(struct socket *so, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; return l2cap_listen_pcb(pcb); } static int l2cap_connect(struct socket *so, struct mbuf *nam, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(nam != NULL); if (pcb == NULL) return EINVAL; sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(so); return l2cap_connect_pcb(pcb, sa); } static int l2cap_connect2(struct socket *so, struct socket *so2) { KASSERT(solocked(so)); if (so->so_pcb == NULL) return EINVAL; return EOPNOTSUPP; } static int l2cap_disconnect(struct socket *so) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; soisdisconnecting(so); return l2cap_disconnect_pcb(pcb, so->so_linger); } static int l2cap_shutdown(struct socket *so) { KASSERT(solocked(so)); socantsendmore(so); return 0; } static int l2cap_abort(struct socket *so) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(solocked(so)); if (pcb == NULL) return EINVAL; l2cap_disconnect_pcb(pcb, 0); soisdisconnected(so); l2cap_detach(so); return 0; } static int l2cap_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) { return EPASSTHROUGH; } static int l2cap_stat(struct socket *so, struct stat *ub) { KASSERT(solocked(so)); return 0; } static int l2cap_peeraddr(struct socket *so, struct mbuf *nam) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(pcb != NULL); KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr_pcb(pcb, sa); } static int l2cap_sockaddr(struct socket *so, struct mbuf *nam) { struct l2cap_channel *pcb = so->so_pcb; struct sockaddr_bt *sa; KASSERT(solocked(so)); KASSERT(pcb != NULL); KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr_pcb(pcb, sa); } static int l2cap_rcvd(struct socket *so, int flags, struct lwp *l) { KASSERT(solocked(so)); return EOPNOTSUPP; } static int l2cap_recvoob(struct socket *so, struct mbuf *m, int flags) { KASSERT(solocked(so)); return EOPNOTSUPP; } static int l2cap_send(struct socket *so, struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct lwp *l) { struct l2cap_channel *pcb = so->so_pcb; struct mbuf *m0; int error = 0; KASSERT(solocked(so)); KASSERT(m != NULL); if (control) m_freem(control); if (pcb == NULL) { error = EINVAL; goto release; } if (m->m_pkthdr.len == 0) goto release; if (m->m_pkthdr.len > pcb->lc_omtu) { error = EMSGSIZE; goto release; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { error = ENOMEM; goto release; } sbappendrecord(&so->so_snd, m); return l2cap_send_pcb(pcb, m0); release: if (m) m_freem(m); return error; } static int l2cap_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); if (m) m_freem(m); if (control) m_freem(control); return EOPNOTSUPP; } static int l2cap_purgeif(struct socket *so, struct ifnet *ifp) { return EOPNOTSUPP; } d88 8 a95 1 * m is optional mbuf chain containing message d98 1 d104 1 a104 1 static int d109 2 d114 28 a141 19 KASSERT(req != PRU_ATTACH); KASSERT(req != PRU_DETACH); KASSERT(req != PRU_ACCEPT); KASSERT(req != PRU_BIND); KASSERT(req != PRU_LISTEN); KASSERT(req != PRU_CONNECT); KASSERT(req != PRU_CONNECT2); KASSERT(req != PRU_DISCONNECT); KASSERT(req != PRU_SHUTDOWN); KASSERT(req != PRU_ABORT); KASSERT(req != PRU_CONTROL); KASSERT(req != PRU_SENSE); KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVD); KASSERT(req != PRU_RCVOOB); KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); KASSERT(req != PRU_PURGEIF); d149 92 d339 1 a339 1 so = sonewconn(so, false); d379 1 a379 1 l2cap_disconnect_pcb(so->so_pcb, 0); a398 46 PR_WRAP_USRREQS(l2cap) #define l2cap_attach l2cap_attach_wrapper #define l2cap_detach l2cap_detach_wrapper #define l2cap_accept l2cap_accept_wrapper #define l2cap_bind l2cap_bind_wrapper #define l2cap_listen l2cap_listen_wrapper #define l2cap_connect l2cap_connect_wrapper #define l2cap_connect2 l2cap_connect2_wrapper #define l2cap_disconnect l2cap_disconnect_wrapper #define l2cap_shutdown l2cap_shutdown_wrapper #define l2cap_abort l2cap_abort_wrapper #define l2cap_ioctl l2cap_ioctl_wrapper #define l2cap_stat l2cap_stat_wrapper #define l2cap_peeraddr l2cap_peeraddr_wrapper #define l2cap_sockaddr l2cap_sockaddr_wrapper #define l2cap_rcvd l2cap_rcvd_wrapper #define l2cap_recvoob l2cap_recvoob_wrapper #define l2cap_send l2cap_send_wrapper #define l2cap_sendoob l2cap_sendoob_wrapper #define l2cap_purgeif l2cap_purgeif_wrapper #define l2cap_usrreq l2cap_usrreq_wrapper const struct pr_usrreqs l2cap_usrreqs = { .pr_attach = l2cap_attach, .pr_detach = l2cap_detach, .pr_accept = l2cap_accept, .pr_bind = l2cap_bind, .pr_listen = l2cap_listen, .pr_connect = l2cap_connect, .pr_connect2 = l2cap_connect2, .pr_disconnect = l2cap_disconnect, .pr_shutdown = l2cap_shutdown, .pr_abort = l2cap_abort, .pr_ioctl = l2cap_ioctl, .pr_stat = l2cap_stat, .pr_peeraddr = l2cap_peeraddr, .pr_sockaddr = l2cap_sockaddr, .pr_rcvd = l2cap_rcvd, .pr_recvoob = l2cap_recvoob, .pr_send = l2cap_send, .pr_sendoob = l2cap_sendoob, .pr_purgeif = l2cap_purgeif, .pr_generic = l2cap_usrreq, }; @ 1.9.38.2 log @update from HEAD @ text @d120 1 a120 1 l2cap_accept(struct socket *so, struct sockaddr *nam) d123 1 d131 3 a133 1 return l2cap_peeraddr_pcb(pcb, (struct sockaddr_bt *)nam); d137 1 a137 1 l2cap_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) d140 1 a140 1 struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; d148 1 d172 1 a172 1 l2cap_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) d175 1 a175 1 struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; d183 1 d259 1 a259 1 l2cap_peeraddr(struct socket *so, struct sockaddr *nam) d262 1 d268 3 a270 1 return l2cap_peeraddr_pcb(pcb, (struct sockaddr_bt *)nam); d274 1 a274 1 l2cap_sockaddr(struct socket *so, struct sockaddr *nam) d277 1 d283 3 a285 1 return l2cap_sockaddr_pcb(pcb, (struct sockaddr_bt *)nam); d305 1 a305 1 l2cap_send(struct socket *so, struct mbuf *m, struct sockaddr *nam, d368 64 d592 1 d614 1 @ 1.9.28.1 log @sync with head. for a reference, the tree before this commit was tagged as yamt-pagecache-tag8. this commit was splitted into small chunks to avoid a limitation of cvs. ("Protocol error: too many arguments") @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $"); d339 1 a339 1 so = sonewconn(so, false); @ 1.9.44.1 log @Checkpoint work in progress: - Initial split of the protocol user-request method into the following methods: pr_attach, pr_detach and pr_generic for old the pr_usrreq. - Adjust socreate(9) and sonewconn(9) to call pr_attach without the socket lock held (as a preparation for the locking scheme adjustment). - Adjust all pr_attach routines to assert that PCB is not set. - Sprinkle various comments, document some routines and their locking. - Remove M_PCB, replace with kmem(9). - Fix few bugs spotted on the way. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $"); a84 34 static int l2cap_attach1(struct socket *so, int proto) { int error; KASSERT(so->so_pcb == NULL); if (so->so_lock == NULL) { mutex_obj_hold(bt_lock); so->so_lock = bt_lock; } /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ error = soreserve(so, l2cap_sendspace, l2cap_recvspace); if (error) return error; return l2cap_attach((struct l2cap_channel **)&so->so_pcb, &l2cap_proto, so); } static void l2cap_detach1(struct socket *so) { struct l2cap_channel *pcb = so->so_pcb; KASSERT(pcb != NULL); l2cap_detach((struct l2cap_channel **)&so->so_pcb); KASSERT(so->so_pcb == NULL); } d94 1 d104 1 a104 1 static int a113 2 KASSERT(req != PRU_ATTACH); KASSERT(req != PRU_DETACH); d121 20 d156 3 a158 2 l2cap_detach1(up); return 0; a398 9 PR_WRAP_USRREQ(l2cap_usrreq) #define l2cap_usrreq l2cap_usrreq_wrapper const struct pr_usrreqs l2cap_usrreqs = { .pr_attach = l2cap_attach1, .pr_detach = l2cap_detach1, .pr_generic = l2cap_usrreq, }; @ 1.9.44.2 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.9.44.1 2013/08/28 15:21:48 rmind Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.9.44.1 2013/08/28 15:21:48 rmind Exp $"); d353 1 a353 1 so = sonewconn(so, false); a414 1 @ 1.8 log @Merge the socket locking patch: - Socket layer becomes MP safe. - Unix protocols become MP safe. - Allows protocol processing interrupts to safely block on locks. - Fixes a number of race conditions. With much feedback from matt@@ and plunky@@. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.7 2007/04/21 06:15:23 plunky Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.7 2007/04/21 06:15:23 plunky Exp $"); d261 1 a261 1 * l2cap_ctloutput(request, socket, level, optname, opt) d267 1 a267 2 l2cap_ctloutput(int req, struct socket *so, int level, int optname, struct mbuf **opt) a269 1 struct mbuf *m; d277 1 a277 1 if (level != BTPROTO_L2CAP) d282 1 a282 8 m = m_get(M_WAIT, MT_SOOPTS); m->m_len = l2cap_getopt(pcb, optname, mtod(m, void *)); if (m->m_len == 0) { m_freem(m); m = NULL; err = ENOPROTOOPT; } *opt = m; d286 1 a286 4 m = *opt; KASSERT(m != NULL); err = l2cap_setopt(pcb, optname, mtod(m, void *)); m_freem(m); d363 1 d371 5 a375 1 (void)l2cap_getopt(so->so_pcb, SO_L2CAP_LM, &mode); @ 1.8.2.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.8 2008/04/24 11:38:37 ad Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.8 2008/04/24 11:38:37 ad Exp $"); d261 1 a261 1 * l2cap_ctloutput(req, socket, sockopt) d267 2 a268 1 l2cap_ctloutput(int req, struct socket *so, struct sockopt *sopt) d271 1 d279 1 a279 1 if (sopt->sopt_level != BTPROTO_L2CAP) d284 8 a291 1 err = l2cap_getopt(pcb, sopt); d295 4 a298 1 err = l2cap_setopt(pcb, sopt); a374 1 struct sockopt sopt; d382 1 a382 5 sockopt_init(&sopt, BTPROTO_L2CAP, SO_L2CAP_LM, 0); (void)l2cap_getopt(so->so_pcb, &sopt); (void)sockopt_getint(&sopt, &mode); sockopt_destroy(&sopt); @ 1.8.8.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $"); d261 1 a261 1 * l2cap_ctloutput(req, socket, sockopt) d267 2 a268 1 l2cap_ctloutput(int req, struct socket *so, struct sockopt *sopt) d271 1 d279 1 a279 1 if (sopt->sopt_level != BTPROTO_L2CAP) d284 8 a291 1 err = l2cap_getopt(pcb, sopt); d295 4 a298 1 err = l2cap_setopt(pcb, sopt); a374 1 struct sockopt sopt; d382 1 a382 5 sockopt_init(&sopt, BTPROTO_L2CAP, SO_L2CAP_LM, 0); (void)l2cap_getopt(so->so_pcb, &sopt); (void)sockopt_getint(&sopt, &mode); sockopt_destroy(&sopt); @ 1.8.4.1 log @Sync with wrstuden-revivesa-base-2. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.8 2008/04/24 11:38:37 ad Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.8 2008/04/24 11:38:37 ad Exp $"); d261 1 a261 1 * l2cap_ctloutput(req, socket, sockopt) d267 2 a268 1 l2cap_ctloutput(int req, struct socket *so, struct sockopt *sopt) d271 1 d279 1 a279 1 if (sopt->sopt_level != BTPROTO_L2CAP) d284 8 a291 1 err = l2cap_getopt(pcb, sopt); d295 4 a298 1 err = l2cap_setopt(pcb, sopt); a374 1 struct sockopt sopt; d382 1 a382 5 sockopt_init(&sopt, BTPROTO_L2CAP, SO_L2CAP_LM, 0); (void)l2cap_getopt(so->so_pcb, &sopt); (void)sockopt_getint(&sopt, &mode); sockopt_destroy(&sopt); @ 1.7 log @Add 'service level' security for L2CAP and RFCOMM connections, following the Linux (BlueZ) API. - L2CAP or RFCOMM connections can require the baseband radio link mode be any of: authenticated (devices are paired) encrypted (implies authentication) secured (encryption, plus generate new link key) - for sockets, the mode is set using setsockopt(2) and the socket connection will be aborted if the mode change fails. - mode settings will be applied during connection establishment, and for safety, we enter a wait state and will only proceed when the mode settings are successfuly set. - It is possible to change the mode on already open connections, but not possible to guarantee that data already queued (from either end) will not be delivered. (this is a feature, not a bug) - bthidev(4) and rfcomm_sppd(1) support "auth", "encrypt" and "secure" options - btdevctl(8) by default enables "auth" for HIDs, and "encrypt" for keyboards (which are required to support it) @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.6 2007/03/31 18:17:13 plunky Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.6 2007/03/31 18:17:13 plunky Exp $"); d123 6 a130 1 @ 1.7.28.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD$ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD$"); a122 6 if (up->so_lock == NULL) { mutex_obj_hold(bt_lock); up->so_lock = bt_lock; solock(up); } KASSERT(solocked(up)); d125 1 @ 1.7.28.2 log @Sync with HEAD. @ text @d261 1 a261 1 * l2cap_ctloutput(req, socket, sockopt) d267 2 a268 1 l2cap_ctloutput(int req, struct socket *so, struct sockopt *sopt) d271 1 d279 1 a279 1 if (sopt->sopt_level != BTPROTO_L2CAP) d284 8 a291 1 err = l2cap_getopt(pcb, sopt); d295 4 a298 1 err = l2cap_setopt(pcb, sopt); a374 1 struct sockopt sopt; d382 1 a382 5 sockopt_init(&sopt, BTPROTO_L2CAP, SO_L2CAP_LM, 0); (void)l2cap_getopt(so->so_pcb, &sopt); (void)sockopt_getint(&sopt, &mode); sockopt_destroy(&sopt); @ 1.7.30.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.7 2007/04/21 06:15:23 plunky Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.7 2007/04/21 06:15:23 plunky Exp $"); a122 6 if (up->so_lock == NULL) { mutex_obj_hold(bt_lock); up->so_lock = bt_lock; solock(up); } KASSERT(solocked(up)); d125 1 @ 1.6 log @change declaration for protosw.h const symbolic strings to static, so that they can be used by more than one source file without causing duplicate definitions. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.5 2007/03/30 20:47:03 plunky Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.5 2007/03/30 20:47:03 plunky Exp $"); d68 1 d77 2 a78 1 l2cap_input d367 18 @ 1.5 log @be more explicit and consistent in use of KASSERT with pointers, test against NULL @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.4 2007/03/05 19:11:54 plunky Exp $ */ d34 7 a40 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.4 2007/03/05 19:11:54 plunky Exp $"); @ 1.4 log @return ENOPROTOOPT when protocol options are not known @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.3 2006/11/16 01:33:45 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.3 2006/11/16 01:33:45 christos Exp $"); d148 1 a148 1 KASSERT(nam); d160 1 a160 1 KASSERT(nam); d173 1 a173 1 KASSERT(nam); d179 1 a179 1 KASSERT(nam); d189 1 a189 1 KASSERT(m); d221 1 a221 1 KASSERT(nam); @ 1.4.4.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.7 2007/04/21 06:15:23 plunky Exp $ */ d34 1 a34 7 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.7 2007/04/21 06:15:23 plunky Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG #define PRUREQUESTS #define PRCOREQUESTS #endif a61 1 static void l2cap_linkmode(void *, int); d70 1 a70 2 l2cap_linkmode, l2cap_input, d148 1 a148 1 KASSERT(nam != NULL); d160 1 a160 1 KASSERT(nam != NULL); d173 1 a173 1 KASSERT(nam != NULL); d179 1 a179 1 KASSERT(nam != NULL); d189 1 a189 1 KASSERT(m != NULL); d221 1 a221 1 KASSERT(nam != NULL); a358 18 l2cap_linkmode(void *arg, int new) { struct socket *so = arg; int mode; DPRINTF("auth %s, encrypt %s, secure %s\n", (new & L2CAP_LM_AUTH ? "on" : "off"), (new & L2CAP_LM_ENCRYPT ? "on" : "off"), (new & L2CAP_LM_SECURE ? "on" : "off")); (void)l2cap_getopt(so->so_pcb, SO_L2CAP_LM, &mode); if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH)) || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT)) || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))) l2cap_disconnect(so->so_pcb, 0); } static void @ 1.4.2.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.4 2007/03/05 19:11:54 plunky Exp $ */ d34 1 a34 7 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.4 2007/03/05 19:11:54 plunky Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG #define PRUREQUESTS #define PRCOREQUESTS #endif d148 1 a148 1 KASSERT(nam != NULL); d160 1 a160 1 KASSERT(nam != NULL); d173 1 a173 1 KASSERT(nam != NULL); d179 1 a179 1 KASSERT(nam != NULL); d189 1 a189 1 KASSERT(m != NULL); d221 1 a221 1 KASSERT(nam != NULL); @ 1.4.2.2 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.4.2.1 2007/04/10 13:26:48 ad Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.4.2.1 2007/04/10 13:26:48 ad Exp $"); a67 1 static void l2cap_linkmode(void *, int); d76 1 a76 2 l2cap_linkmode, l2cap_input, a364 18 l2cap_linkmode(void *arg, int new) { struct socket *so = arg; int mode; DPRINTF("auth %s, encrypt %s, secure %s\n", (new & L2CAP_LM_AUTH ? "on" : "off"), (new & L2CAP_LM_ENCRYPT ? "on" : "off"), (new & L2CAP_LM_SECURE ? "on" : "off")); (void)l2cap_getopt(so->so_pcb, SO_L2CAP_LM, &mode); if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH)) || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT)) || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))) l2cap_disconnect(so->so_pcb, 0); } static void @ 1.3 log @__unused removal on arguments; approved by core. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.2 2006/10/12 01:32:37 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.2 2006/10/12 01:32:37 christos Exp $"); d263 3 d267 1 a267 1 return 0; // err? d276 1 a276 1 err = EINVAL; d289 1 a289 1 err = EINVAL; @ 1.3.8.1 log @Sync w/ NetBSD-4-RC_1 @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.3.2.1 2007/07/19 16:04:18 liamjfoy Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.3.2.1 2007/07/19 16:04:18 liamjfoy Exp $"); a61 1 static void l2cap_linkmode(void *, int); d70 1 a70 2 l2cap_linkmode, l2cap_input, a355 18 l2cap_linkmode(void *arg, int new) { struct socket *so = arg; int mode; DPRINTF("auth %s, encrypt %s, secure %s\n", (new & L2CAP_LM_AUTH ? "on" : "off"), (new & L2CAP_LM_ENCRYPT ? "on" : "off"), (new & L2CAP_LM_SECURE ? "on" : "off")); (void)l2cap_getopt(so->so_pcb, SO_L2CAP_LM, &mode); if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH)) || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT)) || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))) l2cap_disconnect(so->so_pcb, 0); } static void @ 1.3.2.1 log @Pull up following revision(s) (requested by plunky in ticket #744): sys/netbt/l2cap_lower.c: revision 1.6 sys/dev/bluetooth/btdev.h: revision 1.6 sys/netbt/sco_socket.c: revision 1.9 sys/netbt/rfcomm_upper.c: revision 1.3 sys/netbt/l2cap_socket.c: revision 1.7 sys/netbt/rfcomm_upper.c: revision 1.5 lib/libusbhid/usbhid.h: revision 1.5 sys/netbt/rfcomm_upper.c: revision 1.6 usr.sbin/btdevctl/btdevctl.c: revision 1.4 usr.sbin/btdevctl/btdevctl.h: revision 1.3 usr.sbin/btdevctl/btdevctl.8: revision 1.4 sys/netbt/rfcomm_session.c: revision 1.5 sys/netbt/hci.h: revision 1.10 usr.bin/rfcomm_sppd/rfcomm_sppd.c: revision 1.6 sys/netbt/hci_link.c: revision 1.11 usr.bin/rfcomm_sppd/rfcomm_sppd.c: revision 1.7 usr.bin/rfcomm_sppd/rfcomm_sppd.c: revision 1.8 sys/dev/bluetooth/btsco.c: revision 1.14 sys/netbt/rfcomm_session.c: revision 1.9 usr.sbin/btdevctl/sdp.c: revision 1.2 share/man/man9/bluetooth.9: revision 1.2 usr.sbin/btdevctl/sdp.c: revision 1.3 sys/dev/bluetooth/bthidev.c: revision 1.8 sys/netbt/l2cap.h: revision 1.4 sys/netbt/rfcomm.h: revision 1.3 sys/netbt/l2cap.h: revision 1.5 sys/netbt/l2cap_misc.c: revision 1.3 share/man/man4/bluetooth.4: revision 1.5 lib/libusbhid/usbhid.3: revision 1.11 sys/netbt/bluetooth.h: revision 1.5 share/man/man4/bthidev.4: revision 1.8 sys/netbt/rfcomm_dlc.c: revision 1.3 usr.sbin/btdevctl/print.c: revision 1.8 sys/netbt/rfcomm_socket.c: revision 1.7 sys/netbt/l2cap_signal.c: revision 1.4 sys/netbt/l2cap_signal.c: revision 1.5 sys/netbt/l2cap_signal.c: revision 1.7 sys/netbt/hci_event.c: revision 1.6 usr.bin/rfcomm_sppd/rfcomm_sppd.1: revision 1.5 sys/netbt/l2cap_upper.c: revision 1.3 sys/netbt/l2cap_lower.c: revision 1.2 usr.sbin/btdevctl/db.c: revision 1.3 sys/netbt/l2cap_upper.c: revision 1.6 lib/libusbhid/descr.c: revision 1.5 sys/netbt/l2cap_upper.c: revision 1.7 sys/netbt/l2cap_lower.c: revision 1.4 Add 'service level' security for L2CAP and RFCOMM connections, following the Linux (BlueZ) API. - L2CAP or RFCOMM connections can require the baseband radio link mode be any of: authenticated (devices are paired) encrypted (implies authentication) secured (encryption, plus generate new link key) - for sockets, the mode is set using setsockopt(2) and the socket connection will be aborted if the mode change fails. - mode settings will be applied during connection establishment, and for safety, we enter a wait state and will only proceed when the mode settings are successfuly set. - It is possible to change the mode on already open connections, but not possible to guarantee that data already queued (from either end) will not be delivered. (this is a feature, not a bug) - bthidev(4) and rfcomm_sppd(1) support "auth", "encrypt" and "secure" options - btdevctl(8) by default enables "auth" for HIDs, and "encrypt" for keyboards (which are required to support it) - ALSO INCLUDES OTHER MINOR FIXES @ text @d1 1 a1 1 /* $NetBSD$ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD$"); a61 1 static void l2cap_linkmode(void *, int); d70 1 a70 2 l2cap_linkmode, l2cap_input, a355 18 l2cap_linkmode(void *arg, int new) { struct socket *so = arg; int mode; DPRINTF("auth %s, encrypt %s, secure %s\n", (new & L2CAP_LM_AUTH ? "on" : "off"), (new & L2CAP_LM_ENCRYPT ? "on" : "off"), (new & L2CAP_LM_SECURE ? "on" : "off")); (void)l2cap_getopt(so->so_pcb, SO_L2CAP_LM, &mode); if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH)) || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT)) || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))) l2cap_disconnect(so->so_pcb, 0); } static void @ 1.3.4.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.3 2006/11/16 01:33:45 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.3 2006/11/16 01:33:45 christos Exp $"); a262 3 if (pcb == NULL) return EINVAL; d264 1 a264 1 return ENOPROTOOPT; d273 1 a273 1 err = ENOPROTOOPT; d286 1 a286 1 err = ENOPROTOOPT; @ 1.3.4.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.3.4.1 2007/03/12 05:59:34 rmind Exp $ */ d34 1 a34 7 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.3.4.1 2007/03/12 05:59:34 rmind Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG #define PRUREQUESTS #define PRCOREQUESTS #endif d148 1 a148 1 KASSERT(nam != NULL); d160 1 a160 1 KASSERT(nam != NULL); d173 1 a173 1 KASSERT(nam != NULL); d179 1 a179 1 KASSERT(nam != NULL); d189 1 a189 1 KASSERT(m != NULL); d221 1 a221 1 KASSERT(nam != NULL); @ 1.3.4.3 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.3.4.2 2007/04/15 16:03:59 yamt Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.3.4.2 2007/04/15 16:03:59 yamt Exp $"); a67 1 static void l2cap_linkmode(void *, int); d76 1 a76 2 l2cap_linkmode, l2cap_input, a364 18 l2cap_linkmode(void *arg, int new) { struct socket *so = arg; int mode; DPRINTF("auth %s, encrypt %s, secure %s\n", (new & L2CAP_LM_AUTH ? "on" : "off"), (new & L2CAP_LM_ENCRYPT ? "on" : "off"), (new & L2CAP_LM_SECURE ? "on" : "off")); (void)l2cap_getopt(so->so_pcb, SO_L2CAP_LM, &mode); if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH)) || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT)) || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))) l2cap_disconnect(so->so_pcb, 0); } static void @ 1.2 log @- sprinkle __unused on function decls. - fix a couple of unused bugs - no more -Wno-unused for i386 @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $"); d98 1 a98 1 struct mbuf *nam, struct mbuf *ctl, struct lwp *l __unused) d329 2 a330 2 l2cap_newconn(void *arg, struct sockaddr_bt *laddr __unused, struct sockaddr_bt *raddr __unused) @ 1.1 log @Initial import of bluetooth stack on behalf of Iain Hibbert. (plunky@@, NetBSD Foundation Membership still pending.) This stack was written by Iain under sponsorship from Itronix Inc. The stack includes support for rfcomm networking (networking via your bluetooth enabled cell phone), hid devices (keyboards/mice), and headsets. Drivers for both PCMCIA and USB bluetooth controllers are included. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c$ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c$"); d98 1 a98 1 struct mbuf *nam, struct mbuf *ctl, struct lwp *l) d329 2 a330 1 l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) @ 1.1.4.1 log @file l2cap_socket.c was added on branch chap-midi on 2006-06-22 03:39:50 +0000 @ text @d1 370 @ 1.1.4.2 log @Complete a sync sys/ with head. @ text @a0 370 /* $NetBSD: l2cap_socket.c,v 1.1.4.1 2006/06/22 03:39:50 chap Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. * Copyright (c) 2006 Itronix Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of Itronix Inc. may not be used to endorse * or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1.4.1 2006/06/22 03:39:50 chap Exp $"); #include #include #include #include #include #include #include #include #include #include #include /* * L2CAP Sockets * * SOCK_SEQPACKET - normal L2CAP connection * * SOCK_DGRAM - connectionless L2CAP - XXX not yet */ static void l2cap_connecting(void *); static void l2cap_connected(void *); static void l2cap_disconnected(void *, int); static void *l2cap_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); static void l2cap_complete(void *, int); static void l2cap_input(void *, struct mbuf *); static const struct btproto l2cap_proto = { l2cap_connecting, l2cap_connected, l2cap_disconnected, l2cap_newconn, l2cap_complete, l2cap_input }; /* sysctl variables */ int l2cap_sendspace = 4096; int l2cap_recvspace = 4096; /* * User Request. * up is socket * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) * nam is either * optional mbuf chain containing an address * ioctl data (PRU_CONTROL) * optionally protocol number (PRU_ATTACH) * message flags (PRU_RCVD) * ctl is either * optional mbuf chain containing socket options * optional interface pointer (PRU_CONTROL, PRU_PURGEIF) * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ int l2cap_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct l2cap_channel *pcb = up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); switch (req) { case PRU_CONTROL: return EPASSTHROUGH; case PRU_PURGEIF: return EOPNOTSUPP; case PRU_ATTACH: if (pcb != NULL) return EINVAL; /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ err = soreserve(up, l2cap_sendspace, l2cap_recvspace); if (err) return err; return l2cap_attach((struct l2cap_channel **)&up->so_pcb, &l2cap_proto, up); } if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return l2cap_disconnect(pcb, up->so_linger); case PRU_ABORT: l2cap_disconnect(pcb, 0); soisdisconnected(up); /* fall through to */ case PRU_DETACH: return l2cap_detach((struct l2cap_channel **)&up->so_pcb); case PRU_BIND: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind(pcb, sa); case PRU_CONNECT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return l2cap_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m); if (m->m_pkthdr.len == 0) break; if (m->m_pkthdr.len > pcb->lc_omtu) { err = EMSGSIZE; break; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { err = ENOMEM; break; } if (ctl) /* no use for that */ m_freem(ctl); sbappendrecord(&up->so_snd, m); return l2cap_send(pcb, m0); case PRU_SENSE: return 0; /* (no release) */ case PRU_RCVD: case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return l2cap_listen(pcb); case PRU_ACCEPT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_CONNECT2: case PRU_SENDOOB: case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; } /* * l2cap_ctloutput(request, socket, level, optname, opt) * * Apply configuration commands to channel. This corresponds to * "Reconfigure Channel Request" in the L2CAP specification. */ int l2cap_ctloutput(int req, struct socket *so, int level, int optname, struct mbuf **opt) { struct l2cap_channel *pcb = so->so_pcb; struct mbuf *m; int err = 0; DPRINTFN(2, "%s\n", prcorequests[req]); if (level != BTPROTO_L2CAP) return 0; // err? switch(req) { case PRCO_GETOPT: m = m_get(M_WAIT, MT_SOOPTS); m->m_len = l2cap_getopt(pcb, optname, mtod(m, void *)); if (m->m_len == 0) { m_freem(m); m = NULL; err = EINVAL; } *opt = m; break; case PRCO_SETOPT: m = *opt; KASSERT(m != NULL); err = l2cap_setopt(pcb, optname, mtod(m, void *)); m_freem(m); break; default: err = EINVAL; break; } return err; } /********************************************************************** * * L2CAP Protocol socket callbacks * */ static void l2cap_connecting(void *arg) { struct socket *so = arg; DPRINTF("Connecting\n"); soisconnecting(so); } static void l2cap_connected(void *arg) { struct socket *so = arg; DPRINTF("Connected\n"); soisconnected(so); } static void l2cap_disconnected(void *arg, int err) { struct socket *so = arg; DPRINTF("Disconnected (%d)\n", err); so->so_error = err; soisdisconnected(so); } static void * l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) { struct socket *so = arg; DPRINTF("New Connection\n"); so = sonewconn(so, 0); if (so == NULL) return NULL; soisconnecting(so); return so->so_pcb; } static void l2cap_complete(void *arg, int count) { struct socket *so = arg; while (count-- > 0) sbdroprecord(&so->so_snd); sowwakeup(so); } static void l2cap_input(void *arg, struct mbuf *m) { struct socket *so = arg; if (m->m_pkthdr.len > sbspace(&so->so_rcv)) { printf("%s: packet (%d bytes) dropped (socket buffer full)\n", __func__, m->m_pkthdr.len); m_freem(m); return; } DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len); sbappendrecord(&so->so_rcv, m); sorwakeup(so); } @ 1.1.8.1 log @file l2cap_socket.c was added on branch gdamore-uart on 2006-07-13 17:49:58 +0000 @ text @d1 370 @ 1.1.8.2 log @Merge from HEAD. @ text @a0 370 /* $NetBSD: l2cap_socket.c,v 1.1.8.1 2006/07/13 17:49:58 gdamore Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. * Copyright (c) 2006 Itronix Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of Itronix Inc. may not be used to endorse * or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1.8.1 2006/07/13 17:49:58 gdamore Exp $"); #include #include #include #include #include #include #include #include #include #include #include /* * L2CAP Sockets * * SOCK_SEQPACKET - normal L2CAP connection * * SOCK_DGRAM - connectionless L2CAP - XXX not yet */ static void l2cap_connecting(void *); static void l2cap_connected(void *); static void l2cap_disconnected(void *, int); static void *l2cap_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); static void l2cap_complete(void *, int); static void l2cap_input(void *, struct mbuf *); static const struct btproto l2cap_proto = { l2cap_connecting, l2cap_connected, l2cap_disconnected, l2cap_newconn, l2cap_complete, l2cap_input }; /* sysctl variables */ int l2cap_sendspace = 4096; int l2cap_recvspace = 4096; /* * User Request. * up is socket * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) * nam is either * optional mbuf chain containing an address * ioctl data (PRU_CONTROL) * optionally protocol number (PRU_ATTACH) * message flags (PRU_RCVD) * ctl is either * optional mbuf chain containing socket options * optional interface pointer (PRU_CONTROL, PRU_PURGEIF) * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ int l2cap_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct l2cap_channel *pcb = up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); switch (req) { case PRU_CONTROL: return EPASSTHROUGH; case PRU_PURGEIF: return EOPNOTSUPP; case PRU_ATTACH: if (pcb != NULL) return EINVAL; /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ err = soreserve(up, l2cap_sendspace, l2cap_recvspace); if (err) return err; return l2cap_attach((struct l2cap_channel **)&up->so_pcb, &l2cap_proto, up); } if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return l2cap_disconnect(pcb, up->so_linger); case PRU_ABORT: l2cap_disconnect(pcb, 0); soisdisconnected(up); /* fall through to */ case PRU_DETACH: return l2cap_detach((struct l2cap_channel **)&up->so_pcb); case PRU_BIND: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind(pcb, sa); case PRU_CONNECT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return l2cap_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m); if (m->m_pkthdr.len == 0) break; if (m->m_pkthdr.len > pcb->lc_omtu) { err = EMSGSIZE; break; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { err = ENOMEM; break; } if (ctl) /* no use for that */ m_freem(ctl); sbappendrecord(&up->so_snd, m); return l2cap_send(pcb, m0); case PRU_SENSE: return 0; /* (no release) */ case PRU_RCVD: case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return l2cap_listen(pcb); case PRU_ACCEPT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_CONNECT2: case PRU_SENDOOB: case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; } /* * l2cap_ctloutput(request, socket, level, optname, opt) * * Apply configuration commands to channel. This corresponds to * "Reconfigure Channel Request" in the L2CAP specification. */ int l2cap_ctloutput(int req, struct socket *so, int level, int optname, struct mbuf **opt) { struct l2cap_channel *pcb = so->so_pcb; struct mbuf *m; int err = 0; DPRINTFN(2, "%s\n", prcorequests[req]); if (level != BTPROTO_L2CAP) return 0; // err? switch(req) { case PRCO_GETOPT: m = m_get(M_WAIT, MT_SOOPTS); m->m_len = l2cap_getopt(pcb, optname, mtod(m, void *)); if (m->m_len == 0) { m_freem(m); m = NULL; err = EINVAL; } *opt = m; break; case PRCO_SETOPT: m = *opt; KASSERT(m != NULL); err = l2cap_setopt(pcb, optname, mtod(m, void *)); m_freem(m); break; default: err = EINVAL; break; } return err; } /********************************************************************** * * L2CAP Protocol socket callbacks * */ static void l2cap_connecting(void *arg) { struct socket *so = arg; DPRINTF("Connecting\n"); soisconnecting(so); } static void l2cap_connected(void *arg) { struct socket *so = arg; DPRINTF("Connected\n"); soisconnected(so); } static void l2cap_disconnected(void *arg, int err) { struct socket *so = arg; DPRINTF("Disconnected (%d)\n", err); so->so_error = err; soisdisconnected(so); } static void * l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) { struct socket *so = arg; DPRINTF("New Connection\n"); so = sonewconn(so, 0); if (so == NULL) return NULL; soisconnecting(so); return so->so_pcb; } static void l2cap_complete(void *arg, int count) { struct socket *so = arg; while (count-- > 0) sbdroprecord(&so->so_snd); sowwakeup(so); } static void l2cap_input(void *arg, struct mbuf *m) { struct socket *so = arg; if (m->m_pkthdr.len > sbspace(&so->so_rcv)) { printf("%s: packet (%d bytes) dropped (socket buffer full)\n", __func__, m->m_pkthdr.len); m_freem(m); return; } DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len); sbappendrecord(&so->so_rcv, m); sorwakeup(so); } @ 1.1.6.1 log @file l2cap_socket.c was added on branch yamt-pdpolicy on 2006-06-26 12:53:57 +0000 @ text @d1 370 @ 1.1.6.2 log @sync with head. @ text @a0 370 /* $NetBSD: l2cap_socket.c,v 1.1.6.1 2006/06/26 12:53:57 yamt Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. * Copyright (c) 2006 Itronix Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of Itronix Inc. may not be used to endorse * or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1.6.1 2006/06/26 12:53:57 yamt Exp $"); #include #include #include #include #include #include #include #include #include #include #include /* * L2CAP Sockets * * SOCK_SEQPACKET - normal L2CAP connection * * SOCK_DGRAM - connectionless L2CAP - XXX not yet */ static void l2cap_connecting(void *); static void l2cap_connected(void *); static void l2cap_disconnected(void *, int); static void *l2cap_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); static void l2cap_complete(void *, int); static void l2cap_input(void *, struct mbuf *); static const struct btproto l2cap_proto = { l2cap_connecting, l2cap_connected, l2cap_disconnected, l2cap_newconn, l2cap_complete, l2cap_input }; /* sysctl variables */ int l2cap_sendspace = 4096; int l2cap_recvspace = 4096; /* * User Request. * up is socket * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) * nam is either * optional mbuf chain containing an address * ioctl data (PRU_CONTROL) * optionally protocol number (PRU_ATTACH) * message flags (PRU_RCVD) * ctl is either * optional mbuf chain containing socket options * optional interface pointer (PRU_CONTROL, PRU_PURGEIF) * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ int l2cap_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct l2cap_channel *pcb = up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); switch (req) { case PRU_CONTROL: return EPASSTHROUGH; case PRU_PURGEIF: return EOPNOTSUPP; case PRU_ATTACH: if (pcb != NULL) return EINVAL; /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ err = soreserve(up, l2cap_sendspace, l2cap_recvspace); if (err) return err; return l2cap_attach((struct l2cap_channel **)&up->so_pcb, &l2cap_proto, up); } if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return l2cap_disconnect(pcb, up->so_linger); case PRU_ABORT: l2cap_disconnect(pcb, 0); soisdisconnected(up); /* fall through to */ case PRU_DETACH: return l2cap_detach((struct l2cap_channel **)&up->so_pcb); case PRU_BIND: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind(pcb, sa); case PRU_CONNECT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return l2cap_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m); if (m->m_pkthdr.len == 0) break; if (m->m_pkthdr.len > pcb->lc_omtu) { err = EMSGSIZE; break; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { err = ENOMEM; break; } if (ctl) /* no use for that */ m_freem(ctl); sbappendrecord(&up->so_snd, m); return l2cap_send(pcb, m0); case PRU_SENSE: return 0; /* (no release) */ case PRU_RCVD: case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return l2cap_listen(pcb); case PRU_ACCEPT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_CONNECT2: case PRU_SENDOOB: case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; } /* * l2cap_ctloutput(request, socket, level, optname, opt) * * Apply configuration commands to channel. This corresponds to * "Reconfigure Channel Request" in the L2CAP specification. */ int l2cap_ctloutput(int req, struct socket *so, int level, int optname, struct mbuf **opt) { struct l2cap_channel *pcb = so->so_pcb; struct mbuf *m; int err = 0; DPRINTFN(2, "%s\n", prcorequests[req]); if (level != BTPROTO_L2CAP) return 0; // err? switch(req) { case PRCO_GETOPT: m = m_get(M_WAIT, MT_SOOPTS); m->m_len = l2cap_getopt(pcb, optname, mtod(m, void *)); if (m->m_len == 0) { m_freem(m); m = NULL; err = EINVAL; } *opt = m; break; case PRCO_SETOPT: m = *opt; KASSERT(m != NULL); err = l2cap_setopt(pcb, optname, mtod(m, void *)); m_freem(m); break; default: err = EINVAL; break; } return err; } /********************************************************************** * * L2CAP Protocol socket callbacks * */ static void l2cap_connecting(void *arg) { struct socket *so = arg; DPRINTF("Connecting\n"); soisconnecting(so); } static void l2cap_connected(void *arg) { struct socket *so = arg; DPRINTF("Connected\n"); soisconnected(so); } static void l2cap_disconnected(void *arg, int err) { struct socket *so = arg; DPRINTF("Disconnected (%d)\n", err); so->so_error = err; soisdisconnected(so); } static void * l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) { struct socket *so = arg; DPRINTF("New Connection\n"); so = sonewconn(so, 0); if (so == NULL) return NULL; soisconnecting(so); return so->so_pcb; } static void l2cap_complete(void *arg, int count) { struct socket *so = arg; while (count-- > 0) sbdroprecord(&so->so_snd); sowwakeup(so); } static void l2cap_input(void *arg, struct mbuf *m) { struct socket *so = arg; if (m->m_pkthdr.len > sbspace(&so->so_rcv)) { printf("%s: packet (%d bytes) dropped (socket buffer full)\n", __func__, m->m_pkthdr.len); m_freem(m); return; } DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len); sbappendrecord(&so->so_rcv, m); sorwakeup(so); } @ 1.1.14.1 log @file l2cap_socket.c was added on branch rpaulo-netinet-merge-pcb on 2006-09-09 02:58:39 +0000 @ text @d1 370 @ 1.1.14.2 log @sync with head @ text @a0 370 /* $NetBSD: l2cap_socket.c,v 1.1.14.1 2006/09/09 02:58:39 rpaulo Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. * Copyright (c) 2006 Itronix Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of Itronix Inc. may not be used to endorse * or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1.14.1 2006/09/09 02:58:39 rpaulo Exp $"); #include #include #include #include #include #include #include #include #include #include #include /* * L2CAP Sockets * * SOCK_SEQPACKET - normal L2CAP connection * * SOCK_DGRAM - connectionless L2CAP - XXX not yet */ static void l2cap_connecting(void *); static void l2cap_connected(void *); static void l2cap_disconnected(void *, int); static void *l2cap_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); static void l2cap_complete(void *, int); static void l2cap_input(void *, struct mbuf *); static const struct btproto l2cap_proto = { l2cap_connecting, l2cap_connected, l2cap_disconnected, l2cap_newconn, l2cap_complete, l2cap_input }; /* sysctl variables */ int l2cap_sendspace = 4096; int l2cap_recvspace = 4096; /* * User Request. * up is socket * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) * nam is either * optional mbuf chain containing an address * ioctl data (PRU_CONTROL) * optionally protocol number (PRU_ATTACH) * message flags (PRU_RCVD) * ctl is either * optional mbuf chain containing socket options * optional interface pointer (PRU_CONTROL, PRU_PURGEIF) * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ int l2cap_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct l2cap_channel *pcb = up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); switch (req) { case PRU_CONTROL: return EPASSTHROUGH; case PRU_PURGEIF: return EOPNOTSUPP; case PRU_ATTACH: if (pcb != NULL) return EINVAL; /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ err = soreserve(up, l2cap_sendspace, l2cap_recvspace); if (err) return err; return l2cap_attach((struct l2cap_channel **)&up->so_pcb, &l2cap_proto, up); } if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return l2cap_disconnect(pcb, up->so_linger); case PRU_ABORT: l2cap_disconnect(pcb, 0); soisdisconnected(up); /* fall through to */ case PRU_DETACH: return l2cap_detach((struct l2cap_channel **)&up->so_pcb); case PRU_BIND: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind(pcb, sa); case PRU_CONNECT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return l2cap_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m); if (m->m_pkthdr.len == 0) break; if (m->m_pkthdr.len > pcb->lc_omtu) { err = EMSGSIZE; break; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { err = ENOMEM; break; } if (ctl) /* no use for that */ m_freem(ctl); sbappendrecord(&up->so_snd, m); return l2cap_send(pcb, m0); case PRU_SENSE: return 0; /* (no release) */ case PRU_RCVD: case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return l2cap_listen(pcb); case PRU_ACCEPT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_CONNECT2: case PRU_SENDOOB: case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; } /* * l2cap_ctloutput(request, socket, level, optname, opt) * * Apply configuration commands to channel. This corresponds to * "Reconfigure Channel Request" in the L2CAP specification. */ int l2cap_ctloutput(int req, struct socket *so, int level, int optname, struct mbuf **opt) { struct l2cap_channel *pcb = so->so_pcb; struct mbuf *m; int err = 0; DPRINTFN(2, "%s\n", prcorequests[req]); if (level != BTPROTO_L2CAP) return 0; // err? switch(req) { case PRCO_GETOPT: m = m_get(M_WAIT, MT_SOOPTS); m->m_len = l2cap_getopt(pcb, optname, mtod(m, void *)); if (m->m_len == 0) { m_freem(m); m = NULL; err = EINVAL; } *opt = m; break; case PRCO_SETOPT: m = *opt; KASSERT(m != NULL); err = l2cap_setopt(pcb, optname, mtod(m, void *)); m_freem(m); break; default: err = EINVAL; break; } return err; } /********************************************************************** * * L2CAP Protocol socket callbacks * */ static void l2cap_connecting(void *arg) { struct socket *so = arg; DPRINTF("Connecting\n"); soisconnecting(so); } static void l2cap_connected(void *arg) { struct socket *so = arg; DPRINTF("Connected\n"); soisconnected(so); } static void l2cap_disconnected(void *arg, int err) { struct socket *so = arg; DPRINTF("Disconnected (%d)\n", err); so->so_error = err; soisdisconnected(so); } static void * l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) { struct socket *so = arg; DPRINTF("New Connection\n"); so = sonewconn(so, 0); if (so == NULL) return NULL; soisconnecting(so); return so->so_pcb; } static void l2cap_complete(void *arg, int count) { struct socket *so = arg; while (count-- > 0) sbdroprecord(&so->so_snd); sowwakeup(so); } static void l2cap_input(void *arg, struct mbuf *m) { struct socket *so = arg; if (m->m_pkthdr.len > sbspace(&so->so_rcv)) { printf("%s: packet (%d bytes) dropped (socket buffer full)\n", __func__, m->m_pkthdr.len); m_freem(m); return; } DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len); sbappendrecord(&so->so_rcv, m); sorwakeup(so); } @ 1.1.2.1 log @file l2cap_socket.c was added on branch yamt-lazymbuf on 2006-06-21 15:10:51 +0000 @ text @d1 370 @ 1.1.2.2 log @sync with head. @ text @a0 370 /* $NetBSD: l2cap_socket.c,v 1.1.2.1 2006/06/21 15:10:51 yamt Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. * Copyright (c) 2006 Itronix Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of Itronix Inc. may not be used to endorse * or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1.2.1 2006/06/21 15:10:51 yamt Exp $"); #include #include #include #include #include #include #include #include #include #include #include /* * L2CAP Sockets * * SOCK_SEQPACKET - normal L2CAP connection * * SOCK_DGRAM - connectionless L2CAP - XXX not yet */ static void l2cap_connecting(void *); static void l2cap_connected(void *); static void l2cap_disconnected(void *, int); static void *l2cap_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); static void l2cap_complete(void *, int); static void l2cap_input(void *, struct mbuf *); static const struct btproto l2cap_proto = { l2cap_connecting, l2cap_connected, l2cap_disconnected, l2cap_newconn, l2cap_complete, l2cap_input }; /* sysctl variables */ int l2cap_sendspace = 4096; int l2cap_recvspace = 4096; /* * User Request. * up is socket * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) * nam is either * optional mbuf chain containing an address * ioctl data (PRU_CONTROL) * optionally protocol number (PRU_ATTACH) * message flags (PRU_RCVD) * ctl is either * optional mbuf chain containing socket options * optional interface pointer (PRU_CONTROL, PRU_PURGEIF) * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ int l2cap_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct l2cap_channel *pcb = up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); switch (req) { case PRU_CONTROL: return EPASSTHROUGH; case PRU_PURGEIF: return EOPNOTSUPP; case PRU_ATTACH: if (pcb != NULL) return EINVAL; /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ err = soreserve(up, l2cap_sendspace, l2cap_recvspace); if (err) return err; return l2cap_attach((struct l2cap_channel **)&up->so_pcb, &l2cap_proto, up); } if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return l2cap_disconnect(pcb, up->so_linger); case PRU_ABORT: l2cap_disconnect(pcb, 0); soisdisconnected(up); /* fall through to */ case PRU_DETACH: return l2cap_detach((struct l2cap_channel **)&up->so_pcb); case PRU_BIND: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind(pcb, sa); case PRU_CONNECT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return l2cap_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m); if (m->m_pkthdr.len == 0) break; if (m->m_pkthdr.len > pcb->lc_omtu) { err = EMSGSIZE; break; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { err = ENOMEM; break; } if (ctl) /* no use for that */ m_freem(ctl); sbappendrecord(&up->so_snd, m); return l2cap_send(pcb, m0); case PRU_SENSE: return 0; /* (no release) */ case PRU_RCVD: case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return l2cap_listen(pcb); case PRU_ACCEPT: KASSERT(nam); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_CONNECT2: case PRU_SENDOOB: case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; } /* * l2cap_ctloutput(request, socket, level, optname, opt) * * Apply configuration commands to channel. This corresponds to * "Reconfigure Channel Request" in the L2CAP specification. */ int l2cap_ctloutput(int req, struct socket *so, int level, int optname, struct mbuf **opt) { struct l2cap_channel *pcb = so->so_pcb; struct mbuf *m; int err = 0; DPRINTFN(2, "%s\n", prcorequests[req]); if (level != BTPROTO_L2CAP) return 0; // err? switch(req) { case PRCO_GETOPT: m = m_get(M_WAIT, MT_SOOPTS); m->m_len = l2cap_getopt(pcb, optname, mtod(m, void *)); if (m->m_len == 0) { m_freem(m); m = NULL; err = EINVAL; } *opt = m; break; case PRCO_SETOPT: m = *opt; KASSERT(m != NULL); err = l2cap_setopt(pcb, optname, mtod(m, void *)); m_freem(m); break; default: err = EINVAL; break; } return err; } /********************************************************************** * * L2CAP Protocol socket callbacks * */ static void l2cap_connecting(void *arg) { struct socket *so = arg; DPRINTF("Connecting\n"); soisconnecting(so); } static void l2cap_connected(void *arg) { struct socket *so = arg; DPRINTF("Connected\n"); soisconnected(so); } static void l2cap_disconnected(void *arg, int err) { struct socket *so = arg; DPRINTF("Disconnected (%d)\n", err); so->so_error = err; soisdisconnected(so); } static void * l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) { struct socket *so = arg; DPRINTF("New Connection\n"); so = sonewconn(so, 0); if (so == NULL) return NULL; soisconnecting(so); return so->so_pcb; } static void l2cap_complete(void *arg, int count) { struct socket *so = arg; while (count-- > 0) sbdroprecord(&so->so_snd); sowwakeup(so); } static void l2cap_input(void *arg, struct mbuf *m) { struct socket *so = arg; if (m->m_pkthdr.len > sbspace(&so->so_rcv)) { printf("%s: packet (%d bytes) dropped (socket buffer full)\n", __func__, m->m_pkthdr.len); m_freem(m); return; } DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len); sbappendrecord(&so->so_rcv, m); sorwakeup(so); } @ 1.1.2.3 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.1.2.2 2006/12/30 20:50:32 yamt Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1.2.2 2006/12/30 20:50:32 yamt Exp $"); d98 1 a98 1 struct mbuf *nam, struct mbuf *ctl, struct lwp *l) d329 1 a329 2 l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) @ 1.1.2.4 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.1.2.3 2007/09/03 14:42:42 yamt Exp $ */ d34 1 a34 7 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1.2.3 2007/09/03 14:42:42 yamt Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG #define PRUREQUESTS #define PRCOREQUESTS #endif a61 1 static void l2cap_linkmode(void *, int); d70 1 a70 2 l2cap_linkmode, l2cap_input, d148 1 a148 1 KASSERT(nam != NULL); d160 1 a160 1 KASSERT(nam != NULL); d173 1 a173 1 KASSERT(nam != NULL); d179 1 a179 1 KASSERT(nam != NULL); d189 1 a189 1 KASSERT(m != NULL); d221 1 a221 1 KASSERT(nam != NULL); a262 3 if (pcb == NULL) return EINVAL; d264 1 a264 1 return ENOPROTOOPT; d273 1 a273 1 err = ENOPROTOOPT; d286 1 a286 1 err = ENOPROTOOPT; a355 18 l2cap_linkmode(void *arg, int new) { struct socket *so = arg; int mode; DPRINTF("auth %s, encrypt %s, secure %s\n", (new & L2CAP_LM_AUTH ? "on" : "off"), (new & L2CAP_LM_ENCRYPT ? "on" : "off"), (new & L2CAP_LM_SECURE ? "on" : "off")); (void)l2cap_getopt(so->so_pcb, SO_L2CAP_LM, &mode); if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH)) || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT)) || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))) l2cap_disconnect(so->so_pcb, 0); } static void @ 1.1.12.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.3 2006/11/16 01:33:45 christos Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.3 2006/11/16 01:33:45 christos Exp $"); d98 1 a98 1 struct mbuf *nam, struct mbuf *ctl, struct lwp *l) d329 1 a329 2 l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) @ 1.1.16.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $"); d98 1 a98 1 struct mbuf *nam, struct mbuf *ctl, struct lwp *l __unused) d329 1 a329 2 l2cap_newconn(void *arg, struct sockaddr_bt *laddr __unused, struct sockaddr_bt *raddr __unused) @ 1.1.16.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: l2cap_socket.c,v 1.1.16.1 2006/10/22 06:07:28 yamt Exp $ */ d34 1 a34 1 __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.1.16.1 2006/10/22 06:07:28 yamt Exp $"); d98 1 a98 1 struct mbuf *nam, struct mbuf *ctl, struct lwp *l) d329 2 a330 2 l2cap_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr) @