mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn.git
				synced 2025-11-03 21:53:25 +00:00 
			
		
		
		
	Compare commits
	
		
			599 Commits
		
	
	
		
			neels/refa
			...
			1.13.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					ba3d8905f9 | ||
| 
						 | 
					cf65292b0d | ||
| 
						 | 
					71fefdad09 | ||
| 
						 | 
					4b8ebcd784 | ||
| 
						 | 
					446dd65de1 | ||
| 
						 | 
					09142e1c27 | ||
| 
						 | 
					04f5ea4ffa | ||
| 
						 | 
					839c2b9c84 | ||
| 
						 | 
					65e133b42c | ||
| 
						 | 
					95746b9588 | ||
| 
						 | 
					2b161df6af | ||
| 
						 | 
					13d23077d2 | ||
| 
						 | 
					a4cb3eb011 | ||
| 
						 | 
					9f1fd42148 | ||
| 
						 | 
					ad03073219 | ||
| 
						 | 
					234cd12ea5 | ||
| 
						 | 
					d73801ebea | ||
| 
						 | 
					1d7e86ae48 | ||
| 
						 | 
					56a6e025d3 | ||
| 
						 | 
					c075d032b9 | ||
| 
						 | 
					d44bf6fd73 | ||
| 
						 | 
					77d4ae0470 | ||
| 
						 | 
					e6feda5185 | ||
| 
						 | 
					f92d875119 | ||
| 
						 | 
					454110a007 | ||
| 
						 | 
					38b607ece3 | ||
| 
						 | 
					41bec9529f | ||
| 
						 | 
					6041554cef | ||
| 
						 | 
					6d1d181403 | ||
| 
						 | 
					7d80216717 | ||
| 
						 | 
					de385e0253 | ||
| 
						 | 
					ce691d8e64 | ||
| 
						 | 
					8c015bd89a | ||
| 
						 | 
					5f8960b206 | ||
| 
						 | 
					0828b2afc3 | ||
| 
						 | 
					70a1d64e55 | ||
| 
						 | 
					ea3cf1b8ae | ||
| 
						 | 
					7ce14f5e93 | ||
| 
						 | 
					561a9bc77c | ||
| 
						 | 
					7ae1177e04 | ||
| 
						 | 
					57585767dc | ||
| 
						 | 
					488972b442 | ||
| 
						 | 
					08239ccac3 | ||
| 
						 | 
					fbc56063c5 | ||
| 
						 | 
					c1598e0eb4 | ||
| 
						 | 
					519a2e401d | ||
| 
						 | 
					fbef527222 | ||
| 
						 | 
					68f5b086ad | ||
| 
						 | 
					3cb3423a59 | ||
| 
						 | 
					bad5eeba0f | ||
| 
						 | 
					1dd16fa12f | ||
| 
						 | 
					3372625ad9 | ||
| 
						 | 
					1f9cc2674f | ||
| 
						 | 
					4abe361f33 | ||
| 
						 | 
					bb0655d5aa | ||
| 
						 | 
					4e6fe42731 | ||
| 
						 | 
					19a506b705 | ||
| 
						 | 
					ea6c02ac1f | ||
| 
						 | 
					ec357c5377 | ||
| 
						 | 
					768d6d5be9 | ||
| 
						 | 
					fa91a10498 | ||
| 
						 | 
					6929391ecf | ||
| 
						 | 
					9baac03927 | ||
| 
						 | 
					9bd2711f39 | ||
| 
						 | 
					b17fe7bfe9 | ||
| 
						 | 
					0917ce4e22 | ||
| 
						 | 
					2a0d37cb1d | ||
| 
						 | 
					f3d541e353 | ||
| 
						 | 
					8d976444b8 | ||
| 
						 | 
					77734ac81b | ||
| 
						 | 
					848ec697e2 | ||
| 
						 | 
					6a2e82542d | ||
| 
						 | 
					a625bdd136 | ||
| 
						 | 
					08bb5182a4 | ||
| 
						 | 
					4963d1c2ea | ||
| 
						 | 
					37daa5d003 | ||
| 
						 | 
					c4c4d90b85 | ||
| 
						 | 
					59f1539ece | ||
| 
						 | 
					eff88c08e7 | ||
| 
						 | 
					92ac7249f9 | ||
| 
						 | 
					5cf6b75dc9 | ||
| 
						 | 
					4aa2e417c9 | ||
| 
						 | 
					f14c056310 | ||
| 
						 | 
					bf69ddbfef | ||
| 
						 | 
					70a4e2e6f8 | ||
| 
						 | 
					99afe979ef | ||
| 
						 | 
					35066fb0b0 | ||
| 
						 | 
					55fe62f634 | ||
| 
						 | 
					4fac842826 | ||
| 
						 | 
					97f60e3dca | ||
| 
						 | 
					a727e6ed38 | ||
| 
						 | 
					3a55b89777 | ||
| 
						 | 
					9f1f747d8e | ||
| 
						 | 
					b9036af7ca | ||
| 
						 | 
					724ecc6680 | ||
| 
						 | 
					0d3bd3435f | ||
| 
						 | 
					3ed252b58e | ||
| 
						 | 
					ac802e63d7 | ||
| 
						 | 
					bc583d9763 | ||
| 
						 | 
					ade4dc191b | ||
| 
						 | 
					cd05da79e7 | ||
| 
						 | 
					5545bcea5d | ||
| 
						 | 
					c97286f839 | ||
| 
						 | 
					f471800168 | ||
| 
						 | 
					bdf0697a5a | ||
| 
						 | 
					674a912fb5 | ||
| 
						 | 
					1bf3b3d0f9 | ||
| 
						 | 
					fb9303c610 | ||
| 
						 | 
					0585769741 | ||
| 
						 | 
					9b288b788e | ||
| 
						 | 
					134ac7e7c8 | ||
| 
						 | 
					46f04343a5 | ||
| 
						 | 
					a3ca2d185b | ||
| 
						 | 
					8cbdd21867 | ||
| 
						 | 
					ae81195418 | ||
| 
						 | 
					6ee5fa939a | ||
| 
						 | 
					b6a0e3fd2e | ||
| 
						 | 
					bd2b55679e | ||
| 
						 | 
					f32c6a9095 | ||
| 
						 | 
					2eed6ec5ec | ||
| 
						 | 
					641206ad5e | ||
| 
						 | 
					bfd3119ae4 | ||
| 
						 | 
					4b9b19e998 | ||
| 
						 | 
					00e0559e17 | ||
| 
						 | 
					0b1d9dbc40 | ||
| 
						 | 
					5379273ea3 | ||
| 
						 | 
					ecef920b8f | ||
| 
						 | 
					eb9267b15e | ||
| 
						 | 
					1efb2bcd90 | ||
| 
						 | 
					878593f205 | ||
| 
						 | 
					1596463985 | ||
| 
						 | 
					9d82492e49 | ||
| 
						 | 
					303aeea8a8 | ||
| 
						 | 
					18898b4a9f | ||
| 
						 | 
					17cee2056c | ||
| 
						 | 
					67a3c833af | ||
| 
						 | 
					b1f641b5b7 | ||
| 
						 | 
					f01ce65f5b | ||
| 
						 | 
					be1cf99e9a | ||
| 
						 | 
					7710080ffd | ||
| 
						 | 
					798a81d48d | ||
| 
						 | 
					51930f7b63 | ||
| 
						 | 
					00ef1b0d6e | ||
| 
						 | 
					02a82c3c9b | ||
| 
						 | 
					349cbfcf50 | ||
| 
						 | 
					51f99ae250 | ||
| 
						 | 
					12304c0e5a | ||
| 
						 | 
					1719abb409 | ||
| 
						 | 
					3ddf4c6933 | ||
| 
						 | 
					fb2a7298e0 | ||
| 
						 | 
					568ac5ee8e | ||
| 
						 | 
					23c832bb4b | ||
| 
						 | 
					4831851ca3 | ||
| 
						 | 
					080dcfaabe | ||
| 
						 | 
					cbc07bdd82 | ||
| 
						 | 
					aedae4c971 | ||
| 
						 | 
					b36eb9d12f | ||
| 
						 | 
					8df01fad14 | ||
| 
						 | 
					c8020b959d | ||
| 
						 | 
					2154607fb0 | ||
| 
						 | 
					d08a15b343 | ||
| 
						 | 
					4e37fb356a | ||
| 
						 | 
					6a8a389c47 | ||
| 
						 | 
					569e46cbf9 | ||
| 
						 | 
					91d9410157 | ||
| 
						 | 
					065ddb6416 | ||
| 
						 | 
					53244a2132 | ||
| 
						 | 
					db98f309a9 | ||
| 
						 | 
					04715d284f | ||
| 
						 | 
					962146085c | ||
| 
						 | 
					e2b0961f18 | ||
| 
						 | 
					ff2ebee03b | ||
| 
						 | 
					2a1cedd2dc | ||
| 
						 | 
					c43e887e9e | ||
| 
						 | 
					e5d71639e5 | ||
| 
						 | 
					a1b3deefda | ||
| 
						 | 
					964f08a919 | ||
| 
						 | 
					ee1529e5ac | ||
| 
						 | 
					29e7bd0510 | ||
| 
						 | 
					cdcaeda81c | ||
| 
						 | 
					98f8126b98 | ||
| 
						 | 
					a1503b902c | ||
| 
						 | 
					8398bccb0b | ||
| 
						 | 
					5552872733 | ||
| 
						 | 
					61b010c25a | ||
| 
						 | 
					20d9d154c5 | ||
| 
						 | 
					1c8ae66654 | ||
| 
						 | 
					fcdaf31aa8 | ||
| 
						 | 
					9366f4c034 | ||
| 
						 | 
					28c6a32677 | ||
| 
						 | 
					107c813eee | ||
| 
						 | 
					90d1732be1 | ||
| 
						 | 
					1c3505b885 | ||
| 
						 | 
					20539f0271 | ||
| 
						 | 
					ad6eaa2881 | ||
| 
						 | 
					b629240a35 | ||
| 
						 | 
					b283c32027 | ||
| 
						 | 
					e71e0f2af8 | ||
| 
						 | 
					bd8f028bff | ||
| 
						 | 
					a55454d58e | ||
| 
						 | 
					f1be1df0d3 | ||
| 
						 | 
					c22205bec8 | ||
| 
						 | 
					fdf3358959 | ||
| 
						 | 
					1bf41e4f36 | ||
| 
						 | 
					c94837c6a4 | ||
| 
						 | 
					68c5a74557 | ||
| 
						 | 
					bdf2cf9038 | ||
| 
						 | 
					00a6171b8d | ||
| 
						 | 
					26e300fda0 | ||
| 
						 | 
					4e605b32d4 | ||
| 
						 | 
					494d873fe3 | ||
| 
						 | 
					b4c98e7397 | ||
| 
						 | 
					3eb05d2c1a | ||
| 
						 | 
					f5fbb419ef | ||
| 
						 | 
					5d8b226597 | ||
| 
						 | 
					c602d7cf00 | ||
| 
						 | 
					a019631c0b | ||
| 
						 | 
					88ce94c2bd | ||
| 
						 | 
					310ea1db10 | ||
| 
						 | 
					012d51ed7d | ||
| 
						 | 
					1ef2621d3f | ||
| 
						 | 
					f612ffea82 | ||
| 
						 | 
					421f22e8cf | ||
| 
						 | 
					03cce86941 | ||
| 
						 | 
					95cd897c3f | ||
| 
						 | 
					f7884e880e | ||
| 
						 | 
					60ee0dbfa4 | ||
| 
						 | 
					d950134c53 | ||
| 
						 | 
					623c5b36e9 | ||
| 
						 | 
					aab47afe58 | ||
| 
						 | 
					67aebc9d1c | ||
| 
						 | 
					ea1cb3fa33 | ||
| 
						 | 
					0036a60c44 | ||
| 
						 | 
					e47932976c | ||
| 
						 | 
					f1e01517bc | ||
| 
						 | 
					ad252e70aa | ||
| 
						 | 
					08ca425bc2 | ||
| 
						 | 
					1eeb113c34 | ||
| 
						 | 
					d0ba664fec | ||
| 
						 | 
					ec1d8c4004 | ||
| 
						 | 
					36e12d4db8 | ||
| 
						 | 
					2404c5b0b7 | ||
| 
						 | 
					32b76ee1af | ||
| 
						 | 
					7bdc80de00 | ||
| 
						 | 
					83f5266f43 | ||
| 
						 | 
					e725d87d13 | ||
| 
						 | 
					8b90bce962 | ||
| 
						 | 
					f0829ff34b | ||
| 
						 | 
					e589c6544c | ||
| 
						 | 
					d1a2ddfee6 | ||
| 
						 | 
					7b52f00192 | ||
| 
						 | 
					25ab381c0f | ||
| 
						 | 
					9fbcb10568 | ||
| 
						 | 
					eefa30dce8 | ||
| 
						 | 
					5560001af5 | ||
| 
						 | 
					a469a90d5e | ||
| 
						 | 
					84515f4b8b | ||
| 
						 | 
					1cde2c1691 | ||
| 
						 | 
					93dd798a99 | ||
| 
						 | 
					8651573632 | ||
| 
						 | 
					0d0b0592f0 | ||
| 
						 | 
					aad77a0acf | ||
| 
						 | 
					9ee8d3264b | ||
| 
						 | 
					de72d26f49 | ||
| 
						 | 
					ceac078d77 | ||
| 
						 | 
					cd87c5f963 | ||
| 
						 | 
					154f93da51 | ||
| 
						 | 
					742a6b55ce | ||
| 
						 | 
					72ab4bc547 | ||
| 
						 | 
					fb62504160 | ||
| 
						 | 
					d7030d268c | ||
| 
						 | 
					2e8e57a3de | ||
| 
						 | 
					ca276e01eb | ||
| 
						 | 
					977b339abe | ||
| 
						 | 
					9272d212c3 | ||
| 
						 | 
					f653c5bc33 | ||
| 
						 | 
					549417e675 | ||
| 
						 | 
					42c9fa4958 | ||
| 
						 | 
					df404c4296 | ||
| 
						 | 
					ffa227307c | ||
| 
						 | 
					3fc9cc97de | ||
| 
						 | 
					f5a268a96d | ||
| 
						 | 
					6da888c5d0 | ||
| 
						 | 
					33c537e5a7 | ||
| 
						 | 
					aa69034c00 | ||
| 
						 | 
					bf47f71785 | ||
| 
						 | 
					2b7a860ffb | ||
| 
						 | 
					932eeec240 | ||
| 
						 | 
					6f7aabf6a3 | ||
| 
						 | 
					a491e42129 | ||
| 
						 | 
					1ce111f72b | ||
| 
						 | 
					e010dea56e | ||
| 
						 | 
					f4530447f6 | ||
| 
						 | 
					e7361067ac | ||
| 
						 | 
					606837597f | ||
| 
						 | 
					5f8b332e6b | ||
| 
						 | 
					43001cbc7a | ||
| 
						 | 
					65d61c347b | ||
| 
						 | 
					c8ca02b937 | ||
| 
						 | 
					3ce5a3648a | ||
| 
						 | 
					a4cb02699e | ||
| 
						 | 
					f0fb2c2ddd | ||
| 
						 | 
					8a1e7b8658 | ||
| 
						 | 
					b7782d4d41 | ||
| 
						 | 
					b0b9c28284 | ||
| 
						 | 
					3730c550cd | ||
| 
						 | 
					cc8181fefe | ||
| 
						 | 
					7327360d10 | ||
| 
						 | 
					e405c2f196 | ||
| 
						 | 
					411ff3b984 | ||
| 
						 | 
					aee905b790 | ||
| 
						 | 
					fb75adfeda | ||
| 
						 | 
					7b9230acfe | ||
| 
						 | 
					5662cb2152 | ||
| 
						 | 
					e1412d9493 | ||
| 
						 | 
					d1e2342f91 | ||
| 
						 | 
					381b723543 | ||
| 
						 | 
					ee44b82b96 | ||
| 
						 | 
					b5f93346df | ||
| 
						 | 
					8e8c7ef3c7 | ||
| 
						 | 
					57238889eb | ||
| 
						 | 
					d70ab97fa4 | ||
| 
						 | 
					d1bd6fce9c | ||
| 
						 | 
					a32e4c4fb8 | ||
| 
						 | 
					3b84e92ab3 | ||
| 
						 | 
					3e0baa6146 | ||
| 
						 | 
					b673d1c438 | ||
| 
						 | 
					6a2856bab5 | ||
| 
						 | 
					0d95ca59f9 | ||
| 
						 | 
					906c2099da | ||
| 
						 | 
					ac07625086 | ||
| 
						 | 
					36c4fac9c9 | ||
| 
						 | 
					a06b2d3877 | ||
| 
						 | 
					546884d9a1 | ||
| 
						 | 
					f2286395e9 | ||
| 
						 | 
					9eebe15cd1 | ||
| 
						 | 
					31e1dab2c0 | ||
| 
						 | 
					db0366c9e4 | ||
| 
						 | 
					47adad0817 | ||
| 
						 | 
					c5efb5bccb | ||
| 
						 | 
					9a6da455b9 | ||
| 
						 | 
					b4c0828039 | ||
| 
						 | 
					df3dcac439 | ||
| 
						 | 
					0757504a86 | ||
| 
						 | 
					042a445cf3 | ||
| 
						 | 
					a16c7501a4 | ||
| 
						 | 
					9f98822255 | ||
| 
						 | 
					fc8357a2db | ||
| 
						 | 
					3e443ca502 | ||
| 
						 | 
					2c10211d60 | ||
| 
						 | 
					5fdda13f89 | ||
| 
						 | 
					dbeaa044f8 | ||
| 
						 | 
					7ad4d5e8cb | ||
| 
						 | 
					ab4db10750 | ||
| 
						 | 
					dddbbaaee1 | ||
| 
						 | 
					134855c45e | ||
| 
						 | 
					a4942e6566 | ||
| 
						 | 
					4e43ef5ab0 | ||
| 
						 | 
					4ae8d8232d | ||
| 
						 | 
					0bdd8bf5bc | ||
| 
						 | 
					5b1ef9589c | ||
| 
						 | 
					7d54ed48e7 | ||
| 
						 | 
					07730bb9cc | ||
| 
						 | 
					7b38af5cd3 | ||
| 
						 | 
					85ef5833cb | ||
| 
						 | 
					a2a08f7602 | ||
| 
						 | 
					282d4e3dda | ||
| 
						 | 
					42d3250d17 | ||
| 
						 | 
					5aed8de11d | ||
| 
						 | 
					5f5fcff5f3 | ||
| 
						 | 
					a884a95a7b | ||
| 
						 | 
					a4aada0b5f | ||
| 
						 | 
					732131d4d0 | ||
| 
						 | 
					36b940d1fe | ||
| 
						 | 
					e661277b48 | ||
| 
						 | 
					6f539aa259 | ||
| 
						 | 
					1c8c62667f | ||
| 
						 | 
					e5a082d64a | ||
| 
						 | 
					37c45e3998 | ||
| 
						 | 
					f5e40b7011 | ||
| 
						 | 
					02e21af657 | ||
| 
						 | 
					bffc3f9012 | ||
| 
						 | 
					7c4de0776b | ||
| 
						 | 
					077b903e11 | ||
| 
						 | 
					2d6a69e69a | ||
| 
						 | 
					4f0343233b | ||
| 
						 | 
					bcab7fb4af | ||
| 
						 | 
					427699e6eb | ||
| 
						 | 
					9c0f4f49e9 | ||
| 
						 | 
					ac51c7e68e | ||
| 
						 | 
					55d639f0fb | ||
| 
						 | 
					b9ace14717 | ||
| 
						 | 
					d9fff0c543 | ||
| 
						 | 
					1d85bea152 | ||
| 
						 | 
					f1e44c5493 | ||
| 
						 | 
					bebd75c2d1 | ||
| 
						 | 
					878ece768b | ||
| 
						 | 
					a00e79242b | ||
| 
						 | 
					840ce8a0a8 | ||
| 
						 | 
					afd76a731f | ||
| 
						 | 
					fd30bd1032 | ||
| 
						 | 
					227034c88e | ||
| 
						 | 
					3dad951171 | ||
| 
						 | 
					318795635e | ||
| 
						 | 
					22e1573831 | ||
| 
						 | 
					c85e89961a | ||
| 
						 | 
					2fc2bc6bc4 | ||
| 
						 | 
					0d0e242685 | ||
| 
						 | 
					698a2339eb | ||
| 
						 | 
					490782d18e | ||
| 
						 | 
					e3c5918aee | ||
| 
						 | 
					e2a1de5ca5 | ||
| 
						 | 
					4c7d29107f | ||
| 
						 | 
					f55a039048 | ||
| 
						 | 
					fc6676c4a0 | ||
| 
						 | 
					1af543f44c | ||
| 
						 | 
					bd228244da | ||
| 
						 | 
					a06120de77 | ||
| 
						 | 
					b589e78f13 | ||
| 
						 | 
					b11ed0f132 | ||
| 
						 | 
					9c332104eb | ||
| 
						 | 
					51127ea962 | ||
| 
						 | 
					dabb8b4860 | ||
| 
						 | 
					ff069172ce | ||
| 
						 | 
					7bee06e1cc | ||
| 
						 | 
					6c10aa0e6f | ||
| 
						 | 
					a4e24f5546 | ||
| 
						 | 
					29caaab817 | ||
| 
						 | 
					859f9b0752 | ||
| 
						 | 
					a037e5908a | ||
| 
						 | 
					2e7b9ff891 | ||
| 
						 | 
					361cb9e910 | ||
| 
						 | 
					5bacb59a6c | ||
| 
						 | 
					5b0096a236 | ||
| 
						 | 
					df6a105024 | ||
| 
						 | 
					226e95af1f | ||
| 
						 | 
					e37f48eaf9 | ||
| 
						 | 
					8a55263a1b | ||
| 
						 | 
					fed3389112 | ||
| 
						 | 
					081f30cba4 | ||
| 
						 | 
					ea0c26a436 | ||
| 
						 | 
					9d9d91b8e8 | ||
| 
						 | 
					73abc38dc5 | ||
| 
						 | 
					be4baa6d97 | ||
| 
						 | 
					d369013250 | ||
| 
						 | 
					8afec5f86d | ||
| 
						 | 
					5943cbb73f | ||
| 
						 | 
					f6c5f9524f | ||
| 
						 | 
					bc41c8d581 | ||
| 
						 | 
					89e1abcb18 | ||
| 
						 | 
					8376972050 | ||
| 
						 | 
					a964027344 | ||
| 
						 | 
					c5150cecc5 | ||
| 
						 | 
					02af9b3ca2 | ||
| 
						 | 
					db924d3908 | ||
| 
						 | 
					34a7416ec0 | ||
| 
						 | 
					45ce2725ac | ||
| 
						 | 
					a2eb5eb760 | ||
| 
						 | 
					fdd732b130 | ||
| 
						 | 
					1d8ffc6b23 | ||
| 
						 | 
					58c0da7833 | ||
| 
						 | 
					958256f5cf | ||
| 
						 | 
					6748dc90b8 | ||
| 
						 | 
					7bd7b6815a | ||
| 
						 | 
					b16c46b4c3 | ||
| 
						 | 
					840a8e9713 | ||
| 
						 | 
					cee7546f15 | ||
| 
						 | 
					ed1ba2c902 | ||
| 
						 | 
					ed08eb1c5a | ||
| 
						 | 
					2e84d2c29a | ||
| 
						 | 
					dd266066c7 | ||
| 
						 | 
					b5624c3d48 | ||
| 
						 | 
					6a21527a2d | ||
| 
						 | 
					1a8bc9839a | ||
| 
						 | 
					79aa4bd837 | ||
| 
						 | 
					fbb9c7f59a | ||
| 
						 | 
					3c1cce245e | ||
| 
						 | 
					93fed3bc51 | ||
| 
						 | 
					00d346092b | ||
| 
						 | 
					3ca419a2ef | ||
| 
						 | 
					ff438174aa | ||
| 
						 | 
					f85fe9720b | ||
| 
						 | 
					fed598f41d | ||
| 
						 | 
					471e349ecc | ||
| 
						 | 
					7e1175f6d8 | ||
| 
						 | 
					f621498129 | ||
| 
						 | 
					7c20148e39 | ||
| 
						 | 
					b6fc227763 | ||
| 
						 | 
					1d94585f96 | ||
| 
						 | 
					05ac095006 | ||
| 
						 | 
					73d28c9dda | ||
| 
						 | 
					ea70f3619a | ||
| 
						 | 
					98146776dd | ||
| 
						 | 
					b5b02c2a51 | ||
| 
						 | 
					bd60930f36 | ||
| 
						 | 
					720c939799 | ||
| 
						 | 
					4aa22db1b4 | ||
| 
						 | 
					db08819f85 | ||
| 
						 | 
					8fcfe58269 | ||
| 
						 | 
					ce316f4962 | ||
| 
						 | 
					59ffc89d42 | ||
| 
						 | 
					632e843e5f | ||
| 
						 | 
					e80494726c | ||
| 
						 | 
					3591437e0f | ||
| 
						 | 
					dda21ed7d4 | ||
| 
						 | 
					2778ae2b8f | ||
| 
						 | 
					1b6e8e7b5e | ||
| 
						 | 
					e257be1d69 | ||
| 
						 | 
					8a03ea8a32 | ||
| 
						 | 
					9e6dfa0558 | ||
| 
						 | 
					4857f3c2f3 | ||
| 
						 | 
					b513b951bd | ||
| 
						 | 
					33520b43ec | ||
| 
						 | 
					7fc8694b97 | ||
| 
						 | 
					b62983d3c3 | ||
| 
						 | 
					881e97ed00 | ||
| 
						 | 
					c55ece8d91 | ||
| 
						 | 
					8ffd7fc782 | ||
| 
						 | 
					e57cbe2e74 | ||
| 
						 | 
					0ab62fe081 | ||
| 
						 | 
					bdc504e29c | ||
| 
						 | 
					b87da75ae4 | ||
| 
						 | 
					14b1b63710 | ||
| 
						 | 
					367baa3776 | ||
| 
						 | 
					37d5b1557b | ||
| 
						 | 
					54d082e5e8 | ||
| 
						 | 
					b10ee08c2f | ||
| 
						 | 
					23eea1d132 | ||
| 
						 | 
					81bc2aea53 | ||
| 
						 | 
					ab6d189f8f | ||
| 
						 | 
					2e48a44952 | ||
| 
						 | 
					72a38b55e3 | ||
| 
						 | 
					1ae98777d9 | ||
| 
						 | 
					d46bcd236e | ||
| 
						 | 
					d4d6e09fd2 | ||
| 
						 | 
					365f8fa462 | ||
| 
						 | 
					d1bf1e11ba | ||
| 
						 | 
					a0d281db1c | ||
| 
						 | 
					53165ede24 | ||
| 
						 | 
					63ebccdfe3 | ||
| 
						 | 
					d12eab9c4e | ||
| 
						 | 
					d9d8862a58 | ||
| 
						 | 
					283188790b | ||
| 
						 | 
					3142d8d30b | ||
| 
						 | 
					a2861a7428 | ||
| 
						 | 
					19e19e3609 | ||
| 
						 | 
					93c3b386cf | ||
| 
						 | 
					bf6de7a289 | ||
| 
						 | 
					1fce2ce0b3 | ||
| 
						 | 
					a8f71eb24e | ||
| 
						 | 
					8c25b97d3f | ||
| 
						 | 
					a892177dce | ||
| 
						 | 
					9225bfc48c | ||
| 
						 | 
					bf5c0bb4b9 | ||
| 
						 | 
					875e4dc8c3 | ||
| 
						 | 
					68d244d302 | ||
| 
						 | 
					7716860845 | ||
| 
						 | 
					d37b80a6d2 | ||
| 
						 | 
					dbd7024919 | ||
| 
						 | 
					f41f5866ce | ||
| 
						 | 
					f7611c3cee | ||
| 
						 | 
					38929c9131 | ||
| 
						 | 
					ee9d34a9cc | ||
| 
						 | 
					727417dd28 | ||
| 
						 | 
					cd93f4f4be | ||
| 
						 | 
					395e213894 | ||
| 
						 | 
					03dbafb000 | ||
| 
						 | 
					86540de7f3 | ||
| 
						 | 
					cc077ae0bc | ||
| 
						 | 
					6bf2f05df6 | ||
| 
						 | 
					0eaa5b8e6c | ||
| 
						 | 
					176e895bd6 | ||
| 
						 | 
					23d9976039 | ||
| 
						 | 
					466da99934 | ||
| 
						 | 
					8419e33c4a | ||
| 
						 | 
					d9d7be339d | ||
| 
						 | 
					7b31987a46 | ||
| 
						 | 
					f89dc4e127 | ||
| 
						 | 
					b29ff1da55 | ||
| 
						 | 
					d997552d29 | ||
| 
						 | 
					05f3ef3eb8 | ||
| 
						 | 
					134a7752fd | ||
| 
						 | 
					8ddb6805a9 | ||
| 
						 | 
					3a9befb516 | ||
| 
						 | 
					c80680a9c4 | ||
| 
						 | 
					c5fbf9bd68 | ||
| 
						 | 
					4b075b6cb8 | ||
| 
						 | 
					89dcb614e8 | ||
| 
						 | 
					ac0b4f17fe | ||
| 
						 | 
					10abfba949 | ||
| 
						 | 
					a377b0874a | ||
| 
						 | 
					04cbae494d | ||
| 
						 | 
					db852a14fe | ||
| 
						 | 
					e740e81281 | ||
| 
						 | 
					2ea010a1ed | ||
| 
						 | 
					041824dfc8 | ||
| 
						 | 
					cd14094bb6 | ||
| 
						 | 
					0dc4748447 | ||
| 
						 | 
					6c06d25667 | 
							
								
								
									
										1
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					open_collective: osmocom
 | 
				
			||||||
							
								
								
									
										74
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										74
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,7 +1,9 @@
 | 
				
			|||||||
 | 
					# autotools
 | 
				
			||||||
Makefile
 | 
					Makefile
 | 
				
			||||||
Makefile.in
 | 
					Makefile.in
 | 
				
			||||||
aclocal.m4
 | 
					aclocal.m4
 | 
				
			||||||
autom4te.cache
 | 
					autom4te.cache
 | 
				
			||||||
 | 
					compile
 | 
				
			||||||
config.guess
 | 
					config.guess
 | 
				
			||||||
config.h.in*
 | 
					config.h.in*
 | 
				
			||||||
config.h
 | 
					config.h
 | 
				
			||||||
@@ -14,33 +16,73 @@ install-sh
 | 
				
			|||||||
libtool
 | 
					libtool
 | 
				
			||||||
ltmain.sh
 | 
					ltmain.sh
 | 
				
			||||||
missing
 | 
					missing
 | 
				
			||||||
openggsn.spec
 | 
					 | 
				
			||||||
stamp-h1
 | 
					stamp-h1
 | 
				
			||||||
doc/Makefile.in
 | 
					 | 
				
			||||||
ggsn/Makefile.in
 | 
					 | 
				
			||||||
gtp/Makefile.in
 | 
					 | 
				
			||||||
sgsnemu/Makefile.in
 | 
					 | 
				
			||||||
debian/openggsn/
 | 
					 | 
				
			||||||
debian/*.debhelper
 | 
					 | 
				
			||||||
debian/libgtp/
 | 
					 | 
				
			||||||
debian/*.log
 | 
					 | 
				
			||||||
INSTALL
 | 
					INSTALL
 | 
				
			||||||
 | 
					m4/
 | 
				
			||||||
 | 
					Makefile
 | 
				
			||||||
 | 
					osmo-ggsn-*.tar*
 | 
				
			||||||
 | 
					.version
 | 
				
			||||||
 | 
					.tarball-version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# debian
 | 
				
			||||||
 | 
					debian/osmo-ggsn/
 | 
				
			||||||
 | 
					debian/*.debhelper
 | 
				
			||||||
 | 
					debian/libgtp*/
 | 
				
			||||||
 | 
					debian/osmo-ggsn-dbg
 | 
				
			||||||
 | 
					debian/*.log
 | 
				
			||||||
debian/autoreconf.*
 | 
					debian/autoreconf.*
 | 
				
			||||||
debian/*.substvars
 | 
					debian/*.substvars
 | 
				
			||||||
debian/tmp/
 | 
					debian/tmp/
 | 
				
			||||||
sgsnemu/sgsnemu
 | 
					 | 
				
			||||||
debian/files
 | 
					debian/files
 | 
				
			||||||
debian/libgtp-dev/
 | 
					debian/libgtp-dev/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# programs / libraries
 | 
				
			||||||
 | 
					sgsnemu/sgsnemu
 | 
				
			||||||
libgtp.pc
 | 
					libgtp.pc
 | 
				
			||||||
ggsn/ggsn
 | 
					ggsn/osmo-ggsn
 | 
				
			||||||
m4/
 | 
					
 | 
				
			||||||
*.swp
 | 
					# compiler results
 | 
				
			||||||
*.o
 | 
					*.o
 | 
				
			||||||
*.a
 | 
					*.a
 | 
				
			||||||
*.la
 | 
					*.la
 | 
				
			||||||
*.lo
 | 
					*.lo
 | 
				
			||||||
 | 
					*.pyc
 | 
				
			||||||
 | 
					.deps
 | 
				
			||||||
 | 
					.libs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# misc
 | 
				
			||||||
 | 
					*.swp
 | 
				
			||||||
 | 
					.dirstamp
 | 
				
			||||||
 | 
					.deps
 | 
				
			||||||
*.orig
 | 
					*.orig
 | 
				
			||||||
 | 
					*.new
 | 
				
			||||||
*.rej
 | 
					*.rej
 | 
				
			||||||
*/.deps
 | 
					*~
 | 
				
			||||||
*/.libs
 | 
					osmo-ggsn.cfg
 | 
				
			||||||
*/Makefile
 | 
					sgsnemu.pid
 | 
				
			||||||
 | 
					gsn_restart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# testsuite
 | 
				
			||||||
 | 
					tests/atconfig
 | 
				
			||||||
 | 
					tests/*/*_test
 | 
				
			||||||
 | 
					tests/testsuite
 | 
				
			||||||
 | 
					tests/testsuite.log
 | 
				
			||||||
 | 
					tests/package.m4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# manuals
 | 
				
			||||||
 | 
					doc/manuals/*.html
 | 
				
			||||||
 | 
					doc/manuals/*.svg
 | 
				
			||||||
 | 
					doc/manuals/*.pdf
 | 
				
			||||||
 | 
					doc/manuals/*__*.png
 | 
				
			||||||
 | 
					doc/manuals/*.check
 | 
				
			||||||
 | 
					doc/manuals/generated/
 | 
				
			||||||
 | 
					doc/manuals/osmomsc-usermanual.xml
 | 
				
			||||||
 | 
					doc/manuals/common
 | 
				
			||||||
 | 
					doc/manuals/build
 | 
				
			||||||
 | 
					doc/manuals/vty/ggsn_vty_reference.xml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					contrib/osmo-ggsn.spec
 | 
				
			||||||
 | 
					/debian/gtp-echo-responder-dbg/
 | 
				
			||||||
 | 
					/debian/gtp-echo-responder/
 | 
				
			||||||
 | 
					/debian/osmo-ggsn-doc/
 | 
				
			||||||
 | 
					/utils/gtp-echo-responder
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								.gitreview
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitreview
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					[gerrit]
 | 
				
			||||||
 | 
					host=gerrit.osmocom.org
 | 
				
			||||||
 | 
					project=osmo-ggsn
 | 
				
			||||||
							
								
								
									
										23
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								AUTHORS
									
									
									
									
									
								
							@@ -1,9 +1,16 @@
 | 
				
			|||||||
OpenGGSN - Gateway GPRS Support Node
 | 
					OsmoGGSN - Osmocom Gateway GPRS Support Node, based on OpenGGSN
 | 
				
			||||||
Copyright (C) 2002 Mondru AB.
 | 
					Copyright (C) 2002-2004 Mondru AB, Author: Jens Jakobsen <jj@openggsn.org>
 | 
				
			||||||
 | 
					Copyright (C) 2010-2017 Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
The initial developer of the original code is
 | 
					Copyright (C) 2012-2016 Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
Jens Jakobsen <jj@openggsn.org>
 | 
					Copyright (C) 2014-2016 Pablo Neira Ayuso <pablo@gnumonks.org>
 | 
				
			||||||
 | 
					Copyright (C) 2014-2016 sysmocom - s.f.m.c. GmbH
 | 
				
			||||||
Contributor(s):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Contributors:
 | 
				
			||||||
 | 
					Emmanuel Bretelle <chantra@debuntu.org>
 | 
				
			||||||
 | 
					Yann BONNAMY <yann_bonnamy@yahoo.fr>
 | 
				
			||||||
 | 
					Eric Butler <eric@codebutler.com>
 | 
				
			||||||
 | 
					Michael McTernan <mike.mcternan@wavemobile.com>
 | 
				
			||||||
 | 
					Alexander Huemer <alexander.huemer@xx.vu>
 | 
				
			||||||
 | 
					BJovke <bjovan@gmail.com>
 | 
				
			||||||
 | 
					Alexander Couzens <lynxis@fe80.eu>
 | 
				
			||||||
 | 
					Ruben Undheim <ruben.undheim@gmail.com>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										142
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								ChangeLog
									
									
									
									
									
								
							@@ -1,142 +0,0 @@
 | 
				
			|||||||
2004-12-30: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
        Initial MAC OS X support
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Quality assurance and improved error logging
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QoS length bug fix.
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
2004-09-11: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Added selection mode option to sgsnemu.
 | 
					 | 
				
			||||||
	Added charging characteristics option to sgsnemu.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Only include charging characteristics in create PDP context
 | 
					 | 
				
			||||||
	request is if flags are set. (Thanks to Loic Bernable
 | 
					 | 
				
			||||||
	<leto@vilya.org>).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PPP PCO length bug fix. (Thanks to Loic Bernable
 | 
					 | 
				
			||||||
	<leto@vilya.org>).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	IP pool hash table bugfix and improved logging.
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	Improved configure.in and Makefile.am for compilation under
 | 
					 | 
				
			||||||
	Solaris. New config.sub and config.guess.
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
2004-04-28: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Improved Solaris support. OpenGGSN now correctly initializes
 | 
					 | 
				
			||||||
	tun/tap driver under Solaris. As a consequence the ggsn network
 | 
					 | 
				
			||||||
	interface IP address is set to the network address plus one.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added routing manipulation and IP address alias capability for
 | 
					 | 
				
			||||||
	FreeBSD.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2004-01-19: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Initial FreeBSD port (Thanks to	Pavel Andreev <pavel.andreev@hp.com>).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	IMSI bugfix. The IMSI encoding used by create PDP context was
 | 
					 | 
				
			||||||
	missing the leading '1111' to indicate that the 16'nd digit was
 | 
					 | 
				
			||||||
	unused. (Thanks to Pavel Andreev <pavel.andreev@hp.com>).
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2004-01-15: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Added iptables firewall script.
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2004-01-14: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Changes to allow compilation under Solaris: u_int8_t changed to uint8_t
 | 
					 | 
				
			||||||
	and tun api changed for sun platform (#ifdef).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
2004-01-09: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Fixed bug which included NSAPI in GTPv0 create PDP context messages.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2003-11-10: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Added --net option for sgsnemu. Allow user to specify the network
 | 
					 | 
				
			||||||
	address and mask of the local interface.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added --gtpversion option for sgsnemu. Allow user to specify which
 | 
					 | 
				
			||||||
	GTP version to use.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added --nsapi option for sgsnemu. Allow user to specify which
 | 
					 | 
				
			||||||
	NSAPI to use.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Changed the functionality for multiple contexts. Previously
 | 
					 | 
				
			||||||
	contexts were differentiated by nsapi. This limited the number of
 | 
					 | 
				
			||||||
	contexts to 16. Now each context is established with a new imsi
 | 
					 | 
				
			||||||
	and msisdn.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2003-10-22: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Support for GTP1. Currently without support for the secondary pdp
 | 
					 | 
				
			||||||
	context activation procedure.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sgsnemu will first attempt to use GTP1. If that fails it will
 | 
					 | 
				
			||||||
	proceed with GTP0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Various gtplib API changes to allow support for GTP1.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	gtplib now listens to 3 separate UDP ports: GTP0, GTP1 control
 | 
					 | 
				
			||||||
	plane and GTP1 user plane. A socket for each port has to be
 | 
					 | 
				
			||||||
	included in the application select loop.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	gtplib now verifies that messages are valid for the particular
 | 
					 | 
				
			||||||
	type of support node. As an example a received Create PDP Context
 | 
					 | 
				
			||||||
	Request message is not allowed for an SGSN.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Standards compliance document.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
2003-07-07: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Added spec.in file for building binary RPM packages. Now openggsn
 | 
					 | 
				
			||||||
	will install binaries, man pages as well as scripts.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added ggsn and sgsnemu man pages
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added ggsn Sys V init script
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added bootstrap script for autotools automation
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2003-04-11: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Added -ggdb to gtp, sgsnemu and ggsn makefiles in order to include
 | 
					 | 
				
			||||||
	debugging information.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added ippool.c and ippool.h to ggsn. This allows for generic
 | 
					 | 
				
			||||||
	allocation of dynamic ip addresses based on a <net>/<mask>
 | 
					 | 
				
			||||||
	description of ip address space. The same files are also used in
 | 
					 | 
				
			||||||
	sgsnemu, but only for hashing IP addresses. At the same time the
 | 
					 | 
				
			||||||
	corresponding functionality is removed from pdp.c.
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	Added syserr.h and syserr.c to ggsn and sgsnemu. These files allow
 | 
					 | 
				
			||||||
	writing to syslog with file name and line number. Later this
 | 
					 | 
				
			||||||
	should also be introduced in gtp.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added support for DNS protocol configuration options in ggsn for
 | 
					 | 
				
			||||||
	create context response. This allow the MS to setup DNS
 | 
					 | 
				
			||||||
	configuration correctly.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tun.c and tun.h have been updated to allow setting interface IP
 | 
					 | 
				
			||||||
	addresses and routes by means of ioctl and netlink. This allow
 | 
					 | 
				
			||||||
	sgsnemu to allocate an interface IP address for each context
 | 
					 | 
				
			||||||
	established.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2003-01-29: Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
	Added -L../gtp to sgsnemu and ggsn makefiles so that make will
 | 
					 | 
				
			||||||
	work without an installed libgtp.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added sgsnemu check to check for valid pointer when deleting tun.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Removed enabling of ip_forward = 1 from ggsn.c and sgsnemu. From a
 | 
					 | 
				
			||||||
	security point of view it was not very good that openggsn
 | 
					 | 
				
			||||||
	automatically enabled routing.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added ipup, ipdown and createif to sgsnemu/cmdline.ggo. Now
 | 
					 | 
				
			||||||
	sgsnemu will set up default route and then execute ipup script
 | 
					 | 
				
			||||||
	after tun device has been set up. After tun has been deleted the
 | 
					 | 
				
			||||||
	ipdown script is executed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added support for ping to sgsnemu.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Added ipup and ipdown to ggsn/cmdline.ggo.
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
							
								
								
									
										32
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -1,5 +1,35 @@
 | 
				
			|||||||
## Process this file with automake to produce Makefile.in
 | 
					## Process this file with automake to produce Makefile.in
 | 
				
			||||||
SUBDIRS = lib gtp ggsn sgsnemu doc
 | 
					SUBDIRS = \
 | 
				
			||||||
 | 
						  include \
 | 
				
			||||||
 | 
						  lib \
 | 
				
			||||||
 | 
						  gtp \
 | 
				
			||||||
 | 
						  ggsn \
 | 
				
			||||||
 | 
						  sgsnemu \
 | 
				
			||||||
 | 
						  doc \
 | 
				
			||||||
 | 
						  contrib \
 | 
				
			||||||
 | 
						  utils \
 | 
				
			||||||
 | 
						  tests \
 | 
				
			||||||
 | 
						  $(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
					pkgconfigdir = $(libdir)/pkgconfig
 | 
				
			||||||
pkgconfig_DATA = libgtp.pc
 | 
					pkgconfig_DATA = libgtp.pc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BUILT_SOURCES = $(top_srcdir)/.version
 | 
				
			||||||
 | 
					$(top_srcdir)/.version:
 | 
				
			||||||
 | 
						echo $(VERSION) > $@-t && mv $@-t $@
 | 
				
			||||||
 | 
					dist-hook:
 | 
				
			||||||
 | 
						echo $(VERSION) > $(distdir)/.tarball-version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXTRA_DIST = \
 | 
				
			||||||
 | 
						     .version \
 | 
				
			||||||
 | 
						     README.FreeBSD \
 | 
				
			||||||
 | 
						     README.MacOSX \
 | 
				
			||||||
 | 
						     README.md \
 | 
				
			||||||
 | 
						     debian \
 | 
				
			||||||
 | 
						     git-version-gen \
 | 
				
			||||||
 | 
						     $(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AM_DISTCHECK_CONFIGURE_FLAGS = \
 | 
				
			||||||
 | 
						--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@RELMAKE@
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										78
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,78 +0,0 @@
 | 
				
			|||||||
OPENGGSN NEWS
 | 
					 | 
				
			||||||
=============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenGGSN - Gateway GPRS Support Node
 | 
					 | 
				
			||||||
Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Version 0.84
 | 
					 | 
				
			||||||
============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Initial MAC OSX support (Thanks to Pekka Nikander)
 | 
					 | 
				
			||||||
* Quality assurance and improved error logging (Thanks to Pekka
 | 
					 | 
				
			||||||
  Nikander and Jonny Winberg)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Version 0.83
 | 
					 | 
				
			||||||
============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added selection mode and charging characteristics option to sgsnemu.
 | 
					 | 
				
			||||||
* Bug fixes on charging characteristics and PPP PCO length.(Thanks to
 | 
					 | 
				
			||||||
  Loic Bernable	<leto@vilya.org>).
 | 
					 | 
				
			||||||
* Improved Solaris support, hash table bugfix and improved logging.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Version 0.82
 | 
					 | 
				
			||||||
============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Improved Solaris support. 
 | 
					 | 
				
			||||||
* Routing manipulation and IP address alias capability for FreeBSD.
 | 
					 | 
				
			||||||
* Initial Debian port (Thanks to ARAKI Yasuhiro <ar@debian.org>).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Version 0.81
 | 
					 | 
				
			||||||
============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Initial FreeBSD port (Thanks to Pavel Andreev <pavel.andreev@hp.com>).
 | 
					 | 
				
			||||||
 * IMSI '1111' bugfix (Thanks to Pavel Andreev <pavel.andreev@hp.com>).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Version 0.8
 | 
					 | 
				
			||||||
===========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Support for compilation under Solaris.
 | 
					 | 
				
			||||||
 * Iptables firewall script.
 | 
					 | 
				
			||||||
 * New options for sgsnemu
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Version 0.7
 | 
					 | 
				
			||||||
===========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Support for GTP1. Currently without support for the secondary pdp
 | 
					 | 
				
			||||||
   context activation procedure.
 | 
					 | 
				
			||||||
 * sgsnemu will first attempt to use GTP1. If that fails it will
 | 
					 | 
				
			||||||
   fallback to using GTP0.
 | 
					 | 
				
			||||||
 * Standards compliance document.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Version 0.6
 | 
					 | 
				
			||||||
===========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Improved README file.
 | 
					 | 
				
			||||||
 * Now uses ioctl instead of ifconfig and route in ggsn and sgsnemu.
 | 
					 | 
				
			||||||
 * Absolute path to gtp library in ggsn/Makefile.am and ggsn/Makefile.am
 | 
					 | 
				
			||||||
 * Compiles with gengetopt 2.8 (Thanks to Lorenzo Bettini <bettini@gnu.org>)
 | 
					 | 
				
			||||||
 * sgsnemu is now able to handle several contexts and allocate
 | 
					 | 
				
			||||||
   interface IP addresses for each context.
 | 
					 | 
				
			||||||
 * ggsn now supports protocol configuration option DNS
 | 
					 | 
				
			||||||
   addresses. This allow mobile stations to set up DNS based on
 | 
					 | 
				
			||||||
   information configured in the ggsn.
 | 
					 | 
				
			||||||
 * Ping facility in sgsnemu allow testing without the need to route
 | 
					 | 
				
			||||||
   packets through the tun interface.
 | 
					 | 
				
			||||||
 * Man pages for ggsn and sgsnemu.
 | 
					 | 
				
			||||||
 * Sys 5 init script.
 | 
					 | 
				
			||||||
 * Spec file for building binary RPM packages.
 | 
					 | 
				
			||||||
 * If not --createif exit after "ping" or "echo" finishes
 | 
					 | 
				
			||||||
 * If sgsnemu echo failure, exit with code != 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Version 0.5
 | 
					 | 
				
			||||||
===========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * Initial release. See README file for installation and usage
 | 
					 | 
				
			||||||
   instructions.
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
							
								
								
									
										430
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										430
									
								
								README
									
									
									
									
									
								
							@@ -1,430 +0,0 @@
 | 
				
			|||||||
OPENGGSN README
 | 
					 | 
				
			||||||
===============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QuickStart
 | 
					 | 
				
			||||||
==========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Requirements
 | 
					 | 
				
			||||||
------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*Linux* 
 | 
					 | 
				
			||||||
OpenGGSN was developed and tested using Redhat 8.0 and 9.0. It should
 | 
					 | 
				
			||||||
run also on other Linux distributions as well as FreeBSD, but this is
 | 
					 | 
				
			||||||
untested. Compilation on Solaris 2.8 has also been verified.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*Tun*
 | 
					 | 
				
			||||||
The tun driver is required for proper operation of openggsn. For linux
 | 
					 | 
				
			||||||
kernels later than 2.4.7 the driver is typically included, but need
 | 
					 | 
				
			||||||
to be configured for automatic loading:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Add the following line to /etc/modules.conf: alias char-major-10-200 tun 
 | 
					 | 
				
			||||||
2. depmod -a
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Installation from binary
 | 
					 | 
				
			||||||
------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rpm -i openggsn-<version>.rpm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This will install binaries, man pages, configuration files as well as
 | 
					 | 
				
			||||||
a Sys V init script for the ggsn.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Installation from source
 | 
					 | 
				
			||||||
------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. ./configure
 | 
					 | 
				
			||||||
2. make
 | 
					 | 
				
			||||||
3. make install
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You need to be root in order to install the package, but not in order
 | 
					 | 
				
			||||||
to compile.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Running
 | 
					 | 
				
			||||||
-------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*sgsnemu*
 | 
					 | 
				
			||||||
Start the emulator as root using the command:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  sgsnemu -l 10.0.0.50 -r 10.0.0.40 --createif --defaultroute
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This will cause the sgsn emulator to bind to local address 10.0.0.50
 | 
					 | 
				
			||||||
and connect to the ggsn found at 10.0.0.40. It will first send off an
 | 
					 | 
				
			||||||
ECHO_REQUEST message. After this it will attempt to establish a pdp
 | 
					 | 
				
			||||||
context. If successful it will create a local interface and set up
 | 
					 | 
				
			||||||
routing. Now you should be able to ping through the connection. Use a
 | 
					 | 
				
			||||||
network analysator such as ethereal to monitor the traffic.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sgsnemu -h will show a list of available options. 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sgsnemu -c sgsnemu.conf will use sgsnemu.conf as a configuration
 | 
					 | 
				
			||||||
file. A sample file is provided in examples/sgsnemu.conf.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*ggsn*
 | 
					 | 
				
			||||||
Edit the configuration file ggsn.conf found under openggsn/examples.
 | 
					 | 
				
			||||||
Start the ggsn as root using the command:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ggsn --fg -c examples/ggsn.conf -l 10.0.0.40 --statedir ./
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This will run the ggsn in foreground using the local interface
 | 
					 | 
				
			||||||
10.0.0.40. If you don't have a GSM network available for testing you
 | 
					 | 
				
			||||||
can use sgsnemu to test the GGSN.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Support
 | 
					 | 
				
			||||||
-------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you have any questions drop me a line at jj@openggsn.org.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Features
 | 
					 | 
				
			||||||
========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenGGSN is an open source implementation of GPRS Support Nodes
 | 
					 | 
				
			||||||
(GSNs). It implements the GPRS tunneling protocol (GTP) version 0 and
 | 
					 | 
				
			||||||
version 1.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenGGSN provides 3 components:
 | 
					 | 
				
			||||||
 * gtplib
 | 
					 | 
				
			||||||
 * ggsn
 | 
					 | 
				
			||||||
 * sgsnemu
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*gtplib*
 | 
					 | 
				
			||||||
This library contains all functionality relating to the GTP
 | 
					 | 
				
			||||||
protocol. Use this library if you want to implement your own
 | 
					 | 
				
			||||||
GSN. gtplib supports both GTPv0 (GSM 09.60) and GTPv1 (3GPP
 | 
					 | 
				
			||||||
29.060). At the moment no interface documentation is available for
 | 
					 | 
				
			||||||
download.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*ggsn*
 | 
					 | 
				
			||||||
The ggsn implements a Gateway GPRS Support Node. The GGSN is a small
 | 
					 | 
				
			||||||
application which is provided in order to test and demonstrate the use
 | 
					 | 
				
			||||||
of gtplib. It is fully compliant to the 3GPP standards, but lacks
 | 
					 | 
				
			||||||
important functionality such as charging and management. Use this
 | 
					 | 
				
			||||||
application as a starting point if you want to build your own GGSN
 | 
					 | 
				
			||||||
with your own fancy VPN, management and charging functionality.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*sgsnemu*
 | 
					 | 
				
			||||||
This application emulates a Serving GPRS Support Node (SGSN). sgsnemu
 | 
					 | 
				
			||||||
enables you to test your 3GPP core network without the need to invest
 | 
					 | 
				
			||||||
in a 3G radio access network. An important application of sgsnemu is
 | 
					 | 
				
			||||||
the testing of roaming connectivity through a GPRS roaming
 | 
					 | 
				
			||||||
exchange. sgsnemu will first attempt to use GTPv1. If unsuccessful it
 | 
					 | 
				
			||||||
will fallback to GTPv0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Performance
 | 
					 | 
				
			||||||
===========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Two experiments were performed in order to test the performance of
 | 
					 | 
				
			||||||
sgsnemu and ggsn. The ggsn used a 550 MHz Athlon with 384 MB of
 | 
					 | 
				
			||||||
RAM. sgsnemu used a 1 GHz Athlon with 256 MB of RAM. Both machines had
 | 
					 | 
				
			||||||
100 Mb/s NICs (RTL-8139) and were connected through a crossed patch
 | 
					 | 
				
			||||||
cable. Both tests were performed by sending ICMP echo packets from
 | 
					 | 
				
			||||||
sgsnemu to the ggsn.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
89.5 Mb/s IP throughput when sending 10000 ICMP ping packets with a
 | 
					 | 
				
			||||||
payload of 1400 bytes. Transfer time 1.27 sec, no packets lost.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
71.4 Mb/s IP throughput when sending 10000 ICMP ping packets with a
 | 
					 | 
				
			||||||
payload of 1000 bytes. Transfer time 1.15 sec, no packets lost.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
12,1 Mb/s IP throughput when sending 10000 ICMP ping packets with a
 | 
					 | 
				
			||||||
payload of 100 bytes. Transfer time 0.84 sec, no packets lost.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Required software
 | 
					 | 
				
			||||||
=================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Tun
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Both ggsn and sgsnemu uses the tun package. You need at least tun
 | 
					 | 
				
			||||||
version 1.1. With Linux tun is normally included from kernel version
 | 
					 | 
				
			||||||
2.4.7. To configure automatic loading:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Add the following line to /etc/modules.conf: alias char-major-10-200 tun 
 | 
					 | 
				
			||||||
2. depmod -a
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Alternatively you can execute "modprobe tun" on the commandline.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For Solaris the tun driver needs to be installed manually. For general
 | 
					 | 
				
			||||||
information about tun see http://vtun.sourceforge.net/tun/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Gengetopt
 | 
					 | 
				
			||||||
---------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Gengetopt is required if you want to change the options defined in the
 | 
					 | 
				
			||||||
cmdline.ggo source file. You need at least gengetopt version 2.8. If
 | 
					 | 
				
			||||||
you are just going to compile the programs you don't need gengetopt.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
To use gengetopt for the ggsn do the following:
 | 
					 | 
				
			||||||
cd ggsn
 | 
					 | 
				
			||||||
gengetopt < cmdline.ggo --conf-parser
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
To use gengetopt for the sgsnemu do the following:
 | 
					 | 
				
			||||||
cd sgsnemu
 | 
					 | 
				
			||||||
gengetopt < cmdline.ggo --conf-parser
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For more information about gengetopt see
 | 
					 | 
				
			||||||
http://www.gnu.org/software/gengetopt/gengetopt.html
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Compilation and Installation
 | 
					 | 
				
			||||||
============================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Setting up autotools
 | 
					 | 
				
			||||||
--------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You do not need to perform this step if you are only going to compile
 | 
					 | 
				
			||||||
the package:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Get version from somewhere: Script to extract version from configure.in
 | 
					 | 
				
			||||||
2. Copy the latest config.guess and config.sub from ftp://ftp.gnu.org/gnu/config
 | 
					 | 
				
			||||||
3. Run autoscan and copy configure.scan to configure.in
 | 
					 | 
				
			||||||
4. Add/edit the following lines in configure.in:
 | 
					 | 
				
			||||||
   - AC_INIT(openggsn, 0.70, jj@openggsn.org)
 | 
					 | 
				
			||||||
   - AC_CONFIG_SRCDIR([gtp/gtp.c])
 | 
					 | 
				
			||||||
   - AM_CONFIG_HEADER([config.h])
 | 
					 | 
				
			||||||
   - AC_PROG_LIBTOOL
 | 
					 | 
				
			||||||
   - AM_PROG_LIBTOOL
 | 
					 | 
				
			||||||
   - AM_INIT_AUTOMAKE()
 | 
					 | 
				
			||||||
5. libtoolize --automake --copy
 | 
					 | 
				
			||||||
  (ads copy of ltmain.sh)
 | 
					 | 
				
			||||||
6. aclocal
 | 
					 | 
				
			||||||
7. autoheader
 | 
					 | 
				
			||||||
8. automake --add-missing --copy
 | 
					 | 
				
			||||||
  (Ads copy of mkinstalldirs missing, install-sh, depcomp)
 | 
					 | 
				
			||||||
9. automake
 | 
					 | 
				
			||||||
10. autoconf
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The above will initialise the project to the current version of
 | 
					 | 
				
			||||||
autotools (As installed in RedHat 8.0). See
 | 
					 | 
				
			||||||
http://sources.redhat.com/autobook/autobook/autobook_25.html#SEC25 
 | 
					 | 
				
			||||||
for details on autotools.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Checking out from CVS
 | 
					 | 
				
			||||||
---------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
To download the latest source code from anonymous CVS:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ggsn login
 | 
					 | 
				
			||||||
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ggsn co openggsn
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Or to download from developer CVS:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export CVS_RSH=ssh
 | 
					 | 
				
			||||||
cvs -z3 -d:ext:developername@cvs.sourceforge.net:/cvsroot/ggsn co openggsn
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Both the above sets of commands creates a new directory called openggsn.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Compilation and installation
 | 
					 | 
				
			||||||
----------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If compiling under Solaris you need to edit the following line in
 | 
					 | 
				
			||||||
ggsn/Makefile.in and sgsnemu/Makefile.in:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LDFLAGS = -Wl,--rpath -Wl,/usr/local/lib @EXEC_LDFLAGS@
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
should be changed to:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LDFLAGS =  -lresolv -lsocket -lnsl @EXEC_LDFLAGS@ 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Note that the above is not necessary on other platforms. Compilation
 | 
					 | 
				
			||||||
and installation is performed by the following steps:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 1. ./configure
 | 
					 | 
				
			||||||
 2. make clean
 | 
					 | 
				
			||||||
 3. cd gtp
 | 
					 | 
				
			||||||
 4. make
 | 
					 | 
				
			||||||
 5. make install (as root)
 | 
					 | 
				
			||||||
 6. cd ..
 | 
					 | 
				
			||||||
   (Step 3 to 6 you only need to run the first time to install libgtp)
 | 
					 | 
				
			||||||
 7. make
 | 
					 | 
				
			||||||
 8. make install (as root)
 | 
					 | 
				
			||||||
 9. Add /usr/local/lib to /etc/ld.so.conf
 | 
					 | 
				
			||||||
10. run ldconfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(Steps 9 and 10 are not required as path to libgtp is included in Makefile)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Documentation can be converted to html by issuing:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 1. txt2html -pm -tf README > README.html
 | 
					 | 
				
			||||||
 2. txt2html -pm -tf NEWS > NEWS.html
 | 
					 | 
				
			||||||
 3. txt2html -pm -tf ChangeLog > ChangeLog.html
 | 
					 | 
				
			||||||
 4. man2htm ggsn.8 > ggsn.html
 | 
					 | 
				
			||||||
 5. man2htm sgsnemu.8 > sgsnemu.html
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Installation from binary
 | 
					 | 
				
			||||||
------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. rpm -i openggsn-<version>.rpm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This will install binaries, man pages, configuration files as well as
 | 
					 | 
				
			||||||
a Sys V init script for the ggsn.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Running ggsn
 | 
					 | 
				
			||||||
============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Use ggsn -h for a list of available options. All options available on
 | 
					 | 
				
			||||||
the command line can also be given in a configuration file. See
 | 
					 | 
				
			||||||
examples/ggsn.conf for the format of this file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Start the ggsn as root using the command:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ggsn -c examples/ggsn.conf --fg -l 10.0.0.40 --net 192.168.0.0/24 --dynip 192.168.0.0/24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
First a tun network interface will be created. In the above example
 | 
					 | 
				
			||||||
the network interface address is 192.168.0.0 and the mask is
 | 
					 | 
				
			||||||
255.255.255.0. You can check that this interface is up by using
 | 
					 | 
				
			||||||
ifconfig.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
After tun has been successfully established the ggsn will wait for GTP
 | 
					 | 
				
			||||||
create PDP context requests on the local interface
 | 
					 | 
				
			||||||
10.0.0.40. Currently all requests are accepted, and no password,
 | 
					 | 
				
			||||||
username or APN validation is performed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
When receiving a create PDP context request a dynamic IP address will
 | 
					 | 
				
			||||||
be allocated from the address pool determined by --dynip. In the above
 | 
					 | 
				
			||||||
example the first allocated address will be 192.168.0.1, followed by
 | 
					 | 
				
			||||||
192.168.0.2 and so on. The request is confirmed by sending a create
 | 
					 | 
				
			||||||
PDP context response message to the peer (SGSN).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Now IP packets will be forwarded between the tun network interface and
 | 
					 | 
				
			||||||
the established GTP tunnel. In order to allow users to access the
 | 
					 | 
				
			||||||
external network routing needs to be set up. If private addresses are
 | 
					 | 
				
			||||||
used you need to configure network address translation. See the Linux
 | 
					 | 
				
			||||||
Networking HOWTO for details.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Remember to enable routing: 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo 1 > /proc/sys/net/ipv4/ip_forward
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you installed using a binary RPM package it is possible to start
 | 
					 | 
				
			||||||
ggsn by using the Sys 5 script:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/etc/init.d/ggsn start
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Running sgsnemu
 | 
					 | 
				
			||||||
===============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Use sgsnemu -h for a list of available options. All options available
 | 
					 | 
				
			||||||
on the command line can also be given in a configuration file. See
 | 
					 | 
				
			||||||
examples/sgsnemu.conf for the format of this file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you want to test a GRX roaming connection you will need to do the
 | 
					 | 
				
			||||||
following:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Install sgsnemu on a Linux Box. See under installation above.
 | 
					 | 
				
			||||||
2. Connect your Linux box with sgsnemu installed to the GPRS core
 | 
					 | 
				
			||||||
network. Use the same LAN switch as the one your SGSN is connected
 | 
					 | 
				
			||||||
to. You also need a free IP address that can be used by sgsnemu.
 | 
					 | 
				
			||||||
3. You need to configure networking in terms of interface address,
 | 
					 | 
				
			||||||
subnet mask and default route. See the Linux Networking HOWTO for
 | 
					 | 
				
			||||||
details.
 | 
					 | 
				
			||||||
4. Launch sgsnemu with something like:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 0 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sgsnemu will print something like the following on the screen:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<PRE>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Using DNS server:      10.20.38.51 (10.20.38.51)
 | 
					 | 
				
			||||||
  Local IP address is:   10.0.0.50 (10.0.0.50)
 | 
					 | 
				
			||||||
  Remote IP address is:  10.0.0.40 (10.0.0.40)
 | 
					 | 
				
			||||||
  IMSI is:               240011234567890 (0x98765432110042)
 | 
					 | 
				
			||||||
  Using APN:             internet
 | 
					 | 
				
			||||||
  Using MSISDN:          46702123456
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Initialising GTP library
 | 
					 | 
				
			||||||
  OpenGGSN[1823]: GTP: gtp_newgsn() started
 | 
					 | 
				
			||||||
  Done initialising GTP library
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Sending off echo request
 | 
					 | 
				
			||||||
  Waiting for response from ggsn........
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Received echo response. Cause value: 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</PRE>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is quite good. It means that you managed to send off an echo
 | 
					 | 
				
			||||||
request to a remote GGSN, and it was friendly enough to answer you. If
 | 
					 | 
				
			||||||
you did not get an echo response it means that something is wrong
 | 
					 | 
				
			||||||
either with your setup OR with the GRX connection OR with your roaming
 | 
					 | 
				
			||||||
partners connection.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If the above went well you might want to try to establish a PDP
 | 
					 | 
				
			||||||
context to the remote GGSN. Note that you should be careful when
 | 
					 | 
				
			||||||
establishing PDP contexts using sgsnemu as each established PDP
 | 
					 | 
				
			||||||
context will result in a Charge Detail Record (CDR) being generated by
 | 
					 | 
				
			||||||
the GGSN. You should use real IMSI and MSISDN from a valid test SIM
 | 
					 | 
				
			||||||
card. Otherwise some poor customer might get charged for your
 | 
					 | 
				
			||||||
testing. Also note that you are establishing a connection to the Gi
 | 
					 | 
				
			||||||
network, so please be carefull not to route internet traffic onto the
 | 
					 | 
				
			||||||
GPRS core network! Assuming you know what you are doing:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 1 --apn internet --imsi 240011234567890 --msisdn 46702123456 --createif --defaultroute
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sgsnemu will print something like the following on the screen:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<PRE>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Using DNS server:      10.20.38.51 (10.20.38.51)
 | 
					 | 
				
			||||||
  Local IP address is:   10.0.0.50 (10.0.0.50)
 | 
					 | 
				
			||||||
  Remote IP address is:  10.0.0.40 (10.0.0.40)
 | 
					 | 
				
			||||||
  IMSI is:               240011234567890 (0x98765432110042)
 | 
					 | 
				
			||||||
  Using APN:             internet
 | 
					 | 
				
			||||||
  Using MSISDN:          46702123456
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Initialising GTP library
 | 
					 | 
				
			||||||
  OpenGGSN[1838]: GTP: gtp_newgsn() started
 | 
					 | 
				
			||||||
  Done initialising GTP library
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Sending off echo request
 | 
					 | 
				
			||||||
  Setting up PDP context #0
 | 
					 | 
				
			||||||
  Waiting for response from ggsn........
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Received echo response. Cause value: 0
 | 
					 | 
				
			||||||
  Received create PDP context response. Cause value: 128
 | 
					 | 
				
			||||||
  Setting up interface and routing
 | 
					 | 
				
			||||||
  /sbin/ifconfig tun0 192.168.0.1
 | 
					 | 
				
			||||||
  /sbin/route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</PRE>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Now a context is established to the remote GGSN. The IP address of the
 | 
					 | 
				
			||||||
context is 192.168.0.1. You should be able to ping a known address on
 | 
					 | 
				
			||||||
the Gi network of the roaming partner. You should even be able to do
 | 
					 | 
				
			||||||
web browsing through the PDP context.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Note however that you probably need to adjust your routing tables, so
 | 
					 | 
				
			||||||
that you make sure that all GRX traffic is routed to the GPRS core
 | 
					 | 
				
			||||||
network and everything else through the PDP context. The proper way to
 | 
					 | 
				
			||||||
do this is to use policy routing. Also note that you are effectively
 | 
					 | 
				
			||||||
connecting the same computer to both the Gn and Gi network, so please
 | 
					 | 
				
			||||||
be carefull not to route internet traffic onto the GPRS core network
 | 
					 | 
				
			||||||
and please protect yourself against hackers! For this reason it is
 | 
					 | 
				
			||||||
advised to always use --contexts 0 when testing a live network.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
After --timelimit seconds the PDP context is disconnected with the
 | 
					 | 
				
			||||||
following messages from sgsnemu:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<PRE>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Disconnecting PDP context #0
 | 
					 | 
				
			||||||
  Received delete PDP context response. Cause value: 128
 | 
					 | 
				
			||||||
  Deleting tun interface
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</PRE>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
OpenGGSN/FreeBSD notes
 | 
					OsmoGGSN/FreeBSD notes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FreeBSD support is experimental, please test and report bugs. The FreeBSD port is
 | 
					FreeBSD support is experimental, please test and report bugs. The FreeBSD port is
 | 
				
			||||||
tested on FreeBSD 4.x, but may also work on 5.x series.
 | 
					tested on FreeBSD 4.x, but may also work on 5.x series.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
OpenGGSN/Mac OS X notes
 | 
					OsmoGGSN/Mac OS X notes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Mac OS X support is experimental, please test and report bugs. The
 | 
					Mac OS X support is experimental, please test and report bugs. The
 | 
				
			||||||
Mac OS X port is tested on Mac OS X 10.3.5, but may also work on
 | 
					Mac OS X port is tested on Mac OS X 10.3.5, but may also work on
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,41 +0,0 @@
 | 
				
			|||||||
OpenGGSN/Solaris notes
 | 
					 | 
				
			||||||
======================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Solaris support is experimental, please test and report bugs. The
 | 
					 | 
				
			||||||
Solaris port is tested under Solaris 8.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Compiling
 | 
					 | 
				
			||||||
---------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You need to edit the following line in ggsn/Makefile.in and
 | 
					 | 
				
			||||||
sgsnemu/Makefile.in:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LDFLAGS = -Wl,--rpath -Wl,/usr/local/lib @EXEC_LDFLAGS@
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
should be changed to:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LDFLAGS =  -lresolv -lsocket -lnsl @EXEC_LDFLAGS@ 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
After this you install by the following commands:
 | 
					 | 
				
			||||||
./configure
 | 
					 | 
				
			||||||
make
 | 
					 | 
				
			||||||
make install
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TUN
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You might or might not need to install the tun driver manually. For
 | 
					 | 
				
			||||||
general information about tun see http://vtun.sourceforge.net/tun/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Known problems
 | 
					 | 
				
			||||||
--------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Currently multiple IP addresses on the same network interface is not
 | 
					 | 
				
			||||||
implemented for Solaris.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Currently routing table manipulation is not implemented for
 | 
					 | 
				
			||||||
Solaris. You have to set the routes manually after you start ggsn or
 | 
					 | 
				
			||||||
sgsnemu.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										341
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,341 @@
 | 
				
			|||||||
 | 
					OsmoGGSN - Open Source GGSN
 | 
				
			||||||
 | 
					===========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This repository contains a C-language implementation of a GGSN (Gateway
 | 
				
			||||||
 | 
					GPRS Support Node), a core network element of ETSI/3GPP cellular
 | 
				
			||||||
 | 
					networks such as GPRS, EDGE, UMTS or HSPA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**OsmoGGSN** is part of the [Osmocom](https://osmocom.org/) Open Source
 | 
				
			||||||
 | 
					Mobile Communications projects and the successor to OpenGGSN (which was
 | 
				
			||||||
 | 
					developed until 2004 by Mondru AB).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Homepage
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The official homepage of the project is <https://osmocom.org/projects/openggsn/wiki>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GIT Repository
 | 
				
			||||||
 | 
					--------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can clone from the official osmo-ggsn.git repository using
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Documentation
 | 
				
			||||||
 | 
					-------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The user manual and VTY reference are optionally built in PDF form
 | 
				
			||||||
 | 
					as part of the build process. Pre-rendered versions are available here:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [osmo-ggsn user manual](https://ftp.osmocom.org/docs/osmo-ggsn/master/osmoggsn-usermanual.pdf)
 | 
				
			||||||
 | 
					* [osmo-ggsn VTY reference](https://ftp.osmocom.org/docs/osmo-ggsn/master/osmoggsn-vty-reference.pdf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Forum
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We welcome any pySim related discussions in the
 | 
				
			||||||
 | 
					[Cellular Network Infrastructure -> 2G/3G Core Network](https://discourse.osmocom.org/c/cni/2g-3g-cn/)
 | 
				
			||||||
 | 
					section of the osmocom discourse (web based Forum).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Mailing List
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Discussions related to OsmoGGSN are happening on the
 | 
				
			||||||
 | 
					osmocom-net-gprs@lists.osmocom.org mailing list, please see
 | 
				
			||||||
 | 
					<https://lists.osmocom.org/mailman/listinfo/osmocom-net-gprs> for
 | 
				
			||||||
 | 
					subscription options and the list archive.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please observe the [Osmocom Mailing List Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
 | 
				
			||||||
 | 
					when posting.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Issue Tracker
 | 
				
			||||||
 | 
					-------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We use the [issue tracker of the osmo-ggsn project on osmocom.org](https://osmocom.org/projects/openggsn/issues) for
 | 
				
			||||||
 | 
					tracking the state of bug reports and feature requests.  Feel free to submit any issues you may find, or help
 | 
				
			||||||
 | 
					us out by resolving existing issues.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Contributing
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Our coding standards are described at
 | 
				
			||||||
 | 
					<https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We use a Gerrit based patch submission/review process for managing
 | 
				
			||||||
 | 
					contributions.  Please see
 | 
				
			||||||
 | 
					<https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit> for
 | 
				
			||||||
 | 
					more details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The current patch queue for OsmoGGSN can be seen at
 | 
				
			||||||
 | 
					<https://gerrit.osmocom.org/#/q/project:osmo-ggsn+status:open>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QuickStart
 | 
				
			||||||
 | 
					==========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Requirements
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Linux* 
 | 
				
			||||||
 | 
					OsmoGGSN was originally developed and tested using Redhat 8.0 and 9.0
 | 
				
			||||||
 | 
					and is these days mostly developed on Debian GNU/Linux.  It should run
 | 
				
			||||||
 | 
					also on other Linux distributions as well as FreeBSD, but this is
 | 
				
			||||||
 | 
					untested. Compilation on Solaris 2.8 has also been verified.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Tun*
 | 
				
			||||||
 | 
					The tun driver is required for proper operation of openggsn. For Linux
 | 
				
			||||||
 | 
					kernels later than 2.4.7 the driver is typically included, but might
 | 
				
			||||||
 | 
					need to be configured for automatic loading:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Add the following line to `/etc/modules.conf`: `alias char-major-10-200 tun`
 | 
				
			||||||
 | 
					2. `depmod -a`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Installation from binary
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN is built for common versions of Debian, Ubuntu and other distributions part of
 | 
				
			||||||
 | 
					the [Osmocom Nightly Builds](https://osmocom.org/projects/cellular-infrastructure/wiki/Nightly_Builds)
 | 
				
			||||||
 | 
					and [Osmocom Latest Builds](https://osmocom.org/projects/cellular-infrastructure/wiki/Latest_Builds).
 | 
				
			||||||
 | 
					If you don't want to do development, it is suggested to simply use those binary packages, rather than building
 | 
				
			||||||
 | 
					yourself from source.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Installation from source
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					./configure
 | 
				
			||||||
 | 
					make
 | 
				
			||||||
 | 
					make install
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You need to be root in order to install the package, but not in order
 | 
				
			||||||
 | 
					to compile.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Support
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please contact the Mailing List above for community-based support.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Features
 | 
				
			||||||
 | 
					========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN is an open source implementation of GPRS Support Nodes
 | 
				
			||||||
 | 
					(GSNs). It implements the GPRS tunneling protocol (GTP) version 0 and
 | 
				
			||||||
 | 
					version 1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN provides 3 components:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * *libgtp*, a shared library for the GTPv1C protocol
 | 
				
			||||||
 | 
					 * *osmo-ggsn*, the GGSN itself
 | 
				
			||||||
 | 
					 * *sgsnemu*, a SGSN emulator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*gtplib*
 | 
				
			||||||
 | 
					This library contains all functionality relating to the GTP
 | 
				
			||||||
 | 
					protocol. Use this library if you want to implement your own
 | 
				
			||||||
 | 
					GSN. gtplib supports both GTPv0 (GSM 09.60) and GTPv1 (3GPP
 | 
				
			||||||
 | 
					29.060). At the moment no interface documentation is available for
 | 
				
			||||||
 | 
					download.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*osmo-ggsn*
 | 
				
			||||||
 | 
					The osmo-ggsn implements a Gateway GPRS Support Node. The GGSN is a small
 | 
				
			||||||
 | 
					application which is provided in order to test and demonstrate the use
 | 
				
			||||||
 | 
					of gtplib. It is fully compliant to the 3GPP standards, but lacks
 | 
				
			||||||
 | 
					important functionality such as charging and management. Use this
 | 
				
			||||||
 | 
					application as a starting point if you want to build your own GGSN
 | 
				
			||||||
 | 
					with your own fancy VPN, management and charging functionality.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*sgsnemu*
 | 
				
			||||||
 | 
					This application emulates a Serving GPRS Support Node (SGSN). sgsnemu
 | 
				
			||||||
 | 
					enables you to test your 3GPP core network without the need to invest
 | 
				
			||||||
 | 
					in a 3G radio access network. An important application of sgsnemu is
 | 
				
			||||||
 | 
					the testing of roaming connectivity through a GPRS roaming
 | 
				
			||||||
 | 
					exchange. sgsnemu will first attempt to use GTPv1. If unsuccessful it
 | 
				
			||||||
 | 
					will fallback to GTPv0.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required software
 | 
				
			||||||
 | 
					=================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tun
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Both osmo-ggsn and sgsnemu uses the tun package. You need at least tun
 | 
				
			||||||
 | 
					version 1.1. With Linux tun is normally included from kernel version
 | 
				
			||||||
 | 
					2.4.7. To configure automatic loading:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Add the following line to `/etc/modules.conf`: `alias char-major-10-200 tun`
 | 
				
			||||||
 | 
					2. `depmod -a`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Alternatively you can execute `modprobe tun` on the commandline.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Gengetopt
 | 
				
			||||||
 | 
					---------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Gengetopt is required if you want to change the options defined in the
 | 
				
			||||||
 | 
					cmdline.ggo source file. You need at least gengetopt version 2.8. If
 | 
				
			||||||
 | 
					you are just going to compile the programs you don't need gengetopt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To use gengetopt for the sgsnemu do the following:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					cd sgsnemu
 | 
				
			||||||
 | 
					gengetopt < cmdline.ggo --conf-parser
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more information about gengetopt see
 | 
				
			||||||
 | 
					<http://www.gnu.org/software/gengetopt/gengetopt.html>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Compilation and Installation
 | 
				
			||||||
 | 
					============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please refer to the project homepage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Running osmo-ggsn
 | 
				
			||||||
 | 
					=================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use osmo-ggsn -h for a list of available options. All options available on
 | 
				
			||||||
 | 
					the command line can also be given in a configuration file. See
 | 
				
			||||||
 | 
					`doc/examples/osmo-ggsn.cfg` for the format of this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Start osmo-ggsn as root using the command:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`osmo-ggsn -c doc/examples/osmo-ggsn.cfg`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					First, a tun network interface will be created for each configured apn.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After tun has been successfully established the ggsn will wait for GTP
 | 
				
			||||||
 | 
					create PDP context requests on the configured `gtp bind-ip` address.
 | 
				
			||||||
 | 
					Currently all requests are accepted, and no password, username validation is performed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When receiving a create PDP context request for a given APN, a dynamic IP address will
 | 
				
			||||||
 | 
					be allocated from the address pool defined in the config file section for that apn.
 | 
				
			||||||
 | 
					The request is confirmed by sending a create PDP context response message to the peer (SGSN).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now IP packets will be forwarded between the tun network interface and
 | 
				
			||||||
 | 
					the established GTP tunnel. In order to allow users to access the
 | 
				
			||||||
 | 
					external network routing needs to be set up. If private addresses are
 | 
				
			||||||
 | 
					used you need to configure network address translation. See the Linux
 | 
				
			||||||
 | 
					Networking HOWTO for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Remember to enable routing:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`echo 1 > /proc/sys/net/ipv4/ip_forward`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you're using systemd and did `make install` or installed from a bianry package,
 | 
				
			||||||
 | 
					you can start osmo-ggsn by using the included systemd service/unit file:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`systemctl start osmo-ggsn`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Running sgsnemu
 | 
				
			||||||
 | 
					===============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use `sgsnemu -h` for a list of available options. All options available
 | 
				
			||||||
 | 
					on the command line can also be given in a configuration file. See
 | 
				
			||||||
 | 
					`doc/examples/sgsnemu.conf` for the format of this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to test a GRX roaming connection you will need to do the
 | 
				
			||||||
 | 
					following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Install sgsnemu on a Linux Box. See under installation above.
 | 
				
			||||||
 | 
					2. Connect your Linux box with sgsnemu installed to the GPRS core
 | 
				
			||||||
 | 
					network. You also need a free IP address that can be used by sgsnemu.
 | 
				
			||||||
 | 
					3. You need to configure networking in terms of interface address,
 | 
				
			||||||
 | 
					subnet mask and default route. See the Linux Networking HOWTO for
 | 
				
			||||||
 | 
					details.
 | 
				
			||||||
 | 
					4. Launch sgsnemu with something like:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 0`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sgsnemu will print something like the following on the screen:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					  Using DNS server:      10.20.38.51 (10.20.38.51)
 | 
				
			||||||
 | 
					  Local IP address is:   10.0.0.50 (10.0.0.50)
 | 
				
			||||||
 | 
					  Remote IP address is:  10.0.0.40 (10.0.0.40)
 | 
				
			||||||
 | 
					  IMSI is:               240011234567890 (0x98765432110042)
 | 
				
			||||||
 | 
					  Using APN:             internet
 | 
				
			||||||
 | 
					  Using MSISDN:          46702123456
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Initialising GTP library
 | 
				
			||||||
 | 
					  OsmoGGSN[1823]: GTP: gtp_newgsn() started
 | 
				
			||||||
 | 
					  Done initialising GTP library
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Sending off echo request
 | 
				
			||||||
 | 
					  Waiting for response from ggsn........
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Received echo response. Cause value: 0
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is quite good. It means that you managed to send off an echo
 | 
				
			||||||
 | 
					request to a remote GGSN, and it was friendly enough to answer you. If
 | 
				
			||||||
 | 
					you did not get an echo response it means that something is wrong
 | 
				
			||||||
 | 
					either with your setup OR with the GRX connection OR with your roaming
 | 
				
			||||||
 | 
					partners connection.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If the above went well you might want to try to establish a PDP
 | 
				
			||||||
 | 
					context to the remote GGSN. Note that you should be careful when
 | 
				
			||||||
 | 
					establishing PDP contexts using sgsnemu as each established PDP
 | 
				
			||||||
 | 
					context will result in a Charge Detail Record (CDR) being generated by
 | 
				
			||||||
 | 
					the GGSN. You should use real IMSI and MSISDN from a valid test SIM
 | 
				
			||||||
 | 
					card. Otherwise some poor customer might get charged for your
 | 
				
			||||||
 | 
					testing. Also note that you are establishing a connection to the Gi
 | 
				
			||||||
 | 
					network, so please be carefull not to route internet traffic onto the
 | 
				
			||||||
 | 
					GPRS core network! Assuming you know what you are doing:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`sgsnemu --listen 10.0.0.50 --remote 10.0.0.40 --dns 10.20.38.51 --timelimit 10 --contexts 1 --apn internet --imsi 240011234567890 --msisdn 46702123456 --createif --defaultroute`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sgsnemu will print something like the following on the screen:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					  Using DNS server:      10.20.38.51 (10.20.38.51)
 | 
				
			||||||
 | 
					  Local IP address is:   10.0.0.50 (10.0.0.50)
 | 
				
			||||||
 | 
					  Remote IP address is:  10.0.0.40 (10.0.0.40)
 | 
				
			||||||
 | 
					  IMSI is:               240011234567890 (0x98765432110042)
 | 
				
			||||||
 | 
					  Using APN:             internet
 | 
				
			||||||
 | 
					  Using MSISDN:          46702123456
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Initialising GTP library
 | 
				
			||||||
 | 
					  OsmoGGSN[1838]: GTP: gtp_newgsn() started
 | 
				
			||||||
 | 
					  Done initialising GTP library
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Sending off echo request
 | 
				
			||||||
 | 
					  Setting up PDP context #0
 | 
				
			||||||
 | 
					  Waiting for response from ggsn........
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Received echo response. Cause value: 0
 | 
				
			||||||
 | 
					  Received create PDP context response. Cause value: 128
 | 
				
			||||||
 | 
					  Setting up interface and routing
 | 
				
			||||||
 | 
					  /sbin/ifconfig tun0 192.168.0.1
 | 
				
			||||||
 | 
					  /sbin/route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now a context is established to the remote GGSN. The IP address of the
 | 
				
			||||||
 | 
					context is 192.168.0.1. You should be able to ping a known address on
 | 
				
			||||||
 | 
					the Gi network of the roaming partner. You should even be able to do
 | 
				
			||||||
 | 
					web browsing through the PDP context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note however that you probably need to adjust your routing tables, so
 | 
				
			||||||
 | 
					that you make sure that all GRX traffic is routed to the GPRS core
 | 
				
			||||||
 | 
					network and everything else through the PDP context. The proper way to
 | 
				
			||||||
 | 
					do this is to use policy routing. Also note that you are effectively
 | 
				
			||||||
 | 
					connecting the same computer to both the Gn and Gi network, so please
 | 
				
			||||||
 | 
					be carefull not to route internet traffic onto the GPRS core network
 | 
				
			||||||
 | 
					and please protect yourself against hackers! For this reason it is
 | 
				
			||||||
 | 
					advised to always use `--contexts 0` when testing a live network.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After `--timelimit seconds` the PDP context is disconnected with the
 | 
				
			||||||
 | 
					following messages from sgsnemu:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					  Disconnecting PDP context #0
 | 
				
			||||||
 | 
					  Received delete PDP context response. Cause value: 128
 | 
				
			||||||
 | 
					  Deleting tun interface
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
							
								
								
									
										9
									
								
								TODO-RELEASE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								TODO-RELEASE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
 | 
				
			||||||
 | 
					# according to https://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release
 | 
				
			||||||
 | 
					# In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
 | 
				
			||||||
 | 
					# LIBVERSION=c:r:a
 | 
				
			||||||
 | 
					# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a.
 | 
				
			||||||
 | 
					# If any interfaces have been added, removed, or changed since the last update: c + 1:0:a.
 | 
				
			||||||
 | 
					# If any interfaces have been added since the last public release: c:r:a + 1.
 | 
				
			||||||
 | 
					# If any interfaces have been removed or changed since the last public release: c:r:0.
 | 
				
			||||||
 | 
					#library	what			description / commit summary line
 | 
				
			||||||
							
								
								
									
										276
									
								
								configure.ac
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								configure.ac
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,276 @@
 | 
				
			|||||||
 | 
					# Process this file with autoconf to produce a configure script.
 | 
				
			||||||
 | 
					AC_INIT([osmo-ggsn],[m4_esyscmd(./git-version-gen .tarball-version)],[osmocom-net-gprs@lists.osmocom.org])
 | 
				
			||||||
 | 
					AC_CONFIG_SRCDIR([gtp/gtp.c])
 | 
				
			||||||
 | 
					AC_CONFIG_HEADERS([config.h])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dnl *This* is the root dir, even if an install-sh exists in ../ or ../../
 | 
				
			||||||
 | 
					AC_CONFIG_AUX_DIR([.])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_CONFIG_TESTDIR(tests)
 | 
				
			||||||
 | 
					AC_CANONICAL_HOST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CFLAGS="$CFLAGS -std=gnu11"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dnl kernel style compile messages
 | 
				
			||||||
 | 
					m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Checks for programs.
 | 
				
			||||||
 | 
					AC_PROG_CC
 | 
				
			||||||
 | 
					AC_PROG_INSTALL
 | 
				
			||||||
 | 
					AC_PROG_AWK
 | 
				
			||||||
 | 
					AC_PROG_CPP
 | 
				
			||||||
 | 
					LT_INIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang
 | 
				
			||||||
 | 
					AS_CASE(["$LD"],[*clang*],
 | 
				
			||||||
 | 
					  [AS_CASE(["${host_os}"],
 | 
				
			||||||
 | 
					     [*linux*],[archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'])])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
 | 
				
			||||||
 | 
					AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
 | 
				
			||||||
 | 
					if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
 | 
				
			||||||
 | 
					        AC_MSG_WARN([You need to install pkg-config])
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					PKG_PROG_PKG_CONFIG([0.20])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_CONFIG_MACRO_DIR([m4])
 | 
				
			||||||
 | 
					AC_CONFIG_LIBOBJ_DIR([lib])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_ARG_ENABLE(static-exec,
 | 
				
			||||||
 | 
					 [  --enable-static-exec  Enable static linking of executables],
 | 
				
			||||||
 | 
					 [ EXEC_LDFLAGS="-all-static"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_SUBST(EXEC_LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case "${host}" in
 | 
				
			||||||
 | 
					  i*86-*-linux-gnu*)
 | 
				
			||||||
 | 
					    EXEC_LDADD="" ;;
 | 
				
			||||||
 | 
					  *solaris*)
 | 
				
			||||||
 | 
					    EXEC_LDADD="-lresolv -lsocket -lnsl" ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_SUBST(EXEC_LDADD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Checks for libraries.
 | 
				
			||||||
 | 
					# FIXME: Replace `main' with a function in `-le':
 | 
				
			||||||
 | 
					#AC_CHECK_LIB([e], [main])
 | 
				
			||||||
 | 
					# FIXME: Replace `main' with a function in `-lgtp':
 | 
				
			||||||
 | 
					#AC_CHECK_LIB([gtp], [main])
 | 
				
			||||||
 | 
					# FIXME: Replace `main' with a function in `-links':
 | 
				
			||||||
 | 
					#AC_CHECK_LIB([inks], [main])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dnl include release helper
 | 
				
			||||||
 | 
					RELMAKE='-include osmo-release.mk'
 | 
				
			||||||
 | 
					AC_SUBST([RELMAKE])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dnl GTP Linux kernel dependencies
 | 
				
			||||||
 | 
					AC_ARG_ENABLE([gtp-linux],
 | 
				
			||||||
 | 
						AS_HELP_STRING([--enable-gtp-linux], [Build GTP tunneling Linux kernel]),
 | 
				
			||||||
 | 
						[enable_gtp_linux="$enableval"], [enable_gtp_linux="no"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AS_IF([test "x$enable_gtp_linux" = "xyes"], [
 | 
				
			||||||
 | 
						PKG_CHECK_MODULES([LIBGTPNL], [libgtpnl >= 1.3.0])
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AM_CONDITIONAL([ENABLE_GTP_KERNEL], [test "$enable_gtp_linux" = "yes"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Checks for header files.
 | 
				
			||||||
 | 
					AC_HEADER_STDC
 | 
				
			||||||
 | 
					AC_HEADER_SYS_WAIT
 | 
				
			||||||
 | 
					AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Check for if header. Some versions of linux/if.h fail without sys/socket.h included beforehand:
 | 
				
			||||||
 | 
					# see https://algorithmicallyrandom.blogspot.com/2012/07/error-on-including-include.html
 | 
				
			||||||
 | 
					AC_CHECK_HEADERS([linux/if.h net/if.h], [], [], [#ifdef HAVE_SYS_SOCKET_H
 | 
				
			||||||
 | 
					                                                # include <sys/socket.h>
 | 
				
			||||||
 | 
					                                                # endif
 | 
				
			||||||
 | 
					                                                ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Check for tun header
 | 
				
			||||||
 | 
					AC_CHECK_HEADERS([linux/if_tun.h net/if_tun.h])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Check for netlink and rtnetlink headers
 | 
				
			||||||
 | 
					AC_CHECK_HEADERS([linux/netlink.h linux/rtnetlink.h])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Checks for typedefs, structures, and compiler characteristics.
 | 
				
			||||||
 | 
					AC_C_CONST
 | 
				
			||||||
 | 
					AC_TYPE_MODE_T
 | 
				
			||||||
 | 
					AC_TYPE_SIZE_T
 | 
				
			||||||
 | 
					AC_HEADER_TIME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# check for ifaliasreq
 | 
				
			||||||
 | 
					AC_MSG_CHECKING(whether struct ifaliasreq exist)
 | 
				
			||||||
 | 
					AH_TEMPLATE(HAVE_IFALIASREQ)
 | 
				
			||||||
 | 
					AC_EGREP_HEADER(ifaliasreq, net/if.h,
 | 
				
			||||||
 | 
					[AC_MSG_RESULT(yes)
 | 
				
			||||||
 | 
					 AC_DEFINE([HAVE_IFALIASREQ])],
 | 
				
			||||||
 | 
					 AC_MSG_RESULT(no))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# check for ifreq.ifru_netmask
 | 
				
			||||||
 | 
					AC_MSG_CHECKING(whether struct ifreq.ifru_netmask exist)
 | 
				
			||||||
 | 
					AH_TEMPLATE(HAVE_IFREQ_IFRU_NETMASK)
 | 
				
			||||||
 | 
					AC_EGREP_HEADER(ifru_netmask, linux/if.h,
 | 
				
			||||||
 | 
					[AC_MSG_RESULT(yes)
 | 
				
			||||||
 | 
					 AC_DEFINE([HAVE_IFREQ_IFRU_NETMASK])],
 | 
				
			||||||
 | 
					 AC_MSG_RESULT(no))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# check for rt_msghdr
 | 
				
			||||||
 | 
					AC_MSG_CHECKING(whether struct rt_msghdr exist)
 | 
				
			||||||
 | 
					AH_TEMPLATE(HAVE_RT_MSGHDR)
 | 
				
			||||||
 | 
					AC_EGREP_HEADER(rt_msghdr, net/route.h,
 | 
				
			||||||
 | 
					[AC_MSG_RESULT(yes)
 | 
				
			||||||
 | 
					 AC_DEFINE([HAVE_RT_MSGHDR])],
 | 
				
			||||||
 | 
					 AC_MSG_RESULT(no))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_MSG_CHECKING(whether struct iphdr exists)
 | 
				
			||||||
 | 
					AH_TEMPLATE(HAVE_IPHDR)
 | 
				
			||||||
 | 
					AC_EGREP_HEADER(struct iphdr, netinet/ip.h,
 | 
				
			||||||
 | 
					[AC_MSG_RESULT(yes)
 | 
				
			||||||
 | 
					 AC_DEFINE([HAVE_IPHDR])],
 | 
				
			||||||
 | 
					 AC_MSG_RESULT(no))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Address generation modes (enum) implemented in linux 3.17 (bc91b0f07ada5535427373a4e2050877bcc12218)
 | 
				
			||||||
 | 
					# /proc/sys/net/ipv6/conf/${iface}/addr_gen_mode was added in linux 4.11 (d35a00b8e33dab7385f724e713ae71c8be0a49f4)
 | 
				
			||||||
 | 
					AC_MSG_CHECKING(whether enum in6_addr_gen_mode.IN6_ADDR_GEN_MODE_NONE exists)
 | 
				
			||||||
 | 
					AH_TEMPLATE(HAVE_IN6_ADDR_GEN_MODE_NONE)
 | 
				
			||||||
 | 
					AC_EGREP_HEADER(IN6_ADDR_GEN_MODE_NONE, linux/if_link.h,
 | 
				
			||||||
 | 
					[AC_MSG_RESULT(yes)
 | 
				
			||||||
 | 
					 AC_DEFINE([HAVE_IN6_ADDR_GEN_MODE_NONE])],
 | 
				
			||||||
 | 
					 AC_MSG_RESULT(no))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Checks for library functions.
 | 
				
			||||||
 | 
					AC_PROG_GCC_TRADITIONAL
 | 
				
			||||||
 | 
					# AC_FUNC_MALLOC
 | 
				
			||||||
 | 
					# AC_FUNC_MEMCMP
 | 
				
			||||||
 | 
					AC_CHECK_FUNCS([gethostbyname inet_ntoa memset select socket strdup strerror strtol])
 | 
				
			||||||
 | 
					AC_CHECK_FUNCS(inet_aton inet_addr, break)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# check for getopt in standard library
 | 
				
			||||||
 | 
					adl_FUNC_GETOPT_LONG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AM_INIT_AUTOMAKE([foreign])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.11.0)
 | 
				
			||||||
 | 
					PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.11.0)
 | 
				
			||||||
 | 
					PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.11.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_ARG_ENABLE(sanitize,
 | 
				
			||||||
 | 
						[AS_HELP_STRING(
 | 
				
			||||||
 | 
							[--enable-sanitize],
 | 
				
			||||||
 | 
							[Compile with address sanitizer enabled],
 | 
				
			||||||
 | 
						)],
 | 
				
			||||||
 | 
						[sanitize=$enableval], [sanitize="no"])
 | 
				
			||||||
 | 
					if test x"$sanitize" = x"yes"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
 | 
				
			||||||
 | 
						CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_ARG_ENABLE(werror,
 | 
				
			||||||
 | 
						[AS_HELP_STRING(
 | 
				
			||||||
 | 
							[--enable-werror],
 | 
				
			||||||
 | 
							[Turn all compiler warnings into errors, with exceptions:
 | 
				
			||||||
 | 
							 a) deprecation (allow upstream to mark deprecation without breaking builds);
 | 
				
			||||||
 | 
							 b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds)
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						)],
 | 
				
			||||||
 | 
						[werror=$enableval], [werror="no"])
 | 
				
			||||||
 | 
					if test x"$werror" = x"yes"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						WERROR_FLAGS="-Werror"
 | 
				
			||||||
 | 
						WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
 | 
				
			||||||
 | 
						WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
 | 
				
			||||||
 | 
						CFLAGS="$CFLAGS $WERROR_FLAGS"
 | 
				
			||||||
 | 
						CPPFLAGS="$CPPFLAGS $WERROR_FLAGS"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Generate manuals
 | 
				
			||||||
 | 
					AC_ARG_ENABLE(manuals,
 | 
				
			||||||
 | 
						[AS_HELP_STRING(
 | 
				
			||||||
 | 
							[--enable-manuals],
 | 
				
			||||||
 | 
							[Generate manual PDFs [default=no]],
 | 
				
			||||||
 | 
						)],
 | 
				
			||||||
 | 
						[osmo_ac_build_manuals=$enableval], [osmo_ac_build_manuals="no"])
 | 
				
			||||||
 | 
					AM_CONDITIONAL([BUILD_MANUALS], [test x"$osmo_ac_build_manuals" = x"yes"])
 | 
				
			||||||
 | 
					AC_ARG_VAR(OSMO_GSM_MANUALS_DIR, [path to common osmo-gsm-manuals files, overriding pkg-config and "../osmo-gsm-manuals"
 | 
				
			||||||
 | 
						fallback])
 | 
				
			||||||
 | 
					if test x"$osmo_ac_build_manuals" = x"yes"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						# Find OSMO_GSM_MANUALS_DIR (env, pkg-conf, fallback)
 | 
				
			||||||
 | 
						if test -n "$OSMO_GSM_MANUALS_DIR"; then
 | 
				
			||||||
 | 
							echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from env)"
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							OSMO_GSM_MANUALS_DIR="$($PKG_CONFIG osmo-gsm-manuals --variable=osmogsmmanualsdir 2>/dev/null)"
 | 
				
			||||||
 | 
							if test -n "$OSMO_GSM_MANUALS_DIR"; then
 | 
				
			||||||
 | 
								echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from pkg-conf)"
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								OSMO_GSM_MANUALS_DIR="../osmo-gsm-manuals"
 | 
				
			||||||
 | 
								echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (fallback)"
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						if ! test -d "$OSMO_GSM_MANUALS_DIR"; then
 | 
				
			||||||
 | 
							AC_MSG_ERROR("OSMO_GSM_MANUALS_DIR does not exist! Install osmo-gsm-manuals or set OSMO_GSM_MANUALS_DIR.")
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# Find and run check-depends
 | 
				
			||||||
 | 
						CHECK_DEPENDS="$OSMO_GSM_MANUALS_DIR/check-depends.sh"
 | 
				
			||||||
 | 
						if ! test -x "$CHECK_DEPENDS"; then
 | 
				
			||||||
 | 
							CHECK_DEPENDS="osmo-gsm-manuals-check-depends"
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						if ! $CHECK_DEPENDS; then
 | 
				
			||||||
 | 
							AC_MSG_ERROR("missing dependencies for --enable-manuals")
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# Put in Makefile with absolute path
 | 
				
			||||||
 | 
						OSMO_GSM_MANUALS_DIR="$(realpath "$OSMO_GSM_MANUALS_DIR")"
 | 
				
			||||||
 | 
						AC_SUBST([OSMO_GSM_MANUALS_DIR])
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# https://www.freedesktop.org/software/systemd/man/daemon.html
 | 
				
			||||||
 | 
					AC_ARG_WITH([systemdsystemunitdir],
 | 
				
			||||||
 | 
					     [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
 | 
				
			||||||
 | 
					     [with_systemdsystemunitdir=auto])
 | 
				
			||||||
 | 
					AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
 | 
				
			||||||
 | 
					     def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     AS_IF([test "x$def_systemdsystemunitdir" = "x"],
 | 
				
			||||||
 | 
					   [AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
 | 
				
			||||||
 | 
					    [AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
 | 
				
			||||||
 | 
					    with_systemdsystemunitdir=no],
 | 
				
			||||||
 | 
					   [with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
 | 
				
			||||||
 | 
					AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
 | 
				
			||||||
 | 
					      [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
 | 
				
			||||||
 | 
					AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_MSG_RESULT([CFLAGS="$CFLAGS"])
 | 
				
			||||||
 | 
					AC_MSG_RESULT([CPPFLAGS="$CPPFLAGS"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_CONFIG_FILES([Makefile
 | 
				
			||||||
 | 
					                 doc/Makefile
 | 
				
			||||||
 | 
					                 doc/examples/Makefile
 | 
				
			||||||
 | 
					                 ggsn/Makefile
 | 
				
			||||||
 | 
					                 gtp/Makefile
 | 
				
			||||||
 | 
					                 lib/Makefile
 | 
				
			||||||
 | 
					                 intl/Makefile
 | 
				
			||||||
 | 
					                 po/Makefile
 | 
				
			||||||
 | 
					                 utils/Makefile
 | 
				
			||||||
 | 
					                 sgsnemu/Makefile
 | 
				
			||||||
 | 
					                 doc/manuals/Makefile
 | 
				
			||||||
 | 
					                 contrib/Makefile
 | 
				
			||||||
 | 
					                 contrib/systemd/Makefile
 | 
				
			||||||
 | 
					                 tests/Makefile
 | 
				
			||||||
 | 
					                 tests/lib/Makefile
 | 
				
			||||||
 | 
					                 tests/gtp/Makefile
 | 
				
			||||||
 | 
					                 include/Makefile
 | 
				
			||||||
 | 
					                 include/osmocom/Makefile
 | 
				
			||||||
 | 
					                 include/osmocom/gtp/Makefile
 | 
				
			||||||
 | 
					                 libgtp.pc])
 | 
				
			||||||
 | 
					AC_OUTPUT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "
 | 
				
			||||||
 | 
					osmo-ggsn Configuration:
 | 
				
			||||||
 | 
					  GTP Linux kernel support:			${enable_gtp_linux}"
 | 
				
			||||||
							
								
								
									
										121
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								configure.in
									
									
									
									
									
								
							@@ -1,121 +0,0 @@
 | 
				
			|||||||
# Process this file with autoconf to produce a configure script.
 | 
					 | 
				
			||||||
AC_INIT(openggsn, 0.91, laforge@gnumonks.org)
 | 
					 | 
				
			||||||
AC_CONFIG_SRCDIR([gtp/gtp.c])
 | 
					 | 
				
			||||||
AM_CONFIG_HEADER([config.h])
 | 
					 | 
				
			||||||
#AC_CONFIG_HEADER([config.h])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AC_CANONICAL_SYSTEM
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dnl kernel style compile messages
 | 
					 | 
				
			||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Checks for programs.
 | 
					 | 
				
			||||||
AC_PROG_CC
 | 
					 | 
				
			||||||
AC_PROG_INSTALL
 | 
					 | 
				
			||||||
AC_PROG_AWK
 | 
					 | 
				
			||||||
AC_PROG_CPP
 | 
					 | 
				
			||||||
AC_PROG_CXX
 | 
					 | 
				
			||||||
LT_INIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AC_CONFIG_MACRO_DIR([m4])
 | 
					 | 
				
			||||||
AC_CONFIG_LIBOBJ_DIR([lib])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AC_ARG_ENABLE(static-exec,
 | 
					 | 
				
			||||||
 [  --enable-static-exec  Enable static linking of executables],
 | 
					 | 
				
			||||||
 [ EXEC_LDFLAGS="-all-static"])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AC_SUBST(EXEC_LDFLAGS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
case "${host}" in
 | 
					 | 
				
			||||||
  i*86-*-linux-gnu*) 
 | 
					 | 
				
			||||||
    EXEC_LDADD="" ;;
 | 
					 | 
				
			||||||
  *solaris*) 
 | 
					 | 
				
			||||||
    EXEC_LDADD="-lresolv -lsocket -lnsl" ;;
 | 
					 | 
				
			||||||
esac
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AC_SUBST(EXEC_LDADD)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Checks for libraries.
 | 
					 | 
				
			||||||
# FIXME: Replace `main' with a function in `-le':
 | 
					 | 
				
			||||||
#AC_CHECK_LIB([e], [main])
 | 
					 | 
				
			||||||
# FIXME: Replace `main' with a function in `-lgtp':
 | 
					 | 
				
			||||||
#AC_CHECK_LIB([gtp], [main])
 | 
					 | 
				
			||||||
# FIXME: Replace `main' with a function in `-links':
 | 
					 | 
				
			||||||
#AC_CHECK_LIB([inks], [main])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Checks for header files.
 | 
					 | 
				
			||||||
AC_HEADER_STDC
 | 
					 | 
				
			||||||
AC_HEADER_SYS_WAIT
 | 
					 | 
				
			||||||
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Check for if header
 | 
					 | 
				
			||||||
AC_CHECK_HEADERS([linux/if.h net/if.h])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Check for tun header
 | 
					 | 
				
			||||||
AC_CHECK_HEADERS([linux/if_tun.h net/if_tun.h])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Check for netlink and rtnetlink headers
 | 
					 | 
				
			||||||
AC_CHECK_HEADERS([linux/netlink.h linux/rtnetlink.h])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Checks for typedefs, structures, and compiler characteristics.
 | 
					 | 
				
			||||||
AC_C_CONST
 | 
					 | 
				
			||||||
AC_TYPE_MODE_T
 | 
					 | 
				
			||||||
AC_TYPE_SIZE_T
 | 
					 | 
				
			||||||
AC_HEADER_TIME
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# check for ifaliasreq
 | 
					 | 
				
			||||||
AC_MSG_CHECKING(whether struct ifaliasreq exist)
 | 
					 | 
				
			||||||
AH_TEMPLATE(HAVE_IFALIASREQ)
 | 
					 | 
				
			||||||
AC_EGREP_HEADER(ifaliasreq, net/if.h,
 | 
					 | 
				
			||||||
[AC_MSG_RESULT(yes)
 | 
					 | 
				
			||||||
 AC_DEFINE([HAVE_IFALIASREQ])],
 | 
					 | 
				
			||||||
 AC_MSG_RESULT(no))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# check for ifreq.ifru_netmask
 | 
					 | 
				
			||||||
AC_MSG_CHECKING(whether struct ifreq.ifru_netmask exist)
 | 
					 | 
				
			||||||
AH_TEMPLATE(HAVE_IFREQ_IFRU_NETMASK)
 | 
					 | 
				
			||||||
AC_EGREP_HEADER(ifru_netmask, linux/if.h,
 | 
					 | 
				
			||||||
[AC_MSG_RESULT(yes)
 | 
					 | 
				
			||||||
 AC_DEFINE([HAVE_IFREQ_IFRU_NETMASK])],
 | 
					 | 
				
			||||||
 AC_MSG_RESULT(no))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# check for rt_msghdr
 | 
					 | 
				
			||||||
AC_MSG_CHECKING(whether struct rt_msghdr exist)
 | 
					 | 
				
			||||||
AH_TEMPLATE(HAVE_RT_MSGHDR)
 | 
					 | 
				
			||||||
AC_EGREP_HEADER(rt_msghdr, net/route.h,
 | 
					 | 
				
			||||||
[AC_MSG_RESULT(yes)
 | 
					 | 
				
			||||||
 AC_DEFINE([HAVE_RT_MSGHDR])],
 | 
					 | 
				
			||||||
 AC_MSG_RESULT(no))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Checks for library functions.
 | 
					 | 
				
			||||||
AC_PROG_GCC_TRADITIONAL
 | 
					 | 
				
			||||||
# AC_FUNC_MALLOC
 | 
					 | 
				
			||||||
# AC_FUNC_MEMCMP 
 | 
					 | 
				
			||||||
AC_CHECK_FUNCS([gethostbyname inet_ntoa memset select socket strdup strerror strtol])
 | 
					 | 
				
			||||||
AC_CHECK_FUNCS(inet_aton inet_addr, break)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# check for getopt in standard library
 | 
					 | 
				
			||||||
adl_FUNC_GETOPT_LONG
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AM_INIT_AUTOMAKE()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.6.4)
 | 
					 | 
				
			||||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AC_CONFIG_FILES([Makefile
 | 
					 | 
				
			||||||
                 doc/Makefile
 | 
					 | 
				
			||||||
                 ggsn/Makefile
 | 
					 | 
				
			||||||
                 gtp/Makefile
 | 
					 | 
				
			||||||
                 lib/Makefile
 | 
					 | 
				
			||||||
                 intl/Makefile
 | 
					 | 
				
			||||||
                 po/Makefile
 | 
					 | 
				
			||||||
                 sgsnemu/Makefile
 | 
					 | 
				
			||||||
                 tests/Makefile
 | 
					 | 
				
			||||||
                 libgtp.pc
 | 
					 | 
				
			||||||
                 openggsn.spec])
 | 
					 | 
				
			||||||
AC_OUTPUT
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								contrib/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								contrib/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					SUBDIRS = systemd
 | 
				
			||||||
							
								
								
									
										63
									
								
								contrib/jenkins.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										63
									
								
								contrib/jenkins.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env bash
 | 
				
			||||||
 | 
					# jenkins build helper script for openbsc.  This is how we build on jenkins.osmocom.org
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# environment variables:
 | 
				
			||||||
 | 
					# * GTP: configure GTP tunneling Linux kernel (values: "--enable-gtp-linux" or "--disable-gtp-linux")
 | 
				
			||||||
 | 
					# * WITH_MANUALS: build manual PDFs if set to "1"
 | 
				
			||||||
 | 
					# * PUBLISH: upload manuals after building if set to "1" (ignored without WITH_MANUALS = "1")
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
 | 
				
			||||||
 | 
						echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
 | 
				
			||||||
 | 
						exit 2
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set -ex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					base="$PWD"
 | 
				
			||||||
 | 
					deps="$base/deps"
 | 
				
			||||||
 | 
					inst="$deps/install"
 | 
				
			||||||
 | 
					export deps inst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-clean-workspace.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mkdir "$deps" || true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "x$GTP" == "x--enable-gtp-linux" ]; then
 | 
				
			||||||
 | 
						osmo-build-dep.sh libgtpnl
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
 | 
				
			||||||
 | 
					export LD_LIBRARY_PATH="$inst/lib"
 | 
				
			||||||
 | 
					export PATH="$inst/bin:$PATH"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Additional configure options and depends
 | 
				
			||||||
 | 
					CONFIG=""
 | 
				
			||||||
 | 
					if [ "$WITH_MANUALS" = "1" ]; then
 | 
				
			||||||
 | 
						CONFIG="--enable-manuals"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set +x
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo " =============================== OsmoGGSN ==============================="
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					set -x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cd "$base"
 | 
				
			||||||
 | 
					autoreconf --install --force
 | 
				
			||||||
 | 
					./configure --enable-sanitize --enable-werror $GTP $CONFIG
 | 
				
			||||||
 | 
					$MAKE $PARALLEL_MAKE
 | 
				
			||||||
 | 
					DISTCHECK_CONFIGURE_FLAGS="$CONFIG" $MAKE $PARALLEL_MAKE distcheck
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
 | 
				
			||||||
 | 
						make -C "$base/doc/manuals" publish
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$MAKE $PARALLEL_MAKE maintainer-clean
 | 
				
			||||||
 | 
					osmo-clean-workspace.sh
 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
[Unit]
 | 
					 | 
				
			||||||
Description=OpenGGSN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[Service]
 | 
					 | 
				
			||||||
Type=simple
 | 
					 | 
				
			||||||
Restart=always
 | 
					 | 
				
			||||||
ExecStart=/usr/bin/ggsn -c /etc/ggsn.conf -f
 | 
					 | 
				
			||||||
RestartSec=2
 | 
					 | 
				
			||||||
RestartPreventExitStatus=1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[Install]
 | 
					 | 
				
			||||||
WantedBy=multi-user.target
 | 
					 | 
				
			||||||
							
								
								
									
										10
									
								
								contrib/systemd/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								contrib/systemd/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					EXTRA_DIST = \
 | 
				
			||||||
 | 
						osmo-ggsn.service \
 | 
				
			||||||
 | 
						ggsn.network \
 | 
				
			||||||
 | 
						apn0.netdev \
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if HAVE_SYSTEMD
 | 
				
			||||||
 | 
					systemdsystemunit_DATA = \
 | 
				
			||||||
 | 
					  osmo-ggsn.service
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
							
								
								
									
										7
									
								
								contrib/systemd/apn0.netdev
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								contrib/systemd/apn0.netdev
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					[NetDev]
 | 
				
			||||||
 | 
					Name=apn0
 | 
				
			||||||
 | 
					Kind=tun
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Tun]
 | 
				
			||||||
 | 
					User=username
 | 
				
			||||||
 | 
					Group=username
 | 
				
			||||||
							
								
								
									
										6
									
								
								contrib/systemd/ggsn.network
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								contrib/systemd/ggsn.network
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					[Match]
 | 
				
			||||||
 | 
					Name=apn0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Network]
 | 
				
			||||||
 | 
					Address=192.168.7.1/24
 | 
				
			||||||
 | 
					IPMasquerade=yes
 | 
				
			||||||
							
								
								
									
										20
									
								
								contrib/systemd/osmo-ggsn.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								contrib/systemd/osmo-ggsn.service
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					[Unit]
 | 
				
			||||||
 | 
					Description=OsmoGGSN
 | 
				
			||||||
 | 
					After=network-online.target
 | 
				
			||||||
 | 
					Wants=network-online.target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Service]
 | 
				
			||||||
 | 
					Type=simple
 | 
				
			||||||
 | 
					Restart=always
 | 
				
			||||||
 | 
					StateDirectory=osmocom
 | 
				
			||||||
 | 
					WorkingDirectory=%S/osmocom
 | 
				
			||||||
 | 
					ExecStart=/usr/bin/osmo-ggsn -c /etc/osmocom/osmo-ggsn.cfg
 | 
				
			||||||
 | 
					RestartSec=2
 | 
				
			||||||
 | 
					RestartPreventExitStatus=1
 | 
				
			||||||
 | 
					User=osmocom
 | 
				
			||||||
 | 
					Group=osmocom
 | 
				
			||||||
 | 
					# For setting up the gtp0/tun0 devices
 | 
				
			||||||
 | 
					AmbientCapabilities=CAP_NET_ADMIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Install]
 | 
				
			||||||
 | 
					WantedBy=multi-user.target
 | 
				
			||||||
							
								
								
									
										631
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										631
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +1,633 @@
 | 
				
			|||||||
openggsn (0.91+git34) UNRELEASED; urgency=medium
 | 
					osmo-ggsn (1.13.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * gtp: Allow tx Direct Tunnel Flags in UpdatePDPCtx{Req,Resp}
 | 
				
			||||||
 | 
					  * gtp: Store rx Direct Tunnel Flags in UpdatePDPCtx{Req,Resp}
 | 
				
			||||||
 | 
					  * gtp: Allow UpdatePDPContext initiated by GGSN
 | 
				
			||||||
 | 
					  * gtp: Allow setting callback to receive update_context_ind
 | 
				
			||||||
 | 
					  * ggsn: Mark internal cb function static
 | 
				
			||||||
 | 
					  * ggsn: kernel gtpu: Support updating pdp ctx remote IP address and TEID
 | 
				
			||||||
 | 
					  * Move apn allocation code out of vty file
 | 
				
			||||||
 | 
					  * Move ggsn allocation code out of vty file
 | 
				
			||||||
 | 
					  * Move g_ggsn_list declaration to ggsn.c
 | 
				
			||||||
 | 
					  * vty: Fix missing newline in description of 'apn tun-device' cmd
 | 
				
			||||||
 | 
					  * ggsn: Support announcing APN MTU over PCO
 | 
				
			||||||
 | 
					  * ggsn: Support announcing APN MTU over ICMPv6 RA
 | 
				
			||||||
 | 
					  * ggsn: use libosmocore tundev API to create apn tun device
 | 
				
			||||||
 | 
					  * ggsn: Use osmo_netdev_addaddr() libosmocore API
 | 
				
			||||||
 | 
					  * ggsn: apply configured APN MTU to tun
 | 
				
			||||||
 | 
					  * doc: Fix typo in user manual
 | 
				
			||||||
 | 
					  * doc: Remove reference to non longer existing osmo-ggsn.init
 | 
				
			||||||
 | 
					  * doc: Fix typo: wrong interface named
 | 
				
			||||||
 | 
					  * doc: Reorder some chapters
 | 
				
			||||||
 | 
					  * tun: Fix null pointer derefence when in kernel gtp mode
 | 
				
			||||||
 | 
					  * ggsn: Avoid forwarding IPv6 solicited-node multicast addr to tun device
 | 
				
			||||||
 | 
					  * ggsn: Rename confusing functions
 | 
				
			||||||
 | 
					  * tun.h: Remove non-existent tun_decaps()
 | 
				
			||||||
 | 
					  * Rename tun_encaps -> tun_inject_pkt
 | 
				
			||||||
 | 
					  * Refactor tun_t fields and alloc APIs
 | 
				
			||||||
 | 
					  * tun: Use OSMO_STRLCPY_ARRAY
 | 
				
			||||||
 | 
					  * doc: Document MTU features in User Manual and example config files
 | 
				
			||||||
 | 
					  * doc: Update all iptables references with nftables
 | 
				
			||||||
 | 
					  * jenkins.sh: Use --disable-doxygen configure param
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Alexander Couzens ]
 | 
				
			||||||
 | 
					  * gtp_internal.h: add missing include to <stdint.h>
 | 
				
			||||||
 | 
					  * gtpie: fix comment
 | 
				
			||||||
 | 
					  * gtp.h: add more GTP cause code from 29.060 v15.3.30
 | 
				
			||||||
 | 
					  * gtp_new(): use talloc instead of calloc/free
 | 
				
			||||||
 | 
					  * gtpie: add gtp_encaps a modern encapsulation method
 | 
				
			||||||
 | 
					  * gtp: split gtp_req into 2 parts: transmit and fill header
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Daniel Willmann ]
 | 
				
			||||||
 | 
					  * gtp: Make peer addr const in gtp_req/gtp_resp
 | 
				
			||||||
 | 
					  * gtp: Rework gtp_resp() into gtp_resp_pdp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Oliver Smith <osmith@sysmocom.de>  Wed, 12 Feb 2025 12:09:58 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.12.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Daniel Willmann ]
 | 
				
			||||||
 | 
					  * libgtp: Remove defines for reserved causes in gtp.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * pco: Improve IPCP spec reference documentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Oliver Smith ]
 | 
				
			||||||
 | 
					  * Fix a typo
 | 
				
			||||||
 | 
					  * gtp_new: deduplicate create_and_bind_socket code
 | 
				
			||||||
 | 
					  * kernel-gtp: support IPv6 on outer layer
 | 
				
			||||||
 | 
					  * kernel-gtp: support IPv6 on inner layer
 | 
				
			||||||
 | 
					  * Revert "kernel-gtp: support IPv6 on outer layer"
 | 
				
			||||||
 | 
					  * Cosmetic: Makefile.am: make SUBDIRS diff friendly
 | 
				
			||||||
 | 
					  * Cosmetic: AM_CFLAGS: make diff friendly
 | 
				
			||||||
 | 
					  * Cosmetic: {lib,gtp}/Makefile.am: diff friendly
 | 
				
			||||||
 | 
					  * lib/gtp-kernel.c: initialize ret with 0
 | 
				
			||||||
 | 
					  * lib/gtp-kernel.c: check rc of in46a_from_eua
 | 
				
			||||||
 | 
					  * doc: fix typo ndoe -> node
 | 
				
			||||||
 | 
					  * Add clear error for kernel not supporting IPv6
 | 
				
			||||||
 | 
					  * contrib: remove rpm spec file
 | 
				
			||||||
 | 
					  * libgtp: move includes to osmocom/include/gtp
 | 
				
			||||||
 | 
					  * gtp/gsn_internal.h: new file
 | 
				
			||||||
 | 
					  * gtp/gtp.c: move gtp_create_context_resp down
 | 
				
			||||||
 | 
					  * gtp: remove unused conversion functions
 | 
				
			||||||
 | 
					  * gtp: move conversion functions up
 | 
				
			||||||
 | 
					  * gtp/gtp_internal.h: new file
 | 
				
			||||||
 | 
					  * ggsn/ggsn_vty: create state-dir
 | 
				
			||||||
 | 
					  * doc: set state-dir to /var/lib/osmocom/osmo-ggsn
 | 
				
			||||||
 | 
					  * contrib/systemd: run as osmocom user
 | 
				
			||||||
 | 
					  * Use uniform log format for default config files
 | 
				
			||||||
 | 
					  * {contrib,debian}/osmo-ggsn.init: remove
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * Add funding link to github mirror
 | 
				
			||||||
 | 
					  * README.md: Improve markdown formatting
 | 
				
			||||||
 | 
					  * README.md: Add Forum + Issue Tracker sections
 | 
				
			||||||
 | 
					  * README.md: Major overhaul
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * README.md: cosmetic: fix a typo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Oliver Smith <osmith@sysmocom.de>  Wed, 24 Jul 2024 15:13:31 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.11.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Daniel Willmann ]
 | 
				
			||||||
 | 
					  * gtp: Add net GTP cause values and a function to check for success
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Oliver Smith <osmith@sysmocom.de>  Tue, 28 Nov 2023 13:38:29 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.10.2) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * Do not hard-code -g and -O2 in CFLAGS
 | 
				
			||||||
 | 
					  * tests: use -no-install libtool flag to avoid ./lt-* scripts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Oliver Smith ]
 | 
				
			||||||
 | 
					  * doc/manuals/chapters/configuration: fix typo
 | 
				
			||||||
 | 
					  * debian: set compat level to 10
 | 
				
			||||||
 | 
					  * systemd: depend on networking-online.target
 | 
				
			||||||
 | 
					  * README: update documentation section
 | 
				
			||||||
 | 
					  * doc: running: update kernel-gtp limitations
 | 
				
			||||||
 | 
					  * lib/in46_addr: add in46a_from_gsna
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Tue, 12 Sep 2023 14:36:10 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.10.1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Oliver Smith ]
 | 
				
			||||||
 | 
					  * debian/libgtp6.shlibs: new file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * lib/icmpv6.h: fix struct icmpv6_{radv_hdr,opt_prefix}
 | 
				
			||||||
 | 
					  * gtp/gsn.c: fix 'No newline at end of file'
 | 
				
			||||||
 | 
					  * gtp: use OSMO_ASSERT() in gtp_new()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Vadim Yanitskiy <vyanitskiy@sysmocom.de>  Mon, 27 Feb 2023 22:35:47 +0700
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.10.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Max ]
 | 
				
			||||||
 | 
					  * Set working directory in systemd service file
 | 
				
			||||||
 | 
					  * Ignore .deb build byproducts
 | 
				
			||||||
 | 
					  * ctrl: take both address and port from vty config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * cosmetic: gtp: Fix typo in comment
 | 
				
			||||||
 | 
					  * Split gsn_t related APIs out of gtp.{c,h}
 | 
				
			||||||
 | 
					  * Use rate_ctr for gsn_t available_counters
 | 
				
			||||||
 | 
					  * ggsn: Introduce tdef and make it configurable over VTY
 | 
				
			||||||
 | 
					  * gtp: Introduce VTY configurable GTP timer X3
 | 
				
			||||||
 | 
					  * Fix typos in comments and VTY descriptions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ arehbein ]
 | 
				
			||||||
 | 
					  * osmo-ggsn: Transition to use of 'telnet_init_default'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Tue, 07 Feb 2023 14:29:48 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.9.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * tests: in46a_test: Make coverity happy when calling in46a_from_eua
 | 
				
			||||||
 | 
					  * vty: Fix cmd 'no echo-interval' doing nothing
 | 
				
			||||||
 | 
					  * libgtp: Fix ggsn crash if pdp alloc array is full (PDP_MAX)
 | 
				
			||||||
 | 
					  * libgtp: Define retransmit QUEUE_SIZE relative to PDP_MAX (increase)
 | 
				
			||||||
 | 
					  * gtp: Use switch statement in gtp_create_pdp_ind()
 | 
				
			||||||
 | 
					  * gtp: Log detection of rx duplicate
 | 
				
			||||||
 | 
					  * gtp: Small log improvements in gtp_create_pdp_ind()
 | 
				
			||||||
 | 
					  * gtp: Specify retrans queue name & seqnum in log lines
 | 
				
			||||||
 | 
					  * gtp: Log retrans queue register&free entries
 | 
				
			||||||
 | 
					  * gtp: Fix typo in comment
 | 
				
			||||||
 | 
					  * pco.h: Fix typo in reference to spec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * update git URLs (git -> https; gitea)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Tue, 28 Jun 2022 17:48:22 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.8.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Oliver Smith ]
 | 
				
			||||||
 | 
					  * doc/examples/Makefile.am: add sgsnemu.conf
 | 
				
			||||||
 | 
					  * doc/examples/osmo-ggsn-kernel-gtp.cfg: new file
 | 
				
			||||||
 | 
					  * doc/manuals: describe GTP-U kernel module
 | 
				
			||||||
 | 
					  * gitignore: add ggsn_vty_reference.xml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * Don't install osmo-ggsn-kernel-gtp.cfg to /etc/osmocom/
 | 
				
			||||||
 | 
					  * Don't install sgsnemu.conf to /etc/osmocom/
 | 
				
			||||||
 | 
					  * ggsn: Reject PDP CTX ACT for static IP addresses
 | 
				
			||||||
 | 
					  * vty: Inform user that static IP addresses are not supported
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * gtp: Update teic_confirmed only on resp success
 | 
				
			||||||
 | 
					  * gtp: Rework parsing logic of UpdatePdpCtxResponse
 | 
				
			||||||
 | 
					  * ggsn: Improve logging on incoming DL data packets
 | 
				
			||||||
 | 
					  * gtp: Improve logging of failing pdp ctx resolution from TEI/TID
 | 
				
			||||||
 | 
					  * cosmetic: gtpie.c: Fix trailing whitespace
 | 
				
			||||||
 | 
					  * gtp: constify pointer arg
 | 
				
			||||||
 | 
					  * gtp: Support tx/rx RAN Information Relay message
 | 
				
			||||||
 | 
					  * ggsn: Log tun fd write errors
 | 
				
			||||||
 | 
					  * ggsn: Fix heap-use-after-free during Recovery without associated PDP
 | 
				
			||||||
 | 
					  * cosmetic: configure.ac: Fix tabulation in line
 | 
				
			||||||
 | 
					  * Introduce program gtp-echo-responder
 | 
				
			||||||
 | 
					  * gtp_echo_responder: report invalid chars present in node-feautres cmdline arg as error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Tue, 16 Nov 2021 13:49:16 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.7.1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * main: add --vty-ref-mode, use vty_dump_xml_ref_mode()
 | 
				
			||||||
 | 
					  * manuals: generate vty reference xml at build time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Tue, 23 Feb 2021 17:31:24 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.7.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * debian/control: change maintainer to the Osmocom team / mailing list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * configure.ac: Fix trailing whitespace
 | 
				
			||||||
 | 
					  * doc: Update VTY reference xml file
 | 
				
			||||||
 | 
					  * Support setting rt-prio and cpu-affinity mask through VTY
 | 
				
			||||||
 | 
					  * contrib/jenkins: Enable parallel make in make distcheck
 | 
				
			||||||
 | 
					  * ggsn: generate coredump and exit upon SIGABRT received
 | 
				
			||||||
 | 
					  * tests: Explicitly drop category from log
 | 
				
			||||||
 | 
					  * tests: Replace deprecated API log_set_print_filename
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Keith ]
 | 
				
			||||||
 | 
					  * Fix vty PDP lookups by IMSI
 | 
				
			||||||
 | 
					  * Prevent Crash in show pdp-context from vty
 | 
				
			||||||
 | 
					  * Minor: remove code duplication
 | 
				
			||||||
 | 
					  * Use imsi_str2gtp() in sgsnemu
 | 
				
			||||||
 | 
					  * sgsnemu: relax check on length of IMSI cmdline arg.
 | 
				
			||||||
 | 
					  * GTP: Replace recently introduced imsi_str2gtp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * Use OSMO_FD_* instead of deprecated BSC_FD_*
 | 
				
			||||||
 | 
					  * gtp-kernel: Remove duplicate #include section
 | 
				
			||||||
 | 
					  * gtp-kernel: don't #include libmnl headers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Oliver Smith ]
 | 
				
			||||||
 | 
					  * contrib/jenkins: don't build osmo-gsm-manuals
 | 
				
			||||||
 | 
					  * configure.ac: set -std=gnu11
 | 
				
			||||||
 | 
					  * apn_start: avoid segfault if missing tun-device
 | 
				
			||||||
 | 
					  * .gitignore: ignore debian/libgtp*
 | 
				
			||||||
 | 
					  * deb/rpm: build with --enable-gtp-linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@espeweb.net>  Tue, 23 Feb 2021 13:34:39 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.6.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * cosmetic: Fix comment typo
 | 
				
			||||||
 | 
					  * netns: Improve error checking
 | 
				
			||||||
 | 
					  * sgsnemu: cmdline: Drop unused function cmdline_parser_params_create()
 | 
				
			||||||
 | 
					  * sgsnemu: Pass array of in64_addr to in46a_from_eua()
 | 
				
			||||||
 | 
					  * sgsnemu: Rename sgsnemu's libgtp cb_conf
 | 
				
			||||||
 | 
					  * sgsnemu: Set its default loglevel category to INFO
 | 
				
			||||||
 | 
					  * Move icmpv6 and checksum files from ggsn/ dir to lib/
 | 
				
			||||||
 | 
					  * netdev_addaddr6: Use prefixlen arg
 | 
				
			||||||
 | 
					  * sgsnemu: Avoid adding extra autogenerated local link ipv6 addr to tun iface
 | 
				
			||||||
 | 
					  * sgsnemu: Fix ping transmitted statistics output
 | 
				
			||||||
 | 
					  * cosmetic: icmpv6.c: fix typo in comment
 | 
				
			||||||
 | 
					  * icmpv6.c: Mark internal function as static
 | 
				
			||||||
 | 
					  * sgsnemu: Get rid of duplicated options.destaddr
 | 
				
			||||||
 | 
					  * sgsnemu: Get rid of duplicated options.net
 | 
				
			||||||
 | 
					  * sgsnemu: tun_addaddr: Don't set local addr as dstaddr
 | 
				
			||||||
 | 
					  * icmpv6.c: Move code generating ipv6 hdr to its own function
 | 
				
			||||||
 | 
					  * Rename netdev_*route to end in route4
 | 
				
			||||||
 | 
					  * sgsnemu: Fix build/run against linux < 4.11 (no sysctl addr_gen_mode support)
 | 
				
			||||||
 | 
					  * sgsnemu: Handle IPv6 SLAAC in tun iface manually
 | 
				
			||||||
 | 
					  * sgsnemu: Implement ping on IPv6 APNs
 | 
				
			||||||
 | 
					  * sgsnemu: Fix assumption ipv6 Interface-Identifier of public addr == announced Prefix
 | 
				
			||||||
 | 
					  * gtp: queue_test: Fix printf gcc warn under ARM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Andreas Schultz ]
 | 
				
			||||||
 | 
					  * add Linux network namespace support for TUN device
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * lib/netns: fix open_ns(): return fd from open()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Philipp Maier ]
 | 
				
			||||||
 | 
					  * doc: do not use random ip address for dns in default conf
 | 
				
			||||||
 | 
					  * doc: use 127.0.0.2 instead of 127.0.0.6 as bind ip.
 | 
				
			||||||
 | 
					  * debug: use LOGL_NOTICE instead of LOGL_DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Eric ]
 | 
				
			||||||
 | 
					  * configure.ac: fix libtool issue  with clang and sanitizer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * lib/netns.c: Add comments to the code, including doxygen API docs
 | 
				
			||||||
 | 
					  * lib/netns: OSMO_ASSERT() if user doesn't call init_netns()
 | 
				
			||||||
 | 
					  * lib/netns: Fix up error paths
 | 
				
			||||||
 | 
					  * example config: use RFC1918 addresses for GGSN pools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Dmitri Kalashnik ]
 | 
				
			||||||
 | 
					  * sgsnemu: use real tun device name after the device is up.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Oliver Smith ]
 | 
				
			||||||
 | 
					  * osmo-ggsn.spec.in: remove
 | 
				
			||||||
 | 
					  * contrib: import RPM spec
 | 
				
			||||||
 | 
					  * contrib: integrate RPM spec
 | 
				
			||||||
 | 
					  * Makefile.am: EXTRA_DIST: debian, contrib/*.spec.in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Harald Welte <laforge@osmocom.org>  Thu, 13 Aug 2020 12:26:20 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.5.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Jan Engelhardt ]
 | 
				
			||||||
 | 
					  * build: switch AC_CANONICAL_TARGET for AC_CANONICAL_HOST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * libgtp: Remove packets in tx queue belonging pdp being freed
 | 
				
			||||||
 | 
					  * libgtp: announce pdp ctx deletion upon CreatePdpCtx being rejected
 | 
				
			||||||
 | 
					  * Introduce in46a_is_v{4,6}() helpers
 | 
				
			||||||
 | 
					  * ggsn: Move PCO handling code into its own file
 | 
				
			||||||
 | 
					  * in46_addr: Improve in46a_ntop documentation
 | 
				
			||||||
 | 
					  * ggsn_vty.c: Fix wrong use of in46a_from_eua, print IPv6 euas
 | 
				
			||||||
 | 
					  * ggsn: Split application lifecycle related code into ggsn_main.c
 | 
				
			||||||
 | 
					  * Move pdp_get_peer_ipv() to lib/util.*
 | 
				
			||||||
 | 
					  * gtp-kernel.c: Fix wrong use of in46a_from_eua, print IPv6 euas
 | 
				
			||||||
 | 
					  * Introduce LOGTUN log helper
 | 
				
			||||||
 | 
					  * ggsn_vty.c: Avoid printing duplicates for pdp context with v4v6 EUAs
 | 
				
			||||||
 | 
					  * pdp: constify param in pdp_count_secondary()
 | 
				
			||||||
 | 
					  * ggsn_vty.c: Improve output of VTY show pdp-context
 | 
				
			||||||
 | 
					  * doc: Update vty reference xml file
 | 
				
			||||||
 | 
					  * libgtp: Introduce cb_recovery3
 | 
				
			||||||
 | 
					  * ggsn: Implement echo req/resp and recovery
 | 
				
			||||||
 | 
					  * cosmetic: fix formatting in if line
 | 
				
			||||||
 | 
					  * gtp: Log msg retransmits and timeouts
 | 
				
			||||||
 | 
					  * cosmetic: gtp: Drop commented out code calling pdp_freepdp()
 | 
				
			||||||
 | 
					  * cosmetic: gtp: Improve documentation of gtp_delete_context_req2()
 | 
				
			||||||
 | 
					  * ggsn: rx DeletePdpReq confirmation: Improve documentation and use gtp_freepdp()
 | 
				
			||||||
 | 
					  * gtp: Manage queue timers internally
 | 
				
			||||||
 | 
					  * ggsn, sgsnemu: Drop use of no-op deprecated gtp_retrans* APIs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * gtp_update_pdp_ind(): fix NULL-pointer dereference
 | 
				
			||||||
 | 
					  * gtp_error_ind_conf(): fix: guard against an unknown GTP version
 | 
				
			||||||
 | 
					  * gtp/gtp.c: cosmetic: use get_tid() where we need TID
 | 
				
			||||||
 | 
					  * manuals/configuration.adoc: fix Network Address without prefix length
 | 
				
			||||||
 | 
					  * manuals/configuration.adoc: fix IPv4 address mismatch in <<ggsn_no_root>>
 | 
				
			||||||
 | 
					  * contrib/systemd: add systemd-networkd examples from manuals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * sgsnemu: Fix null-pointer format string argument
 | 
				
			||||||
 | 
					  * manual: Fix copy+paste error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Thu, 02 Jan 2020 20:39:39 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.4.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Max ]
 | 
				
			||||||
 | 
					  * Don't return error on normal shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * process_pco() const-ify 'apn' argument
 | 
				
			||||||
 | 
					  * ggsn: Remove magic numbers from pco_contains_proto()
 | 
				
			||||||
 | 
					  * ggsn: const-ify input / read-only arguments of PCO related functions
 | 
				
			||||||
 | 
					  * ggsn: Remove magic numbers from ipcp_contains_option()
 | 
				
			||||||
 | 
					  * ggsn: Fix build_ipcp_pco() in presence of invalid IPCP content
 | 
				
			||||||
 | 
					  * ggsn.c: Refactor PCO processing during PDP activation
 | 
				
			||||||
 | 
					  * ggsn: Add minimalistic PAP support
 | 
				
			||||||
 | 
					  * ggsn: More logging from PCO handling (e.g. in case of malconfiguration)
 | 
				
			||||||
 | 
					  * sgsnemu: Fix format string argument count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * osmo-ggsn: fix VTY command for getting PDP contexts by APN
 | 
				
			||||||
 | 
					  * osmo-ggsn: add VTY command to show PDP context by IPv4
 | 
				
			||||||
 | 
					  * osmo-ggsn: check result of osmo_apn_to_str()
 | 
				
			||||||
 | 
					  * osmo-ggsn: print requested / actual APN in PDP info
 | 
				
			||||||
 | 
					  * osmo-ggsn: properly show subscriber's MSISDN in the VTY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * ggsn: Drop unused param force in apn_stop()
 | 
				
			||||||
 | 
					  * gtp: Document spec reasoning drop of Rx DeleteCtxReq
 | 
				
			||||||
 | 
					  * ggsn: Start gtp retrans timer during startup
 | 
				
			||||||
 | 
					  * gtp: Take queue_resp into account to schedule retrans timer
 | 
				
			||||||
 | 
					  * gtp: Fix typo dublicate->duplicate
 | 
				
			||||||
 | 
					  * pdp: Introduce new API pdp_count_secondary
 | 
				
			||||||
 | 
					  * gtp_create_pdp_ind: simplify code by reordering and compacting parsing
 | 
				
			||||||
 | 
					  * gtp: Refactor code to use gtp_freepdp(_teardown) APIs
 | 
				
			||||||
 | 
					  * cosmetic: gtp: Document free pdp ctx in non-teardown scenario
 | 
				
			||||||
 | 
					  * gtp: Re-arrange free pdp ctx code in non-teardown scenario
 | 
				
			||||||
 | 
					  * pdp: Drop unused code for haship
 | 
				
			||||||
 | 
					  * cosmetic: gtp.h: Remove trailing whitespaces
 | 
				
			||||||
 | 
					  * ggsn: Fix undefined behaviour shifting beyond sign bit
 | 
				
			||||||
 | 
					  * gtp: Introduce new pdp APIs (and deprecate old ones) to support multiple GSN
 | 
				
			||||||
 | 
					  * gtp: Make use of new libgtp APIs with multi-gsn support
 | 
				
			||||||
 | 
					  * ggsn_vty_reference.xml: Update from last code changes
 | 
				
			||||||
 | 
					  * ggsn: vty: Require ggsn param in <show pdp-context> cmd
 | 
				
			||||||
 | 
					  * sgsnemu: Replace use of deprecated libgtp API pdp_newpdp with new one
 | 
				
			||||||
 | 
					  * cosmetic: gtp: queue: remove trailing whitespace
 | 
				
			||||||
 | 
					  * gtp: Add missing headers
 | 
				
			||||||
 | 
					  * gtp: queue.c: Document queue APIs
 | 
				
			||||||
 | 
					  * gtp: queue: Add unit test queue_test
 | 
				
			||||||
 | 
					  * ggsn: Avoid unaligned mem access reading PCO proto id
 | 
				
			||||||
 | 
					  * ggsn: Use structures instead of raw arrays when parsing ipcp_hdr
 | 
				
			||||||
 | 
					  * configure.ac: Replace obosolete macro AC_CANONICAL_SYSTEM
 | 
				
			||||||
 | 
					  * configure.ac: Use brackets in AC_INIT params
 | 
				
			||||||
 | 
					  * configure.ac: Use prefered AC_CONFIG_HEADERS over AM_CONFIG_HEADER
 | 
				
			||||||
 | 
					  * configure.ac: some versions of linux/if.h require including sys/socket.h
 | 
				
			||||||
 | 
					  * sgsnemu: Fix unaligned pointer access during ip/icmp checksum
 | 
				
			||||||
 | 
					  * Remove undefined param passed to {logging,osmo_stats}_vty_add_cmds
 | 
				
			||||||
 | 
					  * Require libosmocore 1.1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Oliver Smith ]
 | 
				
			||||||
 | 
					  * debian: create -doc subpackage with pdf manuals
 | 
				
			||||||
 | 
					  * ggsn: Use gtp_delete_context_req2() everywhere
 | 
				
			||||||
 | 
					  * contrib/jenkins.sh: run "make maintainer-clean"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Daniel Willmann ]
 | 
				
			||||||
 | 
					  * manuals: Add script to regenerate vty/counter documentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Wed, 07 Aug 2019 21:28:30 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.3.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * ggsn: ctrl iface: listen on IP configured by VTY
 | 
				
			||||||
 | 
					  * gtp: Log type name of unexpected signalling message
 | 
				
			||||||
 | 
					  * gtp: Allow recv DEL CTX REQ in sgsn and DEL CTX RSP in ggsn
 | 
				
			||||||
 | 
					  * gtp: Log ignore CTX DEL REQ due to no teardown and only 1 ctx active
 | 
				
			||||||
 | 
					  * gtp: Add new API to avoid freeing pdp contexts during DEL CTX REQ
 | 
				
			||||||
 | 
					  * gtp: Add new replacement cb_recovery2 for cb_recovery
 | 
				
			||||||
 | 
					  * Install systemd services with autotools
 | 
				
			||||||
 | 
					  * Install sample cfg file to /etc/osmocom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Stefan Sperling ]
 | 
				
			||||||
 | 
					  * fix unaligned access in build_ipcp_pco()
 | 
				
			||||||
 | 
					  * fix support for multiple IPCP in PDP protocol configuration options
 | 
				
			||||||
 | 
					  * check ioctl() call return value in tun_new()
 | 
				
			||||||
 | 
					  * fix allocation of ippool's hash table
 | 
				
			||||||
 | 
					  * replace bogus memcpy() call in ippool_newip()
 | 
				
			||||||
 | 
					  * initialize local variable addr in ippool_new()
 | 
				
			||||||
 | 
					  * fix format string error in ippool_printaddr()
 | 
				
			||||||
 | 
					  * fix a format string directives in queue_seqset()
 | 
				
			||||||
 | 
					  * properly store IPv6 addresses in struct tun_t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * debian/rules: Don't overwrite .tarball-version
 | 
				
			||||||
 | 
					  * osmo-ggsn.cfg: Ensure well-formed config file example
 | 
				
			||||||
 | 
					  * sgsnemu: Fix printing of tun device name
 | 
				
			||||||
 | 
					  * ippool.c: Use "%td" format string for ptrdiff_t
 | 
				
			||||||
 | 
					  * initial version of OsmoGGSN user manual
 | 
				
			||||||
 | 
					  * OsmoGGSN: Add VTY reference manual
 | 
				
			||||||
 | 
					  * GGSN: Document how 'ip tuntap' is used for non-root; call netdev 'apn0'
 | 
				
			||||||
 | 
					  * vty-ref: Update URI of docbook 5.0 schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Alexander Couzens ]
 | 
				
			||||||
 | 
					  * libgtp: implement gtp_clear_queues to clear req/resp queue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Neels Hofmeyr ]
 | 
				
			||||||
 | 
					  * Importing history from osmo-gsm-manuals.git
 | 
				
			||||||
 | 
					  * refactor Makefile build rules, don't use the FORCE
 | 
				
			||||||
 | 
					  * GGSN: don't say 'NITB'
 | 
				
			||||||
 | 
					  * OsmoGGSN: more info on non-root operation / tun creation
 | 
				
			||||||
 | 
					  * OsmoGGSN: multiple instances: mention GTP port
 | 
				
			||||||
 | 
					  * OsmoGGSN: add Routing section for IP forward and masquerading
 | 
				
			||||||
 | 
					  * OsmoGGSN: typo: priveleges
 | 
				
			||||||
 | 
					  * OsmoGGSN VTY ref: prep: convert newlines to unix
 | 
				
			||||||
 | 
					  * OsmoGGSN vty: update VTY reference
 | 
				
			||||||
 | 
					  * OsmoGGSN: fix VTY additions' node IDs
 | 
				
			||||||
 | 
					  * OsmoGGSN: update vty reference
 | 
				
			||||||
 | 
					  * ggsn: update vty reference
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Max ]
 | 
				
			||||||
 | 
					  * Expand OsmoGGSN manual
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Oliver Smith ]
 | 
				
			||||||
 | 
					  * build manuals moved here from osmo-gsm-manuals.git
 | 
				
			||||||
 | 
					  * Fix DISTCHECK_CONFIGURE_FLAGS override
 | 
				
			||||||
 | 
					  * contrib/jenkins.sh: build and publish manuals
 | 
				
			||||||
 | 
					  * contrib: fix makedistcheck with disabled systemd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Harald Welte <laforge@gnumonks.org>  Sun, 20 Jan 2019 21:34:22 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.2.2) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vadim Yanitskiy ]
 | 
				
			||||||
 | 
					  * ggsn_vty.c: fix: use CONFIG_NODE as parent by default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Philipp Maier ]
 | 
				
			||||||
 | 
					  * ggsn: fix misinterpreted length field in ipcp_contains_option()
 | 
				
			||||||
 | 
					  * ggsn: make sure ipcp_option_hdr and and ipcp_hdr are packed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Thu, 31 May 2018 12:44:54 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.2.1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * debian/rules: Fix debian packaging after 1.2.0 release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Fri, 04 May 2018 12:19:58 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.2.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Neels Hofmeyr ]
 | 
				
			||||||
 | 
					  * fix compiler warnings: return 0 in main(), in 3 tests
 | 
				
			||||||
 | 
					  * add --enable-sanitize config option
 | 
				
			||||||
 | 
					  * sanitize build: ensure uint16/32 alignment in gtpie_test and in46a_test
 | 
				
			||||||
 | 
					  * configure: add --enable-werror
 | 
				
			||||||
 | 
					  * jenkins.sh: use --enable-werror configure flag, not CFLAGS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * sgsnemu: Don't leak FILE handle in proc_read()
 | 
				
			||||||
 | 
					  * sgsnemu: Fix format string in printing tun-device name
 | 
				
			||||||
 | 
					  * sgsnemu: Make sure buffer has space for terminating-NUL
 | 
				
			||||||
 | 
					  * sgsnemu: Free strings in error path
 | 
				
			||||||
 | 
					  * gtp: Fix buffer overflow in imsi_gtp2str()
 | 
				
			||||||
 | 
					  * gtp: Explicit OSMO_ASSERT to ensure pdp variable is set
 | 
				
			||||||
 | 
					  * tun: Don't copy 16byte IPv6 address to 'struct in_addr'
 | 
				
			||||||
 | 
					  * ippool: Correctly compute size of static pool
 | 
				
			||||||
 | 
					  * remove unused argument to alloc_ippool_blacklist()
 | 
				
			||||||
 | 
					  * factor out netdev_ip_local_get() from tun_ip_local_get()
 | 
				
			||||||
 | 
					  * Properly NULL-out blacklist in alloc_ippool_blacklist()
 | 
				
			||||||
 | 
					  * gtp_kernel: Change gtp_kernel_init() function signature
 | 
				
			||||||
 | 
					  * gtp-kernel: Re-add support for kernel GTP-U acceleration
 | 
				
			||||||
 | 
					  * gtp-kernel: Get rid of hard-coded kernel GTP device name
 | 
				
			||||||
 | 
					  * gtp-kernel: shut down kernel GTP device in apn_down()
 | 
				
			||||||
 | 
					  * gtp-kernel: Align logging for APN start in kernel-gtp case with that of TUN
 | 
				
			||||||
 | 
					  * gtp-kernel: Avoid global state variable
 | 
				
			||||||
 | 
					  * gtp-kernel: Make sure repeated calls to gtp_kernel_init() are safe
 | 
				
			||||||
 | 
					  * gtp-kernel: proper cleanup in error path
 | 
				
			||||||
 | 
					  * gtp-kernel: Get rid of SYS_ERR where not applicable
 | 
				
			||||||
 | 
					  * gtp-kernel: Add function name to pdp_debug() function calls
 | 
				
			||||||
 | 
					  * gtp-kernel: Add device nime in pdp_debug() log statements
 | 
				
			||||||
 | 
					  * contrib/jenkins.sh: Allow jenkins job to specify if kernel GTP is used
 | 
				
			||||||
 | 
					  * ggsn.c: Fix byte order of IPCP IPv4 DNS servers
 | 
				
			||||||
 | 
					  * ggsn: Ignore PCO with length 0, don't abort processing
 | 
				
			||||||
 | 
					  * README.md: Remove misleading sentence on sgsnemu
 | 
				
			||||||
 | 
					  * Add talloc context introspection via VTY
 | 
				
			||||||
 | 
					  * fix segfault in case of kernel gtp-u
 | 
				
			||||||
 | 
					  * lib/tun.c: Generalize tun_sifflags() to netdev_sifflags
 | 
				
			||||||
 | 
					  * lib/tun.c: generalize tun_*route() to netdev_*route()
 | 
				
			||||||
 | 
					  * lib/tun.c: Generalize tun_{set,add}addr*() functions
 | 
				
			||||||
 | 
					  * lib/tun: split generic network device related stuff to lib/netdev
 | 
				
			||||||
 | 
					  * lib/netdev.c: Cosmetic changes (coding style / cleanups)
 | 
				
			||||||
 | 
					  * ggsn: Don't explicitly use tun_setaddr() API anymore
 | 
				
			||||||
 | 
					  * sgsnemu: Convert from tun_setaddr() to tun_addaddr()
 | 
				
			||||||
 | 
					  * lib/tun: Remove tun_setaddr() API, as everyone is using tun_addaddr() now
 | 
				
			||||||
 | 
					  * Move kernel GTP support from ggsn/ to lib/
 | 
				
			||||||
 | 
					  * ggsn: don't use gtp_kernel_tunnel_{add,del}() for userspace tun
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Pau Espin Pedrol ]
 | 
				
			||||||
 | 
					  * ggsn_vty: Stop using deprecated API vty_install_default
 | 
				
			||||||
 | 
					  * contrib/jenkins.sh: Enable Werror in C(PP)FLAGS
 | 
				
			||||||
 | 
					  * examples: Add secondary ipv6 google DNS to osmo-ggsn.cfg
 | 
				
			||||||
 | 
					  * tun_setaddr6: Fix log typo
 | 
				
			||||||
 | 
					  * cosmetic: Reorder tun_addaddr to get rid of decl of tun_setaddr4
 | 
				
			||||||
 | 
					  * ggsn.c: Print version of unhandled ip packet
 | 
				
			||||||
 | 
					  * Remove unused empty src/Makefile.in
 | 
				
			||||||
 | 
					  * tests: Split ipv6 specific tests into a new test group
 | 
				
			||||||
 | 
					  * Add support for IPv4v6 End User Addresses
 | 
				
			||||||
 | 
					  * contrib: jenkins.sh: Build libgtpnl as dep when building with gtp kernel support
 | 
				
			||||||
 | 
					  * cosmetic: sgsnemu.c: Fix trailing whitespace
 | 
				
			||||||
 | 
					  * ggsn.c: Improve logging info on link-local ipv6 addr not found
 | 
				
			||||||
 | 
					  * tun.c: tun_addaddr: Fix segfault and wrong usage of tun_nlattr
 | 
				
			||||||
 | 
					  * Set tun_addaddr ipv agnostic and add support for ipv6
 | 
				
			||||||
 | 
					  * ggsn: Add 'ipv6 link-local' vty cmd
 | 
				
			||||||
 | 
					  * ggsn_vty.c: Print ipv6 link-local cmd when writing config to file
 | 
				
			||||||
 | 
					  * gtp.c: Fix trailing whitespace
 | 
				
			||||||
 | 
					  * gtp.c: Determine GTP version from header
 | 
				
			||||||
 | 
					  * gtp.c: Log unsupported GTP version number
 | 
				
			||||||
 | 
					  * gtp/pdp: Fix trailing whitespace
 | 
				
			||||||
 | 
					  * gtp/pdp: Remove unused APIs pdp_ntoeua pdp_euaton
 | 
				
			||||||
 | 
					  * gtp.c: gtp_gpdu_ind: Convert ifelse to switch statement
 | 
				
			||||||
 | 
					  * gtp.c: gtp_gpdu_ind: Early return to avoid use of uninitialized var
 | 
				
			||||||
 | 
					  * gtp/gtp.c: Remove unused function char2ul_t
 | 
				
			||||||
 | 
					  * gtp/gtp.c: Mark non exported functions as static
 | 
				
			||||||
 | 
					  * gtp/gtp.c: Use uint8_t for version param in static functions
 | 
				
			||||||
 | 
					  * ggsn: encaps_tun: Avoid forwarding packet if EUA is unassigned, fix crash
 | 
				
			||||||
 | 
					  * ggsn: Validate packet src addr from MS
 | 
				
			||||||
 | 
					  * ggsn: Parse PCO_IPCP
 | 
				
			||||||
 | 
					  * ggsn: Parse PCO_IPCP for IPv4v6 pdp ctx
 | 
				
			||||||
 | 
					  * ggsn: Print all addresses on successful pdp ctx creation
 | 
				
			||||||
 | 
					  * ggsn.c: cb_tun_ind: Convert ifelse to switch statement
 | 
				
			||||||
 | 
					  * ggsn.c: cb_tun_ind: log dst addr of packet without pdp ctx
 | 
				
			||||||
 | 
					  * ggsn.c: cb_tun_ind: Don't drop packets targeting pdp ctx ll addr
 | 
				
			||||||
 | 
					  * sgsnemu: Fix bad ptr during context deallocation
 | 
				
			||||||
 | 
					  * sgsnemu: listen param is a host, not an interface
 | 
				
			||||||
 | 
					  * use osmo_init_logging2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Max ]
 | 
				
			||||||
 | 
					  * Log APN and tun names for packets
 | 
				
			||||||
 | 
					  * Enable sanitize for CI tests
 | 
				
			||||||
 | 
					  * Fix stow-enabled jenkins build failure
 | 
				
			||||||
 | 
					  * Add GTP message names
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Viktor Tsymbalyuk ]
 | 
				
			||||||
 | 
					  * sgsnemu: sgsnemu stopped after recieving "Request accepted" from ggsn
 | 
				
			||||||
 | 
					  * sgsnemu: created "pinghost" and "createif" modes for mutual exclusion
 | 
				
			||||||
 | 
					  * sgsnemu: fix: no outgoing GTP-U in "createif" mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Martin Hauke ]
 | 
				
			||||||
 | 
					  * build: Remove AC_PROG_CXX, C++ is never used
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Stefan Sperling ]
 | 
				
			||||||
 | 
					  * remove the -f option from osmo-ggsn.service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Pau Espin Pedrol <pespin@sysmocom.de>  Thu, 03 May 2018 16:05:27 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.1.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * libgtp: pdp.h: Addition of new tx_gpdu_seq struct member member
 | 
				
			||||||
 | 
					  * libgtp: pdp.h: add LOGPDPX() helper to public API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Harald Welte <laforge@gnumonks.org>  Sat, 28 Oct 2017 19:00:23 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-ggsn (1.0.0) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Transition to OsmoGGSN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Harald Welte <laforge@gnumonks.org>  Wed, 06 Sep 2017 12:19:48 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					openggsn (0.94.0) UNRELEASED; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Holger Hans Peter Freyther ]
 | 
				
			||||||
 | 
					  * Bump version to ease upgrading from Debian SID.
 | 
				
			||||||
 | 
					  * Bump libgtp SO version after ABI change.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Harald Welte ]
 | 
				
			||||||
 | 
					  * various documentation / README updates
 | 
				
			||||||
 | 
					  * improve error logging and propagation
 | 
				
			||||||
 | 
					  * endian-safe definition of IP header
 | 
				
			||||||
 | 
					  * IPv6 user plane support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Harald Welte <laforge@gnumonks.org>  Sun, 13 Aug 2017 09:34:20 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					openggsn (0.92) precise; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Release 0.92
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Holger Hans Peter Freyther <holger@moiji-mobile.com>  Mon, 30 Nov 2015 14:05:59 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					openggsn (0.91+git34) precise; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  * Non-maintainer upload.
 | 
					  * Non-maintainer upload.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								debian/compat
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/compat
									
									
									
									
										vendored
									
									
								
							@@ -1 +1 @@
 | 
				
			|||||||
9
 | 
					10
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										106
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										106
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@@ -1,36 +1,102 @@
 | 
				
			|||||||
Source: openggsn
 | 
					Source: osmo-ggsn
 | 
				
			||||||
 | 
					Maintainer: Osmocom team <openbsc@lists.osmocom.org>
 | 
				
			||||||
Section: net
 | 
					Section: net
 | 
				
			||||||
Priority: optional
 | 
					Priority: optional
 | 
				
			||||||
Maintainer: Harald Welte <laforge@gnumonks.org>
 | 
					Build-Depends: debhelper (>= 10),
 | 
				
			||||||
Build-Depends: debhelper (>= 9), autotools-dev, pkg-config, libdpkg-perl, git, dh-autoreconf, libosmocore-dev (>= 0.8.0)
 | 
					               autotools-dev,
 | 
				
			||||||
 | 
					               pkg-config,
 | 
				
			||||||
 | 
					               libdpkg-perl, git,
 | 
				
			||||||
 | 
					               dh-autoreconf,
 | 
				
			||||||
 | 
					               libosmocore-dev (>= 1.11.0),
 | 
				
			||||||
 | 
					               osmo-gsm-manuals-dev (>= 1.6.0),
 | 
				
			||||||
 | 
					               libgtpnl-dev (>= 1.3.0)
 | 
				
			||||||
Standards-Version: 3.9.6
 | 
					Standards-Version: 3.9.6
 | 
				
			||||||
Homepage: http://sourceforge.net/projects/ggsn/
 | 
					Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn
 | 
				
			||||||
Vcs-Git: git://ggsn.git.sourceforge.net/gitroot/ggsn/ggsn
 | 
					Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn
 | 
				
			||||||
Vcs-Browser: http://ggsn.git.sourceforge.net/git/gitweb.cgi?p=ggsn/ggsn;a=summary
 | 
					Homepage: https://projects.osmocom.org/projects/openggsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Package: openggsn
 | 
					Package: osmo-ggsn
 | 
				
			||||||
Architecture: any
 | 
					Architecture: any
 | 
				
			||||||
Depends: ${shlibs:Depends}, ${misc:Depends}
 | 
					Depends: ${shlibs:Depends},
 | 
				
			||||||
Description: Gateway GPRS Support Node
 | 
					         ${misc:Depends}
 | 
				
			||||||
 | 
					Description: Osmocom Gateway GPRS Support Node (GGSN)
 | 
				
			||||||
 | 
					 OsmoGGSN is a Gateway GPRS Support Node (GGSN). It is used by mobile
 | 
				
			||||||
 | 
					 operators as the interface between the Internet and the rest of the
 | 
				
			||||||
 | 
					 mobile network infrastructure.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Package: libgtp0
 | 
					Package: libgtp11
 | 
				
			||||||
Architecture: any
 | 
					Architecture: any
 | 
				
			||||||
 | 
					Multi-Arch: same
 | 
				
			||||||
Section: libs
 | 
					Section: libs
 | 
				
			||||||
Depends: ${shlibs:Depends}, ${misc:Depends}
 | 
					Depends: ${shlibs:Depends},
 | 
				
			||||||
Multi-Arch: same
 | 
					         ${misc:Depends}
 | 
				
			||||||
Description: library implementing the GTP protocol between SGSN and GGSN
 | 
					Description: library implementing the GTP protocol between SGSN and GGSN
 | 
				
			||||||
 | 
					 OsmoGGSN is a Gateway GPRS Support Node (GGSN). It is used by mobile
 | 
				
			||||||
 | 
					 operators as the interface between the Internet and the rest of the
 | 
				
			||||||
 | 
					 mobile network infrastructure.
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
 | 
					 This library is part of OsmoGGSN and implements the GTP protocol between
 | 
				
			||||||
 | 
					 SGSN (Serving GPRS support node) and GGSN.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Package: libgtp0-dev
 | 
					Package: gtp-echo-responder
 | 
				
			||||||
Depends: ${misc:Depends}, libgtp0 (= ${binary:Version})
 | 
					 | 
				
			||||||
Multi-Arch: same
 | 
					 | 
				
			||||||
Architecture: any
 | 
					Architecture: any
 | 
				
			||||||
Section: libdevel
 | 
					Depends: ${shlibs:Depends},
 | 
				
			||||||
Description: Development files for libgtp
 | 
					         ${misc:Depends}
 | 
				
			||||||
 | 
					Description: Small program answering GTP ECHO Request with GTP ECHO Response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Package: openggsn-dbg
 | 
					Package: libgtp-dev
 | 
				
			||||||
 | 
					Architecture: any
 | 
				
			||||||
 | 
					Multi-Arch: same
 | 
				
			||||||
 | 
					Section: libdevel
 | 
				
			||||||
 | 
					Depends: ${misc:Depends},
 | 
				
			||||||
 | 
					         libgtp11 (= ${binary:Version})
 | 
				
			||||||
 | 
					Description: Development files for libgtp
 | 
				
			||||||
 | 
					 OsmoGGSN is a Gateway GPRS Support Node (GGSN). It is used by mobile
 | 
				
			||||||
 | 
					 operators as the interface between the Internet and the rest of the
 | 
				
			||||||
 | 
					 mobile network infrastructure.
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
 | 
					 The library libgtp implements the GTP protocol between SGSN and GGSN
 | 
				
			||||||
 | 
					 and this package contains the development files for this library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Package: osmo-ggsn-dbg
 | 
				
			||||||
Section: debug
 | 
					Section: debug
 | 
				
			||||||
Architecture: any
 | 
					Architecture: any
 | 
				
			||||||
Priority: extra
 | 
					Priority: extra
 | 
				
			||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libgtp0 (= ${binary:Version}), openggsn (= ${binary:Version})
 | 
					Depends: ${shlibs:Depends}, ${misc:Depends}, libgtp11 (= ${binary:Version}), osmo-ggsn (= ${binary:Version})
 | 
				
			||||||
Multi-Arch: same
 | 
					Multi-Arch: same
 | 
				
			||||||
Description: Debug symbols for OpenGGSN
 | 
					Description: Debug symbols for OsmoGGSN
 | 
				
			||||||
 | 
					 OsmoGGSN is a Gateway GPRS Support Node (GGSN). It is used by mobile
 | 
				
			||||||
 | 
					 operators as the interface between the Internet and the rest of the
 | 
				
			||||||
 | 
					 mobile network infrastructure.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Package: gtp-echo-responder-dbg
 | 
				
			||||||
 | 
					Section: debug
 | 
				
			||||||
 | 
					Architecture: any
 | 
				
			||||||
 | 
					Priority: extra
 | 
				
			||||||
 | 
					Depends: ${shlibs:Depends}, ${misc:Depends}, gtp-echo-responder (= ${binary:Version})
 | 
				
			||||||
 | 
					Multi-Arch: same
 | 
				
			||||||
 | 
					Description: Debug symbols for gtp-echo-responder
 | 
				
			||||||
 | 
					 Small program answering GTP ECHO Request with GTP ECHO Response.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Package: libgtp-dbg
 | 
				
			||||||
 | 
					Section: debug
 | 
				
			||||||
 | 
					Architecture: any
 | 
				
			||||||
 | 
					Priority: extra
 | 
				
			||||||
 | 
					Depends: ${shlibs:Depends}, ${misc:Depends}, libgtp11 (= ${binary:Version})
 | 
				
			||||||
 | 
					Multi-Arch: same
 | 
				
			||||||
 | 
					Description: Debug symbols for OsmoGGSN
 | 
				
			||||||
 | 
					 OsmoGGSN is a Gateway GPRS Support Node (GGSN). It is used by mobile
 | 
				
			||||||
 | 
					 operators as the interface between the Internet and the rest of the
 | 
				
			||||||
 | 
					 mobile network infrastructure.
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
 | 
					 The library libgtp implements the GTP protocol between SGSN and GGSN
 | 
				
			||||||
 | 
					 and this package contains the development files for this library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Package: osmo-ggsn-doc
 | 
				
			||||||
 | 
					Architecture: all
 | 
				
			||||||
 | 
					Section: doc
 | 
				
			||||||
 | 
					Priority: optional
 | 
				
			||||||
 | 
					Depends: ${misc:Depends}
 | 
				
			||||||
 | 
					Description: ${misc:Package} PDF documentation
 | 
				
			||||||
 | 
					 Various manuals: user manual, VTY reference manual and/or
 | 
				
			||||||
 | 
					 protocol/interface manuals.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										92
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										92
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							@@ -1,46 +1,62 @@
 | 
				
			|||||||
This work was packaged for Debian by:
 | 
					Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 | 
				
			||||||
 | 
					Upstream-Name: osmo-ggsn
 | 
				
			||||||
 | 
					Source: https://osmocom.org/projects/openggsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Harald Welte <laforge@gnumonks.org> on Tue, 24 Aug 2010 11:23:40 +0200
 | 
					Files: *
 | 
				
			||||||
 | 
					Copyright: 2002-2004 Mondru AB, Author: Jens Jakobsen <jj@openggsn.org>
 | 
				
			||||||
 | 
					           2010-2017 Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					           2012-2016 Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 | 
					           2014-2016 Pablo Neira Ayuso <pablo@gnumonks.org>
 | 
				
			||||||
 | 
					           2014-2016 sysmocom - s.f.m.c. GmbH
 | 
				
			||||||
 | 
					License: GPL-2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It was downloaded from:
 | 
					Files: lib/getopt.c
 | 
				
			||||||
 | 
					       lib/gnugetopt.h
 | 
				
			||||||
 | 
					       lib/getopt1.c
 | 
				
			||||||
 | 
					Copyright: 1987-2001 Free Software Foundation, Inc.
 | 
				
			||||||
 | 
					License: LGPL-2.1+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    http://sourceforge.net/projects/ggsn
 | 
					Files: utils/gtp_echo_responder.c
 | 
				
			||||||
 | 
					       utils/gtp_echo_responder_test.py
 | 
				
			||||||
 | 
					Copyright: 2021 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
				
			||||||
 | 
					License: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Upstream Author(s):
 | 
					Files: debian/*
 | 
				
			||||||
 | 
					Copyright: 2010-2017  Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					           2016       Ruben Undheim <ruben.undheim@gmail.com>
 | 
				
			||||||
 | 
					License: GPL-2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Jens Jakobsen <jj@openggsn.org>
 | 
					 | 
				
			||||||
    Harald Welte <laforge@gnumonks.org>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Copyright:
 | 
					License: GPL-2
 | 
				
			||||||
 | 
					 This package is free software: you can redistribute it and/or modify it
 | 
				
			||||||
 | 
					 under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 the Free Software Foundation; version 2 of the License
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
 | 
					 This program is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 | 
				
			||||||
 | 
					 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 | 
				
			||||||
 | 
					 for more details.
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
 | 
					 You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
 | 
					 On Debian systems, the complete text of the GNU General Public
 | 
				
			||||||
 | 
					 License version 2 can be found in "/usr/share/common-licenses/GPL-2".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2002 Mondru AB
 | 
					 | 
				
			||||||
    Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
License:
 | 
					License: LGPL-2.1+
 | 
				
			||||||
 | 
					 This package is free software: you can redistribute it and/or modify it
 | 
				
			||||||
   This package is free software; you can redistribute it and/or modify
 | 
					 under the terms of the GNU Lesser General Public License as published by
 | 
				
			||||||
   it under the terms of the GNU General Public License version 2 as
 | 
					 the Free Software Foundation, either version 2.1 of the License, or (at
 | 
				
			||||||
   published by the Free Software Foundation.
 | 
					 your option) any later version.
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
    This package is distributed in the hope that it will be useful,
 | 
					 This program is distributed in the hope that it will be useful, but
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					 for more details.
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
    You should have received a copy of the GNU General Public License
 | 
					 You should have received a copy of the GNU Lesser General Public License
 | 
				
			||||||
    along with this program. If not, see <http://www.gnu.org/licenses/>
 | 
					 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 .
 | 
				
			||||||
On Debian systems, the complete text of the GNU General
 | 
					 On Debian systems, the complete text of the GNU Lesser General Public
 | 
				
			||||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
 | 
					 License version 2.1 can be found in "/usr/share/common-licenses/LGPL-2.1".
 | 
				
			||||||
 | 
					 | 
				
			||||||
The Debian packaging is:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
you can redistribute it and/or modify
 | 
					 | 
				
			||||||
it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
(at your option) any later version.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Please also look if there are files or directories which have a
 | 
					 | 
				
			||||||
# different copyright/license attached and list them here.
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								debian/docs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								debian/docs
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1 @@
 | 
				
			|||||||
NEWS
 | 
					README.md
 | 
				
			||||||
README
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								debian/gtp-echo-responder.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/gtp-echo-responder.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					/usr/bin/gtp-echo-responder
 | 
				
			||||||
							
								
								
									
										2
									
								
								debian/libgtp11.shlibs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								debian/libgtp11.shlibs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					# Most recent version of the package that added new symbols (OS#5318)
 | 
				
			||||||
 | 
					libgtp 11 libgtp11 (>= 1.13.0)
 | 
				
			||||||
							
								
								
									
										2
									
								
								debian/openggsn.examples
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/openggsn.examples
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
				
			|||||||
examples/ggsn.conf
 | 
					 | 
				
			||||||
examples/sgsnemu.conf
 | 
					 | 
				
			||||||
							
								
								
									
										163
									
								
								debian/openggsn.init
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										163
									
								
								debian/openggsn.init
									
									
									
									
										vendored
									
									
								
							@@ -1,163 +0,0 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					 | 
				
			||||||
### BEGIN INIT INFO
 | 
					 | 
				
			||||||
# Provides:          openggsn
 | 
					 | 
				
			||||||
# Required-Start:    $network $local_fs $remote_fs
 | 
					 | 
				
			||||||
# Required-Stop:     $network $remote_fs
 | 
					 | 
				
			||||||
# Default-Start:     2 3 4 5
 | 
					 | 
				
			||||||
# Default-Stop:      0 1 6
 | 
					 | 
				
			||||||
# Short-Description: Gateway GPRS Support Node
 | 
					 | 
				
			||||||
# Description:       Gateway GPRS Support Node
 | 
					 | 
				
			||||||
### END INIT INFO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Author: Harald Welte <laforge@gnumonks.org>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
 | 
					 | 
				
			||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
 | 
					 | 
				
			||||||
DESC="OpenGGSN Gateway GPRS Support Node"
 | 
					 | 
				
			||||||
NAME=ggsn
 | 
					 | 
				
			||||||
DAEMON=/usr/bin/ggsn
 | 
					 | 
				
			||||||
DAEMON_ARGS=""             # Arguments to run the daemon with
 | 
					 | 
				
			||||||
PIDFILE=/var/run/$NAME.pid
 | 
					 | 
				
			||||||
SCRIPTNAME=/etc/init.d/openggsn
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Exit if the package is not installed
 | 
					 | 
				
			||||||
[ -x $DAEMON ] || exit 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Read configuration variable file if it is present
 | 
					 | 
				
			||||||
[ -r /etc/default/openggsn ] && . /etc/default/openggsn
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Load the VERBOSE setting and other rcS variables
 | 
					 | 
				
			||||||
. /lib/init/vars.sh
 | 
					 | 
				
			||||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
 | 
					 | 
				
			||||||
. /lib/lsb/init-functions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DAEMON_ARGS="$DAEMON_ARGS"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Function that starts the daemon/service
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
do_start()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	# Return
 | 
					 | 
				
			||||||
	#   0 if daemon has been started
 | 
					 | 
				
			||||||
	#   1 if daemon was already running
 | 
					 | 
				
			||||||
	#   2 if daemon could not be started
 | 
					 | 
				
			||||||
	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
 | 
					 | 
				
			||||||
		|| return 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Check for runtime directory of nonvolatile data
 | 
					 | 
				
			||||||
	if [ ! -d /var/lib/ggsn ]; then
 | 
					 | 
				
			||||||
		mkdir /var/lib/ggsn
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Check for GTP restart counter
 | 
					 | 
				
			||||||
	if [ ! -f /var/lib/ggsn/gsn_restart ]; then
 | 
					 | 
				
			||||||
		echo 0 > /var/lib/ggsn/gsn_restart
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
 | 
					 | 
				
			||||||
		$DAEMON_ARGS \
 | 
					 | 
				
			||||||
		|| return 2
 | 
					 | 
				
			||||||
	# Add code here, if necessary, that waits for the process to be ready
 | 
					 | 
				
			||||||
	# to handle requests from services started subsequently which depend
 | 
					 | 
				
			||||||
	# on this one.  As a last resort, sleep for some time.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Function that stops the daemon/service
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
do_stop()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	# Return
 | 
					 | 
				
			||||||
	#   0 if daemon has been stopped
 | 
					 | 
				
			||||||
	#   1 if daemon was already stopped
 | 
					 | 
				
			||||||
	#   2 if daemon could not be stopped
 | 
					 | 
				
			||||||
	#   other if a failure occurred
 | 
					 | 
				
			||||||
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
 | 
					 | 
				
			||||||
	RETVAL="$?"
 | 
					 | 
				
			||||||
	[ "$RETVAL" = 2 ] && return 2
 | 
					 | 
				
			||||||
	# Wait for children to finish too if this is a daemon that forks
 | 
					 | 
				
			||||||
	# and if the daemon is only ever run from this initscript.
 | 
					 | 
				
			||||||
	# If the above conditions are not satisfied then add some other code
 | 
					 | 
				
			||||||
	# that waits for the process to drop all resources that could be
 | 
					 | 
				
			||||||
	# needed by services started subsequently.  A last resort is to
 | 
					 | 
				
			||||||
	# sleep for some time.
 | 
					 | 
				
			||||||
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
 | 
					 | 
				
			||||||
	[ "$?" = 2 ] && return 2
 | 
					 | 
				
			||||||
	# Many daemons don't delete their pidfiles when they exit.
 | 
					 | 
				
			||||||
	rm -f $PIDFILE
 | 
					 | 
				
			||||||
	return "$RETVAL"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Function that sends a SIGHUP to the daemon/service
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
do_reload() {
 | 
					 | 
				
			||||||
	#
 | 
					 | 
				
			||||||
	# If the daemon can reload its configuration without
 | 
					 | 
				
			||||||
	# restarting (for example, when it is sent a SIGHUP),
 | 
					 | 
				
			||||||
	# then implement that here.
 | 
					 | 
				
			||||||
	#
 | 
					 | 
				
			||||||
	start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
case "$1" in
 | 
					 | 
				
			||||||
  start)
 | 
					 | 
				
			||||||
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
 | 
					 | 
				
			||||||
    do_start
 | 
					 | 
				
			||||||
    case "$?" in
 | 
					 | 
				
			||||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
					 | 
				
			||||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
					 | 
				
			||||||
	esac
 | 
					 | 
				
			||||||
  ;;
 | 
					 | 
				
			||||||
  stop)
 | 
					 | 
				
			||||||
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
 | 
					 | 
				
			||||||
	do_stop
 | 
					 | 
				
			||||||
	case "$?" in
 | 
					 | 
				
			||||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
					 | 
				
			||||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
					 | 
				
			||||||
	esac
 | 
					 | 
				
			||||||
	;;
 | 
					 | 
				
			||||||
  status)
 | 
					 | 
				
			||||||
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
 | 
					 | 
				
			||||||
       ;;
 | 
					 | 
				
			||||||
  #reload|force-reload)
 | 
					 | 
				
			||||||
	#
 | 
					 | 
				
			||||||
	# If do_reload() is not implemented then leave this commented out
 | 
					 | 
				
			||||||
	# and leave 'force-reload' as an alias for 'restart'.
 | 
					 | 
				
			||||||
	#
 | 
					 | 
				
			||||||
	#log_daemon_msg "Reloading $DESC" "$NAME"
 | 
					 | 
				
			||||||
	#do_reload
 | 
					 | 
				
			||||||
	#log_end_msg $?
 | 
					 | 
				
			||||||
	#;;
 | 
					 | 
				
			||||||
  restart|force-reload)
 | 
					 | 
				
			||||||
	#
 | 
					 | 
				
			||||||
	# If the "reload" option is implemented then remove the
 | 
					 | 
				
			||||||
	# 'force-reload' alias
 | 
					 | 
				
			||||||
	#
 | 
					 | 
				
			||||||
	log_daemon_msg "Restarting $DESC" "$NAME"
 | 
					 | 
				
			||||||
	do_stop
 | 
					 | 
				
			||||||
	case "$?" in
 | 
					 | 
				
			||||||
	  0|1)
 | 
					 | 
				
			||||||
		do_start
 | 
					 | 
				
			||||||
		case "$?" in
 | 
					 | 
				
			||||||
			0) log_end_msg 0 ;;
 | 
					 | 
				
			||||||
			1) log_end_msg 1 ;; # Old process is still running
 | 
					 | 
				
			||||||
			*) log_end_msg 1 ;; # Failed to start
 | 
					 | 
				
			||||||
		esac
 | 
					 | 
				
			||||||
		;;
 | 
					 | 
				
			||||||
	  *)
 | 
					 | 
				
			||||||
	  	# Failed to stop
 | 
					 | 
				
			||||||
		log_end_msg 1
 | 
					 | 
				
			||||||
		;;
 | 
					 | 
				
			||||||
	esac
 | 
					 | 
				
			||||||
	;;
 | 
					 | 
				
			||||||
  *)
 | 
					 | 
				
			||||||
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
 | 
					 | 
				
			||||||
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
 | 
					 | 
				
			||||||
	exit 3
 | 
					 | 
				
			||||||
	;;
 | 
					 | 
				
			||||||
esac
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
:
 | 
					 | 
				
			||||||
							
								
								
									
										3
									
								
								debian/openggsn.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								debian/openggsn.install
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +0,0 @@
 | 
				
			|||||||
/usr/bin/ggsn
 | 
					 | 
				
			||||||
/usr/bin/sgsnemu
 | 
					 | 
				
			||||||
/usr/share/man/man8/*
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								debian/osmo-ggsn-doc.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/osmo-ggsn-doc.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					usr/share/doc/osmo-ggsn-doc/*.pdf
 | 
				
			||||||
							
								
								
									
										3
									
								
								debian/osmo-ggsn.examples
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								debian/osmo-ggsn.examples
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					doc/examples/osmo-ggsn.cfg
 | 
				
			||||||
 | 
					doc/examples/osmo-ggsn-kernel-gtp.cfg
 | 
				
			||||||
 | 
					doc/examples/sgsnemu.conf
 | 
				
			||||||
							
								
								
									
										5
									
								
								debian/osmo-ggsn.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								debian/osmo-ggsn.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					/etc/osmocom/osmo-ggsn.cfg
 | 
				
			||||||
 | 
					/lib/systemd/system/osmo-ggsn.service
 | 
				
			||||||
 | 
					/usr/bin/osmo-ggsn
 | 
				
			||||||
 | 
					/usr/bin/sgsnemu
 | 
				
			||||||
 | 
					/usr/share/man/man8/*
 | 
				
			||||||
							
								
								
									
										39
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					#!/bin/sh -e
 | 
				
			||||||
 | 
					case "$1" in
 | 
				
			||||||
 | 
						configure)
 | 
				
			||||||
 | 
							# Create the osmocom group and user (if it doesn't exist yet)
 | 
				
			||||||
 | 
							if ! getent group osmocom >/dev/null; then
 | 
				
			||||||
 | 
								groupadd --system osmocom
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
							if ! getent passwd osmocom >/dev/null; then
 | 
				
			||||||
 | 
								useradd \
 | 
				
			||||||
 | 
									--system \
 | 
				
			||||||
 | 
									--gid osmocom \
 | 
				
			||||||
 | 
									--home-dir /var/lib/osmocom \
 | 
				
			||||||
 | 
									--shell /sbin/nologin \
 | 
				
			||||||
 | 
									--comment "Open Source Mobile Communications" \
 | 
				
			||||||
 | 
									osmocom
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							# Fix permissions of previous (root-owned) install (OS#4107)
 | 
				
			||||||
 | 
							if dpkg --compare-versions "$2" le "1.13.0"; then
 | 
				
			||||||
 | 
								if [ -e /etc/osmocom/osmo-ggsn.cfg ]; then
 | 
				
			||||||
 | 
									chown -v osmocom:osmocom /etc/osmocom/osmo-ggsn.cfg
 | 
				
			||||||
 | 
									chmod -v 0660 /etc/osmocom/osmo-ggsn.cfg
 | 
				
			||||||
 | 
								fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if [ -d /etc/osmocom ]; then
 | 
				
			||||||
 | 
									chown -v root:osmocom /etc/osmocom
 | 
				
			||||||
 | 
									chmod -v 2775 /etc/osmocom
 | 
				
			||||||
 | 
								fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								mkdir -p /var/lib/osmocom
 | 
				
			||||||
 | 
								chown -R -v osmocom:osmocom /var/lib/osmocom
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
							;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# dh_installdeb(1) will replace this with shell code automatically
 | 
				
			||||||
 | 
					# generated by other debhelper scripts.
 | 
				
			||||||
 | 
					#DEBHELPER#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										29
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							@@ -1,24 +1,29 @@
 | 
				
			|||||||
#!/usr/bin/make -f
 | 
					#!/usr/bin/make -f
 | 
				
			||||||
# -*- makefile -*-
 | 
					 | 
				
			||||||
# Sample debian/rules that uses debhelper.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file was originally written by Joey Hess and Craig Small.
 | 
					 | 
				
			||||||
# As a special exception, when this file is copied by dh-make into a
 | 
					 | 
				
			||||||
# dh-make output file, you may use that output file without restriction.
 | 
					 | 
				
			||||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Modified to make a template file for a multi-binary package with separated
 | 
					 | 
				
			||||||
# build-arch and build-indep targets  by Bill Allombert 2001
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Uncomment this to turn on verbose mode.
 | 
					# Uncomment this to turn on verbose mode.
 | 
				
			||||||
#export DH_VERBOSE=1
 | 
					#export DH_VERBOSE=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEBIAN  := $(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
 | 
				
			||||||
 | 
					DEBVERS := $(shell echo '$(DEBIAN)' | cut -d- -f1)
 | 
				
			||||||
 | 
					VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/[+-].*//' -e 's/~//g')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This has to be exported to make some magic below work.
 | 
					# This has to be exported to make some magic below work.
 | 
				
			||||||
#export DH_OPTIONS
 | 
					#export DH_OPTIONS
 | 
				
			||||||
export DEB_BUILD_HARDENING=1
 | 
					export DEB_BUILD_MAINT_OPTIONS = hardening=+all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%:
 | 
					%:
 | 
				
			||||||
	dh $@ --with autoreconf
 | 
						dh $@ --with autoreconf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
override_dh_strip:
 | 
					override_dh_strip:
 | 
				
			||||||
	dh_strip --dbg-package=openggsn-dbg
 | 
						dh_strip -posmo-ggsn --dbg-package=osmo-ggsn-dbg
 | 
				
			||||||
 | 
						dh_strip -plibgtp11 --dbg-package=libgtp-dbg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					override_dh_auto_configure:
 | 
				
			||||||
 | 
						dh_auto_configure -- \
 | 
				
			||||||
 | 
							--enable-gtp-linux \
 | 
				
			||||||
 | 
							--with-systemdsystemunitdir=/lib/systemd/system \
 | 
				
			||||||
 | 
							--enable-manuals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Don't create .pdf.gz files (barely saves space and they can't be opened directly by most pdf readers)
 | 
				
			||||||
 | 
					override_dh_compress:
 | 
				
			||||||
 | 
						dh_compress -X.pdf
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
<h1>Protocol Compliance List</h1>
 | 
					<h1>Protocol Compliance List</h1>
 | 
				
			||||||
OpenGGSN supports both GTP0 (GSM 09.60) and GTP1 (3GPP 29.060). In the
 | 
					OsmoGGSN supports both GTP0 (GSM 09.60) and GTP1 (3GPP 29.060). In the
 | 
				
			||||||
following tables the support of each individual message type is
 | 
					following tables the support of each individual message type is
 | 
				
			||||||
detailed. The numbers before each feature indicates the relevant
 | 
					detailed. The numbers before each feature indicates the relevant
 | 
				
			||||||
section in the standard.<br>
 | 
					section in the standard.<br>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
man_MANS = ggsn.8 sgsnemu.8
 | 
					man_MANS = osmo-ggsn.8 sgsnemu.8
 | 
				
			||||||
man_aux = $(man_MANS:.1=.x)
 | 
					man_aux = $(man_MANS:.1=.x)
 | 
				
			||||||
EXTRA_DIST = $(man_MANS)
 | 
					EXTRA_DIST = $(man_MANS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SUBDIRS = \
 | 
				
			||||||
 | 
						examples \
 | 
				
			||||||
 | 
						manuals \
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								doc/examples/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								doc/examples/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					OSMOCONF_FILES = \
 | 
				
			||||||
 | 
						osmo-ggsn.cfg \
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmoconfdir = $(sysconfdir)/osmocom
 | 
				
			||||||
 | 
					osmoconf_DATA = $(OSMOCONF_FILES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXTRA_DIST = $(OSMOCONF_FILES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CFG_FILES = find $(srcdir) -name '*.cfg' -o -name '*.conf' | sed -e 's,^$(srcdir),,'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dist-hook:
 | 
				
			||||||
 | 
						for f in $$($(CFG_FILES)); do \
 | 
				
			||||||
 | 
							j="$(distdir)/$$f" && \
 | 
				
			||||||
 | 
							mkdir -p "$$(dirname $$j)" && \
 | 
				
			||||||
 | 
							$(INSTALL_DATA) $(srcdir)/$$f $$j; \
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install-data-hook:
 | 
				
			||||||
 | 
						for f in $$($(CFG_FILES)); do \
 | 
				
			||||||
 | 
							j="$(DESTDIR)$(docdir)/examples/$$f" && \
 | 
				
			||||||
 | 
							mkdir -p "$$(dirname $$j)" && \
 | 
				
			||||||
 | 
							$(INSTALL_DATA) $(srcdir)/$$f $$j; \
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uninstall-hook:
 | 
				
			||||||
 | 
						@$(PRE_UNINSTALL)
 | 
				
			||||||
 | 
						for f in $$($(CFG_FILES)); do \
 | 
				
			||||||
 | 
							j="$(DESTDIR)$(docdir)/examples/$$f" && \
 | 
				
			||||||
 | 
							$(RM) $$j; \
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
							
								
								
									
										48
									
								
								doc/examples/firewall
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										48
									
								
								doc/examples/firewall
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Firewall script for GGSN
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Uses $IFGN (eth0) as the Gn interface (Gn) and
 | 
				
			||||||
 | 
					# $IFGI (eth1) as the Gi interface.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# SUMMARY
 | 
				
			||||||
 | 
					# * All connections originating from GGSN are allowed.
 | 
				
			||||||
 | 
					# * Incoming ssh, GTPv0 and GTPv1 is allowed on the Gn interface.
 | 
				
			||||||
 | 
					# * Incoming ssh is allowed on the Gi interface.
 | 
				
			||||||
 | 
					# * Forwarding is allowed to and from the Gi interface, but disallowed
 | 
				
			||||||
 | 
					#   to and from the Gn interface.
 | 
				
			||||||
 | 
					# * Masquerede on Gi interface.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NFT="nft"
 | 
				
			||||||
 | 
					IFGN="eth0"
 | 
				
			||||||
 | 
					IFGI="eth1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$NFT add chain ip filter input '{ policy drop; }'
 | 
				
			||||||
 | 
					$NFT add chain ip filter forward '{ policy accept; }'
 | 
				
			||||||
 | 
					$NFT add chain ip filter output '{ policy accept; }'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Allow related and established on all interfaces (input)
 | 
				
			||||||
 | 
					$NFT add rule ip filter input ct state related,established counter accept
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Allow releated, established, GTP and ssh on $IFGN. Reject everything else.
 | 
				
			||||||
 | 
					$NFT add rule ip filter input iifname $IFGN tcp dport 22 tcp flags syn / fin,syn,rst,ack counter accept
 | 
				
			||||||
 | 
					$NFT add rule ip filter input iifname $IFGN udp dport 2123 counter accept
 | 
				
			||||||
 | 
					$NFT add rule ip filter input iifname $IFGN udp dport 2152 counter accept
 | 
				
			||||||
 | 
					$NFT add rule ip filter input iifname $IFGN udp dport 3386 counter accept
 | 
				
			||||||
 | 
					$NFT add rule ip filter input iifname $IFGN counter reject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Allow related, established and ssh. Drop everything else.
 | 
				
			||||||
 | 
					$NFT add rule ip filter input iifname $IFGI tcp dport 22 tcp flags syn / fin,syn,rst,ack counter accept
 | 
				
			||||||
 | 
					$NFT add rule ip filter input iifname $IFGI counter drop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Masquerade everything going out on $IFGI
 | 
				
			||||||
 | 
					$NFT add rule ip nat POSTROUTING oifname $IFGI counter masquerade
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Allow everything on loopback interface.
 | 
				
			||||||
 | 
					$NFT add rule ip filter input iifname "lo" counter accept
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Drop everything to and from $IFGN (forward)
 | 
				
			||||||
 | 
					$NFT add rule ip filter forward iifname $IFGN counter drop
 | 
				
			||||||
 | 
					$NFT add rule ip filter forward oifname $IFGN counter drop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										54
									
								
								doc/examples/osmo-ggsn-kernel-gtp.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								doc/examples/osmo-ggsn-kernel-gtp.cfg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					!
 | 
				
			||||||
 | 
					! OpenGGSN (0.94.1-adac) configuration saved from vty
 | 
				
			||||||
 | 
					!!
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
 | 
					log stderr
 | 
				
			||||||
 | 
					 logging color 1
 | 
				
			||||||
 | 
					 logging print category-hex 0
 | 
				
			||||||
 | 
					 logging print category 1
 | 
				
			||||||
 | 
					 logging timestamp 0
 | 
				
			||||||
 | 
					 logging print file basename last
 | 
				
			||||||
 | 
					 logging print level 1
 | 
				
			||||||
 | 
					 logging level ip info
 | 
				
			||||||
 | 
					 logging level tun info
 | 
				
			||||||
 | 
					 logging level ggsn info
 | 
				
			||||||
 | 
					 logging level sgsn notice
 | 
				
			||||||
 | 
					 logging level icmp6 notice
 | 
				
			||||||
 | 
					 logging level lglobal notice
 | 
				
			||||||
 | 
					 logging level llapd notice
 | 
				
			||||||
 | 
					 logging level linp notice
 | 
				
			||||||
 | 
					 logging level lmux notice
 | 
				
			||||||
 | 
					 logging level lmi notice
 | 
				
			||||||
 | 
					 logging level lmib notice
 | 
				
			||||||
 | 
					 logging level lsms notice
 | 
				
			||||||
 | 
					 logging level lctrl notice
 | 
				
			||||||
 | 
					 logging level lgtp info
 | 
				
			||||||
 | 
					 logging level lstats notice
 | 
				
			||||||
 | 
					 logging level lgsup notice
 | 
				
			||||||
 | 
					 logging level loap notice
 | 
				
			||||||
 | 
					 logging level lss7 notice
 | 
				
			||||||
 | 
					 logging level lsccp notice
 | 
				
			||||||
 | 
					 logging level lsua notice
 | 
				
			||||||
 | 
					 logging level lm3ua notice
 | 
				
			||||||
 | 
					 logging level lmgcp notice
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
 | 
					stats interval 5
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
 | 
					line vty
 | 
				
			||||||
 | 
					 no login
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
 | 
					ggsn ggsn0
 | 
				
			||||||
 | 
					 gtp state-dir /var/lib/osmocom/osmo-ggsn
 | 
				
			||||||
 | 
					 gtp bind-ip 127.0.0.2
 | 
				
			||||||
 | 
					 apn internet
 | 
				
			||||||
 | 
					  gtpu-mode kernel-gtp
 | 
				
			||||||
 | 
					  tun-device tun4
 | 
				
			||||||
 | 
					  type-support v4
 | 
				
			||||||
 | 
					  mtu default apply
 | 
				
			||||||
 | 
					  ip prefix dynamic 172.16.222.0/24
 | 
				
			||||||
 | 
					  ip dns 0 8.8.8.8
 | 
				
			||||||
 | 
					  ip dns 1 8.8.4.4
 | 
				
			||||||
 | 
					  ip ifconfig 172.16.222.0/24
 | 
				
			||||||
 | 
					  no shutdown
 | 
				
			||||||
 | 
					 default-apn internet
 | 
				
			||||||
 | 
					 no shutdown ggsn
 | 
				
			||||||
							
								
								
									
										78
									
								
								doc/examples/osmo-ggsn.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								doc/examples/osmo-ggsn.cfg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					!
 | 
				
			||||||
 | 
					! OpenGGSN (0.94.1-adac) configuration saved from vty
 | 
				
			||||||
 | 
					!!
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
 | 
					log stderr
 | 
				
			||||||
 | 
					 logging color 1
 | 
				
			||||||
 | 
					 logging print category-hex 0
 | 
				
			||||||
 | 
					 logging print category 1
 | 
				
			||||||
 | 
					 logging timestamp 0
 | 
				
			||||||
 | 
					 logging print file basename last
 | 
				
			||||||
 | 
					 logging print level 1
 | 
				
			||||||
 | 
					 logging level ip info
 | 
				
			||||||
 | 
					 logging level tun info
 | 
				
			||||||
 | 
					 logging level ggsn info
 | 
				
			||||||
 | 
					 logging level sgsn notice
 | 
				
			||||||
 | 
					 logging level icmp6 notice
 | 
				
			||||||
 | 
					 logging level lglobal notice
 | 
				
			||||||
 | 
					 logging level llapd notice
 | 
				
			||||||
 | 
					 logging level linp notice
 | 
				
			||||||
 | 
					 logging level lmux notice
 | 
				
			||||||
 | 
					 logging level lmi notice
 | 
				
			||||||
 | 
					 logging level lmib notice
 | 
				
			||||||
 | 
					 logging level lsms notice
 | 
				
			||||||
 | 
					 logging level lctrl notice
 | 
				
			||||||
 | 
					 logging level lgtp info
 | 
				
			||||||
 | 
					 logging level lstats notice
 | 
				
			||||||
 | 
					 logging level lgsup notice
 | 
				
			||||||
 | 
					 logging level loap notice
 | 
				
			||||||
 | 
					 logging level lss7 notice
 | 
				
			||||||
 | 
					 logging level lsccp notice
 | 
				
			||||||
 | 
					 logging level lsua notice
 | 
				
			||||||
 | 
					 logging level lm3ua notice
 | 
				
			||||||
 | 
					 logging level lmgcp notice
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
 | 
					stats interval 5
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
 | 
					line vty
 | 
				
			||||||
 | 
					 no login
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
 | 
					ggsn ggsn0
 | 
				
			||||||
 | 
					 gtp state-dir /var/lib/osmocom/osmo-ggsn
 | 
				
			||||||
 | 
					 gtp bind-ip 127.0.0.2
 | 
				
			||||||
 | 
					 apn internet
 | 
				
			||||||
 | 
					  gtpu-mode tun
 | 
				
			||||||
 | 
					  tun-device tun4
 | 
				
			||||||
 | 
					  type-support v4
 | 
				
			||||||
 | 
					  mtu default apply
 | 
				
			||||||
 | 
					  ip prefix dynamic 172.16.222.0/24
 | 
				
			||||||
 | 
					  ip dns 0 8.8.8.8
 | 
				
			||||||
 | 
					  ip dns 1 8.8.4.4
 | 
				
			||||||
 | 
					  ip ifconfig 172.16.222.0/24
 | 
				
			||||||
 | 
					  no shutdown
 | 
				
			||||||
 | 
					 apn inet6
 | 
				
			||||||
 | 
					  gtpu-mode tun
 | 
				
			||||||
 | 
					  tun-device tun6
 | 
				
			||||||
 | 
					  type-support v6
 | 
				
			||||||
 | 
					  mtu default apply
 | 
				
			||||||
 | 
					  ipv6 prefix dynamic 2001:780:44:2000:0:0:0:0/56
 | 
				
			||||||
 | 
					  ipv6 dns 0 2001:4860:4860::8888
 | 
				
			||||||
 | 
					  ipv6 dns 1 2001:4860:4860::8844
 | 
				
			||||||
 | 
					  ipv6 ifconfig 2001:780:44:2000:0:0:0:0/56
 | 
				
			||||||
 | 
					  no shutdown
 | 
				
			||||||
 | 
					 apn inet46
 | 
				
			||||||
 | 
					  gtpu-mode tun
 | 
				
			||||||
 | 
					  tun-device tun46
 | 
				
			||||||
 | 
					  type-support v4v6
 | 
				
			||||||
 | 
					  mtu default apply
 | 
				
			||||||
 | 
					  ip prefix dynamic 172.16.46.0/24
 | 
				
			||||||
 | 
					  ip dns 0 8.8.8.8
 | 
				
			||||||
 | 
					  ip dns 1 8.8.4.4
 | 
				
			||||||
 | 
					  ip ifconfig 172.16.46.0/24
 | 
				
			||||||
 | 
					  ipv6 prefix dynamic 2001:780:44:2100:0:0:0:0/56
 | 
				
			||||||
 | 
					  ipv6 dns 0 2001:4860:4860::8888
 | 
				
			||||||
 | 
					  ipv6 dns 1 2001:4860:4860::8844
 | 
				
			||||||
 | 
					  ipv6 ifconfig 2001:780:44:2100:0:0:0:0/56
 | 
				
			||||||
 | 
					  no shutdown
 | 
				
			||||||
 | 
					 default-apn internet
 | 
				
			||||||
 | 
					 no shutdown ggsn
 | 
				
			||||||
							
								
								
									
										24
									
								
								doc/manuals/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								doc/manuals/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					EXTRA_DIST = osmoggsn-usermanual.adoc \
 | 
				
			||||||
 | 
					    osmoggsn-usermanual-docinfo.xml \
 | 
				
			||||||
 | 
					    osmoggsn-vty-reference.xml \
 | 
				
			||||||
 | 
					    regen_doc.sh \
 | 
				
			||||||
 | 
					    chapters \
 | 
				
			||||||
 | 
					    vty
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if BUILD_MANUALS
 | 
				
			||||||
 | 
					  ASCIIDOC = osmoggsn-usermanual.adoc
 | 
				
			||||||
 | 
					  ASCIIDOC_DEPS = $(srcdir)/chapters/*.adoc
 | 
				
			||||||
 | 
					  include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  VTY_REFERENCE = osmoggsn-vty-reference.xml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BUILT_REFERENCE_XML = $(builddir)/vty/ggsn_vty_reference.xml
 | 
				
			||||||
 | 
					  $(builddir)/vty/ggsn_vty_reference.xml: $(top_builddir)/ggsn/osmo-ggsn
 | 
				
			||||||
 | 
						mkdir -p $(builddir)/vty
 | 
				
			||||||
 | 
						$(top_builddir)/ggsn/osmo-ggsn --vty-ref-xml > $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  OSMO_REPOSITORY=osmo-ggsn
 | 
				
			||||||
 | 
					  include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
							
								
								
									
										346
									
								
								doc/manuals/chapters/configuration.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								doc/manuals/chapters/configuration.adoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,346 @@
 | 
				
			|||||||
 | 
					[[osmoggsn_configuring]]
 | 
				
			||||||
 | 
					== Configuring OsmoGGSN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All configuration of OsmoGGSN is performed using the VTY. For more
 | 
				
			||||||
 | 
					general information on the VTY interface, see <<vty>>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Configuring a virtual GGSN instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN can run multiple GGSN instances inside one program/process.
 | 
				
			||||||
 | 
					Each GGSN instance binds to its own transport-layer GTP IP address and
 | 
				
			||||||
 | 
					has its own set of APNs and associated IP address pools + tun/gtp
 | 
				
			||||||
 | 
					devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In most usage cases, yo will only have a single GGSN instance inside
 | 
				
			||||||
 | 
					your configuration file, like in below example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Single GGSN configuration section
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					ggsn ggsn0
 | 
				
			||||||
 | 
					 gtp state-dir /var/lib/osmocom/osmo-ggsn
 | 
				
			||||||
 | 
					 gtp bind-ip 127.0.0.6
 | 
				
			||||||
 | 
					 apn internet
 | 
				
			||||||
 | 
					  gtpu-mode tun
 | 
				
			||||||
 | 
					  tun-device tun4
 | 
				
			||||||
 | 
					  type-support v4
 | 
				
			||||||
 | 
					  mtu default apply
 | 
				
			||||||
 | 
					  ip prefix dynamic 176.16.222.0/24
 | 
				
			||||||
 | 
					  ip dns 0 192.168.100.1
 | 
				
			||||||
 | 
					  ip dns 1 8.8.8.8
 | 
				
			||||||
 | 
					  ip ifconfig 176.16.222.0/24
 | 
				
			||||||
 | 
					  no shutdown
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Creating/Editing a GGSN instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Creating/Editing a GGSN instance can be done by the following sequence
 | 
				
			||||||
 | 
					of VTY commands:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN> enable <1>
 | 
				
			||||||
 | 
					OsmoGGSN# configure terminal <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config)# ggsn ggsn0 <3>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# <4>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Change into privileged mode
 | 
				
			||||||
 | 
					<2> Enter the interactive configuration mode
 | 
				
			||||||
 | 
					<3> Create or edit the GGSN instance `ggsn0`. The name can be any ASCII
 | 
				
			||||||
 | 
					    string, its significance is only to the local user.
 | 
				
			||||||
 | 
					<4> Your prompt is now in the `ggsn` config node, where you can
 | 
				
			||||||
 | 
					    configure the properties of this GGSN instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOTE:: After creating a new GGSN instance, it is in `shutdown` mode. See
 | 
				
			||||||
 | 
					<<unshutdown_apn>> to take it out of shutdown, but make sure to configure it fully
 | 
				
			||||||
 | 
					before taking it out of shutdown.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Configuring a GGSN instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following two mandatory configuration statements have to be given
 | 
				
			||||||
 | 
					for every GGSN instance:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# gtp state-dir /var/lib/osmocom/osmo-ggsn <1>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# gtp bind-ip 127.0.0.6 <2>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Store the GSN restart state in the specified directory
 | 
				
			||||||
 | 
					<2> Bind the GGSN instance to the specified local IPv4 address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are some further configuration statements that can be used at the
 | 
				
			||||||
 | 
					GGSN node, some examples are given below.  For a full list, see the
 | 
				
			||||||
 | 
					_OsmoGGSN VTY reference manual_ <<vty-ref-osmoggsn>>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# default-apn foobar <1>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Configure a default APN to be used if the user-requested APN is not
 | 
				
			||||||
 | 
					    found.  The named APN must previously be configured
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Deleting a GGSN instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A GGSN instance can be removed like this
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Deleting a GGSN instance
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN> enable <1>
 | 
				
			||||||
 | 
					OsmoGGSN# configure terminal <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config)# no ggsn ggsn0 <3>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Change into privileged mode
 | 
				
			||||||
 | 
					<2> Enter the interactive configuration mode
 | 
				
			||||||
 | 
					<3> Delete the GGSN instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Taking a GGSN instance out of shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Taking a GGSN instance out of shutdown
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN> enable <1>
 | 
				
			||||||
 | 
					OsmoGGSN# configure terminal <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config)# ggsn ggsn0 <3>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# no shutdown ggsn <4>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Change into privileged mode
 | 
				
			||||||
 | 
					<2> Enter the interactive configuration mode
 | 
				
			||||||
 | 
					<3> Enter the config node of the GGSN instance `ggsn0`
 | 
				
			||||||
 | 
					<4> Take the GGSN instance out of shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Shutting a GGSN instance down
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you would like to take a GGSN instance out of service, you can
 | 
				
			||||||
 | 
					put it into shutdown mode.  This will make the entire GGSN unavailable
 | 
				
			||||||
 | 
					to user traffic and permit you to e.g. reconfigure it before taking it
 | 
				
			||||||
 | 
					out of shutdown again.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Shutting down a GGSN instance
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN> enable <1>
 | 
				
			||||||
 | 
					OsmoGGSN# configure terminal <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config)# ggsn ggsn0 <3>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# shutdown ggsn <4>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Change into privileged mode
 | 
				
			||||||
 | 
					<2> Enter the interactive configuration mode
 | 
				
			||||||
 | 
					<3> Enter the config node of the GGSN instance `ggsn0`
 | 
				
			||||||
 | 
					<4> Shut down the GGSN instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Configuring an Access Point Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					An Access Point Name (APN) represents a connection to an external packet
 | 
				
			||||||
 | 
					data network, such as the public Internet or private corporate networsk.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					APNs are selected by terminals (MS/UE) when establishing PDP contexts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Each OsmoGGSN GGSN instance can have any number of APNs configured.
 | 
				
			||||||
 | 
					Each APN is identified by a string name.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Creating/Editing an APN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Creating a new APN
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN> enable <1>
 | 
				
			||||||
 | 
					OsmoGGSN# configure terminal <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config)# ggsn ggsn0 <3>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# apn internet <4>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# <5>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Change into privileged mode
 | 
				
			||||||
 | 
					<2> Enter the interactive configuration mode
 | 
				
			||||||
 | 
					<3> Enter the config node of the GGSN instance `ggsn0`
 | 
				
			||||||
 | 
					<4> Create or Edit an APN called `internet`
 | 
				
			||||||
 | 
					<5> Your prompt is now in the `ggsn` config node, where you can
 | 
				
			||||||
 | 
					    configure the properties of this GGSN instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOTE:: The newly-create APN is created in `shutdown` mode. See <<unshutdown_apn>> to take it
 | 
				
			||||||
 | 
					out of shutdown.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Configuring an APN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Configuring an APN
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# gtpu-mode tun <1>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# type-support v4 <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# mtu 1420 apply <3>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# ip prefix dynamic 176.16.222.0/24 <4>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# ip dns 0 192.168.100.1 <5>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# ip dns 1 8.8.8.8 <6>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# ip ifconfig 176.16.222.0/24 <7>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Use the userspace GTP-U handling using a TUN device
 | 
				
			||||||
 | 
					<2> Support (only) IPv4 Addresses
 | 
				
			||||||
 | 
					<3> Specify MTU to announce to MS. Apply the MTU on the tunnel interface.
 | 
				
			||||||
 | 
					<4> Specify the pool of dynamic IPv4 addresses to be allocated to PDP
 | 
				
			||||||
 | 
					    contexts
 | 
				
			||||||
 | 
					<5> Specify the primary DNS server to be provided using IPCP/PCO
 | 
				
			||||||
 | 
					<6> Specify the secondary DNS server to be provided using IPCP/PCO
 | 
				
			||||||
 | 
					<7> Request OsmoGGSN to configure the `tun4` device network/netmask
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOTE:: If you use the optional `ip ifconfig` command to set the network
 | 
				
			||||||
 | 
					device address/mask, OsmoGGSN must run with root or `CAP_NET_ADMIN`
 | 
				
			||||||
 | 
					support.  It might be better to configure related tun devices at system
 | 
				
			||||||
 | 
					startup and run OsmoGGSN as non-privileged user.  See <<ggsn_no_root>> for more
 | 
				
			||||||
 | 
					details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Deleting an APN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					An APN configuration can be removed like this
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Deleting an APN
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN> enable <1>
 | 
				
			||||||
 | 
					OsmoGGSN# configure terminal <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config)# ggsn ggsn0 <3>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# no apn internet <4>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Change into privileged mode
 | 
				
			||||||
 | 
					<2> Enter the interactive configuration mode
 | 
				
			||||||
 | 
					<3> Enter the config node of the GGSN instance `ggsn0`
 | 
				
			||||||
 | 
					<4> Delete the APN `internet`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[unshutdown_apn]]
 | 
				
			||||||
 | 
					==== Taking an APN out of shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In order to bring a deactived APN in `shutdown` state into active
 | 
				
			||||||
 | 
					operation, use the `no shutdown` command at the APN node as explained in
 | 
				
			||||||
 | 
					the following example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Taking an APN out of shutdown
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN> enable <1>
 | 
				
			||||||
 | 
					OsmoGGSN# configure terminal <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config)# ggsn ggsn0 <3>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# apn internet <4>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# no shutdown <5>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Change into privileged mode
 | 
				
			||||||
 | 
					<2> Enter the interactive configuration mode
 | 
				
			||||||
 | 
					<3> Enter the config node of the GGSN instance `ggsn0`
 | 
				
			||||||
 | 
					<4> Enter the config node of the APN `internet`
 | 
				
			||||||
 | 
					<5> Take the APN out of shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Shutting an APN down
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you would like to take an APN instance out of service, you can
 | 
				
			||||||
 | 
					put it into shutdown mode.  This will make the APN unavailable
 | 
				
			||||||
 | 
					to user traffic and permit you to e.g. reconfigure it before taking it
 | 
				
			||||||
 | 
					out of shutdown again.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Shutting down an APN
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					OsmoGGSN> enable <1>
 | 
				
			||||||
 | 
					OsmoGGSN# configure terminal <2>
 | 
				
			||||||
 | 
					OsmoGGSN(config)# ggsn ggsn0 <3>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn)# apn internet <4>
 | 
				
			||||||
 | 
					OsmoGGSN(config-ggsn-apn)# shutdown <5>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> Change into privileged mode
 | 
				
			||||||
 | 
					<2> Enter the interactive configuration mode
 | 
				
			||||||
 | 
					<3> Enter the config node of the GGSN instance `ggsn0`
 | 
				
			||||||
 | 
					<4> Enter the config node of the APN `internet`
 | 
				
			||||||
 | 
					<5> Shut down the APN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[ggsn_no_root]]
 | 
				
			||||||
 | 
					=== Configuring for running without root privileges
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It's possible to run OsmoGGSN without root privileges if the tun devices are already configured.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The interface creation + configuration must then happen before osmo-ggsn starting up.  This can be
 | 
				
			||||||
 | 
					achieved by means such as
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* a custom shell script run as root before starting osmo-ggsn (e.g. as init script)
 | 
				
			||||||
 | 
					* systemd .netdev and .network files, if your system is using systemd-networkd (see `networkctl status`).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Manual TUN device creation / configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you chose to go for custom shell/init scripts, you may use the `ip` program which is the standard
 | 
				
			||||||
 | 
					tool for network interface configuration on Linux, part of the `iproute2` package.  In order to
 | 
				
			||||||
 | 
					create a tun device, you must call it like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: iproute2 command to create a tun device
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					# ip tuntap add dev apn0 mode tun user username group groupname
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Where _username_ and _groupname_ correspond to the User and Group that will have ownership over the
 | 
				
			||||||
 | 
					device, i.e. the privileges which you intend to run osmo-ggsn under, and _apn0_ will be the
 | 
				
			||||||
 | 
					name of the network device created.  After creating the interface, you can configure its addresses
 | 
				
			||||||
 | 
					using standard means like `ip addr add` or your distribution-specific utilities/tools
 | 
				
			||||||
 | 
					to match the `ip prefix dynamic` config item, and activate the link, for example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					# ip addr add 192.168.7.1/24 dev apn0
 | 
				
			||||||
 | 
					# ip link set mtu 1420 dev apn0
 | 
				
			||||||
 | 
					# ip link set apn0 up
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== systemd based TUN device creation+configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to have systemd take care of creating and configuring a tun device for you,
 | 
				
			||||||
 | 
					you can use the below example config files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: device config via systemd-networkd using apn0.netdev
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					[NetDev]
 | 
				
			||||||
 | 
					Name=apn0 <1>
 | 
				
			||||||
 | 
					Kind=tun
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Tun]
 | 
				
			||||||
 | 
					User=username <2>
 | 
				
			||||||
 | 
					Group=username <3>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> The network interface name of the newly-created device
 | 
				
			||||||
 | 
					<2> The username under which you will run OsmoGGSN
 | 
				
			||||||
 | 
					<3> The group name under which you will run OsmoGGSN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: network settings via systemd-networkd using ggsn.network
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					[Match]
 | 
				
			||||||
 | 
					Name=apn0 <1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Link]
 | 
				
			||||||
 | 
					MTUBytes=1420 <2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Network]
 | 
				
			||||||
 | 
					Address=192.168.7.1/24 <3>
 | 
				
			||||||
 | 
					IPMasquerade=yes <4>
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					<1> The network device name, which must match the one in the apn0.netdev unit file above
 | 
				
			||||||
 | 
					<2> Requesting systemd to set the MTU for this interface. The MTU of the tun
 | 
				
			||||||
 | 
					    interface should be lower than regular, since it must accommodate the extra IP/UDP/GTPv1U headers.
 | 
				
			||||||
 | 
					<3> The local IP address configured on the device
 | 
				
			||||||
 | 
					<4> Requesting systemd to configure IP masquerading for this interface.  Depending on your needs,
 | 
				
			||||||
 | 
					    You may not want this if you have proper end-to-end routing set up, and want to have transparent
 | 
				
			||||||
 | 
					    inbound IP access to your GPRS-attached devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Config Changes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With the tun device pre-configured in one of the ways outlined above, the main
 | 
				
			||||||
 | 
					changes in your osmo-ggsn.cfg file are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* remove `ip ifconfig` directive,
 | 
				
			||||||
 | 
					* make sure that `no shutdown` is present in the `apn` section as well as
 | 
				
			||||||
 | 
					  `no shutdown ggsn` in the `ggsn` section.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: using externally configured tun device `apn0` as non-root
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					ggsn ggsn0
 | 
				
			||||||
 | 
					 gtp state-dir /tmp
 | 
				
			||||||
 | 
					 gtp bind-ip 127.0.0.6
 | 
				
			||||||
 | 
					 apn internet
 | 
				
			||||||
 | 
					  gtpu-mode tun
 | 
				
			||||||
 | 
					  tun-device apn0
 | 
				
			||||||
 | 
					  type-support v4
 | 
				
			||||||
 | 
					  mtu 1420
 | 
				
			||||||
 | 
					  ip prefix dynamic 192.168.7.0/24
 | 
				
			||||||
 | 
					  ip dns 0 192.168.100.1
 | 
				
			||||||
 | 
					  ip dns 1 8.8.8.8
 | 
				
			||||||
 | 
					  no shutdown
 | 
				
			||||||
 | 
					 default-apn internet
 | 
				
			||||||
 | 
					 no shutdown ggsn
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
							
								
								
									
										171
									
								
								doc/manuals/chapters/mtu.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								doc/manuals/chapters/mtu.adoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
				
			|||||||
 | 
					=== MTU considerations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When running OsmoGGSN, the user may want to take network Maximum Transmission
 | 
				
			||||||
 | 
					Unit (MTU) into consideration, and configure it based on network specific setup.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Applying and announcing a proper MTU provides, for the MS employing it, reduced
 | 
				
			||||||
 | 
					transmission overhead (ie. due to IP fragmentation) and avoids potential
 | 
				
			||||||
 | 
					problems due to misconfigured nodes in the path (e.g. ICMP packet filtering).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In OsmoGGSN, the MTU can be configured per APN through the VTY, see
 | 
				
			||||||
 | 
					<<osmoggsn_configuring>>. If told so by the config, osmo-ggsn will apply the MTU
 | 
				
			||||||
 | 
					on the APN network interface.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== MTU announced to MS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The configured MTU is also announced to the MS through:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* IPv4 APN: GTPv1C Create PDP Context Response, PCO IE "IPv4 Link MTU", 3GPP TS
 | 
				
			||||||
 | 
					  24.008 Table 10.5.154.
 | 
				
			||||||
 | 
					* IPv6 APN: ICMPv6 Routing Advertisement during IPv6 SLAAC procedure, RFC 4861.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOTE: It is up to the MS to request and use the link MTU size provided by the
 | 
				
			||||||
 | 
					network. Hence, providing an MTU size does not guarantee that there will be no
 | 
				
			||||||
 | 
					packets larger than the provided value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== GTP-U tunnel overhead
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN is encapsulating traffic over GTP-U, it means the packets being received,
 | 
				
			||||||
 | 
					encapsulated and transmitted over the tunnel get their size increased by the sum of
 | 
				
			||||||
 | 
					IP/UDP/GTPv1U headers being prepended:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* IP: IPv4 headers can take up to 60 bytes (due to IPv4 options). IPv6 headers
 | 
				
			||||||
 | 
					  can take up to 40 bytes (assuming no extension headers for IPv6 in general,
 | 
				
			||||||
 | 
					  since they are uncommon). Hence, the 60 bytes of IPv4 are picked since that's
 | 
				
			||||||
 | 
					  greater than the IPv4.
 | 
				
			||||||
 | 
					* UDP: The UDP header takes 8 bytes.
 | 
				
			||||||
 | 
					* GTPv1U: The GTPv1U header takes 12 bytes, assuming here no extensions headers
 | 
				
			||||||
 | 
					  are used (OsmoGGSN doesn't use them).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Hence, these headers add an overhead of up to `80`` bytes, as per the below formula:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					GTPv1U_OVERHEAD = 60 + 8 + 12 = 80 bytes
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Figuring out optimal MTU value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is no golden MTU value, since it really depends on the local (and remote)
 | 
				
			||||||
 | 
					networks where traffic is routed. The idea is finding out a value that:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Is as big as possible, to avoid need to split big chunks of data into lots of
 | 
				
			||||||
 | 
					  small packets, hence affecting performance due to processing overhead: extra
 | 
				
			||||||
 | 
					  headers being trnasmitted, plus processing of extra packets.
 | 
				
			||||||
 | 
					* Is small enough so that it can be transported over the lower layers of the
 | 
				
			||||||
 | 
					  links involving the communication, avoiding IP fragmentation, which again hurts
 | 
				
			||||||
 | 
					  performance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN, by default, assumes that traffic is transported over an Ethernet
 | 
				
			||||||
 | 
					network, which has a standarized maximum MTU of 1500 bytes. Hence, by default it
 | 
				
			||||||
 | 
					announces an MTU of of `1420` bytes as per the following formula:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					TUNNEL_MTU = ETH_MTU - GTPv1U_OVERHEAD = 1500 - 80 = 1420 bytes
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Under certain networks, the base MTU may already be smaller than Ethernet's MTU
 | 
				
			||||||
 | 
					(1500 bytes), due to, for instance, existence of some sort of extra tunneling
 | 
				
			||||||
 | 
					protocol in the path, such as a VPN, ipsec, extra VLAN levels, etc. Under this
 | 
				
			||||||
 | 
					scenario, the user must take care of figuring out the new base MTU value to use
 | 
				
			||||||
 | 
					for the calculations presented above. This can be accomplished by packet
 | 
				
			||||||
 | 
					inspection (eg. `wireshark`) or with tools such as `ping`, running it with a
 | 
				
			||||||
 | 
					certain packet size and the IPv4 DF bit set, and see up to which packet size the
 | 
				
			||||||
 | 
					networks is able to forward the message.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Test if packets of 1420 bytes can reach peer host 176.16.222.4
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					$ ping -M probe 176.16.222.4 -s 1420
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Increasing outer MTU
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Specifications at IEEE 802.3 establish that standard Ethernet has a maximum MTU
 | 
				
			||||||
 | 
					of `1500` bytes.
 | 
				
			||||||
 | 
					However, many Ethernet controllers can nowadays overcome this limit and allow
 | 
				
			||||||
 | 
					the use of so called _jumbo frames_. The _jumbo frames_ maximum MTU varies
 | 
				
			||||||
 | 
					depending on the implementation, with `9000` bytes being a commonly used limit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that using MTUs over the standarized `1500` bytes by means of _jumbo frames_
 | 
				
			||||||
 | 
					can create interoperability problems with networks not supporting such frames
 | 
				
			||||||
 | 
					(eg. forcing of IP packet fragmentation), plus the fact that larger frames
 | 
				
			||||||
 | 
					consume more Ethernet link transmission time, causing greater delays and
 | 
				
			||||||
 | 
					increasing latency.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Nevertheless, if the operator:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* is in control of the whole GTP-U path between OsmoGGSN and the MS, and
 | 
				
			||||||
 | 
					* has Ethernet NICs supporting MTUs bigger than 1500 or uses any other link
 | 
				
			||||||
 | 
					  layer supporting as well bigger MTUs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then, it may be wise for the operator to configure such links with an increased
 | 
				
			||||||
 | 
					outer MTU so that they can end up transporting GTP-U inner payload of 1500 bytes
 | 
				
			||||||
 | 
					without fragmentation ocurring.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Hence, following the examples presented on the above sections, one could
 | 
				
			||||||
 | 
					configure *all the links* which are part of the GTP-U path to use an outer MTU
 | 
				
			||||||
 | 
					of `1580` bytes, as per the following formula:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					TUNNEL_MTU = ETH_MTU + GTPv1U_OVERHEAD = 1500 + 80 = 1580 bytes
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Setting an MTU of `1580` to network interface `eth0` under Linux
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					ip link set mtu 1580 dev eth0
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== TCP MSS Clamping
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Usually endpoints use Path MTU Discovery (PMTUD) to determine the maximum MTU to
 | 
				
			||||||
 | 
					reach the peer. However, this technique may sometimes not be optimal for all
 | 
				
			||||||
 | 
					users of OsmoGGSN:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* MS may not support requesting and/or configuring the MTU OsmoGGSN announced.
 | 
				
			||||||
 | 
					* MS may not support PMTUD on its network stack, or may not have it enabled or
 | 
				
			||||||
 | 
					  may be buggy.
 | 
				
			||||||
 | 
					* Network may be misconfigured or some middlebox may be buggy (eg. not
 | 
				
			||||||
 | 
					  forwarding ICMP `Packet Too Big` packets).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Furthermore, PMTUD takes time to figure out the maximum MTU to use, since it
 | 
				
			||||||
 | 
					relies on sending data and checking if it got lost, and adapting to the fact,
 | 
				
			||||||
 | 
					reducing efficiency (throughput) of connections or even stalling them completely
 | 
				
			||||||
 | 
					when big packets are generated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Hence, it may become useful for the operator of OsmoGGSN to, on top of MTU
 | 
				
			||||||
 | 
					configuration, also configure its network to tune TCP Maximum Segment Size (MSS)
 | 
				
			||||||
 | 
					option of TCP connections being established over the GTPv1U tunnel. This will
 | 
				
			||||||
 | 
					make sure at least TCP connections can use the full capacity of the path MTU
 | 
				
			||||||
 | 
					without passing its imit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The MSS TCP option is an optional parameter in the TCP header sent during TCP
 | 
				
			||||||
 | 
					initial handshake (`SYN,SYN/ACK`) that specifies the maximum amount of bytes of
 | 
				
			||||||
 | 
					TCP payload a TCP chunk may transport. The MSS value doesn't count the
 | 
				
			||||||
 | 
					underlaying IP/TCP headers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Hence, following up on MTU size calculations from previous section, with a
 | 
				
			||||||
 | 
					sample GTPv1U MTU of 1420 bytes and IP header of 60 bytes, plus taking into
 | 
				
			||||||
 | 
					account that TCP header can span up to 56 bytes, we'd get to an MSS value of:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					MSS = TUNNEL_MTU - IP_HDR - TCP_HDR = 1420 - 60 - 56 = 1304
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In linux, the MSS of TCP connections can be clamped using nftables:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					nft 'add rule ip nat prerouting iifname "apn0" tcp flags syn / syn,rst counter tcp option maxseg size set 1304'
 | 
				
			||||||
 | 
					nft 'insert rule ip nat postrouting oifname "apn0" tcp flags syn / syn,rst counter tcp option maxseg size set 1304'
 | 
				
			||||||
 | 
					nft 'add rule ip6 nat prerouting iifname "apn0" tcp flags syn / syn,rst counter tcp option maxseg size set 1304'
 | 
				
			||||||
 | 
					nft 'insert rule ip6 nat postrouting oifname "apn0" tcp flags syn / syn,rst counter tcp option maxseg size set 1304'
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== Further Reading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Check the following specs regarding MTU in 3GPP mobile networks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* 3GPP TS 29.061 section 11.2.1.5
 | 
				
			||||||
 | 
					* 3GPP TS 290.060 section 13.2 IP Fragmentation
 | 
				
			||||||
 | 
					* 3GPP TS 25.414 section 6.1.3.3
 | 
				
			||||||
 | 
					* 3GPP TS 23.060 section 9.3, Annex C
 | 
				
			||||||
 | 
					* 3GPP TS 24.008 (PCO IPv4 MTU)
 | 
				
			||||||
 | 
					* RFC 4861 (IPv6 Router Advertisement)
 | 
				
			||||||
							
								
								
									
										140
									
								
								doc/manuals/chapters/overview.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								doc/manuals/chapters/overview.adoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
				
			|||||||
 | 
					[[chapter_introduction]]
 | 
				
			||||||
 | 
					== Overview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[intro_overview]]
 | 
				
			||||||
 | 
					=== About OsmoGGSN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN is a Free / Open Source Software implementation of the GPRS
 | 
				
			||||||
 | 
					GGSN (Gateway GPRS support node) element in side the packet switched
 | 
				
			||||||
 | 
					core network of 2G and 3G cellular networks.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The GGSN function is the tunnel endpoint on the core network side,
 | 
				
			||||||
 | 
					from where the external (IP) packet data network
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Software Components
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== GTP Implementation (libgtp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The OsmoGGSN source code includes a shared library implementation of
 | 
				
			||||||
 | 
					the GTP protocol used on the GGSN-SGSN interface.  This library
 | 
				
			||||||
 | 
					and associated header files are installed system-wide and are
 | 
				
			||||||
 | 
					available to other programs/applications.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In fact, libgtp is what the OsmoSGSN also uses for its use of GTP.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== sgsnemu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In order to test OsmoGGSN without running a SGSN and other elements
 | 
				
			||||||
 | 
					of a cellular network, there is a small command-line utility called
 | 
				
			||||||
 | 
					*sgsnemu* which is able to simulate the customary operations of a SGSN
 | 
				
			||||||
 | 
					towards the GGSN, such as a PDP Context Activation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*sgsnemu* can even be used for testing against other GGSNs, as the GTP
 | 
				
			||||||
 | 
					protocol is standardized across implementations.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== osmo-ggsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*osmo-ggsn* is the actual name of the OsmoGGSN executable program.  It
 | 
				
			||||||
 | 
					implements the GGSN functionality.  All parameters are set using the
 | 
				
			||||||
 | 
					configuration file, by default located in *./osmo-ggsn.cfg*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== systemd service file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In *contrib/osmo-ggsn.service* you can find a sample service file for
 | 
				
			||||||
 | 
					OsmoGGSN which can be used with systemd.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Limitations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN supports both GTP0 (GSM 09.60) and GTP1 (3GPP 29.060). In the
 | 
				
			||||||
 | 
					following tables the support of each individual message type is
 | 
				
			||||||
 | 
					detailed. The numbers before each feature indicates the relevant
 | 
				
			||||||
 | 
					section in the standard.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== GSM 09.60 (GTPv0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[options="header",cols="50%,15%,15%,15%,5%"]
 | 
				
			||||||
 | 
					|===
 | 
				
			||||||
 | 
					| Feature                | gtplib      | osmo-ggsn   | sgsnemu     | notes
 | 
				
			||||||
 | 
					5+<|*7.4 Path Management Messages*
 | 
				
			||||||
 | 
					|7.4.1 Echo Request      |Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.4.2 Echo Response     |Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.4.3 Version Not Supported      |Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					5+<| *7.5 Tunnel Management Messages*
 | 
				
			||||||
 | 
					|7.5.1 Create PDP Context Request|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.5.2 Create PDP Context Response|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.5.3 Update PDP Context Request|Supported   |Supported   |Not         |
 | 
				
			||||||
 | 
					|7.5.4 Update PDP Context Response|Supported   |Supported   |Not         |
 | 
				
			||||||
 | 
					|7.5.5 Delete PDP Context Request|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.5.6 Delete PDP Context Response|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.5.7 Create AA PDP Context Request|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.5.8 Create AA PDP Response|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.5.9 Delete AA PDP Context Request|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.5.10 Delete AA PDP Context Response|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.5.11 Error Indication |Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.5.12 PDU Notification Request|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.5.13 PDU Notification Response|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.5.14 PDU Notification Reject Request|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.5.15 PDU Notification Reject Response|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					5+<| *7.6 Location Management Messages*
 | 
				
			||||||
 | 
					|7.6.1 Send Routeing Information for GPRS Request|Unsupported |Unsupported |Not applicable  |
 | 
				
			||||||
 | 
					|7.6.2 Send Routeing Information for GPRS Response|Unsupported |Unsupported |Not applicable  |
 | 
				
			||||||
 | 
					|7.6.3 Failure Report Request|Unsupported |Unsupported |Not applicable |
 | 
				
			||||||
 | 
					|7.6.3 Failure Report Response|Unsupported |Unsupported |Not applicable |
 | 
				
			||||||
 | 
					|7.6.5 Note MS GPRS Present Request|Unsupported |Unsupported |Not applicable|
 | 
				
			||||||
 | 
					|7.6.6 Note MS GPRS Present Response|Unsupported |Unsupported |Not applicable|
 | 
				
			||||||
 | 
					5+<| *7.5 Mobility Management Messages*
 | 
				
			||||||
 | 
					|7.5.1 Identification Request|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.2 Identification Response|Unsupported |Not applicable|Not applicable |
 | 
				
			||||||
 | 
					|7.5.3 SGSN Context Request|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.4 SGSN Context Response|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.5 SGSN Context Acknowledge|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== 3GPP 29.060 (GTPv1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[options="header",cols="50%,15%,15%,15%,5%"]
 | 
				
			||||||
 | 
					|===
 | 
				
			||||||
 | 
					|Feature                 |gtplib      |osmo-ggsn   |sgsnemu     |notes
 | 
				
			||||||
 | 
					5+<|*7.2 Path Management Messages*
 | 
				
			||||||
 | 
					|7.2.1 Echo Request      |Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.2.2 Echo Response     |Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.2.3 Version Not Supported|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.2.4 Extension Headers Notification|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					5+<|*7.3 Tunnel Management Messages*
 | 
				
			||||||
 | 
					|7.3.1 Create PDP Context Request|Supported   |Supported   |Supported   |1
 | 
				
			||||||
 | 
					|7.3.2 Create PDP Context Response|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.3.3 Update PDP Context Request|Supported   |Supported   |Not applicable|1
 | 
				
			||||||
 | 
					|7.3.4 Update PDP Context Response|Supported   |Supported   |Not applicable|
 | 
				
			||||||
 | 
					|7.3.5 Delete PDP Context Request|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.3.6 Delete PDP Context Response|Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.3.7 Error Indication  |Supported   |Supported   |Supported   |
 | 
				
			||||||
 | 
					|7.3.8 PDU Notification Request|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.3.9 PDU Notification Response|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.3.10 PDU Notification Reject Request|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					|7.3.10 PDU Notification Reject Response|Unsupported |Unsupported |Unsupported |
 | 
				
			||||||
 | 
					5+<|*7.4 Location Management Messages*
 | 
				
			||||||
 | 
					|7.4.1 Send Routeing Information for GPRS Request|Unsupported |Unsupported |Not applicable  |
 | 
				
			||||||
 | 
					|7.4.2 Send Routeing Information for GPRS Response|Unsupported |Unsupported |Not applicable  |
 | 
				
			||||||
 | 
					|7.4.3 Failure Report Request|Unsupported |Unsupported |Not applicable|
 | 
				
			||||||
 | 
					|7.4.3 Failure Report Response|Unsupported |Unsupported |Not applicable|
 | 
				
			||||||
 | 
					|7.4.5 Note MS GPRS Present Request|Unsupported |Unsupported |Not applicable|
 | 
				
			||||||
 | 
					|7.4.6 Note MS GPRS Present Response|Unsupported |Unsupported |Not applicable|
 | 
				
			||||||
 | 
					5+<|*7.5 Mobility Management Messages*
 | 
				
			||||||
 | 
					|7.5.1 Identification Request|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.2 Identification Response|Unsupported |Not applicable |Not applicable|
 | 
				
			||||||
 | 
					|7.5.3 SGSN Context Request|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.4 SGSN Context Response|Unsupported |Not applicable |Not applicable|
 | 
				
			||||||
 | 
					|7.5.5 SGSN Context Acknowledge|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.6 Forward Relocation Request|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.7 Forward Relocation Response|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.8 Forward Relocation Complete|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.9 Relocation Cancel Request|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.10 Relocation Cancel Response|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.11 Forward Relocation Complete     |Unsupported |Not applicable |Not applicable  |
 | 
				
			||||||
 | 
					|7.5.12 Forward SRNS Context Acknowledge|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|7.5.13 Forward SRNS Context|Unsupported |Not applicable|Not applicable|
 | 
				
			||||||
 | 
					|===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Notes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1) The "Secondary PDP Context Activation Procedure" is not supported.
 | 
				
			||||||
							
								
								
									
										133
									
								
								doc/manuals/chapters/running.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								doc/manuals/chapters/running.adoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
				
			|||||||
 | 
					== Running OsmoGGSN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The OsmoGGSN executable (`osmo-ggsn`) offers the following command-line
 | 
				
			||||||
 | 
					arguments:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== SYNOPSIS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*osmo-ggsn* [-h|-V] [-D] [-c 'CONFIGFILE']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== OPTIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*-h, --help*::
 | 
				
			||||||
 | 
						Print a short help message about the supported options
 | 
				
			||||||
 | 
					*-V, --version*::
 | 
				
			||||||
 | 
						Print the compile-time version number of the program
 | 
				
			||||||
 | 
					*-D, --daemonize*::
 | 
				
			||||||
 | 
						Fork the process as a daemon into background.
 | 
				
			||||||
 | 
					*-c, --config-file 'CONFIGFILE'*::
 | 
				
			||||||
 | 
						Specify the file and path name of the configuration file to be
 | 
				
			||||||
 | 
						used. If none is specified, use `osmo-ggsn.cfg` in the current
 | 
				
			||||||
 | 
						working directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Routing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Operating the OpenGGSN tun device naturally creates a network setup with
 | 
				
			||||||
 | 
					multiple interfaces. Consider:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Typical Linux setups prevent forwarding of packets between separate
 | 
				
			||||||
 | 
					  interfaces by default. To let subscribers reach the internet uplink from the
 | 
				
			||||||
 | 
					  tun device, it may be required to enable IP forwarding.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Having a locally defined address range assigned to the tun device requires
 | 
				
			||||||
 | 
					  either sensible routing for this address range, or that masquerading is
 | 
				
			||||||
 | 
					  enabled to allow your single uplink IP address to "proxy" for the tun.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These are decisions to be made on a network administration level.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In a trivial case where you have a single box serving GPRS to few subscribers
 | 
				
			||||||
 | 
					on an arbitrary IP address range not known in the larger network, the easiest
 | 
				
			||||||
 | 
					way to enable GPRS uplink would be to enable IP forwarding and masquerading.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To manually enable IPv4 forwarding and masquerading ad-hoc, you can do:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
 | 
				
			||||||
 | 
					nft 'add rule ip nat postrouting oifname "\*" counter masquerade'
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(You may want to replace `*` with the network device name, like `-o eth0`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are various ways to enable these settings persistently, please refer to
 | 
				
			||||||
 | 
					your distribution's documentation -- e.g. look for @net.ipv4.ip_forward=1@ in
 | 
				
			||||||
 | 
					@/etc/sysctl.d/@, and https://wiki.debian.org/nftables for masquerading.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::{srcdir}/chapters/mtu.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Multiple instances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Running multiple instances of `osmo-ggsn` is possible if all GGSN instances
 | 
				
			||||||
 | 
					are binding to different local IP addresses and all other interfaces (VTY,
 | 
				
			||||||
 | 
					CTRL) are separated using the appropriate configuration options. The IP based
 | 
				
			||||||
 | 
					interfaces are binding to local host by default. In order to separate the
 | 
				
			||||||
 | 
					processes, the user has to bind those services to specific but different
 | 
				
			||||||
 | 
					IP addresses.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The VTY and the control interface can be bound to IP addresses from the loopback
 | 
				
			||||||
 | 
					address range.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: Binding VTY and control interface to a specific ip-address
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					line vty
 | 
				
			||||||
 | 
					 bind 127.0.0.2
 | 
				
			||||||
 | 
					ctrl
 | 
				
			||||||
 | 
					 bind 127.0.0.2
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also make sure to place each instance's GTP bind on a separate IP address (GTP
 | 
				
			||||||
 | 
					uses a port number that is fixed in the GTP specifications, so it will not be
 | 
				
			||||||
 | 
					possible to pick differing ports on the same IP address), like:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					ggsn ggsn0
 | 
				
			||||||
 | 
					 gtp bind-ip 127.0.0.2
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== GTP-U kernel module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WARNING: As of writing, IPv6 support for the kernel module has not been
 | 
				
			||||||
 | 
					         upstreamed yet (OS#1952).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WARNING: As of writing, it is not possible to configure multiple APNs with
 | 
				
			||||||
 | 
					         gtpu-mode kernel-gpt. This is a limitation in OsmoGGSN, not in the
 | 
				
			||||||
 | 
					         kernel module (OS#6106).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OsmoGGSN has support to use the Linux kernel GTP-U tunnel driver to accelerate
 | 
				
			||||||
 | 
					the data/user plane while still implementing the control plane (GTP-C) in
 | 
				
			||||||
 | 
					userspace in OsmoGGSN. The kernel module is included in Linux 4.7.0 and higher.
 | 
				
			||||||
 | 
					Notably the Debian GNU/Linux distribution has it enabled by default.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In order to use this feature, make sure that your Linux kernel was configured
 | 
				
			||||||
 | 
					to support it (`CONFIG_GTP=m` or `=y`). Furthermore, `osmo-ggsn` must have been
 | 
				
			||||||
 | 
					built with `./configure` argument `--enable-gtp-linux` (which requires libgtpnl
 | 
				
			||||||
 | 
					to be installed).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Load the kernel module with:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					$ sudo modprobe gtp
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then start OsmoGGSN with a configuration file that uses `gtpu-mode kernel-gtp`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A full example configuration is in `osmo-ggsn-kernel-gtp.cfg`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					$ sudo osmo-ggsn -c /usr/share/doc/osmo-ggsn/examples/osmo-ggsn-kernel-gtp.cfg
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Example: APN with kernel-gtp
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					ggsn ggsn0
 | 
				
			||||||
 | 
					 gtp state-dir /tmp
 | 
				
			||||||
 | 
					 gtp bind-ip 127.0.0.2
 | 
				
			||||||
 | 
					 apn internet
 | 
				
			||||||
 | 
					  gtpu-mode kernel-gtp
 | 
				
			||||||
 | 
					  tun-device tun4
 | 
				
			||||||
 | 
					  type-support v4
 | 
				
			||||||
 | 
					  ip prefix dynamic 172.16.222.0/24
 | 
				
			||||||
 | 
					  ip dns 0 8.8.8.8
 | 
				
			||||||
 | 
					  ip dns 1 8.8.4.4
 | 
				
			||||||
 | 
					  ip ifconfig 172.16.222.0/24
 | 
				
			||||||
 | 
					  no shutdown
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
							
								
								
									
										46
									
								
								doc/manuals/osmoggsn-usermanual-docinfo.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								doc/manuals/osmoggsn-usermanual-docinfo.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					<revhistory>
 | 
				
			||||||
 | 
					  <revision>
 | 
				
			||||||
 | 
					    <revnumber>1</revnumber>
 | 
				
			||||||
 | 
					    <date>August 2017</date>
 | 
				
			||||||
 | 
					    <authorinitials>HW</authorinitials>
 | 
				
			||||||
 | 
					    <revremark>
 | 
				
			||||||
 | 
					      Initial version.
 | 
				
			||||||
 | 
					    </revremark>
 | 
				
			||||||
 | 
					  </revision>
 | 
				
			||||||
 | 
					 </revhistory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<authorgroup>
 | 
				
			||||||
 | 
					  <author>
 | 
				
			||||||
 | 
					    <firstname>Harald</firstname>
 | 
				
			||||||
 | 
					    <surname>Welte</surname>
 | 
				
			||||||
 | 
					    <email>hwelte@sysmocom.de</email>
 | 
				
			||||||
 | 
					    <authorinitials>HW</authorinitials>
 | 
				
			||||||
 | 
					    <affiliation>
 | 
				
			||||||
 | 
					      <shortaffil>sysmocom</shortaffil>
 | 
				
			||||||
 | 
					      <orgname>sysmocom - s.f.m.c. GmbH</orgname>
 | 
				
			||||||
 | 
					      <jobtitle>Managing Director</jobtitle>
 | 
				
			||||||
 | 
					    </affiliation>
 | 
				
			||||||
 | 
					  </author>
 | 
				
			||||||
 | 
					</authorgroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<copyright>
 | 
				
			||||||
 | 
					  <year>2013-2017</year>
 | 
				
			||||||
 | 
					  <holder>sysmocom - s.f.m.c. GmbH</holder>
 | 
				
			||||||
 | 
					</copyright>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<legalnotice>
 | 
				
			||||||
 | 
					  <para>
 | 
				
			||||||
 | 
						Permission is granted to copy, distribute and/or modify this
 | 
				
			||||||
 | 
						document under the terms of the GNU Free Documentation License,
 | 
				
			||||||
 | 
						Version 1.3 or any later version published by the Free Software
 | 
				
			||||||
 | 
						Foundation; with no Invariant Sections, no Front-Cover Texts,
 | 
				
			||||||
 | 
						and no Back-Cover Texts.  A copy of the license is included in
 | 
				
			||||||
 | 
						the section entitled "GNU Free Documentation License".
 | 
				
			||||||
 | 
					  </para>
 | 
				
			||||||
 | 
					  <para>
 | 
				
			||||||
 | 
						The Asciidoc source code of this manual can be found at
 | 
				
			||||||
 | 
						<ulink url="http://git.osmocom.org/osmo-gsm-manuals/">
 | 
				
			||||||
 | 
							http://git.osmocom.org/osmo-gsm-manuals/
 | 
				
			||||||
 | 
						</ulink>
 | 
				
			||||||
 | 
					  </para>
 | 
				
			||||||
 | 
					</legalnotice>
 | 
				
			||||||
							
								
								
									
										30
									
								
								doc/manuals/osmoggsn-usermanual.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								doc/manuals/osmoggsn-usermanual.adoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					OsmoGGSN User Manual
 | 
				
			||||||
 | 
					====================
 | 
				
			||||||
 | 
					Harald Welte <hwelte@sysmocom.de>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/preface.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::{srcdir}/chapters/overview.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::{srcdir}/chapters/running.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//include::{srcdir}/chapters/control.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::{srcdir}/chapters/configuration.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/vty.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/logging.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/control_if.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/vty_cpu_sched.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/port_numbers.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/bibliography.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/glossary.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::./common/chapters/gfdl.adoc[]
 | 
				
			||||||
							
								
								
									
										38
									
								
								doc/manuals/osmoggsn-vty-reference.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								doc/manuals/osmoggsn-vty-reference.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<!--
 | 
				
			||||||
 | 
					  ex:ts=2:sw=42sts=2:et
 | 
				
			||||||
 | 
					  -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
 | 
				
			||||||
 | 
					-->
 | 
				
			||||||
 | 
					<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
 | 
				
			||||||
 | 
					"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
 | 
				
			||||||
 | 
					<!ENTITY chapter-vty      SYSTEM      "./common/chapters/vty.xml" >
 | 
				
			||||||
 | 
					<!ENTITY sections-vty     SYSTEM      "generated/docbook_vty.xml"  >
 | 
				
			||||||
 | 
					]>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<book>
 | 
				
			||||||
 | 
					  <info>
 | 
				
			||||||
 | 
					    <revhistory>
 | 
				
			||||||
 | 
					        <revision>
 | 
				
			||||||
 | 
					            <revnumber>v1</revnumber>
 | 
				
			||||||
 | 
					            <date>06th September 2017</date>
 | 
				
			||||||
 | 
					            <authorinitials>hw</authorinitials>
 | 
				
			||||||
 | 
					            <revremark>Initial version as of OsmoGGSN v1.0.0</revremark>
 | 
				
			||||||
 | 
					        </revision>
 | 
				
			||||||
 | 
					    </revhistory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <title>OsmoGGSN VTY Reference</title>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <copyright>
 | 
				
			||||||
 | 
					      <year>2017</year>
 | 
				
			||||||
 | 
					    </copyright>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <legalnotice>
 | 
				
			||||||
 | 
					      <para>This work is copyright by <orgname>sysmocom - s.f.m.c. GmbH</orgname>. All rights reserved.
 | 
				
			||||||
 | 
					      </para>
 | 
				
			||||||
 | 
					    </legalnotice>
 | 
				
			||||||
 | 
					  </info>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <!-- Main chapters-->
 | 
				
			||||||
 | 
					  &chapter-vty;
 | 
				
			||||||
 | 
					</book>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								doc/manuals/regen_doc.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								doc/manuals/regen_doc.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					#!/bin/sh -x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ -z "$DOCKER_PLAYGROUND" ]; then
 | 
				
			||||||
 | 
						echo "You need to set DOCKER_PLAYGROUND"
 | 
				
			||||||
 | 
						exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SCRIPT=$(realpath "$0")
 | 
				
			||||||
 | 
					MANUAL_DIR=$(dirname "$SCRIPT")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COMMIT=${COMMIT:-$(git log -1 --format=format:%H)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cd "$DOCKER_PLAYGROUND/scripts" || exit 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OSMO_GGSN_BRANCH=$COMMIT ./regen_doc.sh osmo-ggsn 4260 \
 | 
				
			||||||
 | 
						"$MANUAL_DIR/chapters/counters_generated.adoc" \
 | 
				
			||||||
 | 
						"$MANUAL_DIR/vty/ggsn_vty_reference.xml"
 | 
				
			||||||
							
								
								
									
										30
									
								
								doc/manuals/vty/ggsn_vty_additions.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								doc/manuals/vty/ggsn_vty_additions.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
 | 
				
			||||||
 | 
						<node id='config-line'>
 | 
				
			||||||
 | 
							<child_of nodeid='config' />
 | 
				
			||||||
 | 
							<name>Telnet/VTY Configuration Node</name>
 | 
				
			||||||
 | 
							<description>
 | 
				
			||||||
 | 
								Configure parameters of the Telnet/VTY Interface, such as to which IP address it should bind/listen to.
 | 
				
			||||||
 | 
							</description>
 | 
				
			||||||
 | 
						</node>
 | 
				
			||||||
 | 
						<node id='config-ctrl'>
 | 
				
			||||||
 | 
							<child_of nodeid='config' />
 | 
				
			||||||
 | 
							<name>CTRL Configuration Node</name>
 | 
				
			||||||
 | 
							<description>
 | 
				
			||||||
 | 
								Configure parameters of the CTRL Interface, such as to which IP address it should bind/listen to.
 | 
				
			||||||
 | 
							</description>
 | 
				
			||||||
 | 
						</node>
 | 
				
			||||||
 | 
						<node id='config-ggsn'>
 | 
				
			||||||
 | 
							<child_of nodeid='config' />
 | 
				
			||||||
 | 
							<name>GGSN Instance Configuration Node</name>
 | 
				
			||||||
 | 
							<description>
 | 
				
			||||||
 | 
								Configure an Instance of a (virtual) GGSN
 | 
				
			||||||
 | 
							</description>
 | 
				
			||||||
 | 
						</node>
 | 
				
			||||||
 | 
						<node id='config-ggsn-apn'>
 | 
				
			||||||
 | 
							<child_of nodeid='config-ggsn' />
 | 
				
			||||||
 | 
							<name>APN Configuration Node</name>
 | 
				
			||||||
 | 
							<description>
 | 
				
			||||||
 | 
								Configure an Access Point Name (APN) inside a GGSN Instance
 | 
				
			||||||
 | 
							</description>
 | 
				
			||||||
 | 
						</node>
 | 
				
			||||||
 | 
					</vtydoc>
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.\" * OpenGGSN - Gateway GPRS Support Node
 | 
					.\" * OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
.\" * Copyright (C) 2002, 2003 Mondru AB.
 | 
					.\" * Copyright (C) 2002, 2003 Mondru AB.
 | 
				
			||||||
.\" * 
 | 
					.\" * 
 | 
				
			||||||
.\" * The contents of this file may be used under the terms of the GNU
 | 
					.\" * The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
@@ -12,57 +12,37 @@
 | 
				
			|||||||
.\" * 
 | 
					.\" * 
 | 
				
			||||||
.\" * Contributor(s):
 | 
					.\" * Contributor(s):
 | 
				
			||||||
.\" * 
 | 
					.\" * 
 | 
				
			||||||
.\" Manual page for ggsn
 | 
					.\" Manual page for osmo-ggsn
 | 
				
			||||||
.\" SH section heading
 | 
					.\" SH section heading
 | 
				
			||||||
.\" SS subsection heading
 | 
					.\" SS subsection heading
 | 
				
			||||||
.\" LP paragraph
 | 
					.\" LP paragraph
 | 
				
			||||||
.\" IP indented paragraph
 | 
					.\" IP indented paragraph
 | 
				
			||||||
.\" TP hanging label
 | 
					.\" TP hanging label
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.TH ggsn 8 "July 2003"
 | 
					.TH osmo-ggsn 8 "August 2017"
 | 
				
			||||||
.SH NAME
 | 
					.SH NAME
 | 
				
			||||||
ggsn \- Gateway GPRS Support Node.
 | 
					osmo-ggsn \- Gateway GPRS Support Node.
 | 
				
			||||||
.SH SYNOPSIS
 | 
					.SH SYNOPSIS
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
\-\-help
 | 
					\-\-help
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
\-\-version
 | 
					\-\-version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
[
 | 
					[
 | 
				
			||||||
.BI \-\-fg
 | 
					.BI \-\-help
 | 
				
			||||||
] [
 | 
					] [
 | 
				
			||||||
.BI \-\-debug
 | 
					.BI \-\-daemonize
 | 
				
			||||||
] [
 | 
					] [
 | 
				
			||||||
.BI \-\-conf " file"
 | 
					.BI \-\-config-file " file"
 | 
				
			||||||
] [
 | 
					] [
 | 
				
			||||||
.BI \-\-pidfile " file"
 | 
					.BI \-\-version
 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-statedir " file" 
 | 
					 | 
				
			||||||
] [ 
 | 
					 | 
				
			||||||
.BI \-\-listen " host" 
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-net " net" 
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-ipup " script" 
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-ipdown " script" 
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-dynip " net" 
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-statip " net" 
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-pcodns1 " host" 
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-pcodns2 " host" 
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
.BI \-\-timelimit " seconds" 
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
.SH DESCRIPTION
 | 
					.SH DESCRIPTION
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
is part of the 
 | 
					is part of the 
 | 
				
			||||||
.B OpenGGSN
 | 
					.B OsmoGGSN
 | 
				
			||||||
project, and implements a Gateway GPRS Support Node. It is used by
 | 
					project, and implements a Gateway GPRS Support Node. It is used by
 | 
				
			||||||
mobile operators as the interface between the Internet and the rest of
 | 
					mobile operators as the interface between the Internet and the rest of
 | 
				
			||||||
the mobile network infrastructure.
 | 
					the mobile network infrastructure.
 | 
				
			||||||
@@ -82,14 +62,14 @@ over IP.
 | 
				
			|||||||
The other interface can be thought of as the uplink interface, and
 | 
					The other interface can be thought of as the uplink interface, and
 | 
				
			||||||
interfaces the GGSN to an external data network. Gi is most often an
 | 
					interfaces the GGSN to an external data network. Gi is most often an
 | 
				
			||||||
interface to the Internet.
 | 
					interface to the Internet.
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
uses the 
 | 
					uses the 
 | 
				
			||||||
.B TUN/TAP driver
 | 
					.B TUN/TAP driver
 | 
				
			||||||
for the Gi interface. A tun network interface is established when the
 | 
					for the Gi interface. A tun network interface is established when the
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
is started.
 | 
					is started.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.B ggsn 
 | 
					.B osmo-ggsn 
 | 
				
			||||||
will accept incoming connections from mobile stations through the
 | 
					will accept incoming connections from mobile stations through the
 | 
				
			||||||
radio access network and the SGSN. When a connection request is
 | 
					radio access network and the SGSN. When a connection request is
 | 
				
			||||||
received the ggsn will allocate a dynamic IP address for the mobile
 | 
					received the ggsn will allocate a dynamic IP address for the mobile
 | 
				
			||||||
@@ -99,7 +79,7 @@ the SGSN. Runtime errors are reported using the Osmocom logging
 | 
				
			|||||||
framework.
 | 
					framework.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Typically 
 | 
					Typically 
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
will be deployed with two Ethernet interfaces. One for the Gn/Gp
 | 
					will be deployed with two Ethernet interfaces. One for the Gn/Gp
 | 
				
			||||||
interface, and one for the Gi interface. Policy routing and firewall
 | 
					interface, and one for the Gi interface. Policy routing and firewall
 | 
				
			||||||
rules should be used in order to separate Gi traffic from Gn/Gp
 | 
					rules should be used in order to separate Gi traffic from Gn/Gp
 | 
				
			||||||
@@ -115,104 +95,35 @@ Print help and exit.
 | 
				
			|||||||
Print version and exit.
 | 
					Print version and exit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
.BI --fg
 | 
					.BI --daemonize
 | 
				
			||||||
Run in foreground (default = off)
 | 
					Run in background as a daemon (default = off)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.TP
 | 
					.TP
 | 
				
			||||||
.BI --debug
 | 
					.BI --config-file " file"
 | 
				
			||||||
Run in debug mode (default = off)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --conf " file"
 | 
					 | 
				
			||||||
Read configuration 
 | 
					Read configuration 
 | 
				
			||||||
.I file
 | 
					.I file
 | 
				
			||||||
(default = /etc/ggsn.conf) where each line corresponds to one command
 | 
					(default = ./openggsn.cfg)
 | 
				
			||||||
line option, but with the leading '--' removed. Command line options
 | 
					 | 
				
			||||||
override the options given in the configuration file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --pidfile " file"
 | 
					 | 
				
			||||||
Filename of process id 
 | 
					 | 
				
			||||||
.I file
 | 
					 | 
				
			||||||
(default = /var/run/ggsn.pid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --statedir " path"
 | 
					 | 
				
			||||||
.I path
 | 
					 | 
				
			||||||
to directory of nonvolatile data (default = /var/lib/ggsn/)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --listen " host"
 | 
					 | 
				
			||||||
Local interface IP address to use for the Gn/Gp interface. This option
 | 
					 | 
				
			||||||
must be specified. For security issues it is not possible to use
 | 
					 | 
				
			||||||
INADDR_ANY.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --net " net"
 | 
					 | 
				
			||||||
Network address of the Gi interface (default = 192.168.0.0/24). The
 | 
					 | 
				
			||||||
network address is set during initialisation when
 | 
					 | 
				
			||||||
.B ggsn
 | 
					 | 
				
			||||||
establishes a tun device for the Gi interface.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --ipup " script"
 | 
					 | 
				
			||||||
Script executed after the Gi tun network interface has been brought
 | 
					 | 
				
			||||||
up.  Executed with the following parameters: <devicename> <ip address>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --ipdown " script"
 | 
					 | 
				
			||||||
Script executed after the Gi tun network interface has been taken
 | 
					 | 
				
			||||||
down.  Executed with the following parameters: <devicename> <ip
 | 
					 | 
				
			||||||
address>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --dynip " net"
 | 
					 | 
				
			||||||
Dynamic IP address pool. Specifies a pool of dynamic IP addresses. If
 | 
					 | 
				
			||||||
this option is omitted the network address specified by the
 | 
					 | 
				
			||||||
.BI --net
 | 
					 | 
				
			||||||
option is used for dynamic IP address allocation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --pcodns1 " host"
 | 
					 | 
				
			||||||
PCO DNS Server 1 (default = 0.0.0.0). PCO stands for Protocol
 | 
					 | 
				
			||||||
Configuration options, and is part of the GPRS protocols. It is used
 | 
					 | 
				
			||||||
to inform the mobile station about the DNS address to use for host
 | 
					 | 
				
			||||||
name resolution.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --pcodns2 " host"
 | 
					 | 
				
			||||||
PCO DNS Server 2 (default = 0.0.0.0). PCO stands for Protocol
 | 
					 | 
				
			||||||
Configuration options, and is part of the GPRS protocols. It is used
 | 
					 | 
				
			||||||
to inform the mobile station about the DNS address to use for host
 | 
					 | 
				
			||||||
name resolution.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.TP
 | 
					 | 
				
			||||||
.BI --timelimit " seconds"
 | 
					 | 
				
			||||||
Exit 
 | 
					 | 
				
			||||||
.b ggsn
 | 
					 | 
				
			||||||
after \fIseconds\fP. Used for debugging.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.SH FILES
 | 
					.SH FILES
 | 
				
			||||||
.I /etc/ggsn.conf
 | 
					.I ./osmo-ggsn.cfg
 | 
				
			||||||
.RS
 | 
					.RS
 | 
				
			||||||
The configuration file for
 | 
					The configuration file for
 | 
				
			||||||
.B ggsn.
 | 
					.B osmo-ggsn.
 | 
				
			||||||
.RE
 | 
					.RE
 | 
				
			||||||
.I /var/run/ggsn.pid
 | 
					.I /var/run/osmo-ggsn.pid
 | 
				
			||||||
.RS
 | 
					.RS
 | 
				
			||||||
Process ID file.
 | 
					Process ID file.
 | 
				
			||||||
.RE
 | 
					.RE
 | 
				
			||||||
.I /var/lib/ggsn
 | 
					.I /var/lib/osmo-ggsn
 | 
				
			||||||
.RS
 | 
					.RS
 | 
				
			||||||
Directory holding nonvolatile data.
 | 
					Directory holding nonvolatile data.
 | 
				
			||||||
.RE
 | 
					.RE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.SH BUGS
 | 
					.SH BUGS
 | 
				
			||||||
Report all bugs to the OpenGGSN bug tracking list at 
 | 
					Report all bugs to the OsmoGGSN bug tracking list at 
 | 
				
			||||||
.I http://sourceforge.net/projects/ggsn/
 | 
					.I https://osmocom.org/projects/openggsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
has very limited management support. Currently both SNMP as well as
 | 
					has very limited management support. Currently both SNMP as well as
 | 
				
			||||||
billing mechanisms are missing.
 | 
					billing mechanisms are missing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -224,13 +135,13 @@ billing mechanisms are missing.
 | 
				
			|||||||
.LP
 | 
					.LP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Besides the long options documented in this man page
 | 
					Besides the long options documented in this man page
 | 
				
			||||||
.B ggsn
 | 
					.B osmo-ggsn
 | 
				
			||||||
also accepts a number of short options with the same functionality. Use
 | 
					also accepts a number of short options with the same functionality. Use
 | 
				
			||||||
.B ggsn --help
 | 
					.B osmo-ggsn --help
 | 
				
			||||||
for a full list of all the available options.
 | 
					for a full list of all the available options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The TUN/TAP driver is required for proper operation of
 | 
					The TUN/TAP driver is required for proper operation of
 | 
				
			||||||
.B ggsn. 
 | 
					.B osmo-ggsn. 
 | 
				
			||||||
For linux kernels later than 2.4.7 the TUN/TAP driver is included in the kernel, but typically needs to be loaded manually with
 | 
					For linux kernels later than 2.4.7 the TUN/TAP driver is included in the kernel, but typically needs to be loaded manually with
 | 
				
			||||||
.B modprobe tun.
 | 
					.B modprobe tun.
 | 
				
			||||||
For automatic loading the line
 | 
					For automatic loading the line
 | 
				
			||||||
@@ -241,7 +152,7 @@ For other platforms see
 | 
				
			|||||||
.I http://vtun.sourceforge.net/tun/
 | 
					.I http://vtun.sourceforge.net/tun/
 | 
				
			||||||
for information on how to install and configure the tun driver.
 | 
					for information on how to install and configure the tun driver.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.B ggsn 
 | 
					.B osmo-ggsn 
 | 
				
			||||||
uses the GPRS Tunneling Protocol (GTP) as specified by the Third
 | 
					uses the GPRS Tunneling Protocol (GTP) as specified by the Third
 | 
				
			||||||
Generation Partnership Project (3GPP). 3GPP protocols specifications
 | 
					Generation Partnership Project (3GPP). 3GPP protocols specifications
 | 
				
			||||||
can be found at
 | 
					can be found at
 | 
				
			||||||
@@ -250,6 +161,7 @@ can be found at
 | 
				
			|||||||
.SH COPYRIGHT
 | 
					.SH COPYRIGHT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Copyright (C) 2002, 2003 by Mondru AB.
 | 
					Copyright (C) 2002, 2003 by Mondru AB.
 | 
				
			||||||
 | 
					Copyright (C) 2017 Harald Welte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The contents of this file may be used under the terms of the GNU
 | 
					The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
General Public License Version 2, provided that the above copyright
 | 
					General Public License Version 2, provided that the above copyright
 | 
				
			||||||
@@ -258,3 +170,4 @@ substantial portions of the software.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.SH AUTHORS
 | 
					.SH AUTHORS
 | 
				
			||||||
Jens Jakobsen <jj@openggsn.org>
 | 
					Jens Jakobsen <jj@openggsn.org>
 | 
				
			||||||
 | 
					Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.\" * OpenGGSN - Gateway GPRS Support Node
 | 
					.\" * OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
.\" * Copyright (C) 2002, 2003 Mondru AB.
 | 
					.\" * Copyright (C) 2002, 2003 Mondru AB.
 | 
				
			||||||
.\" * 
 | 
					.\" * 
 | 
				
			||||||
.\" * The contents of this file may be used under the terms of the GNU
 | 
					.\" * The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
@@ -90,7 +90,7 @@ sgsnemu \- Serving GPRS Support Node Emulator
 | 
				
			|||||||
.SH DESCRIPTION
 | 
					.SH DESCRIPTION
 | 
				
			||||||
.B sgsnemu
 | 
					.B sgsnemu
 | 
				
			||||||
is part of the 
 | 
					is part of the 
 | 
				
			||||||
.B OpenGGSN
 | 
					.B OsmoGGSN
 | 
				
			||||||
project, and implements a Serving GPRS Support Node (SGSN)
 | 
					project, and implements a Serving GPRS Support Node (SGSN)
 | 
				
			||||||
emulator. It can be used for testing Gateway GPRS Support Nodes
 | 
					emulator. It can be used for testing Gateway GPRS Support Nodes
 | 
				
			||||||
(GGSNs), GPRS core networks as well as GPRS roaming connections.
 | 
					(GGSNs), GPRS core networks as well as GPRS roaming connections.
 | 
				
			||||||
@@ -329,7 +329,7 @@ indicates infinite.
 | 
				
			|||||||
.TP
 | 
					.TP
 | 
				
			||||||
.BI --pingquiet
 | 
					.BI --pingquiet
 | 
				
			||||||
Do not print information for each packet received (default = off). Is
 | 
					Do not print information for each packet received (default = off). Is
 | 
				
			||||||
quite usefull for high pingrates.
 | 
					quite useful for high pingrates.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.SH FILES
 | 
					.SH FILES
 | 
				
			||||||
@@ -348,8 +348,8 @@ Directory holding nonvolatile data.
 | 
				
			|||||||
.RE
 | 
					.RE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.SH BUGS
 | 
					.SH BUGS
 | 
				
			||||||
Report all bugs to the OpenGGSN bug tracking list at 
 | 
					Report all bugs to the OsmoGGSN bug tracking list at 
 | 
				
			||||||
.I http://sourceforge.net/projects/sgsnemu/
 | 
					.I http://osmocom.org/projects/openggsn/issues
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.SH "SEE ALSO"
 | 
					.SH "SEE ALSO"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,48 +0,0 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Firewall script for GGSN
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Uses $IFGN (eth0) as the Gn interface (Gn) and
 | 
					 | 
				
			||||||
# $IFGI (eth1) as the Gi interface.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# SUMMARY
 | 
					 | 
				
			||||||
# * All connections originating from GGSN are allowed.
 | 
					 | 
				
			||||||
# * Incoming ssh, GTPv0 and GTPv1 is allowed on the Gn interface.
 | 
					 | 
				
			||||||
# * Incoming ssh is allowed on the Gi interface.
 | 
					 | 
				
			||||||
# * Forwarding is allowed to and from the Gi interface, but disallowed
 | 
					 | 
				
			||||||
#   to and from the Gn interface.
 | 
					 | 
				
			||||||
# * Masquerede on Gi interface.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
IPTABLES="/sbin/iptables"
 | 
					 | 
				
			||||||
IFGN="eth0"
 | 
					 | 
				
			||||||
IFGI="eth1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$IPTABLES -P INPUT DROP
 | 
					 | 
				
			||||||
$IPTABLES -P FORWARD ACCEPT
 | 
					 | 
				
			||||||
$IPTABLES -P OUTPUT ACCEPT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#Allow related and established on all interfaces (input)
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#Allow releated, established, GTP and ssh on $IFGN. Reject everything else.
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -i $IFGN -p tcp -m tcp --dport 22 --syn -j ACCEPT
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -i $IFGN -p udp -m udp --dport 2123 -j ACCEPT
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -i $IFGN -p udp -m udp --dport 2152 -j ACCEPT
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -i $IFGN -p udp -m udp --dport 3386 -j ACCEPT
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -i $IFGN -j REJECT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#Allow related, established and ssh. Drop everything else.
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -i $IFGI -p tcp -m tcp --dport 22 --syn -j ACCEPT
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -i $IFGI -j DROP
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Masquerade everything going out on $IFGI
 | 
					 | 
				
			||||||
$IPTABLES -t nat -A POSTROUTING -o $IFGI -j MASQUERADE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#Allow everything on loopback interface.
 | 
					 | 
				
			||||||
$IPTABLES -A INPUT -i lo -j ACCEPT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Drop everything to and from $IFGN (forward)
 | 
					 | 
				
			||||||
$IPTABLES -A FORWARD -i $IFGN -j DROP
 | 
					 | 
				
			||||||
$IPTABLES -A FORWARD -o $IFGN -j DROP
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,92 +0,0 @@
 | 
				
			|||||||
##############################################################################
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Sample ggsn configuration file
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
##############################################################################
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: fg
 | 
					 | 
				
			||||||
# Include this flag if process is to run in the foreground
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
#fg
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: debug
 | 
					 | 
				
			||||||
# Include this flag to include debug information.
 | 
					 | 
				
			||||||
#debug
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: conf
 | 
					 | 
				
			||||||
# Configuration file to use. This file is the configuration file, 
 | 
					 | 
				
			||||||
# so changing this parameter in the configuration file does not make
 | 
					 | 
				
			||||||
# sense. Use it on the command line instead.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: pidfile
 | 
					 | 
				
			||||||
# File to store information about the process id of the program.
 | 
					 | 
				
			||||||
# The program must have write access to this file/directory.
 | 
					 | 
				
			||||||
#pidfile /var/run/ggsn.pid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: statedir
 | 
					 | 
				
			||||||
# Directory to use for nonvolatile storage. 
 | 
					 | 
				
			||||||
# The program must have write access to this directory.
 | 
					 | 
				
			||||||
#statedir /var/lib/ggsn/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: listen
 | 
					 | 
				
			||||||
# Specifies the local IP address to listen to
 | 
					 | 
				
			||||||
#listen 10.0.0.240
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: net
 | 
					 | 
				
			||||||
# IP network address of external packet data network
 | 
					 | 
				
			||||||
# Used to set up network interface.
 | 
					 | 
				
			||||||
#net 192.168.0.0/24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: ipup
 | 
					 | 
				
			||||||
# Script executed after network interface has been brought up.
 | 
					 | 
				
			||||||
# Executed with the following parameters: <devicename> <ip address>
 | 
					 | 
				
			||||||
#ipup /etc/ggsn/ip-up
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: ipdown
 | 
					 | 
				
			||||||
# Script executed after network interface has been taken down.
 | 
					 | 
				
			||||||
# Executed with the following parameters: <devicename> <ip address>
 | 
					 | 
				
			||||||
#ipdown /etc/ggsn/ip-down
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: dynip
 | 
					 | 
				
			||||||
# Dynamic IP address pool.
 | 
					 | 
				
			||||||
# Used for allocation of dynamic IP address when address is not given
 | 
					 | 
				
			||||||
# by HLR.
 | 
					 | 
				
			||||||
# If this option is not given then the net option is used as a substitute.
 | 
					 | 
				
			||||||
#dynip 192.168.0.0/24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: statip
 | 
					 | 
				
			||||||
# Use of this tag is currently UNSUPPORTED
 | 
					 | 
				
			||||||
# Static IP address pool.
 | 
					 | 
				
			||||||
# Used for allocation of static IP address by means of HLR.
 | 
					 | 
				
			||||||
#statip 192.168.1.0/24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: pcodns1
 | 
					 | 
				
			||||||
# Protocol configuration option domain name system server 1.
 | 
					 | 
				
			||||||
#pcodns1 0.0.0.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: pcodns2
 | 
					 | 
				
			||||||
# Protocol configuration option domain name system server 2.
 | 
					 | 
				
			||||||
#pcodns2 0.0.0.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: timelimit
 | 
					 | 
				
			||||||
# Exit after timelimit seconds.
 | 
					 | 
				
			||||||
# Setting timelimit to zero will cause the program not to exit.
 | 
					 | 
				
			||||||
#timelimit 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: apn
 | 
					 | 
				
			||||||
# Use of this tag is EXPERIMENTAL
 | 
					 | 
				
			||||||
# Access point name to connect to when run in client mode.
 | 
					 | 
				
			||||||
#apn internet
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TAG: qos
 | 
					 | 
				
			||||||
# Use of this tag is EXPERIMENTAL
 | 
					 | 
				
			||||||
# Requested Quality of Service used when run in client mode.
 | 
					 | 
				
			||||||
# 3 bytes corresponding to ????
 | 
					 | 
				
			||||||
#qos 0x0b921f
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,97 +0,0 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# ggsn          This shell script takes care of starting and stopping
 | 
					 | 
				
			||||||
#               ggsn.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# chkconfig: - 65 35
 | 
					 | 
				
			||||||
# description: ggsn is a Gateway GPRS Support Node.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Source function library.
 | 
					 | 
				
			||||||
. /etc/rc.d/init.d/functions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Source networking configuration.
 | 
					 | 
				
			||||||
. /etc/sysconfig/network
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [ -f /etc/sysconfig/ggsn ]; then
 | 
					 | 
				
			||||||
        . /etc/sysconfig/ggsn
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Check that networking is up.
 | 
					 | 
				
			||||||
[ ${NETWORKING} = "no" ] && exit 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[ -f /usr/bin/ggsn ] || exit 0
 | 
					 | 
				
			||||||
[ -f /etc/ggsn.conf ] || exit 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RETVAL=0
 | 
					 | 
				
			||||||
prog="ggsn"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start() {
 | 
					 | 
				
			||||||
	# Start daemons.
 | 
					 | 
				
			||||||
	echo -n $"Starting $prog: "
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Load tun module
 | 
					 | 
				
			||||||
	/sbin/modprobe tun >/dev/null 2>&1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Enable routing of packets: WARNING!!!
 | 
					 | 
				
			||||||
	# Users should enable this explicitly
 | 
					 | 
				
			||||||
	# echo 1 > /proc/sys/net/ipv4/ip_forward
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Check for runtime directory of nonvolatile data
 | 
					 | 
				
			||||||
	if [ ! -d  /var/lib/ggsn ]; then
 | 
					 | 
				
			||||||
	  mkdir /var/lib/ggsn
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Check for GTP restart counter
 | 
					 | 
				
			||||||
	if [ ! -d  /var/lib/ggsn/gsn_restart ]; then
 | 
					 | 
				
			||||||
	  echo 0 > /var/lib/ggsn/gsn_restart
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	daemon /usr/bin/ggsn 
 | 
					 | 
				
			||||||
	RETVAL=$?
 | 
					 | 
				
			||||||
	echo
 | 
					 | 
				
			||||||
	[ $RETVAL -eq 0 ] && touch /var/lock/subsys/ggsn
 | 
					 | 
				
			||||||
	return $RETVAL
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
stop() {
 | 
					 | 
				
			||||||
	# Stop daemons.
 | 
					 | 
				
			||||||
	echo -n $"Shutting down $prog: "
 | 
					 | 
				
			||||||
	killproc ggsn
 | 
					 | 
				
			||||||
	RETVAL=$?
 | 
					 | 
				
			||||||
	echo
 | 
					 | 
				
			||||||
	[ $RETVAL = 0 ] && rm -f /var/lock/subsys/ggsn /var/run/ggsn.pid
 | 
					 | 
				
			||||||
	return $RETVAL
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# See how we were called.
 | 
					 | 
				
			||||||
case "$1" in
 | 
					 | 
				
			||||||
  start)
 | 
					 | 
				
			||||||
	start
 | 
					 | 
				
			||||||
	;;
 | 
					 | 
				
			||||||
  stop)
 | 
					 | 
				
			||||||
	stop
 | 
					 | 
				
			||||||
	;;
 | 
					 | 
				
			||||||
  restart|reload)
 | 
					 | 
				
			||||||
	stop
 | 
					 | 
				
			||||||
	start
 | 
					 | 
				
			||||||
	RETVAL=$?
 | 
					 | 
				
			||||||
	;;
 | 
					 | 
				
			||||||
  condrestart)
 | 
					 | 
				
			||||||
	if [ -f /var/lock/subsys/ggsn ] ; then
 | 
					 | 
				
			||||||
	    stop
 | 
					 | 
				
			||||||
	    start
 | 
					 | 
				
			||||||
	    RETVAL=$?
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	;;
 | 
					 | 
				
			||||||
  status)
 | 
					 | 
				
			||||||
	status ggsn
 | 
					 | 
				
			||||||
	RETVAL=$?
 | 
					 | 
				
			||||||
	;;
 | 
					 | 
				
			||||||
  *)
 | 
					 | 
				
			||||||
	echo $"Usage: $0 {start|stop|restart|condrestart|status}"
 | 
					 | 
				
			||||||
	exit 1
 | 
					 | 
				
			||||||
esac
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
exit $RETVAL
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,10 +1,24 @@
 | 
				
			|||||||
bin_PROGRAMS = ggsn
 | 
					bin_PROGRAMS = osmo-ggsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AM_LDFLAGS = @EXEC_LDFLAGS@
 | 
					AM_LDFLAGS = @EXEC_LDFLAGS@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AM_CFLAGS = -O2 -D_GNU_SOURCE -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
 | 
					AM_CFLAGS = \
 | 
				
			||||||
 | 
						    -D_GNU_SOURCE \
 | 
				
			||||||
 | 
						    -fno-builtin \
 | 
				
			||||||
 | 
						    -Wall \
 | 
				
			||||||
 | 
						    -DSBINDIR='"$(sbindir)"' \
 | 
				
			||||||
 | 
						    -I$(top_srcdir)/include \
 | 
				
			||||||
 | 
						    $(LIBOSMOCORE_CFLAGS) \
 | 
				
			||||||
 | 
						    $(LIBOSMOCTRL_CFLAGS) \
 | 
				
			||||||
 | 
						    $(LIBOSMOVTY_CFLAGS) \
 | 
				
			||||||
 | 
						    $(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ggsn_LDADD = @EXEC_LDADD@ -lgtp -L../gtp ../lib/libmisc.a $(LIBOSMOCORE_LIBS)
 | 
					osmo_ggsn_LDADD = @EXEC_LDADD@ -lgtp -L../gtp ../lib/libmisc.a $(LIBOSMOCORE_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOVTY_LIBS)
 | 
				
			||||||
ggsn_DEPENDENCIES = ../gtp/libgtp.la ../lib/libmisc.a
 | 
					 | 
				
			||||||
ggsn_SOURCES = ggsn.c cmdline.c cmdline.h
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ENABLE_GTP_KERNEL
 | 
				
			||||||
 | 
					AM_CFLAGS += -DGTP_KERNEL $(LIBGTPNL_CFLAGS)
 | 
				
			||||||
 | 
					osmo_ggsn_LDADD += $(LIBGTPNL_LIBS)
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo_ggsn_DEPENDENCIES = ../gtp/libgtp.la ../lib/libmisc.a
 | 
				
			||||||
 | 
					osmo_ggsn_SOURCES = ggsn_main.c ggsn_vty.c ggsn.c ggsn.h sgsn.c sgsn.h pco.c pco.h
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1145
									
								
								ggsn/cmdline.c
									
									
									
									
									
								
							
							
						
						
									
										1145
									
								
								ggsn/cmdline.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,35 +0,0 @@
 | 
				
			|||||||
# OpenGGSN - Gateway GPRS Support Node
 | 
					 | 
				
			||||||
# Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
					 | 
				
			||||||
#  
 | 
					 | 
				
			||||||
# The contents of this file may be used under the terms of the GNU
 | 
					 | 
				
			||||||
# General Public License Version 2, provided that the above copyright
 | 
					 | 
				
			||||||
# notice and this permission notice is included in all copies or
 | 
					 | 
				
			||||||
# substantial portions of the software.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Use "gengetopt --conf-parser < cmdline.ggo" 
 | 
					 | 
				
			||||||
# to generate cmdline.c and cmdline.h
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
option  "fg"          f "Run in foreground"             flag   off
 | 
					 | 
				
			||||||
option  "debug"       d "Run in debug mode"             flag   off
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
option  "conf"        c "Read configuration file"       string default="/etc/ggsn.conf" no
 | 
					 | 
				
			||||||
option  "pidfile"     - "Filename of process id file"   string default="/var/run/ggsn.pid" no
 | 
					 | 
				
			||||||
option  "statedir"    - "Directory of nonvolatile data" string default="/var/lib/ggsn/" no
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
option  "listen"      l "Local interface"               string no
 | 
					 | 
				
			||||||
option  "net"         n "Network"                       string default="192.168.0.0/24" no
 | 
					 | 
				
			||||||
option  "ipup"        - "Script to run after link-up"    string no
 | 
					 | 
				
			||||||
option  "ipdown"      - "Script to run after link-down"  string no
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
option  "dynip"       - "Dynamic IP address pool"       string no
 | 
					 | 
				
			||||||
option  "statip"      - "Static IP address pool"        string no
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
option  "pcodns1"     - "PCO DNS Server 1"              string default="0.0.0.0" no
 | 
					 | 
				
			||||||
option  "pcodns2"     - "PCO DNS Server 2"              string default="0.0.0.0" no
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
option  "timelimit"   - "Exit after timelimit seconds"  int default="0" no
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
option  "apn"         a "Access point name"             string default="internet" no
 | 
					 | 
				
			||||||
option  "qos"         q "Requested quality of service"  int    default="0x0b921f" no
 | 
					 | 
				
			||||||
option  "logfile"     - "Logfile for errors"            string no
 | 
					 | 
				
			||||||
option  "loglevel"    - "Global log ldevel"		string default="error" no
 | 
					 | 
				
			||||||
							
								
								
									
										272
									
								
								ggsn/cmdline.h
									
									
									
									
									
								
							
							
						
						
									
										272
									
								
								ggsn/cmdline.h
									
									
									
									
									
								
							@@ -1,272 +0,0 @@
 | 
				
			|||||||
/** @file cmdline.h
 | 
					 | 
				
			||||||
 *  @brief The header file for the command line option parser
 | 
					 | 
				
			||||||
 *  generated by GNU Gengetopt version 2.22.6
 | 
					 | 
				
			||||||
 *  http://www.gnu.org/software/gengetopt.
 | 
					 | 
				
			||||||
 *  DO NOT modify this file, since it can be overwritten
 | 
					 | 
				
			||||||
 *  @author GNU Gengetopt by Lorenzo Bettini */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef CMDLINE_H
 | 
					 | 
				
			||||||
#define CMDLINE_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* If we use autoconf.  */
 | 
					 | 
				
			||||||
#ifdef HAVE_CONFIG_H
 | 
					 | 
				
			||||||
#include "config.h"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdio.h> /* for FILE */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
extern "C" {
 | 
					 | 
				
			||||||
#endif /* __cplusplus */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef CMDLINE_PARSER_PACKAGE
 | 
					 | 
				
			||||||
/** @brief the program name (used for printing errors) */
 | 
					 | 
				
			||||||
#define CMDLINE_PARSER_PACKAGE PACKAGE
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef CMDLINE_PARSER_PACKAGE_NAME
 | 
					 | 
				
			||||||
/** @brief the complete program name (used for help and version) */
 | 
					 | 
				
			||||||
#ifdef PACKAGE_NAME
 | 
					 | 
				
			||||||
#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE_NAME
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef CMDLINE_PARSER_VERSION
 | 
					 | 
				
			||||||
/** @brief the program version */
 | 
					 | 
				
			||||||
#define CMDLINE_PARSER_VERSION VERSION
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** @brief Where the command line options are stored */
 | 
					 | 
				
			||||||
struct gengetopt_args_info
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  const char *help_help; /**< @brief Print help and exit help description.  */
 | 
					 | 
				
			||||||
  const char *version_help; /**< @brief Print version and exit help description.  */
 | 
					 | 
				
			||||||
  int fg_flag;	/**< @brief Run in foreground (default=off).  */
 | 
					 | 
				
			||||||
  const char *fg_help; /**< @brief Run in foreground help description.  */
 | 
					 | 
				
			||||||
  int debug_flag;	/**< @brief Run in debug mode (default=off).  */
 | 
					 | 
				
			||||||
  const char *debug_help; /**< @brief Run in debug mode help description.  */
 | 
					 | 
				
			||||||
  char * conf_arg;	/**< @brief Read configuration file (default='/etc/ggsn.conf').  */
 | 
					 | 
				
			||||||
  char * conf_orig;	/**< @brief Read configuration file original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *conf_help; /**< @brief Read configuration file help description.  */
 | 
					 | 
				
			||||||
  char * pidfile_arg;	/**< @brief Filename of process id file (default='/var/run/ggsn.pid').  */
 | 
					 | 
				
			||||||
  char * pidfile_orig;	/**< @brief Filename of process id file original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *pidfile_help; /**< @brief Filename of process id file help description.  */
 | 
					 | 
				
			||||||
  char * statedir_arg;	/**< @brief Directory of nonvolatile data (default='/var/lib/ggsn/').  */
 | 
					 | 
				
			||||||
  char * statedir_orig;	/**< @brief Directory of nonvolatile data original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *statedir_help; /**< @brief Directory of nonvolatile data help description.  */
 | 
					 | 
				
			||||||
  char * listen_arg;	/**< @brief Local interface.  */
 | 
					 | 
				
			||||||
  char * listen_orig;	/**< @brief Local interface original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *listen_help; /**< @brief Local interface help description.  */
 | 
					 | 
				
			||||||
  char * net_arg;	/**< @brief Network (default='192.168.0.0/24').  */
 | 
					 | 
				
			||||||
  char * net_orig;	/**< @brief Network original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *net_help; /**< @brief Network help description.  */
 | 
					 | 
				
			||||||
  char * ipup_arg;	/**< @brief Script to run after link-up.  */
 | 
					 | 
				
			||||||
  char * ipup_orig;	/**< @brief Script to run after link-up original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *ipup_help; /**< @brief Script to run after link-up help description.  */
 | 
					 | 
				
			||||||
  char * ipdown_arg;	/**< @brief Script to run after link-down.  */
 | 
					 | 
				
			||||||
  char * ipdown_orig;	/**< @brief Script to run after link-down original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *ipdown_help; /**< @brief Script to run after link-down help description.  */
 | 
					 | 
				
			||||||
  char * dynip_arg;	/**< @brief Dynamic IP address pool.  */
 | 
					 | 
				
			||||||
  char * dynip_orig;	/**< @brief Dynamic IP address pool original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *dynip_help; /**< @brief Dynamic IP address pool help description.  */
 | 
					 | 
				
			||||||
  char * statip_arg;	/**< @brief Static IP address pool.  */
 | 
					 | 
				
			||||||
  char * statip_orig;	/**< @brief Static IP address pool original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *statip_help; /**< @brief Static IP address pool help description.  */
 | 
					 | 
				
			||||||
  char * pcodns1_arg;	/**< @brief PCO DNS Server 1 (default='0.0.0.0').  */
 | 
					 | 
				
			||||||
  char * pcodns1_orig;	/**< @brief PCO DNS Server 1 original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *pcodns1_help; /**< @brief PCO DNS Server 1 help description.  */
 | 
					 | 
				
			||||||
  char * pcodns2_arg;	/**< @brief PCO DNS Server 2 (default='0.0.0.0').  */
 | 
					 | 
				
			||||||
  char * pcodns2_orig;	/**< @brief PCO DNS Server 2 original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *pcodns2_help; /**< @brief PCO DNS Server 2 help description.  */
 | 
					 | 
				
			||||||
  int timelimit_arg;	/**< @brief Exit after timelimit seconds (default='0').  */
 | 
					 | 
				
			||||||
  char * timelimit_orig;	/**< @brief Exit after timelimit seconds original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *timelimit_help; /**< @brief Exit after timelimit seconds help description.  */
 | 
					 | 
				
			||||||
  char * apn_arg;	/**< @brief Access point name (default='internet').  */
 | 
					 | 
				
			||||||
  char * apn_orig;	/**< @brief Access point name original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *apn_help; /**< @brief Access point name help description.  */
 | 
					 | 
				
			||||||
  int qos_arg;	/**< @brief Requested quality of service (default='0x0b921f').  */
 | 
					 | 
				
			||||||
  char * qos_orig;	/**< @brief Requested quality of service original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *qos_help; /**< @brief Requested quality of service help description.  */
 | 
					 | 
				
			||||||
  char * logfile_arg;	/**< @brief Logfile for errors.  */
 | 
					 | 
				
			||||||
  char * logfile_orig;	/**< @brief Logfile for errors original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *logfile_help; /**< @brief Logfile for errors help description.  */
 | 
					 | 
				
			||||||
  char * loglevel_arg;	/**< @brief Global log ldevel (default='error').  */
 | 
					 | 
				
			||||||
  char * loglevel_orig;	/**< @brief Global log ldevel original value given at command line.  */
 | 
					 | 
				
			||||||
  const char *loglevel_help; /**< @brief Global log ldevel help description.  */
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  unsigned int help_given ;	/**< @brief Whether help was given.  */
 | 
					 | 
				
			||||||
  unsigned int version_given ;	/**< @brief Whether version was given.  */
 | 
					 | 
				
			||||||
  unsigned int fg_given ;	/**< @brief Whether fg was given.  */
 | 
					 | 
				
			||||||
  unsigned int debug_given ;	/**< @brief Whether debug was given.  */
 | 
					 | 
				
			||||||
  unsigned int conf_given ;	/**< @brief Whether conf was given.  */
 | 
					 | 
				
			||||||
  unsigned int pidfile_given ;	/**< @brief Whether pidfile was given.  */
 | 
					 | 
				
			||||||
  unsigned int statedir_given ;	/**< @brief Whether statedir was given.  */
 | 
					 | 
				
			||||||
  unsigned int listen_given ;	/**< @brief Whether listen was given.  */
 | 
					 | 
				
			||||||
  unsigned int net_given ;	/**< @brief Whether net was given.  */
 | 
					 | 
				
			||||||
  unsigned int ipup_given ;	/**< @brief Whether ipup was given.  */
 | 
					 | 
				
			||||||
  unsigned int ipdown_given ;	/**< @brief Whether ipdown was given.  */
 | 
					 | 
				
			||||||
  unsigned int dynip_given ;	/**< @brief Whether dynip was given.  */
 | 
					 | 
				
			||||||
  unsigned int statip_given ;	/**< @brief Whether statip was given.  */
 | 
					 | 
				
			||||||
  unsigned int pcodns1_given ;	/**< @brief Whether pcodns1 was given.  */
 | 
					 | 
				
			||||||
  unsigned int pcodns2_given ;	/**< @brief Whether pcodns2 was given.  */
 | 
					 | 
				
			||||||
  unsigned int timelimit_given ;	/**< @brief Whether timelimit was given.  */
 | 
					 | 
				
			||||||
  unsigned int apn_given ;	/**< @brief Whether apn was given.  */
 | 
					 | 
				
			||||||
  unsigned int qos_given ;	/**< @brief Whether qos was given.  */
 | 
					 | 
				
			||||||
  unsigned int logfile_given ;	/**< @brief Whether logfile was given.  */
 | 
					 | 
				
			||||||
  unsigned int loglevel_given ;	/**< @brief Whether loglevel was given.  */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** @brief The additional parameters to pass to parser functions */
 | 
					 | 
				
			||||||
struct cmdline_parser_params
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int override; /**< @brief whether to override possibly already present options (default 0) */
 | 
					 | 
				
			||||||
  int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */
 | 
					 | 
				
			||||||
  int check_required; /**< @brief whether to check that all required options were provided (default 1) */
 | 
					 | 
				
			||||||
  int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */
 | 
					 | 
				
			||||||
  int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */
 | 
					 | 
				
			||||||
} ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** @brief the purpose string of the program */
 | 
					 | 
				
			||||||
extern const char *gengetopt_args_info_purpose;
 | 
					 | 
				
			||||||
/** @brief the usage string of the program */
 | 
					 | 
				
			||||||
extern const char *gengetopt_args_info_usage;
 | 
					 | 
				
			||||||
/** @brief the description string of the program */
 | 
					 | 
				
			||||||
extern const char *gengetopt_args_info_description;
 | 
					 | 
				
			||||||
/** @brief all the lines making the help output */
 | 
					 | 
				
			||||||
extern const char *gengetopt_args_info_help[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * The command line parser
 | 
					 | 
				
			||||||
 * @param argc the number of command line options
 | 
					 | 
				
			||||||
 * @param argv the command line options
 | 
					 | 
				
			||||||
 * @param args_info the structure where option information will be stored
 | 
					 | 
				
			||||||
 * @return 0 if everything went fine, NON 0 if an error took place
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int cmdline_parser (int argc, char **argv,
 | 
					 | 
				
			||||||
  struct gengetopt_args_info *args_info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * The command line parser (version with additional parameters - deprecated)
 | 
					 | 
				
			||||||
 * @param argc the number of command line options
 | 
					 | 
				
			||||||
 * @param argv the command line options
 | 
					 | 
				
			||||||
 * @param args_info the structure where option information will be stored
 | 
					 | 
				
			||||||
 * @param override whether to override possibly already present options
 | 
					 | 
				
			||||||
 * @param initialize whether to initialize the option structure my_args_info
 | 
					 | 
				
			||||||
 * @param check_required whether to check that all required options were provided
 | 
					 | 
				
			||||||
 * @return 0 if everything went fine, NON 0 if an error took place
 | 
					 | 
				
			||||||
 * @deprecated use cmdline_parser_ext() instead
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int cmdline_parser2 (int argc, char **argv,
 | 
					 | 
				
			||||||
  struct gengetopt_args_info *args_info,
 | 
					 | 
				
			||||||
  int override, int initialize, int check_required);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * The command line parser (version with additional parameters)
 | 
					 | 
				
			||||||
 * @param argc the number of command line options
 | 
					 | 
				
			||||||
 * @param argv the command line options
 | 
					 | 
				
			||||||
 * @param args_info the structure where option information will be stored
 | 
					 | 
				
			||||||
 * @param params additional parameters for the parser
 | 
					 | 
				
			||||||
 * @return 0 if everything went fine, NON 0 if an error took place
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int cmdline_parser_ext (int argc, char **argv,
 | 
					 | 
				
			||||||
  struct gengetopt_args_info *args_info,
 | 
					 | 
				
			||||||
  struct cmdline_parser_params *params);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Save the contents of the option struct into an already open FILE stream.
 | 
					 | 
				
			||||||
 * @param outfile the stream where to dump options
 | 
					 | 
				
			||||||
 * @param args_info the option struct to dump
 | 
					 | 
				
			||||||
 * @return 0 if everything went fine, NON 0 if an error took place
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int cmdline_parser_dump(FILE *outfile,
 | 
					 | 
				
			||||||
  struct gengetopt_args_info *args_info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Save the contents of the option struct into a (text) file.
 | 
					 | 
				
			||||||
 * This file can be read by the config file parser (if generated by gengetopt)
 | 
					 | 
				
			||||||
 * @param filename the file where to save
 | 
					 | 
				
			||||||
 * @param args_info the option struct to save
 | 
					 | 
				
			||||||
 * @return 0 if everything went fine, NON 0 if an error took place
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int cmdline_parser_file_save(const char *filename,
 | 
					 | 
				
			||||||
  struct gengetopt_args_info *args_info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Print the help
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void cmdline_parser_print_help(void);
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Print the version
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void cmdline_parser_print_version(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes all the fields a cmdline_parser_params structure 
 | 
					 | 
				
			||||||
 * to their default values
 | 
					 | 
				
			||||||
 * @param params the structure to initialize
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void cmdline_parser_params_init(struct cmdline_parser_params *params);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Allocates dynamically a cmdline_parser_params structure and initializes
 | 
					 | 
				
			||||||
 * all its fields to their default values
 | 
					 | 
				
			||||||
 * @return the created and initialized cmdline_parser_params structure
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct cmdline_parser_params *cmdline_parser_params_create(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes the passed gengetopt_args_info structure's fields
 | 
					 | 
				
			||||||
 * (also set default values for options that have a default)
 | 
					 | 
				
			||||||
 * @param args_info the structure to initialize
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void cmdline_parser_init (struct gengetopt_args_info *args_info);
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Deallocates the string fields of the gengetopt_args_info structure
 | 
					 | 
				
			||||||
 * (but does not deallocate the structure itself)
 | 
					 | 
				
			||||||
 * @param args_info the structure to deallocate
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void cmdline_parser_free (struct gengetopt_args_info *args_info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * The config file parser (deprecated version)
 | 
					 | 
				
			||||||
 * @param filename the name of the config file
 | 
					 | 
				
			||||||
 * @param args_info the structure where option information will be stored
 | 
					 | 
				
			||||||
 * @param override whether to override possibly already present options
 | 
					 | 
				
			||||||
 * @param initialize whether to initialize the option structure my_args_info
 | 
					 | 
				
			||||||
 * @param check_required whether to check that all required options were provided
 | 
					 | 
				
			||||||
 * @return 0 if everything went fine, NON 0 if an error took place
 | 
					 | 
				
			||||||
 * @deprecated use cmdline_parser_config_file() instead
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int cmdline_parser_configfile (const char *filename,
 | 
					 | 
				
			||||||
  struct gengetopt_args_info *args_info,
 | 
					 | 
				
			||||||
  int override, int initialize, int check_required);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * The config file parser
 | 
					 | 
				
			||||||
 * @param filename the name of the config file
 | 
					 | 
				
			||||||
 * @param args_info the structure where option information will be stored
 | 
					 | 
				
			||||||
 * @param params additional parameters for the parser
 | 
					 | 
				
			||||||
 * @return 0 if everything went fine, NON 0 if an error took place
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int cmdline_parser_config_file (const char *filename,
 | 
					 | 
				
			||||||
  struct gengetopt_args_info *args_info,
 | 
					 | 
				
			||||||
  struct cmdline_parser_params *params);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Checks that all the required options were specified
 | 
					 | 
				
			||||||
 * @param args_info the structure to check
 | 
					 | 
				
			||||||
 * @param prog_name the name of the program that will be used to print
 | 
					 | 
				
			||||||
 *   possible errors
 | 
					 | 
				
			||||||
 * @return
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int cmdline_parser_required (struct gengetopt_args_info *args_info,
 | 
					 | 
				
			||||||
  const char *prog_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif /* __cplusplus */
 | 
					 | 
				
			||||||
#endif /* CMDLINE_H */
 | 
					 | 
				
			||||||
							
								
								
									
										1427
									
								
								ggsn/ggsn.c
									
									
									
									
									
								
							
							
						
						
									
										1427
									
								
								ggsn/ggsn.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										187
									
								
								ggsn/ggsn.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								ggsn/ggsn.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,187 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/utils.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/linuxlist.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/select.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/timer.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/tdef.h>
 | 
				
			||||||
 | 
					#include <osmocom/ctrl/control_if.h>
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../lib/tun.h"
 | 
				
			||||||
 | 
					#include "../lib/ippool.h"
 | 
				
			||||||
 | 
					#include "../lib/syserr.h"
 | 
				
			||||||
 | 
					#include "../lib/in46_addr.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "sgsn.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define APN_TYPE_IPv4	0x01	/* v4-only */
 | 
				
			||||||
 | 
					#define APN_TYPE_IPv6	0x02	/* v6-only */
 | 
				
			||||||
 | 
					#define APN_TYPE_IPv4v6	0x04	/* v4v6 dual-stack */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The maximum sane MTU over GTP-U somebody may wish to configure:
 | 
				
			||||||
 | 
					 * 9000 bytes aka jumbo frames. */
 | 
				
			||||||
 | 
					#define MAX_POSSIBLE_APN_MTU 9000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* See 3GPP TS 23.060 Annex C: */
 | 
				
			||||||
 | 
					#define ETHERNET_MTU      1500
 | 
				
			||||||
 | 
					#define IPV4_HDR_MAX_SIZE 60
 | 
				
			||||||
 | 
					#define IPV6_HDR_MAX_SIZE 40 /* Assume no extension headers in general... */
 | 
				
			||||||
 | 
					#define UDP_HDR_MAX_SIZE  8
 | 
				
			||||||
 | 
					#define GTPU_HDR_MAX_SIZE 12 /* Assume no extension headers in general... */
 | 
				
			||||||
 | 
					#define MAX_DESIRED_APN_MTU ((ETHERNET_MTU) - (GTPU_HDR_MAX_SIZE) - (UDP_HDR_MAX_SIZE) - (IPV4_HDR_MAX_SIZE))
 | 
				
			||||||
 | 
					/* MAX_DESIRED_APN_MTU = 1500 - 60 - 8 - 12 = 1500 - 80 = 1420 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ggsn_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct apn_ctx_ip {
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct in46_prefix ifconfig_prefix;
 | 
				
			||||||
 | 
							struct in46_prefix ll_prefix;
 | 
				
			||||||
 | 
							struct in46_prefix static_prefix;
 | 
				
			||||||
 | 
							struct in46_prefix dynamic_prefix;
 | 
				
			||||||
 | 
							/* v4 DNS server names */
 | 
				
			||||||
 | 
							struct in46_addr dns[2];
 | 
				
			||||||
 | 
						} cfg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* v4 address pool */
 | 
				
			||||||
 | 
						struct ippool_t *pool;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct apn_name {
 | 
				
			||||||
 | 
						struct llist_head list;
 | 
				
			||||||
 | 
						char *name;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum apn_gtpu_mode {
 | 
				
			||||||
 | 
						APN_GTPU_MODE_TUN = 0,		/* default */
 | 
				
			||||||
 | 
						APN_GTPU_MODE_KERNEL_GTP,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct apn_ctx {
 | 
				
			||||||
 | 
						/* list of APNs inside GGSN */
 | 
				
			||||||
 | 
						struct llist_head list;
 | 
				
			||||||
 | 
						/* back-pointer to GGSN */
 | 
				
			||||||
 | 
						struct ggsn_ctx *ggsn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool started;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							/* Primary name */
 | 
				
			||||||
 | 
							char *name;
 | 
				
			||||||
 | 
							/* Description string */
 | 
				
			||||||
 | 
							char *description;
 | 
				
			||||||
 | 
							/* List of secondary APN names */
 | 
				
			||||||
 | 
							struct llist_head name_list;
 | 
				
			||||||
 | 
							/* types supported address types on this APN */
 | 
				
			||||||
 | 
							uint32_t apn_type_mask;
 | 
				
			||||||
 | 
							/* GTP-U via TUN device or in Linux kernel */
 | 
				
			||||||
 | 
							enum apn_gtpu_mode gtpu_mode;
 | 
				
			||||||
 | 
							/* administratively shut down (true) or not (false) */
 | 
				
			||||||
 | 
							bool shutdown;
 | 
				
			||||||
 | 
							/* transmit G-PDU sequence numbers (true) or not (false) */
 | 
				
			||||||
 | 
							bool tx_gpdu_seq;
 | 
				
			||||||
 | 
							/* MTU announced to the UE */
 | 
				
			||||||
 | 
							uint16_t mtu;
 | 
				
			||||||
 | 
						} cfg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* corresponding tun device */
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								/* name of the network device */
 | 
				
			||||||
 | 
								char *dev_name;
 | 
				
			||||||
 | 
								/* ip-up and ip-down script names/paths */
 | 
				
			||||||
 | 
								char *ipup_script;
 | 
				
			||||||
 | 
								char *ipdown_script;
 | 
				
			||||||
 | 
								/* Whether to apply the MTU (apn->cfg.mtu) on the tun device: */
 | 
				
			||||||
 | 
								bool mtu_apply;
 | 
				
			||||||
 | 
							} cfg;
 | 
				
			||||||
 | 
							struct tun_t *tun;
 | 
				
			||||||
 | 
						} tun;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ipv6 link-local address */
 | 
				
			||||||
 | 
						struct in6_addr v6_lladdr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct apn_ctx_ip v4;
 | 
				
			||||||
 | 
						struct apn_ctx_ip v6;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pdp_priv_t {
 | 
				
			||||||
 | 
						struct pdp_t *lib; /* pointer to libgtp associated pdp_t instance */
 | 
				
			||||||
 | 
						struct sgsn_peer *sgsn;
 | 
				
			||||||
 | 
						struct apn_ctx *apn;
 | 
				
			||||||
 | 
						struct llist_head entry; /* to be included into sgsn_peer */
 | 
				
			||||||
 | 
						/* struct ggsn_ctx can be reached through lib->gsn->priv, or through sgsn->ggsn */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ggsn_ctx {
 | 
				
			||||||
 | 
						/* global list of GGSNs */
 | 
				
			||||||
 | 
						struct llist_head list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* list of APNs in this GGSN */
 | 
				
			||||||
 | 
						struct llist_head apn_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* list of SGSN peers (struct sgsn_peer) in this GGSN. TODO: hash table with key <ip+port>? */
 | 
				
			||||||
 | 
						struct llist_head sgsn_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool started;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							char *name;
 | 
				
			||||||
 | 
							/* Description string */
 | 
				
			||||||
 | 
							char *description;
 | 
				
			||||||
 | 
							/* an APN that shall be used as default for any non-matching APN */
 | 
				
			||||||
 | 
							struct apn_ctx *default_apn;
 | 
				
			||||||
 | 
							/* ADdress to which we listen for GTP */
 | 
				
			||||||
 | 
							struct in46_addr listen_addr;
 | 
				
			||||||
 | 
							/* Local GTP-C address advertised in GTP */
 | 
				
			||||||
 | 
							struct in46_addr gtpc_addr;
 | 
				
			||||||
 | 
							/* Local GTP-U address advertised in GTP */
 | 
				
			||||||
 | 
							struct in46_addr gtpu_addr;
 | 
				
			||||||
 | 
							/* directory for state file */
 | 
				
			||||||
 | 
							char *state_dir;
 | 
				
			||||||
 | 
							/* Time between Echo requests on each SGSN */
 | 
				
			||||||
 | 
							unsigned int echo_interval;
 | 
				
			||||||
 | 
							/* administratively shut down (true) or not (false) */
 | 
				
			||||||
 | 
							bool shutdown;
 | 
				
			||||||
 | 
						} cfg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The libgtp (G)GSN instance, i.e. what listens to GTP */
 | 
				
			||||||
 | 
						struct gsn_t *gsn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* osmo-fd for gsn */
 | 
				
			||||||
 | 
						struct osmo_fd gtp_fd0;
 | 
				
			||||||
 | 
						struct osmo_fd gtp_fd1c;
 | 
				
			||||||
 | 
						struct osmo_fd gtp_fd1u;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ggsn_vty.c */
 | 
				
			||||||
 | 
					extern struct llist_head g_ggsn_list;
 | 
				
			||||||
 | 
					extern struct vty_app_info g_vty_info;
 | 
				
			||||||
 | 
					extern int ggsn_vty_init(void);
 | 
				
			||||||
 | 
					struct ggsn_ctx *ggsn_find(const char *name);
 | 
				
			||||||
 | 
					struct ggsn_ctx *ggsn_find_or_create(void *ctx, const char *name);
 | 
				
			||||||
 | 
					struct apn_ctx *ggsn_find_apn(struct ggsn_ctx *ggsn, const char *name);
 | 
				
			||||||
 | 
					struct apn_ctx *ggsn_find_or_create_apn(struct ggsn_ctx *ggsn, const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ggsn_main.c */
 | 
				
			||||||
 | 
					extern struct ctrl_handle *g_ctrlh;
 | 
				
			||||||
 | 
					extern void *tall_ggsn_ctx;
 | 
				
			||||||
 | 
					extern struct osmo_tdef_group ggsn_tdef_group[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ggsn.c */
 | 
				
			||||||
 | 
					extern int ggsn_start(struct ggsn_ctx *ggsn);
 | 
				
			||||||
 | 
					extern int ggsn_stop(struct ggsn_ctx *ggsn);
 | 
				
			||||||
 | 
					extern int apn_start(struct apn_ctx *apn);
 | 
				
			||||||
 | 
					extern int apn_stop(struct apn_ctx *apn);
 | 
				
			||||||
 | 
					void ggsn_close_one_pdp(struct pdp_t *pdp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LOGPAPN(level, apn, fmt, args...)			\
 | 
				
			||||||
 | 
						LOGP(DGGSN, level, "APN(%s): " fmt, (apn)->cfg.name, ## args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LOGPGGSN(level, ggsn, fmt, args...)			\
 | 
				
			||||||
 | 
						LOGP(DGGSN, level, "GGSN(%s): " fmt, (ggsn)->cfg.name, ## args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LOGPPDP(level, pdp, fmt, args...) LOGPDPX(DGGSN, level, pdp, fmt, ## args)
 | 
				
			||||||
							
								
								
									
										261
									
								
								ggsn/ggsn_main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								ggsn/ggsn_main.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,261 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 | 
					 * Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
				
			||||||
 | 
					 * Copyright (C) 2017-2019 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2019 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 | 
					 * General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 | 
					 * notice and this permission notice is included in all copies or
 | 
				
			||||||
 | 
					 * substantial portions of the software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_STDINT_H
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <getopt.h>
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/application.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/select.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/stats.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/rate_ctr.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/timer.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/tdef.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/utils.h>
 | 
				
			||||||
 | 
					#include <osmocom/ctrl/control_if.h>
 | 
				
			||||||
 | 
					#include <osmocom/ctrl/control_cmd.h>
 | 
				
			||||||
 | 
					#include <osmocom/ctrl/control_vty.h>
 | 
				
			||||||
 | 
					#include <osmocom/ctrl/ports.h>
 | 
				
			||||||
 | 
					#include <osmocom/vty/telnet_interface.h>
 | 
				
			||||||
 | 
					#include <osmocom/vty/logging.h>
 | 
				
			||||||
 | 
					#include <osmocom/vty/stats.h>
 | 
				
			||||||
 | 
					#include <osmocom/vty/ports.h>
 | 
				
			||||||
 | 
					#include <osmocom/vty/command.h>
 | 
				
			||||||
 | 
					#include <osmocom/vty/misc.h>
 | 
				
			||||||
 | 
					#include <osmocom/vty/cpu_sched_vty.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ggsn.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *tall_ggsn_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int end = 0;
 | 
				
			||||||
 | 
					static int daemonize = 0;
 | 
				
			||||||
 | 
					struct ctrl_handle *g_ctrlh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ul255_t qos;
 | 
				
			||||||
 | 
					struct ul255_t apn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *config_file = "osmo-ggsn.cfg";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct osmo_tdef_group ggsn_tdef_group[] = {
 | 
				
			||||||
 | 
						{.name = "gtp", .tdefs = gtp_T_defs, .desc = "GTP (libgtp) timers" },
 | 
				
			||||||
 | 
						{ }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* To exit gracefully. Used with GCC compilation flag -pg and gprof */
 | 
				
			||||||
 | 
					static void signal_handler(int s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						LOGP(DGGSN, LOGL_NOTICE, "signal %d received\n", s);
 | 
				
			||||||
 | 
						switch (s) {
 | 
				
			||||||
 | 
						case SIGINT:
 | 
				
			||||||
 | 
						case SIGTERM:
 | 
				
			||||||
 | 
							LOGP(DGGSN, LOGL_NOTICE, "SIGINT received, shutting down\n");
 | 
				
			||||||
 | 
							end = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGABRT:
 | 
				
			||||||
 | 
							/* in case of abort, we want to obtain a talloc report and
 | 
				
			||||||
 | 
							 * then run default SIGABRT handler, who will generate coredump
 | 
				
			||||||
 | 
							 * and abort the process. abort() should do this for us after we
 | 
				
			||||||
 | 
							 * return, but program wouldn't exit if an external SIGABRT is
 | 
				
			||||||
 | 
							 * received.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							talloc_report(tall_vty_ctx, stderr);
 | 
				
			||||||
 | 
							talloc_report_full(tall_ggsn_ctx, stderr);
 | 
				
			||||||
 | 
							signal(SIGABRT, SIG_DFL);
 | 
				
			||||||
 | 
							raise(SIGABRT);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGUSR1:
 | 
				
			||||||
 | 
							talloc_report(tall_vty_ctx, stderr);
 | 
				
			||||||
 | 
							talloc_report_full(tall_ggsn_ctx, stderr);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGUSR2:
 | 
				
			||||||
 | 
							talloc_report_full(tall_vty_ctx, stderr);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_usage()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						printf("Usage: osmo-ggsn [-h] [-D] [-c configfile] [-V]\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_help()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						printf(	"  Some useful help...\n"
 | 
				
			||||||
 | 
							"  -h --help		This help text\n"
 | 
				
			||||||
 | 
							"  -D --daemonize	Fork the process into a background daemon\n"
 | 
				
			||||||
 | 
							"  -c --config-file	filename The config file to use\n"
 | 
				
			||||||
 | 
							"  -V --version		Print the version of OsmoGGSN\n"
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("\nVTY reference generation:\n");
 | 
				
			||||||
 | 
						printf("     --vty-ref-mode MODE        VTY reference generation mode (e.g. 'expert').\n");
 | 
				
			||||||
 | 
						printf("     --vty-ref-xml              Generate the VTY reference XML output and exit.\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_long_options(const char *prog_name, const int long_option)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (long_option) {
 | 
				
			||||||
 | 
						case 1:
 | 
				
			||||||
 | 
							vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
 | 
				
			||||||
 | 
							if (vty_ref_mode < 0) {
 | 
				
			||||||
 | 
								fprintf(stderr, "%s: Unknown VTY reference generation "
 | 
				
			||||||
 | 
									"mode '%s'\n", prog_name, optarg);
 | 
				
			||||||
 | 
								exit(2);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 2:
 | 
				
			||||||
 | 
							fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
 | 
				
			||||||
 | 
								get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
 | 
				
			||||||
 | 
								get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
 | 
				
			||||||
 | 
							vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
 | 
				
			||||||
 | 
							exit(0);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
 | 
				
			||||||
 | 
							exit(2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_options(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (1) {
 | 
				
			||||||
 | 
							int option_index = 0, c;
 | 
				
			||||||
 | 
							static int long_option = 0;
 | 
				
			||||||
 | 
							static struct option long_options[] = {
 | 
				
			||||||
 | 
								{ "help", 0, 0, 'h' },
 | 
				
			||||||
 | 
								{ "daemonize", 0, 0, 'D' },
 | 
				
			||||||
 | 
								{ "config-file", 1, 0, 'c' },
 | 
				
			||||||
 | 
								{ "version", 0, 0, 'V' },
 | 
				
			||||||
 | 
								{ "vty-ref-mode", 1, &long_option, 1 },
 | 
				
			||||||
 | 
								{ "vty-ref-xml", 0, &long_option, 2 },
 | 
				
			||||||
 | 
								{ 0, 0, 0, 0 }
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							c = getopt_long(argc, argv, "hdc:V", long_options, &option_index);
 | 
				
			||||||
 | 
							if (c == -1)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (c) {
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								handle_long_options(argv[0], long_option);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'h':
 | 
				
			||||||
 | 
								print_usage();
 | 
				
			||||||
 | 
								print_help();
 | 
				
			||||||
 | 
								exit(0);
 | 
				
			||||||
 | 
							case 'D':
 | 
				
			||||||
 | 
								daemonize = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'c':
 | 
				
			||||||
 | 
								config_file = optarg;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'V':
 | 
				
			||||||
 | 
								print_version(1);
 | 
				
			||||||
 | 
								exit(0);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ggsn_ctx *ggsn;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tall_ggsn_ctx = talloc_named_const(NULL, 0, "OsmoGGSN");
 | 
				
			||||||
 | 
						msgb_talloc_ctx_init(tall_ggsn_ctx, 0);
 | 
				
			||||||
 | 
						g_vty_info.tall_ctx = tall_ggsn_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Handle keyboard interrupt SIGINT */
 | 
				
			||||||
 | 
						signal(SIGINT, &signal_handler);
 | 
				
			||||||
 | 
						signal(SIGTERM, &signal_handler);
 | 
				
			||||||
 | 
						signal(SIGABRT, &signal_handler);
 | 
				
			||||||
 | 
						signal(SIGUSR1, &signal_handler);
 | 
				
			||||||
 | 
						signal(SIGUSR2, &signal_handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						osmo_init_ignore_signals();
 | 
				
			||||||
 | 
						osmo_init_logging2(tall_ggsn_ctx, &log_info);
 | 
				
			||||||
 | 
						osmo_stats_init(tall_ggsn_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vty_init(&g_vty_info);
 | 
				
			||||||
 | 
						logging_vty_add_cmds();
 | 
				
			||||||
 | 
						osmo_talloc_vty_add_cmds();
 | 
				
			||||||
 | 
						osmo_stats_vty_add_cmds();
 | 
				
			||||||
 | 
						ggsn_vty_init();
 | 
				
			||||||
 | 
						ctrl_vty_init(tall_ggsn_ctx);
 | 
				
			||||||
 | 
						osmo_cpu_sched_vty_init(tall_ggsn_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handle_options(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rate_ctr_init(tall_ggsn_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = vty_read_config_file(config_file, NULL);
 | 
				
			||||||
 | 
						if (rc < 0) {
 | 
				
			||||||
 | 
							fprintf(stderr, "Failed to open config file: '%s'\n", config_file);
 | 
				
			||||||
 | 
							exit(2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = telnet_init_default(tall_ggsn_ctx, NULL, OSMO_VTY_PORT_GGSN);
 | 
				
			||||||
 | 
						if (rc < 0)
 | 
				
			||||||
 | 
							exit(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						g_ctrlh = ctrl_interface_setup(NULL, OSMO_CTRL_PORT_GGSN, NULL);
 | 
				
			||||||
 | 
						if (!g_ctrlh) {
 | 
				
			||||||
 | 
							LOGP(DGGSN, LOGL_ERROR, "Failed to create CTRL interface.\n");
 | 
				
			||||||
 | 
							exit(1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (daemonize) {
 | 
				
			||||||
 | 
							rc = osmo_daemonize();
 | 
				
			||||||
 | 
							if (rc < 0) {
 | 
				
			||||||
 | 
								perror("Error during daemonize");
 | 
				
			||||||
 | 
								exit(1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
						/* qos                                                             */
 | 
				
			||||||
 | 
						qos.l = 3;
 | 
				
			||||||
 | 
						qos.v[2] = (args_info.qos_arg) & 0xff;
 | 
				
			||||||
 | 
						qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
 | 
				
			||||||
 | 
						qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Main select loop */
 | 
				
			||||||
 | 
						while (!end) {
 | 
				
			||||||
 | 
							osmo_select_main(0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						llist_for_each_entry(ggsn, &g_ggsn_list, list)
 | 
				
			||||||
 | 
							ggsn_stop(ggsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1178
									
								
								ggsn/ggsn_vty.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1178
									
								
								ggsn/ggsn_vty.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										263
									
								
								ggsn/pco.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								ggsn/pco.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,263 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * PCO parsing related code
 | 
				
			||||||
 | 
					 * Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
				
			||||||
 | 
					 * Copyright (C) 2017-2019 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2019 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 | 
					 * General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 | 
					 * notice and this permission notice is included in all copies or
 | 
				
			||||||
 | 
					 * substantial portions of the software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/msgb.h>
 | 
				
			||||||
 | 
					#include <osmocom/gsm/tlv.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../lib/util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pco.h"
 | 
				
			||||||
 | 
					#include "ggsn.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* determine if IPCP contains given option */
 | 
				
			||||||
 | 
					static const uint8_t *ipcp_contains_option(const struct ipcp_hdr *ipcp, size_t ipcp_len,
 | 
				
			||||||
 | 
										   enum ipcp_options opt, size_t opt_minlen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const uint8_t *cur_opt = ipcp->options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* iterate over Options and check if protocol contained */
 | 
				
			||||||
 | 
						while (cur_opt + sizeof(struct ipcp_option_hdr) <= (uint8_t*)ipcp + ipcp_len) {
 | 
				
			||||||
 | 
							const struct ipcp_option_hdr *cur_opt_hdr = (const struct ipcp_option_hdr *)cur_opt;
 | 
				
			||||||
 | 
							/* length value includes 2 bytes type/length */
 | 
				
			||||||
 | 
							if (cur_opt_hdr->len < sizeof(struct ipcp_option_hdr))
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							if (cur_opt_hdr->type == opt &&
 | 
				
			||||||
 | 
							    cur_opt_hdr->len >= sizeof(struct ipcp_option_hdr) + opt_minlen)
 | 
				
			||||||
 | 
								return cur_opt;
 | 
				
			||||||
 | 
							cur_opt += cur_opt_hdr->len;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *pap_welcome = "Welcome to OsmoGGSN " PACKAGE_VERSION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Handle PAP protocol according to RFC 1334 */
 | 
				
			||||||
 | 
					static void process_pco_element_pap(const struct pco_element *pco_in, struct msgb *resp,
 | 
				
			||||||
 | 
									    const struct apn_ctx *apn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct pap_element *pap_in = (const struct pap_element *) pco_in->data;
 | 
				
			||||||
 | 
						uint16_t pap_in_len;
 | 
				
			||||||
 | 
						uint8_t peer_id_len;
 | 
				
			||||||
 | 
						const uint8_t *peer_id;
 | 
				
			||||||
 | 
						unsigned int pap_welcome_len;
 | 
				
			||||||
 | 
						uint8_t pap_out_size;
 | 
				
			||||||
 | 
						struct pap_element *pap_out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pco_in->length < sizeof(struct pap_element))
 | 
				
			||||||
 | 
							goto ret_broken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pap_in_len = osmo_load16be(&pap_in->len);
 | 
				
			||||||
 | 
						if (pco_in->length < pap_in_len)
 | 
				
			||||||
 | 
							goto ret_broken;
 | 
				
			||||||
 | 
						/* "pco_in->length > pap_in_len" is allowed: RFC1334 2.2 states:
 | 
				
			||||||
 | 
						   "Octets outside the range of the Length field should be treated as
 | 
				
			||||||
 | 
						   Data Link Layer padding and should be ignored on reception."
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (pap_in->code) {
 | 
				
			||||||
 | 
						case PAP_CODE_AUTH_REQ:
 | 
				
			||||||
 | 
							if (pap_in_len < sizeof(struct pap_element) + 1)
 | 
				
			||||||
 | 
								goto ret_broken_auth;
 | 
				
			||||||
 | 
							peer_id_len = pap_in->data[0];
 | 
				
			||||||
 | 
							if (pap_in_len < sizeof(struct pap_element) + 1 + peer_id_len)
 | 
				
			||||||
 | 
								goto ret_broken_auth;
 | 
				
			||||||
 | 
							peer_id = &pap_in->data[1];
 | 
				
			||||||
 | 
							LOGPPDP(LOGL_DEBUG, pdp, "PCO PAP PeerId = %s, ACKing\n",
 | 
				
			||||||
 | 
								osmo_quote_str((const char *)peer_id, peer_id_len));
 | 
				
			||||||
 | 
							/* Password-Length + Password following here, but we don't care */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Prepare response, we ACK all of them: */
 | 
				
			||||||
 | 
							pap_welcome_len = strlen(pap_welcome);
 | 
				
			||||||
 | 
							/* +1: Length field of pap_welcome Message */
 | 
				
			||||||
 | 
							pap_out_size = sizeof(struct pap_element) + 1 + pap_welcome_len;
 | 
				
			||||||
 | 
							pap_out = alloca(pap_out_size);
 | 
				
			||||||
 | 
							pap_out->code = PAP_CODE_AUTH_ACK;
 | 
				
			||||||
 | 
							pap_out->id = pap_in->id;
 | 
				
			||||||
 | 
							pap_out->len = htons(pap_out_size);
 | 
				
			||||||
 | 
							pap_out->data[0] = pap_welcome_len;
 | 
				
			||||||
 | 
							memcpy(pap_out->data+1, pap_welcome, pap_welcome_len);
 | 
				
			||||||
 | 
							msgb_t16lv_put(resp, PCO_P_PAP, pap_out_size, (uint8_t *) pap_out);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PAP_CODE_AUTH_ACK:
 | 
				
			||||||
 | 
						case PAP_CODE_AUTH_NAK:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							LOGPPDP(LOGL_NOTICE, pdp, "Unsupported PAP PCO Code %u, ignoring\n", pap_in->code);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ret_broken_auth:
 | 
				
			||||||
 | 
						LOGPPDP(LOGL_NOTICE, pdp, "Invalid PAP AuthenticateReq: %s, ignoring\n",
 | 
				
			||||||
 | 
							osmo_hexdump_nospc((const uint8_t *)pco_in, pco_in->length));
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ret_broken:
 | 
				
			||||||
 | 
						LOGPPDP(LOGL_NOTICE, pdp, "Invalid PAP PCO Length: %s, ignoring\n",
 | 
				
			||||||
 | 
							osmo_hexdump_nospc((const uint8_t *)pco_in, pco_in->length));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Handle IP Control Protocol, RFC 1332, extensions in RFC 1877 */
 | 
				
			||||||
 | 
					static void process_pco_element_ipcp(const struct pco_element *pco_elem, struct msgb *resp,
 | 
				
			||||||
 | 
									     const struct apn_ctx *apn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ippoolm_t *peer_v4 = pdp_get_peer_ipv(pdp, false);
 | 
				
			||||||
 | 
						const struct in46_addr *dns1 = &apn->v4.cfg.dns[0];
 | 
				
			||||||
 | 
						const struct in46_addr *dns2 = &apn->v4.cfg.dns[1];
 | 
				
			||||||
 | 
						uint8_t *start = resp->tail;
 | 
				
			||||||
 | 
						const struct ipcp_hdr *ipcp;
 | 
				
			||||||
 | 
						uint16_t ipcp_len;
 | 
				
			||||||
 | 
						uint8_t *len1, *len2;
 | 
				
			||||||
 | 
						unsigned int len_appended;
 | 
				
			||||||
 | 
						ptrdiff_t consumed;
 | 
				
			||||||
 | 
						size_t remain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!peer_v4) {
 | 
				
			||||||
 | 
							LOGPPDP(LOGL_ERROR, pdp, "IPCP but no IPv4 type ?!?\n");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ipcp = (const struct ipcp_hdr *)pco_elem->data;
 | 
				
			||||||
 | 
						consumed = (pco_elem->data - &pdp->pco_req.v[0]);
 | 
				
			||||||
 | 
						remain = sizeof(pdp->pco_req.v) - consumed;
 | 
				
			||||||
 | 
						ipcp_len = osmo_load16be(&ipcp->len);
 | 
				
			||||||
 | 
						if (remain < 0 || remain < ipcp_len) {
 | 
				
			||||||
 | 
							LOGPPDP(LOGL_ERROR, pdp, "Malformed IPCP, ignoring\n");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Three byte T16L header */
 | 
				
			||||||
 | 
						msgb_put_u16(resp, 0x8021);	/* IPCP */
 | 
				
			||||||
 | 
						len1 = msgb_put(resp, 1);	/* Length of contents: delay */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msgb_put_u8(resp, 0x02);	/* ACK */
 | 
				
			||||||
 | 
						msgb_put_u8(resp, ipcp->id);	/* ID: Needs to match request */
 | 
				
			||||||
 | 
						msgb_put_u8(resp, 0x00);	/* Length MSB */
 | 
				
			||||||
 | 
						len2 = msgb_put(resp, 1);	/* Length LSB: delay */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dns1->len == 4 && ipcp_contains_option(ipcp, ipcp_len, IPCP_OPT_PRIMARY_DNS, 4)) {
 | 
				
			||||||
 | 
							msgb_put_u8(resp, 0x81);		/* DNS1 Tag */
 | 
				
			||||||
 | 
							msgb_put_u8(resp, 2 + dns1->len);	/* DNS1 Length, incl. TL */
 | 
				
			||||||
 | 
							msgb_put_u32(resp, ntohl(dns1->v4.s_addr));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dns2->len == 4 && ipcp_contains_option(ipcp, ipcp_len, IPCP_OPT_SECONDARY_DNS, 4)) {
 | 
				
			||||||
 | 
							msgb_put_u8(resp, 0x83);		/* DNS2 Tag */
 | 
				
			||||||
 | 
							msgb_put_u8(resp, 2 + dns2->len);	/* DNS2 Length, incl. TL */
 | 
				
			||||||
 | 
							msgb_put_u32(resp, ntohl(dns2->v4.s_addr));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* patch in length values */
 | 
				
			||||||
 | 
						len_appended = resp->tail - start;
 | 
				
			||||||
 | 
						*len1 = len_appended - 3;
 | 
				
			||||||
 | 
						*len2 = len_appended - 3;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void process_pco_element_dns_ipv6(const struct pco_element *pco_elem, struct msgb *resp,
 | 
				
			||||||
 | 
										 const struct apn_ctx *apn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
						const uint8_t *tail = resp->tail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(apn->v6.cfg.dns); i++) {
 | 
				
			||||||
 | 
							const struct in46_addr *i46a = &apn->v6.cfg.dns[i];
 | 
				
			||||||
 | 
							if (i46a->len != 16)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							msgb_t16lv_put(resp, PCO_P_DNS_IPv6_ADDR, i46a->len, i46a->v6.s6_addr);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (resp->tail == tail)
 | 
				
			||||||
 | 
							LOGPPDP(LOGL_NOTICE, pdp, "MS requested IPv6 DNS, but APN has none configured\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void process_pco_element_dns_ipv4(const struct pco_element *pco_elem, struct msgb *resp,
 | 
				
			||||||
 | 
										 const struct apn_ctx *apn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
						const uint8_t *tail = resp->tail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(apn->v4.cfg.dns); i++) {
 | 
				
			||||||
 | 
							const struct in46_addr *i46a = &apn->v4.cfg.dns[i];
 | 
				
			||||||
 | 
							if (i46a->len != 4)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							msgb_t16lv_put(resp, PCO_P_DNS_IPv4_ADDR, i46a->len, (uint8_t *)&i46a->v4);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (resp->tail == tail)
 | 
				
			||||||
 | 
							LOGPPDP(LOGL_NOTICE, pdp, "MS requested IPv4 DNS, but APN has none configured\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void process_pco_element_link_mtu_ipv4(const struct pco_element *pco_elem, struct msgb *resp,
 | 
				
			||||||
 | 
										      const struct apn_ctx *apn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const uint16_t val_be = osmo_htons(apn->cfg.mtu);
 | 
				
			||||||
 | 
						msgb_t16lv_put(resp, PCO_P_IPv4_LINK_MTU, 2, (const uint8_t *)&val_be);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void process_pco_element(const struct pco_element *pco_elem, struct msgb *resp,
 | 
				
			||||||
 | 
									const struct apn_ctx *apn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint16_t protocol_id = osmo_load16be(&pco_elem->protocol_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						LOGPPDP(LOGL_DEBUG, pdp, "PCO Protocol 0x%04x\n", protocol_id);
 | 
				
			||||||
 | 
						switch (protocol_id) {
 | 
				
			||||||
 | 
						case PCO_P_PAP:
 | 
				
			||||||
 | 
							process_pco_element_pap(pco_elem, resp, apn, pdp);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PCO_P_IPCP:
 | 
				
			||||||
 | 
							process_pco_element_ipcp(pco_elem, resp, apn, pdp);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PCO_P_DNS_IPv6_ADDR:
 | 
				
			||||||
 | 
							process_pco_element_dns_ipv6(pco_elem, resp, apn, pdp);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PCO_P_DNS_IPv4_ADDR:
 | 
				
			||||||
 | 
							process_pco_element_dns_ipv4(pco_elem, resp, apn, pdp);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case PCO_P_IPv4_LINK_MTU:
 | 
				
			||||||
 | 
							process_pco_element_link_mtu_ipv4(pco_elem, resp, apn, pdp);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							LOGPPDP(LOGL_INFO, pdp, "Unknown/Unimplemented PCO Protocol 0x%04x: %s\n",
 | 
				
			||||||
 | 
								protocol_id, osmo_hexdump_nospc(pco_elem->data, pco_elem->length));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* process one PCO request from a MS/UE, putting together the proper responses */
 | 
				
			||||||
 | 
					void process_pco(const struct apn_ctx *apn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct msgb *resp = msgb_alloc(256, "PCO.resp");
 | 
				
			||||||
 | 
						const struct ul255_t *pco = &pdp->pco_req;
 | 
				
			||||||
 | 
						const struct pco_element *pco_elem;
 | 
				
			||||||
 | 
						const uint8_t *cur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* build the header of the PCO response */
 | 
				
			||||||
 | 
						OSMO_ASSERT(resp);
 | 
				
			||||||
 | 
						msgb_put_u8(resp, 0x80); /* ext-bit + configuration protocol byte */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* iterate over the PCO elements in the request; call process_pco_element() for each */
 | 
				
			||||||
 | 
						for (cur = pco->v + 1, pco_elem = (const struct pco_element *) cur;
 | 
				
			||||||
 | 
						     cur + sizeof(struct pco_element) <= pco->v + pco->l;
 | 
				
			||||||
 | 
						     cur += pco_elem->length + sizeof(*pco_elem), pco_elem = (const struct pco_element *) cur) {
 | 
				
			||||||
 | 
							process_pco_element(pco_elem, resp, apn, pdp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* copy the PCO response msgb and copy its contents over to the PDP context */
 | 
				
			||||||
 | 
						if (msgb_length(resp) > 1) {
 | 
				
			||||||
 | 
							memcpy(pdp->pco_neg.v, msgb_data(resp), msgb_length(resp));
 | 
				
			||||||
 | 
							pdp->pco_neg.l = msgb_length(resp);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							pdp->pco_neg.l = 0;
 | 
				
			||||||
 | 
						msgb_free(resp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										80
									
								
								ggsn/pco.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								ggsn/pco.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 3GPP TS 24.008 10.5.6.3 */
 | 
				
			||||||
 | 
					enum pco_protocols {
 | 
				
			||||||
 | 
						PCO_P_LCP		= 0xC021,
 | 
				
			||||||
 | 
						PCO_P_PAP		= 0xC023,
 | 
				
			||||||
 | 
						PCO_P_CHAP		= 0xC223,
 | 
				
			||||||
 | 
						PCO_P_IPCP		= 0x8021,
 | 
				
			||||||
 | 
						PCO_P_PCSCF_ADDR	= 0x0001,
 | 
				
			||||||
 | 
						PCO_P_IM_CN_SS_F	= 0x0002,
 | 
				
			||||||
 | 
						PCO_P_DNS_IPv6_ADDR	= 0x0003,
 | 
				
			||||||
 | 
						PCO_P_POLICY_CTRL_REJ	= 0x0004,	/* only in Network->MS */
 | 
				
			||||||
 | 
						PCO_P_MS_SUP_NETREQ_BCI	= 0x0005,
 | 
				
			||||||
 | 
						/* reserved */
 | 
				
			||||||
 | 
						PCO_P_DSMIPv6_HA_ADDR	= 0x0007,
 | 
				
			||||||
 | 
						PCO_P_DSMIPv6_HN_PREF	= 0x0008,
 | 
				
			||||||
 | 
						PCO_P_DSMIPv6_v4_HA_ADDR= 0x0009,
 | 
				
			||||||
 | 
						PCO_P_IP_ADDR_VIA_NAS	= 0x000a,	/* only MS->Network */
 | 
				
			||||||
 | 
						PCO_P_IPv4_ADDR_VIA_DHCP= 0x000b,	/* only MS->Netowrk */
 | 
				
			||||||
 | 
						PCO_P_PCSCF_IPv4_ADDR	= 0x000c,
 | 
				
			||||||
 | 
						PCO_P_DNS_IPv4_ADDR	= 0x000d,
 | 
				
			||||||
 | 
						PCO_P_MSISDN		= 0x000e,
 | 
				
			||||||
 | 
						PCO_P_IFOM_SUPPORT	= 0x000f,
 | 
				
			||||||
 | 
						PCO_P_IPv4_LINK_MTU	= 0x0010,
 | 
				
			||||||
 | 
						PCO_P_MS_SUPP_LOC_A_TFT	= 0x0011,
 | 
				
			||||||
 | 
						PCO_P_PCSCF_RESEL_SUP	= 0x0012,	/* only MS->Network */
 | 
				
			||||||
 | 
						PCO_P_NBIFOM_REQ	= 0x0013,
 | 
				
			||||||
 | 
						PCO_P_NBIFOM_MODE	= 0x0014,
 | 
				
			||||||
 | 
						PCO_P_NONIP_LINK_MTU	= 0x0015,
 | 
				
			||||||
 | 
						PCO_P_APN_RATE_CTRL_SUP	= 0x0016,
 | 
				
			||||||
 | 
						PCO_P_PS_DATA_OFF_UE	= 0x0017,
 | 
				
			||||||
 | 
						PCO_P_REL_DATA_SVC	= 0x0018,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pco_element {
 | 
				
			||||||
 | 
						uint16_t protocol_id;	/* network byte order */
 | 
				
			||||||
 | 
						uint8_t length;		/* length of data below */
 | 
				
			||||||
 | 
						uint8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC 1332 IP Control Protocol options, extensions in RFC 1877 */
 | 
				
			||||||
 | 
					enum ipcp_options {
 | 
				
			||||||
 | 
						IPCP_OPT_IPADDR = 3, /* RFC 1332 3.3 */
 | 
				
			||||||
 | 
						IPCP_OPT_PRIMARY_DNS = 129, /* RFC 1877 1.1 */
 | 
				
			||||||
 | 
						IPCP_OPT_SECONDARY_DNS = 131,  /* RFC 1877 1.2 */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ipcp_option_hdr {
 | 
				
			||||||
 | 
						uint8_t type;
 | 
				
			||||||
 | 
						uint8_t len;
 | 
				
			||||||
 | 
						uint8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ipcp_hdr {
 | 
				
			||||||
 | 
						uint8_t code;
 | 
				
			||||||
 | 
						uint8_t id;
 | 
				
			||||||
 | 
						uint16_t len;
 | 
				
			||||||
 | 
						uint8_t options[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC 1334, section 3.2. Packet Format */
 | 
				
			||||||
 | 
					struct pap_element {
 | 
				
			||||||
 | 
						uint8_t code;
 | 
				
			||||||
 | 
						uint8_t id;
 | 
				
			||||||
 | 
						uint16_t len; /* length including header */
 | 
				
			||||||
 | 
						uint8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum pap_code {
 | 
				
			||||||
 | 
						PAP_CODE_AUTH_REQ = 1,
 | 
				
			||||||
 | 
						PAP_CODE_AUTH_ACK = 2,
 | 
				
			||||||
 | 
						PAP_CODE_AUTH_NAK = 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct apn_ctx;
 | 
				
			||||||
 | 
					void process_pco(const struct apn_ctx *apn, struct pdp_t *pdp);
 | 
				
			||||||
							
								
								
									
										168
									
								
								ggsn/sgsn.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								ggsn/sgsn.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
				
			|||||||
 | 
					#include "sgsn.h"
 | 
				
			||||||
 | 
					#include "ggsn.h"
 | 
				
			||||||
 | 
					#include "../gtp/gtp_internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool sgsn_peer_attempt_free(struct sgsn_peer *sgsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* We have to be careful here, since if all pdp ctx for that sgsn were
 | 
				
			||||||
 | 
						   deactivated in-between we sent the Echo Req and receivied the timeout
 | 
				
			||||||
 | 
						   indication, the sgsn (cbp) may be already gone. We need to add some
 | 
				
			||||||
 | 
						   counter reference of echo requets in flight and only free sgsn
 | 
				
			||||||
 | 
						   structures when it goes to zero decreased for all Echo Resp. We do it
 | 
				
			||||||
 | 
						   this way because currently in libgtp there's no understanding of "gsn
 | 
				
			||||||
 | 
						   peer" for which messages are grouped and hence we cannot request
 | 
				
			||||||
 | 
						   libgtp to drop all queued messages for a specific peer. */
 | 
				
			||||||
 | 
						if (sgsn->tx_msgs_queued) {
 | 
				
			||||||
 | 
							LOGSGSN(LOGL_INFO, sgsn, "Delaying delete, still %u echo messages queued\n",
 | 
				
			||||||
 | 
								sgsn->tx_msgs_queued);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						llist_del(&sgsn->entry);
 | 
				
			||||||
 | 
						LOGSGSN(LOGL_INFO, sgsn, "Deleting SGSN\n");
 | 
				
			||||||
 | 
						talloc_free(sgsn);
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void sgsn_peer_echo_req(struct sgsn_peer *sgsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ggsn_ctx *ggsn = sgsn->ggsn;
 | 
				
			||||||
 | 
						LOGSGSN(LOGL_INFO, sgsn, "Tx Echo Request\n");
 | 
				
			||||||
 | 
						gtp_echo_req(ggsn->gsn, sgsn->gtp_version, sgsn, &sgsn->addr);
 | 
				
			||||||
 | 
						sgsn->tx_msgs_queued++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sgsn_peer_echo_resp(struct sgsn_peer *sgsn, bool timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (timeout) {
 | 
				
			||||||
 | 
							LOGSGSN(LOGL_NOTICE, sgsn, "Rx Echo Request timed out!\n");
 | 
				
			||||||
 | 
							sgsn_peer_drop_all_pdp(sgsn);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							LOGSGSN(LOGL_INFO, sgsn, "Rx Echo Response\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We decrement it here after dropping all pdps to make sure sgsn was
 | 
				
			||||||
 | 
						   not freed upon last pdp ctx deleted and is still alive now */
 | 
				
			||||||
 | 
						sgsn->tx_msgs_queued--;
 | 
				
			||||||
 | 
						if (llist_empty(&sgsn->pdp_list))
 | 
				
			||||||
 | 
							sgsn_peer_attempt_free(sgsn);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sgsn_echo_timer_start(struct sgsn_peer *sgsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (sgsn->ggsn->cfg.echo_interval == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						sgsn_peer_echo_req(sgsn);
 | 
				
			||||||
 | 
						osmo_timer_schedule(&sgsn->echo_timer, sgsn->ggsn->cfg.echo_interval, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sgsn_echo_timer_stop(struct sgsn_peer *sgsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						osmo_timer_del(&sgsn->echo_timer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void sgsn_echo_timer_cb(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sgsn_peer *sgsn = (struct sgsn_peer *) data;
 | 
				
			||||||
 | 
						sgsn_echo_timer_start(sgsn);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sgsn_peer *sgsn_peer_allocate(struct ggsn_ctx *ggsn, struct in_addr *ia, unsigned int gtp_version)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sgsn_peer *sgsn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sgsn = talloc_zero_size(ggsn, sizeof(struct sgsn_peer));
 | 
				
			||||||
 | 
						sgsn->ggsn = ggsn;
 | 
				
			||||||
 | 
						sgsn->addr = *ia;
 | 
				
			||||||
 | 
						sgsn->gtp_version = gtp_version;
 | 
				
			||||||
 | 
						sgsn->remote_restart_ctr = -1;
 | 
				
			||||||
 | 
						INIT_LLIST_HEAD(&sgsn->pdp_list);
 | 
				
			||||||
 | 
						INIT_LLIST_HEAD(&sgsn->entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						osmo_timer_setup(&sgsn->echo_timer, sgsn_echo_timer_cb, sgsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						LOGSGSN(LOGL_INFO, sgsn, "Discovered\n");
 | 
				
			||||||
 | 
						return sgsn;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sgsn_peer_add_pdp_priv(struct sgsn_peer *sgsn, struct pdp_priv_t *pdp_priv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool was_empty = llist_empty(&sgsn->pdp_list);
 | 
				
			||||||
 | 
						pdp_priv->sgsn = sgsn;
 | 
				
			||||||
 | 
						llist_add(&pdp_priv->entry, &sgsn->pdp_list);
 | 
				
			||||||
 | 
						if (was_empty)
 | 
				
			||||||
 | 
							sgsn_echo_timer_start(sgsn);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sgsn_peer_remove_pdp_priv(struct pdp_priv_t* pdp_priv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sgsn_peer *sgsn = pdp_priv->sgsn;
 | 
				
			||||||
 | 
						llist_del(&pdp_priv->entry);
 | 
				
			||||||
 | 
						if (sgsn && llist_empty(&sgsn->pdp_list)) {
 | 
				
			||||||
 | 
							/* No PDP contexts associated to this SGSN, no need to keep it */
 | 
				
			||||||
 | 
							sgsn_echo_timer_stop(sgsn);
 | 
				
			||||||
 | 
							/* sgsn may not be freed if there are some messages still queued
 | 
				
			||||||
 | 
							   in libgtp which could return a pointer to it */
 | 
				
			||||||
 | 
							sgsn_peer_attempt_free(sgsn);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pdp_priv->sgsn = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* High-level function to be called in case a GGSN has disappeared or
 | 
				
			||||||
 | 
					 * otherwise lost state (recovery procedure). It will detach all related pdp ctx
 | 
				
			||||||
 | 
					 * from a ggsn and communicate deact to MS. Optionally (!NULL), one pdp ctx can
 | 
				
			||||||
 | 
					 * be kept alive to allow handling later message which contained the Recovery IE. */
 | 
				
			||||||
 | 
					static unsigned int sgsn_peer_drop_all_pdp_except(struct sgsn_peer *sgsn, struct pdp_priv_t *except)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int num = 0;
 | 
				
			||||||
 | 
						char buf[INET_ADDRSTRLEN];
 | 
				
			||||||
 | 
						unsigned int count = llist_count(&sgsn->pdp_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inet_ntop(AF_INET, &sgsn->addr, buf, sizeof(buf));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct pdp_priv_t *pdp, *pdp2;
 | 
				
			||||||
 | 
						llist_for_each_entry_safe(pdp, pdp2, &sgsn->pdp_list, entry) {
 | 
				
			||||||
 | 
							if (pdp == except)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							ggsn_close_one_pdp(pdp->lib);
 | 
				
			||||||
 | 
							num++;
 | 
				
			||||||
 | 
							if (num == count) {
 | 
				
			||||||
 | 
								/* Note: if except is NULL, all pdp contexts are freed and sgsn
 | 
				
			||||||
 | 
								 * is most probably already freed at this point.
 | 
				
			||||||
 | 
								 * As a result, last access to sgsn->pdp_list before exiting
 | 
				
			||||||
 | 
								 * loop would access already freed memory. Avoid it by exiting
 | 
				
			||||||
 | 
								 * the loop without the last check, and make sure sgsn is not
 | 
				
			||||||
 | 
								 * accessed after this loop. */
 | 
				
			||||||
 | 
								 break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						LOGP(DGGSN, LOGL_INFO, "SGSN(%s) Dropped %u PDP contexts\n", buf, num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return num;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int sgsn_peer_drop_all_pdp(struct sgsn_peer *sgsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return sgsn_peer_drop_all_pdp_except(sgsn, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sgsn_peer_handle_recovery(struct sgsn_peer *sgsn, struct pdp_t *pdp, uint8_t recovery)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pdp_priv_t *pdp_priv = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sgsn->remote_restart_ctr == -1) {
 | 
				
			||||||
 | 
							/* First received ECHO RESPONSE, note the restart ctr */
 | 
				
			||||||
 | 
							sgsn->remote_restart_ctr = recovery;
 | 
				
			||||||
 | 
						} else if (sgsn->remote_restart_ctr != recovery) {
 | 
				
			||||||
 | 
							/* counter has changed (SGSN restart): release all PDP */
 | 
				
			||||||
 | 
							LOGSGSN(LOGL_NOTICE, sgsn, "SGSN recovery (%u->%u) pdp=%p, "
 | 
				
			||||||
 | 
							     "releasing all%s PDP contexts\n",
 | 
				
			||||||
 | 
							     sgsn->remote_restart_ctr, recovery, pdp, pdp ? " other" : "");
 | 
				
			||||||
 | 
							sgsn->remote_restart_ctr = recovery;
 | 
				
			||||||
 | 
							if (pdp)
 | 
				
			||||||
 | 
								pdp_priv = pdp->priv;
 | 
				
			||||||
 | 
							sgsn_peer_drop_all_pdp_except(sgsn, pdp_priv);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								ggsn/sgsn.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								ggsn/sgsn.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/linuxlist.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/timer.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ggsn_ctx;
 | 
				
			||||||
 | 
					struct pdp_priv_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sgsn_peer {
 | 
				
			||||||
 | 
						struct llist_head entry; /* to be included into ggsn_ctx */
 | 
				
			||||||
 | 
						struct ggsn_ctx *ggsn; /* backpointer to ggsn_ctx */
 | 
				
			||||||
 | 
						struct in_addr addr;	/* Addr of the sgsn peer */
 | 
				
			||||||
 | 
						unsigned int gtp_version; /* GTP version */
 | 
				
			||||||
 | 
						int remote_restart_ctr; /* Last received Restart Ctr from sgsn peer, -1 == unknown */
 | 
				
			||||||
 | 
						/* list of pdp contexts associated with this sgsn */
 | 
				
			||||||
 | 
						struct llist_head pdp_list;
 | 
				
			||||||
 | 
						/* Sends echo request towards SGSN on expiration. Echo Resp is received
 | 
				
			||||||
 | 
						   through cb_recovery2(), and echo Req timeout through
 | 
				
			||||||
 | 
						   cb_conf(GTP_ECHO_REQ, EOF, NULL, cbp); */
 | 
				
			||||||
 | 
						struct osmo_timer_list echo_timer;
 | 
				
			||||||
 | 
						/* Number of GTP messages in libgtp transmit queue */
 | 
				
			||||||
 | 
						unsigned int tx_msgs_queued;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sgsn_peer *sgsn_peer_allocate(struct ggsn_ctx *ggsn, struct in_addr *ia, unsigned int gtp_version);
 | 
				
			||||||
 | 
					void sgsn_peer_add_pdp_priv(struct sgsn_peer *sgsn, struct pdp_priv_t *pdp_priv);
 | 
				
			||||||
 | 
					void sgsn_peer_remove_pdp_priv(struct pdp_priv_t *pdp_priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sgsn_echo_timer_start(struct sgsn_peer *sgsn);
 | 
				
			||||||
 | 
					void sgsn_echo_timer_stop(struct sgsn_peer *sgsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void sgsn_peer_echo_resp(struct sgsn_peer *sgsn, bool timeout);
 | 
				
			||||||
 | 
					unsigned int sgsn_peer_drop_all_pdp(struct sgsn_peer *sgsn);
 | 
				
			||||||
 | 
					int sgsn_peer_handle_recovery(struct sgsn_peer *sgsn, struct pdp_t *pdp, uint8_t recovery);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LOGSGSN(level, sgsn, fmt, args...) { \
 | 
				
			||||||
 | 
						char _buf[INET_ADDRSTRLEN]; \
 | 
				
			||||||
 | 
						LOGP(DGGSN, level, "SGSN(%s): " fmt, inet_ntop(AF_INET, &sgsn->addr, _buf, sizeof(_buf)), ## args); \
 | 
				
			||||||
 | 
						} while (0)
 | 
				
			||||||
							
								
								
									
										151
									
								
								git-version-gen
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										151
									
								
								git-version-gen
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,151 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					# Print a version string.
 | 
				
			||||||
 | 
					scriptversion=2010-01-28.01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Copyright (C) 2007-2010 Free Software Foundation, Inc.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation; either version 3 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
 | 
				
			||||||
 | 
					# It may be run two ways:
 | 
				
			||||||
 | 
					# - from a git repository in which the "git describe" command below
 | 
				
			||||||
 | 
					#   produces useful output (thus requiring at least one signed tag)
 | 
				
			||||||
 | 
					# - from a non-git-repo directory containing a .tarball-version file, which
 | 
				
			||||||
 | 
					#   presumes this script is invoked like "./git-version-gen .tarball-version".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# In order to use intra-version strings in your project, you will need two
 | 
				
			||||||
 | 
					# separate generated version string files:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# .tarball-version - present only in a distribution tarball, and not in
 | 
				
			||||||
 | 
					#   a checked-out repository.  Created with contents that were learned at
 | 
				
			||||||
 | 
					#   the last time autoconf was run, and used by git-version-gen.  Must not
 | 
				
			||||||
 | 
					#   be present in either $(srcdir) or $(builddir) for git-version-gen to
 | 
				
			||||||
 | 
					#   give accurate answers during normal development with a checked out tree,
 | 
				
			||||||
 | 
					#   but must be present in a tarball when there is no version control system.
 | 
				
			||||||
 | 
					#   Therefore, it cannot be used in any dependencies.  GNUmakefile has
 | 
				
			||||||
 | 
					#   hooks to force a reconfigure at distribution time to get the value
 | 
				
			||||||
 | 
					#   correct, without penalizing normal development with extra reconfigures.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# .version - present in a checked-out repository and in a distribution
 | 
				
			||||||
 | 
					#   tarball.  Usable in dependencies, particularly for files that don't
 | 
				
			||||||
 | 
					#   want to depend on config.h but do want to track version changes.
 | 
				
			||||||
 | 
					#   Delete this file prior to any autoconf run where you want to rebuild
 | 
				
			||||||
 | 
					#   files to pick up a version string change; and leave it stale to
 | 
				
			||||||
 | 
					#   minimize rebuild time after unrelated changes to configure sources.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# It is probably wise to add these two files to .gitignore, so that you
 | 
				
			||||||
 | 
					# don't accidentally commit either generated file.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Use the following line in your configure.ac, so that $(VERSION) will
 | 
				
			||||||
 | 
					# automatically be up-to-date each time configure is run (and note that
 | 
				
			||||||
 | 
					# since configure.ac no longer includes a version string, Makefile rules
 | 
				
			||||||
 | 
					# should not depend on configure.ac for version updates).
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# AC_INIT([GNU project],
 | 
				
			||||||
 | 
					#         m4_esyscmd([build-aux/git-version-gen .tarball-version]),
 | 
				
			||||||
 | 
					#         [bug-project@example])
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Then use the following lines in your Makefile.am, so that .version
 | 
				
			||||||
 | 
					# will be present for dependencies, and so that .tarball-version will
 | 
				
			||||||
 | 
					# exist in distribution tarballs.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# BUILT_SOURCES = $(top_srcdir)/.version
 | 
				
			||||||
 | 
					# $(top_srcdir)/.version:
 | 
				
			||||||
 | 
					#	echo $(VERSION) > $@-t && mv $@-t $@
 | 
				
			||||||
 | 
					# dist-hook:
 | 
				
			||||||
 | 
					#	echo $(VERSION) > $(distdir)/.tarball-version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case $# in
 | 
				
			||||||
 | 
					    1) ;;
 | 
				
			||||||
 | 
					    *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tarball_version_file=$1
 | 
				
			||||||
 | 
					nl='
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# First see if there is a tarball-only version file.
 | 
				
			||||||
 | 
					# then try "git describe", then default.
 | 
				
			||||||
 | 
					if test -f $tarball_version_file
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
					    v=`cat $tarball_version_file` || exit 1
 | 
				
			||||||
 | 
					    case $v in
 | 
				
			||||||
 | 
						*$nl*) v= ;; # reject multi-line output
 | 
				
			||||||
 | 
						[0-9]*) ;;
 | 
				
			||||||
 | 
						*) v= ;;
 | 
				
			||||||
 | 
					    esac
 | 
				
			||||||
 | 
					    test -z "$v" \
 | 
				
			||||||
 | 
						&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if test -n "$v"
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
					    : # use $v
 | 
				
			||||||
 | 
					elif
 | 
				
			||||||
 | 
					       v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
 | 
				
			||||||
 | 
						  || git describe --abbrev=4 HEAD 2>/dev/null` \
 | 
				
			||||||
 | 
					    && case $v in
 | 
				
			||||||
 | 
						 [0-9]*) ;;
 | 
				
			||||||
 | 
						 v[0-9]*) ;;
 | 
				
			||||||
 | 
						 *) (exit 1) ;;
 | 
				
			||||||
 | 
					       esac
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
					    # Is this a new git that lists number of commits since the last
 | 
				
			||||||
 | 
					    # tag or the previous older version that did not?
 | 
				
			||||||
 | 
					    #   Newer: v6.10-77-g0f8faeb
 | 
				
			||||||
 | 
					    #   Older: v6.10-g0f8faeb
 | 
				
			||||||
 | 
					    case $v in
 | 
				
			||||||
 | 
						*-*-*) : git describe is okay three part flavor ;;
 | 
				
			||||||
 | 
						*-*)
 | 
				
			||||||
 | 
						    : git describe is older two part flavor
 | 
				
			||||||
 | 
						    # Recreate the number of commits and rewrite such that the
 | 
				
			||||||
 | 
						    # result is the same as if we were using the newer version
 | 
				
			||||||
 | 
						    # of git describe.
 | 
				
			||||||
 | 
						    vtag=`echo "$v" | sed 's/-.*//'`
 | 
				
			||||||
 | 
						    numcommits=`git rev-list "$vtag"..HEAD | wc -l`
 | 
				
			||||||
 | 
						    v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
 | 
				
			||||||
 | 
						    ;;
 | 
				
			||||||
 | 
					    esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Change the first '-' to a '.', so version-comparing tools work properly.
 | 
				
			||||||
 | 
					    # Remove the "g" in git describe's output string, to save a byte.
 | 
				
			||||||
 | 
					    v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					    v=UNKNOWN
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v=`echo "$v" |sed 's/^v//'`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Don't declare a version "dirty" merely because a time stamp has changed.
 | 
				
			||||||
 | 
					git status > /dev/null 2>&1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
 | 
				
			||||||
 | 
					case "$dirty" in
 | 
				
			||||||
 | 
					    '') ;;
 | 
				
			||||||
 | 
					    *) # Append the suffix only if there isn't one already.
 | 
				
			||||||
 | 
						case $v in
 | 
				
			||||||
 | 
						  *-dirty) ;;
 | 
				
			||||||
 | 
						  *) v="$v-dirty" ;;
 | 
				
			||||||
 | 
						esac ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Omit the trailing newline, so that m4_esyscmd can use the result directly.
 | 
				
			||||||
 | 
					echo "$v" | tr -d '\012'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Local variables:
 | 
				
			||||||
 | 
					# eval: (add-hook 'write-file-hooks 'time-stamp)
 | 
				
			||||||
 | 
					# time-stamp-start: "scriptversion="
 | 
				
			||||||
 | 
					# time-stamp-format: "%:y-%02m-%02d.%02H"
 | 
				
			||||||
 | 
					# time-stamp-end: "$"
 | 
				
			||||||
 | 
					# End:
 | 
				
			||||||
@@ -1,12 +1,31 @@
 | 
				
			|||||||
 | 
					# This is _NOT_ the library release version, it's an API version.
 | 
				
			||||||
 | 
					# Please read chapter "Library interface versions" of the libtool documentation
 | 
				
			||||||
 | 
					# before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html
 | 
				
			||||||
 | 
					# If major=current-age is increased, remember to update the dh_strip line in debian/rules!
 | 
				
			||||||
 | 
					LIBVERSION=11:0:0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lib_LTLIBRARIES = libgtp.la
 | 
					lib_LTLIBRARIES = libgtp.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include_HEADERS = gtp.h pdp.h
 | 
					AM_CFLAGS = \
 | 
				
			||||||
 | 
						    -fno-builtin \
 | 
				
			||||||
 | 
						    -Wall \
 | 
				
			||||||
 | 
						    -DSBINDIR='"$(sbindir)"' \
 | 
				
			||||||
 | 
						    -I$(top_srcdir)/include \
 | 
				
			||||||
 | 
						    $(LIBOSMOCORE_CFLAGS) \
 | 
				
			||||||
 | 
						    $(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AM_CFLAGS = -O2 -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
 | 
					libgtp_la_SOURCES = \
 | 
				
			||||||
 | 
							    gsn.c \
 | 
				
			||||||
 | 
							    gsn_internal.h \
 | 
				
			||||||
 | 
							    gtp.c \
 | 
				
			||||||
 | 
							    gtp_internal.h \
 | 
				
			||||||
 | 
							    gtpie.c \
 | 
				
			||||||
 | 
							    lookupa.c \
 | 
				
			||||||
 | 
							    lookupa.h \
 | 
				
			||||||
 | 
							    pdp.c \
 | 
				
			||||||
 | 
							    queue.c \
 | 
				
			||||||
 | 
							    queue.h \
 | 
				
			||||||
 | 
							    $(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libgtp_la_SOURCES = gtp.c gtp.h gtpie.c gtpie.h pdp.c pdp.h lookupa.c lookupa.h queue.c queue.h
 | 
					libgtp_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined
 | 
				
			||||||
libgtp_la_LIBADD = $(LIBOSMOCORE_LIBS)
 | 
					libgtp_la_LIBADD = $(LIBOSMOCORE_LIBS)
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										587
									
								
								gtp/gsn.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										587
									
								
								gtp/gsn.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,587 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 | 
					 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
				
			||||||
 | 
					 *  Copyright (C) 2010-2011, 2016-2017 Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 *  Copyright (C) 2015-2017 sysmocom - s.f.m.c. GmbH
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 | 
					 *  General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 | 
					 *  notice and this permission notice is included in all copies or
 | 
				
			||||||
 | 
					 *  substantial portions of the software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * gtp.c: Contains all GTP functionality. Should be able to handle multiple
 | 
				
			||||||
 | 
					 * tunnels in the same program.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * TODO:
 | 
				
			||||||
 | 
					 *  - Do we need to handle fragmentation?
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __linux__
 | 
				
			||||||
 | 
					#define _GNU_SOURCE 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/logging.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/utils.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/stats.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/rate_ctr.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__FreeBSD__)
 | 
				
			||||||
 | 
					#include <sys/endian.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../config.h"
 | 
				
			||||||
 | 
					#ifdef HAVE_STDINT_H
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* #include <stdint.h>  ISO C99 types */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtp.h>
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtpie.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "queue.h"
 | 
				
			||||||
 | 
					#include "gsn_internal.h"
 | 
				
			||||||
 | 
					#include "gtp_internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Error reporting functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LOGP_WITH_ADDR(ss, level, addr, fmt, args...)                    \
 | 
				
			||||||
 | 
							LOGP(ss, level, "addr(%s:%d) " fmt,                      \
 | 
				
			||||||
 | 
							     inet_ntoa((addr).sin_addr), htons((addr).sin_port), \
 | 
				
			||||||
 | 
							     ##args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct rate_ctr_desc gsn_ctr_description[] = {
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_SOCKET] = { "err:socket", "Socket error" },
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_READFROM] = { "err:readfrom", "readfrom() errors" },
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_SENDTO] = { "err:sendto", "sendto() errors" },
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_QUEUEFULL] = { "err:queuefull", "Failed to queue message because queue is full" },
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_SEQ] = { "err:seq", "Sequence number out of range" },
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_ADDRESS] = { "err:address", "GSN address conversion failed" },
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_UNKNOWN_PDP] = { "err:unknown_pdp", "Failed looking up PDP context" },
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_UNEXPECTED_CAUSE] = { "err:unexpected_cause", "Unexpected cause value received" },
 | 
				
			||||||
 | 
						[GSN_CTR_ERR_OUT_OF_PDP] = { "err:out_of_pdp", "Out of storage for PDP contexts" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_EMPTY] = { "pkt:empty", "Empty packet received" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_UNSUP] = { "pkt:unsupported", "Unsupported GTP version received" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_TOOSHORT] = { "pkt:too_short", "Packet too short received" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_UNKNOWN] = { "pkt:unknown", "Unknown packet type received" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_UNEXPECT] = { "pkt:unexpected", "Unexpected packet type received" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_DUPLICATE] = { "pkt:duplicate", "Duplicate or unsolicited packet received" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_MISSING] = { "pkt:missing", "Missing IE in packet received" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_INCORRECT] = { "pkt:incorrect", "Incorrect IE in packet received" },
 | 
				
			||||||
 | 
						[GSN_CTR_PKT_INVALID] = { "pkt:invalid", "Invalid format in packet received" },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct rate_ctr_group_desc gsn_ctrg_desc = {
 | 
				
			||||||
 | 
						"gsn",
 | 
				
			||||||
 | 
						"GSN Statistics",
 | 
				
			||||||
 | 
						OSMO_STATS_CLASS_PEER,
 | 
				
			||||||
 | 
						ARRAY_SIZE(gsn_ctr_description),
 | 
				
			||||||
 | 
						gsn_ctr_description,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static unsigned int gsn_ctr_next_idx = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Global timer definitions for GTP operation, provided for convenience. To make these user configurable, it is convenient to add
 | 
				
			||||||
 | 
					 * gtp_gsn_tdefs as one of your program's osmo_tdef_group entries and call osmo_tdef_vty_init(). */
 | 
				
			||||||
 | 
					struct osmo_tdef gtp_T_defs[] = {
 | 
				
			||||||
 | 
						{ .T = GTP_GSN_TIMER_T3_RESPONSE, .default_val = 5, .unit = OSMO_TDEF_S,
 | 
				
			||||||
 | 
						  .desc = "Timer T3-RESPONSE holds the maximum wait time for a response of a request message"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{ .T = GTP_GSN_TIMER_N3_REQUESTS, .default_val = 3, .unit = OSMO_TDEF_CUSTOM,
 | 
				
			||||||
 | 
						  .desc = "Counter N3-REQUESTS holds the maximum number of attempts made by GTP to send a request message"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{ .T = GTP_GSN_TIMER_T3_HOLD_RESPONSE, .default_val = 5 * 3 /* (GTP_GSN_TIMER_T3_RESPONSE * GTP_GSN_TIMER_N3_REQUESTS) */, .unit = OSMO_TDEF_S,
 | 
				
			||||||
 | 
						  .desc = "Time a GTP respoonse message is kept cached to re-transmit it when a duplicate request is received. Value is generally equal to (T3-RESPONSE * N3-REQUESTS) set at the peer"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* API Functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Deprecated, use gtp_pdp_newpdp() instead */
 | 
				
			||||||
 | 
					int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
 | 
				
			||||||
 | 
						       uint64_t imsi, uint8_t nsapi)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
						rc = gtp_pdp_newpdp(gsn, pdp, imsi, nsapi, NULL);
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (gsn->cb_delete_context)
 | 
				
			||||||
 | 
							gsn->cb_delete_context(pdp);
 | 
				
			||||||
 | 
						return pdp_freepdp(pdp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Free pdp and all its secondary PDP contexts. Must be called on the primary PDP context. */
 | 
				
			||||||
 | 
					int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int n;
 | 
				
			||||||
 | 
						struct pdp_t *secondary_pdp;
 | 
				
			||||||
 | 
						OSMO_ASSERT(!pdp->secondary);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (n = 0; n < PDP_MAXNSAPI; n++) {
 | 
				
			||||||
 | 
							if (pdp->secondary_tei[n]) {
 | 
				
			||||||
 | 
								if (gtp_pdp_getgtp1(gsn, &secondary_pdp,
 | 
				
			||||||
 | 
										     pdp->secondary_tei[n])) {
 | 
				
			||||||
 | 
									LOGP(DLGTP, LOGL_ERROR,
 | 
				
			||||||
 | 
										"Unknown secondary PDP context\n");
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (pdp != secondary_pdp) {
 | 
				
			||||||
 | 
									gtp_freepdp(gsn, secondary_pdp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return gtp_freepdp(gsn, pdp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* gtp_gpdu */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_fd(struct gsn_t *gsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return gsn->fd0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								 int (*cb) (struct sockaddr_in * peer))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_unsup_ind = cb;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								     int (*cb) (struct sockaddr_in * peer))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_extheader_ind = cb;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_set_cb_ran_info_relay_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								     int (*cb) (struct sockaddr_in * peer, union gtpie_member **ie))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_ran_info_relay_ind = cb;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* API: Initialise delete context callback */
 | 
				
			||||||
 | 
					/* Called whenever a pdp context is deleted for any reason */
 | 
				
			||||||
 | 
					int gtp_set_cb_delete_context(struct gsn_t *gsn, int (*cb) (struct pdp_t * pdp))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_delete_context = cb;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_set_cb_conf(struct gsn_t *gsn,
 | 
				
			||||||
 | 
							    int (*cb) (int type, int cause,
 | 
				
			||||||
 | 
								       struct pdp_t * pdp, void *cbp))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_conf = cb;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_set_cb_recovery(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								int (*cb) (struct sockaddr_in * peer, uint8_t recovery))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_recovery = cb;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* cb_recovery()
 | 
				
			||||||
 | 
					 * pdp may be NULL if Recovery IE was received from a message independent
 | 
				
			||||||
 | 
					 * of any PDP ctx (such as Echo Response), or because pdp ctx is unknown to the
 | 
				
			||||||
 | 
					 * local setup. In case pdp is known, caller may want to keep that pdp alive to
 | 
				
			||||||
 | 
					 * handle subsequent msg cb as this specific pdp ctx is still valid according to
 | 
				
			||||||
 | 
					 * specs.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int gtp_set_cb_recovery2(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								int (*cb_recovery2) (struct sockaddr_in * peer, struct pdp_t * pdp, uint8_t recovery))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_recovery2 = cb_recovery2;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* cb_recovery()
 | 
				
			||||||
 | 
					 * pdp may be NULL if Recovery IE was received from a message independent
 | 
				
			||||||
 | 
					 * of any PDP ctx (such as Echo Response), or because pdp ctx is unknown to the
 | 
				
			||||||
 | 
					 * local setup. In case pdp is known, caller may want to keep that pdp alive to
 | 
				
			||||||
 | 
					 * handle subsequent msg cb as this specific pdp ctx is still valid according to
 | 
				
			||||||
 | 
					 * specs.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int gtp_set_cb_recovery3(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								 int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer,
 | 
				
			||||||
 | 
										      struct pdp_t *pdp, uint8_t recovery))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_recovery3 = cb_recovery3;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_set_cb_data_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								       int (*cb_data_ind) (struct pdp_t * pdp,
 | 
				
			||||||
 | 
											   void *pack, unsigned len))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_data_ind = cb_data_ind;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int queue_timer_retrans(struct gsn_t *gsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Retransmit any outstanding packets */
 | 
				
			||||||
 | 
						/* Remove from queue if maxretrans exceeded */
 | 
				
			||||||
 | 
						time_t now;
 | 
				
			||||||
 | 
						struct qmsg_t *qmsg;
 | 
				
			||||||
 | 
						unsigned int t3_response, n3_requests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						now = time(NULL);
 | 
				
			||||||
 | 
						t3_response = osmo_tdef_get(gsn->tdef, GTP_GSN_TIMER_T3_RESPONSE, OSMO_TDEF_S, -1);
 | 
				
			||||||
 | 
						n3_requests = osmo_tdef_get(gsn->tdef, GTP_GSN_TIMER_N3_REQUESTS, OSMO_TDEF_CUSTOM, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* get first element in queue, as long as the timeout of that
 | 
				
			||||||
 | 
						 * element has expired */
 | 
				
			||||||
 | 
						while ((!queue_getfirst(gsn->queue_req, &qmsg)) &&
 | 
				
			||||||
 | 
						       (qmsg->timeout <= now)) {
 | 
				
			||||||
 | 
							if (qmsg->retrans > n3_requests) {	/* Too many retrans */
 | 
				
			||||||
 | 
								LOGP(DLGTP, LOGL_NOTICE, "Retransmit req queue timeout of seq %" PRIu16 "\n",
 | 
				
			||||||
 | 
								     qmsg->seq);
 | 
				
			||||||
 | 
								if (gsn->cb_conf)
 | 
				
			||||||
 | 
									gsn->cb_conf(qmsg->type, EOF, NULL, qmsg->cbp);
 | 
				
			||||||
 | 
								queue_freemsg(gsn->queue_req, qmsg);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								LOGP(DLGTP, LOGL_INFO, "Retransmit (%d) of seq %" PRIu16 "\n",
 | 
				
			||||||
 | 
								     qmsg->retrans, qmsg->seq);
 | 
				
			||||||
 | 
								if (sendto(qmsg->fd, &qmsg->p, qmsg->l, 0,
 | 
				
			||||||
 | 
									   (struct sockaddr *)&qmsg->peer,
 | 
				
			||||||
 | 
									   sizeof(struct sockaddr_in)) < 0) {
 | 
				
			||||||
 | 
									rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SENDTO);
 | 
				
			||||||
 | 
									LOGP(DLGTP, LOGL_ERROR,
 | 
				
			||||||
 | 
										"Sendto(fd0=%d, msg=%lx, len=%d) failed: Error = %s\n",
 | 
				
			||||||
 | 
										gsn->fd0, (unsigned long)&qmsg->p,
 | 
				
			||||||
 | 
										qmsg->l, strerror(errno));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								queue_back(gsn->queue_req, qmsg);
 | 
				
			||||||
 | 
								qmsg->timeout = now + t3_response;
 | 
				
			||||||
 | 
								qmsg->retrans++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Also clean up reply timeouts */
 | 
				
			||||||
 | 
						while ((!queue_getfirst(gsn->queue_resp, &qmsg)) &&
 | 
				
			||||||
 | 
						       (qmsg->timeout < now)) {
 | 
				
			||||||
 | 
							LOGP(DLGTP, LOGL_DEBUG, "Retransmit resp queue seq %"
 | 
				
			||||||
 | 
							     PRIu16 " expired, removing from queue\n", qmsg->seq);
 | 
				
			||||||
 | 
							queue_freemsg(gsn->queue_resp, qmsg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int queue_timer_retranstimeout(struct gsn_t *gsn, struct timeval *timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						time_t now, later, diff;
 | 
				
			||||||
 | 
						struct qmsg_t *qmsg;
 | 
				
			||||||
 | 
						timeout->tv_usec = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (queue_getfirst(gsn->queue_req, &qmsg)) {
 | 
				
			||||||
 | 
							timeout->tv_sec = 10;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							now = time(NULL);
 | 
				
			||||||
 | 
							later = qmsg->timeout;
 | 
				
			||||||
 | 
							timeout->tv_sec = later - now;
 | 
				
			||||||
 | 
							if (timeout->tv_sec < 0)
 | 
				
			||||||
 | 
								timeout->tv_sec = 0;	/* No negative allowed */
 | 
				
			||||||
 | 
							if (timeout->tv_sec > 10)
 | 
				
			||||||
 | 
								timeout->tv_sec = 10;	/* Max sleep for 10 sec */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (queue_getfirst(gsn->queue_resp, &qmsg)) {
 | 
				
			||||||
 | 
							/* already set by queue_req, do nothing */
 | 
				
			||||||
 | 
						} else { /* trigger faster if earlier timeout exists in queue_resp */
 | 
				
			||||||
 | 
							now = time(NULL);
 | 
				
			||||||
 | 
							later = qmsg->timeout;
 | 
				
			||||||
 | 
							diff = later - now;
 | 
				
			||||||
 | 
							if (diff < 0)
 | 
				
			||||||
 | 
								diff = 0;
 | 
				
			||||||
 | 
							if (diff < timeout->tv_sec)
 | 
				
			||||||
 | 
								timeout->tv_sec = diff;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void gtp_queue_timer_start(struct gsn_t *gsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct timeval next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Retrieve next retransmission as timeval */
 | 
				
			||||||
 | 
						queue_timer_retranstimeout(gsn, &next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* re-schedule the timer */
 | 
				
			||||||
 | 
						osmo_timer_schedule(&gsn->queue_timer, next.tv_sec, next.tv_usec/1000);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* timer callback for libgtp retransmission and ping */
 | 
				
			||||||
 | 
					static void queue_timer_cb(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsn_t *gsn = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* do all the retransmissions as needed */
 | 
				
			||||||
 | 
						queue_timer_retrans(gsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gtp_queue_timer_start(gsn);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief clear the request and response queue. Useful for debugging to reset "some" state.
 | 
				
			||||||
 | 
					 * @param gsn The GGSN instance
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void gtp_clear_queues(struct gsn_t *gsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct qmsg_t *qmsg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						LOGP(DLGTP, LOGL_INFO, "Clearing req & resp retransmit queues\n");
 | 
				
			||||||
 | 
						while (!queue_getfirst(gsn->queue_req, &qmsg)) {
 | 
				
			||||||
 | 
							queue_freemsg(gsn->queue_req, qmsg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!queue_getfirst(gsn->queue_resp, &qmsg)) {
 | 
				
			||||||
 | 
							queue_freemsg(gsn->queue_resp, qmsg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Perform restoration and recovery error handling as described in 29.060 */
 | 
				
			||||||
 | 
					static void log_restart(struct gsn_t *gsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *f;
 | 
				
			||||||
 | 
						int i, rc;
 | 
				
			||||||
 | 
						int counter = 0;
 | 
				
			||||||
 | 
						char *filename;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						filename = talloc_asprintf(NULL, "%s/%s", gsn->statedir, RESTART_FILE);
 | 
				
			||||||
 | 
						OSMO_ASSERT(filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We try to open file. On failure we will later try to create file */
 | 
				
			||||||
 | 
						if (!(f = fopen(filename, "r"))) {
 | 
				
			||||||
 | 
							LOGP(DLGTP, LOGL_NOTICE,
 | 
				
			||||||
 | 
								"State information file (%s) not found. Creating new file.\n",
 | 
				
			||||||
 | 
								filename);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							rc = fscanf(f, "%d", &counter);
 | 
				
			||||||
 | 
							if (rc != 1) {
 | 
				
			||||||
 | 
								LOGP(DLGTP, LOGL_ERROR,
 | 
				
			||||||
 | 
									"fscanf failed to read counter value\n");
 | 
				
			||||||
 | 
								goto close_file;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (fclose(f)) {
 | 
				
			||||||
 | 
								LOGP(DLGTP, LOGL_ERROR,
 | 
				
			||||||
 | 
									"fclose failed: Error = %s\n", strerror(errno));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gsn->restart_counter = (unsigned char)counter;
 | 
				
			||||||
 | 
						gsn->restart_counter++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Keep the umask closely wrapped around our fopen() call in case the
 | 
				
			||||||
 | 
						 * log outputs cause file creation. */
 | 
				
			||||||
 | 
						i = umask(022);
 | 
				
			||||||
 | 
						f = fopen(filename, "w");
 | 
				
			||||||
 | 
						umask(i);
 | 
				
			||||||
 | 
						if (!f) {
 | 
				
			||||||
 | 
							LOGP(DLGTP, LOGL_ERROR,
 | 
				
			||||||
 | 
								"fopen(path=%s, mode=%s) failed: Error = %s\n", filename,
 | 
				
			||||||
 | 
								"w", strerror(errno));
 | 
				
			||||||
 | 
							goto free_filename;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fprintf(f, "%d\n", gsn->restart_counter);
 | 
				
			||||||
 | 
					close_file:
 | 
				
			||||||
 | 
						if (fclose(f))
 | 
				
			||||||
 | 
							LOGP(DLGTP, LOGL_ERROR,
 | 
				
			||||||
 | 
								"fclose failed: Error = %s\n", strerror(errno));
 | 
				
			||||||
 | 
					free_filename:
 | 
				
			||||||
 | 
						talloc_free(filename);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int create_and_bind_socket(const char *name, struct gsn_t *gsn, int *fd, int domain,
 | 
				
			||||||
 | 
									  const struct in_addr *listen, int port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sockaddr_in addr;
 | 
				
			||||||
 | 
						int type = SOCK_DGRAM;
 | 
				
			||||||
 | 
						int protocol = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*fd = socket(domain, type, protocol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*fd < 0) {
 | 
				
			||||||
 | 
							rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SOCKET);
 | 
				
			||||||
 | 
							LOGP(DLGTP, LOGL_ERROR,
 | 
				
			||||||
 | 
							     "%s socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
 | 
				
			||||||
 | 
							     name, domain, type, protocol, strerror(errno));
 | 
				
			||||||
 | 
							return -errno;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&addr, 0, sizeof(addr));
 | 
				
			||||||
 | 
						addr.sin_family = domain;
 | 
				
			||||||
 | 
						addr.sin_addr = *listen;
 | 
				
			||||||
 | 
						addr.sin_port = htons(port);
 | 
				
			||||||
 | 
					#if defined(__FreeBSD__) || defined(__APPLE__)
 | 
				
			||||||
 | 
						addr.sin_len = sizeof(addr);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bind(*fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
 | 
				
			||||||
 | 
							rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SOCKET);
 | 
				
			||||||
 | 
							LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
 | 
				
			||||||
 | 
								       "%s bind(fd=%d) failed: Error = %s\n",
 | 
				
			||||||
 | 
								       name, *fd, strerror(errno));
 | 
				
			||||||
 | 
							return -errno;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
 | 
				
			||||||
 | 
						    int mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						LOGP(DLGTP, LOGL_NOTICE, "GTP: gtp_newgsn() started at %s\n", inet_ntoa(*listen));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*gsn = talloc_zero(tall_libgtp_ctx, struct gsn_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(*gsn)->statedir = statedir;
 | 
				
			||||||
 | 
						log_restart(*gsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialise sequence number */
 | 
				
			||||||
 | 
						(*gsn)->seq_next = (*gsn)->restart_counter * 1024;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialize timers: */
 | 
				
			||||||
 | 
						(*gsn)->tdef = gtp_T_defs;
 | 
				
			||||||
 | 
						/* Small hack to properly reset tdef for old clients not using the tdef_group: */
 | 
				
			||||||
 | 
						OSMO_ASSERT(gtp_T_defs[0].default_val != 0);
 | 
				
			||||||
 | 
						if (gtp_T_defs[0].val == 0)
 | 
				
			||||||
 | 
							osmo_tdefs_reset((*gsn)->tdef);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialise request retransmit queue */
 | 
				
			||||||
 | 
						queue_new(&(*gsn)->queue_req);
 | 
				
			||||||
 | 
						queue_new(&(*gsn)->queue_resp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialise pdp table */
 | 
				
			||||||
 | 
						pdp_init(*gsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialize internal queue timer */
 | 
				
			||||||
 | 
						osmo_timer_setup(&(*gsn)->queue_timer, queue_timer_cb, *gsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialize counter group: */
 | 
				
			||||||
 | 
						(*gsn)->ctrg = rate_ctr_group_alloc(NULL, &gsn_ctrg_desc, gsn_ctr_next_idx++);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialise call back functions */
 | 
				
			||||||
 | 
						(*gsn)->cb_create_context_ind = 0;
 | 
				
			||||||
 | 
						(*gsn)->cb_update_context_ind = 0;
 | 
				
			||||||
 | 
						(*gsn)->cb_delete_context = 0;
 | 
				
			||||||
 | 
						(*gsn)->cb_unsup_ind = 0;
 | 
				
			||||||
 | 
						(*gsn)->cb_conf = 0;
 | 
				
			||||||
 | 
						(*gsn)->cb_data_ind = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Store function parameters */
 | 
				
			||||||
 | 
						/* Same IP for user traffic and signalling */
 | 
				
			||||||
 | 
						(*gsn)->gsnc = *listen;
 | 
				
			||||||
 | 
						(*gsn)->gsnu = *listen;
 | 
				
			||||||
 | 
						(*gsn)->mode = mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(*gsn)->fd0 = -1;
 | 
				
			||||||
 | 
						(*gsn)->fd1c = -1;
 | 
				
			||||||
 | 
						(*gsn)->fd1u = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Create GTP version 0 socket */
 | 
				
			||||||
 | 
						if (create_and_bind_socket("GTPv0", *gsn, &(*gsn)->fd0, AF_INET, listen, GTP0_PORT) < 0)
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Create GTP version 1 control plane socket */
 | 
				
			||||||
 | 
						if (create_and_bind_socket("GTPv1 control plane", *gsn, &(*gsn)->fd1c, AF_INET, listen, GTP1C_PORT) < 0)
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Create GTP version 1 user plane socket */
 | 
				
			||||||
 | 
						if (create_and_bind_socket("GTPv1 user plane", *gsn, &(*gsn)->fd1u, AF_INET, listen, GTP1U_PORT) < 0)
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Start internal queue timer */
 | 
				
			||||||
 | 
						gtp_queue_timer_start(*gsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						gtp_free(*gsn);
 | 
				
			||||||
 | 
						*gsn = NULL;
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_free(struct gsn_t *gsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Cleanup internal queue timer */
 | 
				
			||||||
 | 
						osmo_timer_del(&gsn->queue_timer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Clean up retransmit queues */
 | 
				
			||||||
 | 
						queue_free(gsn->queue_req);
 | 
				
			||||||
 | 
						queue_free(gsn->queue_resp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						close(gsn->fd0);
 | 
				
			||||||
 | 
						close(gsn->fd1c);
 | 
				
			||||||
 | 
						close(gsn->fd1u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rate_ctr_group_free(gsn->ctrg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						talloc_free(gsn);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* API: Register create context indication callback */
 | 
				
			||||||
 | 
					int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
									  int (*cb_create_context_ind) (struct pdp_t *
 | 
				
			||||||
 | 
													pdp))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_create_context_ind = cb_create_context_ind;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_set_cb_update_context_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
									  int (*cb_update_context_ind)(struct pdp_t *pdp))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gsn->cb_update_context_ind = cb_update_context_ind;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_retrans(struct gsn_t *gsn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* dummy API, deprecated. */
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						timeout->tv_sec = 24*60*60;
 | 
				
			||||||
 | 
						timeout->tv_usec = 0;
 | 
				
			||||||
 | 
						/* dummy API, deprecated. Return a huge timer to do nothing */
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								gtp/gsn_internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								gtp/gsn_internal.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void gtp_queue_timer_start(struct gsn_t *gsn);
 | 
				
			||||||
							
								
								
									
										8
									
								
								gtp/gtp_internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								gtp/gtp_internal.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <talloc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t gtp_imsi_str2gtp(const char *str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern TALLOC_CTX *tall_libgtp_ctx;
 | 
				
			||||||
							
								
								
									
										544
									
								
								gtp/gtpie.c
									
									
									
									
									
								
							
							
						
						
									
										544
									
								
								gtp/gtpie.c
									
									
									
									
									
								
							@@ -1,17 +1,17 @@
 | 
				
			|||||||
/* 
 | 
					/*
 | 
				
			||||||
 *  OpenGGSN - Gateway GPRS Support Node
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 *  Copyright (C) 2002 Mondru AB.
 | 
					 *  Copyright (C) 2002 Mondru AB.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 *  The contents of this file may be used under the terms of the GNU
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 *  General Public License Version 2, provided that the above copyright
 | 
					 *  General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 *  notice and this permission notice is included in all copies or
 | 
					 *  notice and this permission notice is included in all copies or
 | 
				
			||||||
 *  substantial portions of the software.
 | 
					 *  substantial portions of the software.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * gtpie.c: Contains functions to encapsulate and decapsulate GTP 
 | 
					 * gtpie.c: Contains functions to encapsulate and decapsulate GTP
 | 
				
			||||||
 * information elements 
 | 
					 * information elements
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Encapsulation
 | 
					 * Encapsulation
 | 
				
			||||||
@@ -37,10 +37,18 @@
 | 
				
			|||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gtpie.h"
 | 
					#include <osmocom/gtp/gtpie.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode a TLV type Information Element.
 | 
				
			||||||
 | 
					 *  \param[inout] p Pointer to output packet to which IE is appended
 | 
				
			||||||
 | 
					 *  \param[inout] length Up to which byte length is \a p used/filled
 | 
				
			||||||
 | 
					 *  \param[in] size Total size of \a p in bytes
 | 
				
			||||||
 | 
					 *  \param[in] t Tag / Information Element Identifier
 | 
				
			||||||
 | 
					 *  \param[in] l Length of value \a v in bytes
 | 
				
			||||||
 | 
					 *  \param[in] v Pointer to input value
 | 
				
			||||||
 | 
					 *  \returns 0 on success, 1 on error */
 | 
				
			||||||
int gtpie_tlv(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
					int gtpie_tlv(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			||||||
	      int l, void *v)
 | 
						      int l, const void *v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ((*length + 3 + l) >= size)
 | 
						if ((*length + 3 + l) >= size)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
@@ -51,8 +59,16 @@ int gtpie_tlv(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode a TV0 (Tag + value) type Information Element.
 | 
				
			||||||
 | 
					 *  \param[inout] p Pointer to output packet to which IE is appended
 | 
				
			||||||
 | 
					 *  \param[inout] length Up to which byte length is \a p used/filled
 | 
				
			||||||
 | 
					 *  \param[in] size Total size of \a p in bytes
 | 
				
			||||||
 | 
					 *  \param[in] t Tag / Information Element Identifier
 | 
				
			||||||
 | 
					 *  \param[in] l Length of value \a v in bytes
 | 
				
			||||||
 | 
					 *  \param[in] v Pointer to input value
 | 
				
			||||||
 | 
					 *  \returns 0 on success, 1 on error */
 | 
				
			||||||
int gtpie_tv0(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
					int gtpie_tv0(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			||||||
	      int l, uint8_t * v)
 | 
						      int l, const uint8_t * v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ((*length + 1 + l) >= size)
 | 
						if ((*length + 1 + l) >= size)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
@@ -62,6 +78,13 @@ int gtpie_tv0(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode a TV1 (Tag + 8bit value) type Information Element.
 | 
				
			||||||
 | 
					 *  \param[inout] p Pointer to output packet to which IE is appended
 | 
				
			||||||
 | 
					 *  \param[inout] length Up to which byte length is \a p used/filled
 | 
				
			||||||
 | 
					 *  \param[in] size Total size of \a p in bytes
 | 
				
			||||||
 | 
					 *  \param[in] t Tag / Information Element Identifier
 | 
				
			||||||
 | 
					 *  \param[in] v Input value
 | 
				
			||||||
 | 
					 *  \returns 0 on success, 1 on error */
 | 
				
			||||||
int gtpie_tv1(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
					int gtpie_tv1(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			||||||
	      uint8_t v)
 | 
						      uint8_t v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -73,6 +96,13 @@ int gtpie_tv1(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode a TV2 (Tag + 16bit value) type Information Element.
 | 
				
			||||||
 | 
					 *  \param[inout] p Pointer to output packet to which IE is appended
 | 
				
			||||||
 | 
					 *  \param[inout] length Up to which byte length is \a p used/filled
 | 
				
			||||||
 | 
					 *  \param[in] size Total size of \a p in bytes
 | 
				
			||||||
 | 
					 *  \param[in] t Tag / Information Element Identifier
 | 
				
			||||||
 | 
					 *  \param[in] v Input value
 | 
				
			||||||
 | 
					 *  \returns 0 on success, 1 on error */
 | 
				
			||||||
int gtpie_tv2(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
					int gtpie_tv2(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			||||||
	      uint16_t v)
 | 
						      uint16_t v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -84,6 +114,13 @@ int gtpie_tv2(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode a TV4 (Tag + 32bit value) type Information Element.
 | 
				
			||||||
 | 
					 *  \param[inout] p Pointer to output packet to which IE is appended
 | 
				
			||||||
 | 
					 *  \param[inout] length Up to which byte length is \a p used/filled
 | 
				
			||||||
 | 
					 *  \param[in] size Total size of \a p in bytes
 | 
				
			||||||
 | 
					 *  \param[in] t Tag / Information Element Identifier
 | 
				
			||||||
 | 
					 *  \param[in] v Input value
 | 
				
			||||||
 | 
					 *  \returns 0 on success, 1 on error */
 | 
				
			||||||
int gtpie_tv4(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
					int gtpie_tv4(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			||||||
	      uint32_t v)
 | 
						      uint32_t v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -95,6 +132,13 @@ int gtpie_tv4(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode a TV8 (Tag + 64bit value) type Information Element.
 | 
				
			||||||
 | 
					 *  \param[inout] p Pointer to output packet to which IE is appended
 | 
				
			||||||
 | 
					 *  \param[inout] length Up to which byte length is \a p used/filled
 | 
				
			||||||
 | 
					 *  \param[in] size Total size of \a p in bytes
 | 
				
			||||||
 | 
					 *  \param[in] t Tag / Information Element Identifier
 | 
				
			||||||
 | 
					 *  \param[in] v Input value
 | 
				
			||||||
 | 
					 *  \returns 0 on success, 1 on error */
 | 
				
			||||||
int gtpie_tv8(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
					int gtpie_tv8(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			||||||
	      uint64_t v)
 | 
						      uint64_t v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -106,6 +150,11 @@ int gtpie_tv8(void *p, unsigned int *length, unsigned int size, uint8_t t,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Obtain a GTP IE for a given tag/IEI from a list/array.
 | 
				
			||||||
 | 
					 *  \param[in] ie Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] type Tag/IEI for which we're looking
 | 
				
			||||||
 | 
					 *  \param[in] instance Instance (number of occurence) of this IEI
 | 
				
			||||||
 | 
					 *  \returns index into \a ie on success; -1 if not found */
 | 
				
			||||||
int gtpie_getie(union gtpie_member *ie[], int type, int instance)
 | 
					int gtpie_getie(union gtpie_member *ie[], int type, int instance)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int j;
 | 
						int j;
 | 
				
			||||||
@@ -118,6 +167,11 @@ int gtpie_getie(union gtpie_member *ie[], int type, int instance)
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Determine if IE for a given tag/IEI exists in a list/array.
 | 
				
			||||||
 | 
					 *  \param[in] ie Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] type Tag/IEI for which we're looking
 | 
				
			||||||
 | 
					 *  \param[in] instance Instance (number of occurence) of this IEI
 | 
				
			||||||
 | 
					 *  \returns 1 if IEI instance present in \a ie; 0 if not */
 | 
				
			||||||
int gtpie_exist(union gtpie_member *ie[], int type, int instance)
 | 
					int gtpie_exist(union gtpie_member *ie[], int type, int instance)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int j;
 | 
						int j;
 | 
				
			||||||
@@ -130,6 +184,14 @@ int gtpie_exist(union gtpie_member *ie[], int type, int instance)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Obtain Value of TLV-type IE for a given tag/IEI from a list/array.
 | 
				
			||||||
 | 
					 *  \param[in] ie Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] type Tag/IEI for which we're looking
 | 
				
			||||||
 | 
					 *  \param[in] instance Instance (number of occurence) of this IEI
 | 
				
			||||||
 | 
					 *  \param[out] length Length of IE
 | 
				
			||||||
 | 
					 *  \param[inout] dst Caller-allocated buffer where to store value
 | 
				
			||||||
 | 
					 *  \param[in] size Size of \a dst in bytes
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; EOF in case value is larger than \a size */
 | 
				
			||||||
int gtpie_gettlv(union gtpie_member *ie[], int type, int instance,
 | 
					int gtpie_gettlv(union gtpie_member *ie[], int type, int instance,
 | 
				
			||||||
		 unsigned int *length, void *dst, unsigned int size)
 | 
							 unsigned int *length, void *dst, unsigned int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -145,6 +207,13 @@ int gtpie_gettlv(union gtpie_member *ie[], int type, int instance,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Obtain Value of TV0-type IE for a given tag/IEI from a list/array.
 | 
				
			||||||
 | 
					 *  \param[in] ie Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] type Tag/IEI for which we're looking
 | 
				
			||||||
 | 
					 *  \param[in] instance Instance (number of occurence) of this IEI
 | 
				
			||||||
 | 
					 *  \param[inout] dst Caller-allocated buffer where to store value
 | 
				
			||||||
 | 
					 *  \param[in] size Size of value in bytes
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; EOF in case IE not found */
 | 
				
			||||||
int gtpie_gettv0(union gtpie_member *ie[], int type, int instance,
 | 
					int gtpie_gettv0(union gtpie_member *ie[], int type, int instance,
 | 
				
			||||||
		 void *dst, unsigned int size)
 | 
							 void *dst, unsigned int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -157,6 +226,12 @@ int gtpie_gettv0(union gtpie_member *ie[], int type, int instance,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Obtain Value of TV1-type IE for a given tag/IEI from a list/array.
 | 
				
			||||||
 | 
					 *  \param[in] ie Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] type Tag/IEI for which we're looking
 | 
				
			||||||
 | 
					 *  \param[in] instance Instance (number of occurence) of this IEI
 | 
				
			||||||
 | 
					 *  \param[inout] dst Caller-allocated buffer where to store value
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; EOF in case IE not found */
 | 
				
			||||||
int gtpie_gettv1(union gtpie_member *ie[], int type, int instance,
 | 
					int gtpie_gettv1(union gtpie_member *ie[], int type, int instance,
 | 
				
			||||||
		 uint8_t * dst)
 | 
							 uint8_t * dst)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -169,6 +244,12 @@ int gtpie_gettv1(union gtpie_member *ie[], int type, int instance,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Obtain Value of TV2-type IE for a given tag/IEI from a list/array.
 | 
				
			||||||
 | 
					 *  \param[in] ie Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] type Tag/IEI for which we're looking
 | 
				
			||||||
 | 
					 *  \param[in] instance Instance (number of occurence) of this IEI
 | 
				
			||||||
 | 
					 *  \param[inout] dst Caller-allocated buffer where to store value
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; EOF in case IE not found */
 | 
				
			||||||
int gtpie_gettv2(union gtpie_member *ie[], int type, int instance,
 | 
					int gtpie_gettv2(union gtpie_member *ie[], int type, int instance,
 | 
				
			||||||
		 uint16_t * dst)
 | 
							 uint16_t * dst)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -181,6 +262,12 @@ int gtpie_gettv2(union gtpie_member *ie[], int type, int instance,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Obtain Value of TV4-type IE for a given tag/IEI from a list/array.
 | 
				
			||||||
 | 
					 *  \param[in] ie Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] type Tag/IEI for which we're looking
 | 
				
			||||||
 | 
					 *  \param[in] instance Instance (number of occurence) of this IEI
 | 
				
			||||||
 | 
					 *  \param[inout] dst Caller-allocated buffer where to store value
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; EOF in case IE not found */
 | 
				
			||||||
int gtpie_gettv4(union gtpie_member *ie[], int type, int instance,
 | 
					int gtpie_gettv4(union gtpie_member *ie[], int type, int instance,
 | 
				
			||||||
		 uint32_t * dst)
 | 
							 uint32_t * dst)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -193,6 +280,12 @@ int gtpie_gettv4(union gtpie_member *ie[], int type, int instance,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Obtain Value of TV8-type IE for a given tag/IEI from a list/array.
 | 
				
			||||||
 | 
					 *  \param[in] ie Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] type Tag/IEI for which we're looking
 | 
				
			||||||
 | 
					 *  \param[in] instance Instance (number of occurence) of this IEI
 | 
				
			||||||
 | 
					 *  \param[inout] dst Caller-allocated buffer where to store value
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; EOF in case IE not found */
 | 
				
			||||||
int gtpie_gettv8(union gtpie_member *ie[], int type, int instance,
 | 
					int gtpie_gettv8(union gtpie_member *ie[], int type, int instance,
 | 
				
			||||||
		 uint64_t * dst)
 | 
							 uint64_t * dst)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -205,13 +298,19 @@ int gtpie_gettv8(union gtpie_member *ie[], int type, int instance,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gtpie_decaps(union gtpie_member *ie[], int version, void *pack,
 | 
					/*! Parse an incoming GTP packet into its Information Elements.
 | 
				
			||||||
 | 
					 *  \param[out] ie Caller-allocated Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] version GTP protocol version
 | 
				
			||||||
 | 
					 *  \param[in] pack Pointer to raw GTP packet (payload part)
 | 
				
			||||||
 | 
					 *  \param[in] len Length of \a pack in bytes
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; EOF in case IE not found */
 | 
				
			||||||
 | 
					int gtpie_decaps(union gtpie_member *ie[], int version, const void *pack,
 | 
				
			||||||
		 unsigned len)
 | 
							 unsigned len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int j = 0;
 | 
						int j = 0;
 | 
				
			||||||
	unsigned char *p;
 | 
						const unsigned char *p;
 | 
				
			||||||
	unsigned char *end;
 | 
						const unsigned char *end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	end = (unsigned char *)pack + len;
 | 
						end = (unsigned char *)pack + len;
 | 
				
			||||||
	p = pack;
 | 
						p = pack;
 | 
				
			||||||
@@ -243,6 +342,7 @@ int gtpie_decaps(union gtpie_member *ie[], int version, void *pack,
 | 
				
			|||||||
		case GTPIE_RP_SMS:
 | 
							case GTPIE_RP_SMS:
 | 
				
			||||||
		case GTPIE_RP:
 | 
							case GTPIE_RP:
 | 
				
			||||||
		case GTPIE_MS_NOT_REACH:
 | 
							case GTPIE_MS_NOT_REACH:
 | 
				
			||||||
 | 
							case GTPIE_BCM:
 | 
				
			||||||
			if (j < GTPIE_SIZE) {
 | 
								if (j < GTPIE_SIZE) {
 | 
				
			||||||
				ie[j] = (union gtpie_member *)p;
 | 
									ie[j] = (union gtpie_member *)p;
 | 
				
			||||||
				if (GTPIE_DEBUG)
 | 
									if (GTPIE_DEBUG)
 | 
				
			||||||
@@ -390,11 +490,76 @@ int gtpie_decaps(union gtpie_member *ie[], int version, void *pack,
 | 
				
			|||||||
		case GTPIE_RAB_SETUP:
 | 
							case GTPIE_RAB_SETUP:
 | 
				
			||||||
		case GTPIE_TRIGGER_ID:
 | 
							case GTPIE_TRIGGER_ID:
 | 
				
			||||||
		case GTPIE_OMC_ID:
 | 
							case GTPIE_OMC_ID:
 | 
				
			||||||
		case GTPIE_CHARGING_ADDR:
 | 
							case GTPIE_RAN_T_CONTAIN:
 | 
				
			||||||
 | 
							case GTPIE_PDP_CTX_PRIO:
 | 
				
			||||||
 | 
							case GTPIE_ADDL_RAB_S_I:
 | 
				
			||||||
 | 
							case GTPIE_SGSN_NUMBER:
 | 
				
			||||||
 | 
							case GTPIE_COMMON_FLAGS:
 | 
				
			||||||
 | 
							case GTPIE_APN_RESTR:
 | 
				
			||||||
 | 
							case GTPIE_R_PRIO_LCS:
 | 
				
			||||||
		case GTPIE_RAT_TYPE:
 | 
							case GTPIE_RAT_TYPE:
 | 
				
			||||||
		case GTPIE_USER_LOC:
 | 
							case GTPIE_USER_LOC:
 | 
				
			||||||
		case GTPIE_MS_TZ:
 | 
							case GTPIE_MS_TZ:
 | 
				
			||||||
		case GTPIE_IMEI_SV:
 | 
							case GTPIE_IMEI_SV:
 | 
				
			||||||
 | 
							case GTPIE_CML_CHG_I_CT:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_UE_CTX:
 | 
				
			||||||
 | 
							case GTPIE_TMGI:
 | 
				
			||||||
 | 
							case GTPIE_RIM_ROUT_ADDR:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_PCO:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_SA:
 | 
				
			||||||
 | 
							case GTPIE_SRNC_PDCP_CTX:
 | 
				
			||||||
 | 
							case GTPIE_ADDL_TRACE:
 | 
				
			||||||
 | 
							case GTPIE_HOP_CTR:
 | 
				
			||||||
 | 
							case GTPIE_SEL_PLMN_ID:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_SESS_ID:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_2_3G_IND:
 | 
				
			||||||
 | 
							case GTPIE_ENH_NSAPI:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_SESS_DUR:
 | 
				
			||||||
 | 
							case GTPIE_A_MBMS_TRAC_I:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_S_REP_N:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_TTDT:
 | 
				
			||||||
 | 
							case GTPIE_PS_HO_REQ_CTX:
 | 
				
			||||||
 | 
							case GTPIE_BSS_CONTAINER:
 | 
				
			||||||
 | 
							case GTPIE_CELL_ID:
 | 
				
			||||||
 | 
							case GTPIE_PDU_NUMBERS:
 | 
				
			||||||
 | 
							case GTPIE_BSSGP_CAUSE:
 | 
				
			||||||
 | 
							case GTPIE_RQD_MBMS_BCAP:
 | 
				
			||||||
 | 
							case GTPIE_RIM_RA_DISCR:
 | 
				
			||||||
 | 
							case GTPIE_L_SETUP_PFCS:
 | 
				
			||||||
 | 
							case GTPIE_PS_HO_XID_PAR:
 | 
				
			||||||
 | 
							case GTPIE_MS_CHG_REP_A:
 | 
				
			||||||
 | 
							case GTPIE_DIR_TUN_FLAGS:
 | 
				
			||||||
 | 
							case GTPIE_CORREL_ID:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_FLOWI:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_MC_DIST:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_DIST_ACK:
 | 
				
			||||||
 | 
							case GTPIE_R_IRAT_HO_INF:
 | 
				
			||||||
 | 
							case GTPIE_RFSP_IDX:
 | 
				
			||||||
 | 
							case GTPIE_FQDN:
 | 
				
			||||||
 | 
							case GTPIE_E_ALL_PRIO_1:
 | 
				
			||||||
 | 
							case GTPIE_E_ALL_PRIO_2:
 | 
				
			||||||
 | 
							case GTPIE_E_CMN_FLAGS:
 | 
				
			||||||
 | 
							case GTPIE_U_CSG_INFO:
 | 
				
			||||||
 | 
							case GTPIE_CSG_I_REP_ACT:
 | 
				
			||||||
 | 
							case GTPIE_CSG_ID:
 | 
				
			||||||
 | 
							case GTPIE_CSG_MEMB_IND:
 | 
				
			||||||
 | 
							case GTPIE_AMBR:
 | 
				
			||||||
 | 
							case GTPIE_UE_NET_CAPA:
 | 
				
			||||||
 | 
							case GTPIE_UE_AMBR:
 | 
				
			||||||
 | 
							case GTPIE_APN_AMBR_NS:
 | 
				
			||||||
 | 
							case GTPIE_GGSN_BACKOFF:
 | 
				
			||||||
 | 
							case GTPIE_S_PRIO_IND:
 | 
				
			||||||
 | 
							case GTPIE_S_PRIO_IND_NS:
 | 
				
			||||||
 | 
							case GTPIE_H_BR_16MBPS_F:
 | 
				
			||||||
 | 
							case GTPIE_A_MMCTX_SRVCC:
 | 
				
			||||||
 | 
							case GTPIE_A_FLAGS_SRVCC:
 | 
				
			||||||
 | 
							case GTPIE_STN_SR:
 | 
				
			||||||
 | 
							case GTPIE_C_MSISDN:
 | 
				
			||||||
 | 
							case GTPIE_E_RANAP_CAUSE:
 | 
				
			||||||
 | 
							case GTPIE_ENODEB_ID:
 | 
				
			||||||
 | 
							case GTPIE_SEL_MODE_NS:
 | 
				
			||||||
 | 
							case GTPIE_ULI_TIMESTAMP:
 | 
				
			||||||
 | 
							case GTPIE_CHARGING_ADDR:
 | 
				
			||||||
		case GTPIE_PRIVATE:
 | 
							case GTPIE_PRIVATE:
 | 
				
			||||||
			if (j < GTPIE_SIZE) {
 | 
								if (j < GTPIE_SIZE) {
 | 
				
			||||||
				ie[j] = (union gtpie_member *)p;
 | 
									ie[j] = (union gtpie_member *)p;
 | 
				
			||||||
@@ -429,12 +594,16 @@ int gtpie_decaps(union gtpie_member *ie[], int version, void *pack,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode GTP packet payload from Array of Information Elements.
 | 
				
			||||||
 | 
					 *  \param[out] ie Input Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[out] pack Pointer to caller-allocated buffer for raw GTP packet (GTPIE_MAX length)
 | 
				
			||||||
 | 
					 *  \param[out] len Encoded length of \a pack in bytes
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; 2 for out-of-space */
 | 
				
			||||||
int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
 | 
					int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned char *p;
 | 
						unsigned char *p;
 | 
				
			||||||
	unsigned char *end;
 | 
						unsigned char *end;
 | 
				
			||||||
	union gtpie_member *m;
 | 
					 | 
				
			||||||
	int iesize;
 | 
						int iesize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p = pack;
 | 
						p = pack;
 | 
				
			||||||
@@ -445,7 +614,6 @@ int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
 | 
				
			|||||||
		if (ie[i] != 0) {
 | 
							if (ie[i] != 0) {
 | 
				
			||||||
			if (GTPIE_DEBUG)
 | 
								if (GTPIE_DEBUG)
 | 
				
			||||||
				printf("gtpie_encaps. Type %d\n", i);
 | 
									printf("gtpie_encaps. Type %d\n", i);
 | 
				
			||||||
			m = (union gtpie_member *)p;
 | 
					 | 
				
			||||||
			switch (i) {
 | 
								switch (i) {
 | 
				
			||||||
			case GTPIE_CAUSE:	/* TV GTPIE types with value length 1 */
 | 
								case GTPIE_CAUSE:	/* TV GTPIE types with value length 1 */
 | 
				
			||||||
			case GTPIE_REORDER:
 | 
								case GTPIE_REORDER:
 | 
				
			||||||
@@ -459,6 +627,7 @@ int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
 | 
				
			|||||||
			case GTPIE_RP_SMS:
 | 
								case GTPIE_RP_SMS:
 | 
				
			||||||
			case GTPIE_RP:
 | 
								case GTPIE_RP:
 | 
				
			||||||
			case GTPIE_MS_NOT_REACH:
 | 
								case GTPIE_MS_NOT_REACH:
 | 
				
			||||||
 | 
								case GTPIE_BCM:
 | 
				
			||||||
				iesize = 2;
 | 
									iesize = 2;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case GTPIE_FL_DI:	/* TV GTPIE types with value length 2 */
 | 
								case GTPIE_FL_DI:	/* TV GTPIE types with value length 2 */
 | 
				
			||||||
@@ -483,11 +652,13 @@ int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
 | 
				
			|||||||
			case GTPIE_TEI_DII:	/* TV GTPIE types with value length 5 */
 | 
								case GTPIE_TEI_DII:	/* TV GTPIE types with value length 5 */
 | 
				
			||||||
				iesize = 6;
 | 
									iesize = 6;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
								case GTPIE_RAI:		/* TV GTPIE types with value length 6 */
 | 
				
			||||||
 | 
									iesize = 7;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
			case GTPIE_RAB_CONTEXT:	/* TV GTPIE types with value length 7 */
 | 
								case GTPIE_RAB_CONTEXT:	/* TV GTPIE types with value length 7 */
 | 
				
			||||||
				iesize = 8;
 | 
									iesize = 8;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case GTPIE_IMSI:	/* TV GTPIE types with value length 8 */
 | 
								case GTPIE_IMSI:	/* TV GTPIE types with value length 8 */
 | 
				
			||||||
			case GTPIE_RAI:
 | 
					 | 
				
			||||||
				iesize = 9;
 | 
									iesize = 9;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case GTPIE_AUTH_TRIPLET:	/* TV GTPIE types with value length 28 */
 | 
								case GTPIE_AUTH_TRIPLET:	/* TV GTPIE types with value length 28 */
 | 
				
			||||||
@@ -511,6 +682,75 @@ int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
 | 
				
			|||||||
			case GTPIE_RAB_SETUP:
 | 
								case GTPIE_RAB_SETUP:
 | 
				
			||||||
			case GTPIE_TRIGGER_ID:
 | 
								case GTPIE_TRIGGER_ID:
 | 
				
			||||||
			case GTPIE_OMC_ID:
 | 
								case GTPIE_OMC_ID:
 | 
				
			||||||
 | 
								case GTPIE_RAN_T_CONTAIN:
 | 
				
			||||||
 | 
								case GTPIE_PDP_CTX_PRIO:
 | 
				
			||||||
 | 
								case GTPIE_ADDL_RAB_S_I:
 | 
				
			||||||
 | 
								case GTPIE_SGSN_NUMBER:
 | 
				
			||||||
 | 
								case GTPIE_COMMON_FLAGS:
 | 
				
			||||||
 | 
								case GTPIE_APN_RESTR:
 | 
				
			||||||
 | 
								case GTPIE_R_PRIO_LCS:
 | 
				
			||||||
 | 
								case GTPIE_RAT_TYPE:
 | 
				
			||||||
 | 
								case GTPIE_USER_LOC:
 | 
				
			||||||
 | 
								case GTPIE_MS_TZ:
 | 
				
			||||||
 | 
								case GTPIE_IMEI_SV:
 | 
				
			||||||
 | 
								case GTPIE_CML_CHG_I_CT:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_UE_CTX:
 | 
				
			||||||
 | 
								case GTPIE_TMGI:
 | 
				
			||||||
 | 
								case GTPIE_RIM_ROUT_ADDR:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_PCO:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_SA:
 | 
				
			||||||
 | 
								case GTPIE_SRNC_PDCP_CTX:
 | 
				
			||||||
 | 
								case GTPIE_ADDL_TRACE:
 | 
				
			||||||
 | 
								case GTPIE_HOP_CTR:
 | 
				
			||||||
 | 
								case GTPIE_SEL_PLMN_ID:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_SESS_ID:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_2_3G_IND:
 | 
				
			||||||
 | 
								case GTPIE_ENH_NSAPI:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_SESS_DUR:
 | 
				
			||||||
 | 
								case GTPIE_A_MBMS_TRAC_I:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_S_REP_N:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_TTDT:
 | 
				
			||||||
 | 
								case GTPIE_PS_HO_REQ_CTX:
 | 
				
			||||||
 | 
								case GTPIE_BSS_CONTAINER:
 | 
				
			||||||
 | 
								case GTPIE_CELL_ID:
 | 
				
			||||||
 | 
								case GTPIE_PDU_NUMBERS:
 | 
				
			||||||
 | 
								case GTPIE_BSSGP_CAUSE:
 | 
				
			||||||
 | 
								case GTPIE_RQD_MBMS_BCAP:
 | 
				
			||||||
 | 
								case GTPIE_RIM_RA_DISCR:
 | 
				
			||||||
 | 
								case GTPIE_L_SETUP_PFCS:
 | 
				
			||||||
 | 
								case GTPIE_PS_HO_XID_PAR:
 | 
				
			||||||
 | 
								case GTPIE_MS_CHG_REP_A:
 | 
				
			||||||
 | 
								case GTPIE_DIR_TUN_FLAGS:
 | 
				
			||||||
 | 
								case GTPIE_CORREL_ID:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_FLOWI:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_MC_DIST:
 | 
				
			||||||
 | 
								case GTPIE_MBMS_DIST_ACK:
 | 
				
			||||||
 | 
								case GTPIE_R_IRAT_HO_INF:
 | 
				
			||||||
 | 
								case GTPIE_RFSP_IDX:
 | 
				
			||||||
 | 
								case GTPIE_FQDN:
 | 
				
			||||||
 | 
								case GTPIE_E_ALL_PRIO_1:
 | 
				
			||||||
 | 
								case GTPIE_E_ALL_PRIO_2:
 | 
				
			||||||
 | 
								case GTPIE_E_CMN_FLAGS:
 | 
				
			||||||
 | 
								case GTPIE_U_CSG_INFO:
 | 
				
			||||||
 | 
								case GTPIE_CSG_I_REP_ACT:
 | 
				
			||||||
 | 
								case GTPIE_CSG_ID:
 | 
				
			||||||
 | 
								case GTPIE_CSG_MEMB_IND:
 | 
				
			||||||
 | 
								case GTPIE_AMBR:
 | 
				
			||||||
 | 
								case GTPIE_UE_NET_CAPA:
 | 
				
			||||||
 | 
								case GTPIE_UE_AMBR:
 | 
				
			||||||
 | 
								case GTPIE_APN_AMBR_NS:
 | 
				
			||||||
 | 
								case GTPIE_GGSN_BACKOFF:
 | 
				
			||||||
 | 
								case GTPIE_S_PRIO_IND:
 | 
				
			||||||
 | 
								case GTPIE_S_PRIO_IND_NS:
 | 
				
			||||||
 | 
								case GTPIE_H_BR_16MBPS_F:
 | 
				
			||||||
 | 
								case GTPIE_A_MMCTX_SRVCC:
 | 
				
			||||||
 | 
								case GTPIE_A_FLAGS_SRVCC:
 | 
				
			||||||
 | 
								case GTPIE_STN_SR:
 | 
				
			||||||
 | 
								case GTPIE_C_MSISDN:
 | 
				
			||||||
 | 
								case GTPIE_E_RANAP_CAUSE:
 | 
				
			||||||
 | 
								case GTPIE_ENODEB_ID:
 | 
				
			||||||
 | 
								case GTPIE_SEL_MODE_NS:
 | 
				
			||||||
 | 
								case GTPIE_ULI_TIMESTAMP:
 | 
				
			||||||
			case GTPIE_CHARGING_ADDR:
 | 
								case GTPIE_CHARGING_ADDR:
 | 
				
			||||||
			case GTPIE_PRIVATE:
 | 
								case GTPIE_PRIVATE:
 | 
				
			||||||
				iesize = 3 + hton16(ie[i]->tlv.l);
 | 
									iesize = 3 + hton16(ie[i]->tlv.l);
 | 
				
			||||||
@@ -528,13 +768,18 @@ int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode GTP packet payload from Array of Information Elements.
 | 
				
			||||||
 | 
					 *  \param[out] ie Input Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] size Size of ie
 | 
				
			||||||
 | 
					 *  \param[out] pack Pointer to caller-allocated buffer for raw GTP packet (GTPIE_MAX length)
 | 
				
			||||||
 | 
					 *  \param[out] len Encoded length of \a pack in bytes
 | 
				
			||||||
 | 
					 *  \returns 0 on sucess; 2 for out-of-space */
 | 
				
			||||||
int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
					int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
				
			||||||
		  void *pack, unsigned *len)
 | 
							  void *pack, unsigned *len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int i, j;
 | 
						unsigned int i, j;
 | 
				
			||||||
	unsigned char *p;
 | 
						unsigned char *p;
 | 
				
			||||||
	unsigned char *end;
 | 
						unsigned char *end;
 | 
				
			||||||
	union gtpie_member *m;
 | 
					 | 
				
			||||||
	int iesize;
 | 
						int iesize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p = pack;
 | 
						p = pack;
 | 
				
			||||||
@@ -548,7 +793,6 @@ int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
				
			|||||||
					printf
 | 
										printf
 | 
				
			||||||
					    ("gtpie_encaps. Number %d, Type %d\n",
 | 
										    ("gtpie_encaps. Number %d, Type %d\n",
 | 
				
			||||||
					     i, ie[i].t);
 | 
										     i, ie[i].t);
 | 
				
			||||||
				m = (union gtpie_member *)p;
 | 
					 | 
				
			||||||
				switch (ie[i].t) {
 | 
									switch (ie[i].t) {
 | 
				
			||||||
				case GTPIE_CAUSE:	/* TV GTPIE types with value length 1 */
 | 
									case GTPIE_CAUSE:	/* TV GTPIE types with value length 1 */
 | 
				
			||||||
				case GTPIE_REORDER:
 | 
									case GTPIE_REORDER:
 | 
				
			||||||
@@ -562,6 +806,7 @@ int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
				
			|||||||
				case GTPIE_RP_SMS:
 | 
									case GTPIE_RP_SMS:
 | 
				
			||||||
				case GTPIE_RP:
 | 
									case GTPIE_RP:
 | 
				
			||||||
				case GTPIE_MS_NOT_REACH:
 | 
									case GTPIE_MS_NOT_REACH:
 | 
				
			||||||
 | 
									case GTPIE_BCM:
 | 
				
			||||||
					iesize = 2;
 | 
										iesize = 2;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				case GTPIE_PFI:	/* TV GTPIE types with value length 2 */
 | 
									case GTPIE_PFI:	/* TV GTPIE types with value length 2 */
 | 
				
			||||||
@@ -578,16 +823,19 @@ int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
				
			|||||||
				case GTPIE_P_TMSI:
 | 
									case GTPIE_P_TMSI:
 | 
				
			||||||
				case GTPIE_TEI_DI:
 | 
									case GTPIE_TEI_DI:
 | 
				
			||||||
				case GTPIE_TEI_C:
 | 
									case GTPIE_TEI_C:
 | 
				
			||||||
 | 
									case GTPIE_CHARGING_ID:
 | 
				
			||||||
					iesize = 5;
 | 
										iesize = 5;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				case GTPIE_TEI_DII:	/* TV GTPIE types with value length 5 */
 | 
									case GTPIE_TEI_DII:	/* TV GTPIE types with value length 5 */
 | 
				
			||||||
					iesize = 6;
 | 
										iesize = 6;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
 | 
									case GTPIE_RAI:		/* TV GTPIE types with value length 6 */
 | 
				
			||||||
 | 
										iesize = 7;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
				case GTPIE_RAB_CONTEXT:	/* TV GTPIE types with value length 7 */
 | 
									case GTPIE_RAB_CONTEXT:	/* TV GTPIE types with value length 7 */
 | 
				
			||||||
					iesize = 8;
 | 
										iesize = 8;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				case GTPIE_IMSI:	/* TV GTPIE types with value length 8 */
 | 
									case GTPIE_IMSI:	/* TV GTPIE types with value length 8 */
 | 
				
			||||||
				case GTPIE_RAI:
 | 
					 | 
				
			||||||
					iesize = 9;
 | 
										iesize = 9;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				case GTPIE_AUTH_TRIPLET:	/* TV GTPIE types with value length 28 */
 | 
									case GTPIE_AUTH_TRIPLET:	/* TV GTPIE types with value length 28 */
 | 
				
			||||||
@@ -596,8 +844,7 @@ int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
				
			|||||||
				case GTPIE_EXT_HEADER_T:	/* GTP extension header */
 | 
									case GTPIE_EXT_HEADER_T:	/* GTP extension header */
 | 
				
			||||||
					iesize = 2 + hton8(ie[i].ext.l);
 | 
										iesize = 2 + hton8(ie[i].ext.l);
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				case GTPIE_CHARGING_ID:	/* TLV GTPIE types with length length 2 */
 | 
									case GTPIE_EUA:	/* TLV GTPIE types with length length 2 */
 | 
				
			||||||
				case GTPIE_EUA:
 | 
					 | 
				
			||||||
				case GTPIE_MM_CONTEXT:
 | 
									case GTPIE_MM_CONTEXT:
 | 
				
			||||||
				case GTPIE_PDP_CONTEXT:
 | 
									case GTPIE_PDP_CONTEXT:
 | 
				
			||||||
				case GTPIE_APN:
 | 
									case GTPIE_APN:
 | 
				
			||||||
@@ -612,6 +859,75 @@ int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
				
			|||||||
				case GTPIE_RAB_SETUP:
 | 
									case GTPIE_RAB_SETUP:
 | 
				
			||||||
				case GTPIE_TRIGGER_ID:
 | 
									case GTPIE_TRIGGER_ID:
 | 
				
			||||||
				case GTPIE_OMC_ID:
 | 
									case GTPIE_OMC_ID:
 | 
				
			||||||
 | 
									case GTPIE_RAN_T_CONTAIN:
 | 
				
			||||||
 | 
									case GTPIE_PDP_CTX_PRIO:
 | 
				
			||||||
 | 
									case GTPIE_ADDL_RAB_S_I:
 | 
				
			||||||
 | 
									case GTPIE_SGSN_NUMBER:
 | 
				
			||||||
 | 
									case GTPIE_COMMON_FLAGS:
 | 
				
			||||||
 | 
									case GTPIE_APN_RESTR:
 | 
				
			||||||
 | 
									case GTPIE_R_PRIO_LCS:
 | 
				
			||||||
 | 
									case GTPIE_RAT_TYPE:
 | 
				
			||||||
 | 
									case GTPIE_USER_LOC:
 | 
				
			||||||
 | 
									case GTPIE_MS_TZ:
 | 
				
			||||||
 | 
									case GTPIE_IMEI_SV:
 | 
				
			||||||
 | 
									case GTPIE_CML_CHG_I_CT:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_UE_CTX:
 | 
				
			||||||
 | 
									case GTPIE_TMGI:
 | 
				
			||||||
 | 
									case GTPIE_RIM_ROUT_ADDR:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_PCO:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_SA:
 | 
				
			||||||
 | 
									case GTPIE_SRNC_PDCP_CTX:
 | 
				
			||||||
 | 
									case GTPIE_ADDL_TRACE:
 | 
				
			||||||
 | 
									case GTPIE_HOP_CTR:
 | 
				
			||||||
 | 
									case GTPIE_SEL_PLMN_ID:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_SESS_ID:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_2_3G_IND:
 | 
				
			||||||
 | 
									case GTPIE_ENH_NSAPI:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_SESS_DUR:
 | 
				
			||||||
 | 
									case GTPIE_A_MBMS_TRAC_I:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_S_REP_N:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_TTDT:
 | 
				
			||||||
 | 
									case GTPIE_PS_HO_REQ_CTX:
 | 
				
			||||||
 | 
									case GTPIE_BSS_CONTAINER:
 | 
				
			||||||
 | 
									case GTPIE_CELL_ID:
 | 
				
			||||||
 | 
									case GTPIE_PDU_NUMBERS:
 | 
				
			||||||
 | 
									case GTPIE_BSSGP_CAUSE:
 | 
				
			||||||
 | 
									case GTPIE_RQD_MBMS_BCAP:
 | 
				
			||||||
 | 
									case GTPIE_RIM_RA_DISCR:
 | 
				
			||||||
 | 
									case GTPIE_L_SETUP_PFCS:
 | 
				
			||||||
 | 
									case GTPIE_PS_HO_XID_PAR:
 | 
				
			||||||
 | 
									case GTPIE_MS_CHG_REP_A:
 | 
				
			||||||
 | 
									case GTPIE_DIR_TUN_FLAGS:
 | 
				
			||||||
 | 
									case GTPIE_CORREL_ID:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_FLOWI:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_MC_DIST:
 | 
				
			||||||
 | 
									case GTPIE_MBMS_DIST_ACK:
 | 
				
			||||||
 | 
									case GTPIE_R_IRAT_HO_INF:
 | 
				
			||||||
 | 
									case GTPIE_RFSP_IDX:
 | 
				
			||||||
 | 
									case GTPIE_FQDN:
 | 
				
			||||||
 | 
									case GTPIE_E_ALL_PRIO_1:
 | 
				
			||||||
 | 
									case GTPIE_E_ALL_PRIO_2:
 | 
				
			||||||
 | 
									case GTPIE_E_CMN_FLAGS:
 | 
				
			||||||
 | 
									case GTPIE_U_CSG_INFO:
 | 
				
			||||||
 | 
									case GTPIE_CSG_I_REP_ACT:
 | 
				
			||||||
 | 
									case GTPIE_CSG_ID:
 | 
				
			||||||
 | 
									case GTPIE_CSG_MEMB_IND:
 | 
				
			||||||
 | 
									case GTPIE_AMBR:
 | 
				
			||||||
 | 
									case GTPIE_UE_NET_CAPA:
 | 
				
			||||||
 | 
									case GTPIE_UE_AMBR:
 | 
				
			||||||
 | 
									case GTPIE_APN_AMBR_NS:
 | 
				
			||||||
 | 
									case GTPIE_GGSN_BACKOFF:
 | 
				
			||||||
 | 
									case GTPIE_S_PRIO_IND:
 | 
				
			||||||
 | 
									case GTPIE_S_PRIO_IND_NS:
 | 
				
			||||||
 | 
									case GTPIE_H_BR_16MBPS_F:
 | 
				
			||||||
 | 
									case GTPIE_A_MMCTX_SRVCC:
 | 
				
			||||||
 | 
									case GTPIE_A_FLAGS_SRVCC:
 | 
				
			||||||
 | 
									case GTPIE_STN_SR:
 | 
				
			||||||
 | 
									case GTPIE_C_MSISDN:
 | 
				
			||||||
 | 
									case GTPIE_E_RANAP_CAUSE:
 | 
				
			||||||
 | 
									case GTPIE_ENODEB_ID:
 | 
				
			||||||
 | 
									case GTPIE_SEL_MODE_NS:
 | 
				
			||||||
 | 
									case GTPIE_ULI_TIMESTAMP:
 | 
				
			||||||
				case GTPIE_CHARGING_ADDR:
 | 
									case GTPIE_CHARGING_ADDR:
 | 
				
			||||||
				case GTPIE_PRIVATE:
 | 
									case GTPIE_PRIVATE:
 | 
				
			||||||
					iesize = 3 + hton16(ie[i].tlv.l);
 | 
										iesize = 3 + hton16(ie[i].tlv.l);
 | 
				
			||||||
@@ -628,3 +944,189 @@ int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Encode GTP packet payload from Array of Information Elements.
 | 
				
			||||||
 | 
					 *  \param[in] ie Input Array of GTPIE
 | 
				
			||||||
 | 
					 *  \param[in] ie_len Length of \a ie array
 | 
				
			||||||
 | 
					 *  \param[in] pack Pointer to caller-allocated buffer for raw GTP packet (GTPIE_MAX length)
 | 
				
			||||||
 | 
					 *  \param[in] pack_len Length of \a pack buffer
 | 
				
			||||||
 | 
					 *  \param[out] encoded_len Encoded length of \a pack in bytes
 | 
				
			||||||
 | 
					 *  \returns 0 on success; 2 for out-of-space
 | 
				
			||||||
 | 
					 *  GTP requires a certain order, the call must follow those which are defined for every message */
 | 
				
			||||||
 | 
					int gtpie_encaps3(union gtpie_member *ies[], unsigned int ie_len,
 | 
				
			||||||
 | 
							  void *pack, unsigned pack_len, unsigned *encoded_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
						unsigned char *p;
 | 
				
			||||||
 | 
						unsigned char *end;
 | 
				
			||||||
 | 
						int iesize;
 | 
				
			||||||
 | 
						union gtpie_member *ie;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*encoded_len = 0;
 | 
				
			||||||
 | 
						p = pack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(pack, 0, pack_len);
 | 
				
			||||||
 | 
						end = p + pack_len;
 | 
				
			||||||
 | 
						for (i = 0; i < ie_len; i++) {
 | 
				
			||||||
 | 
							if (!ies[i])
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							ie = ies[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (GTPIE_DEBUG)
 | 
				
			||||||
 | 
								printf
 | 
				
			||||||
 | 
								    ("gtpie_encaps. Number %d, Type %d\n",
 | 
				
			||||||
 | 
								     i, ie->t);
 | 
				
			||||||
 | 
							switch (ie->t) {
 | 
				
			||||||
 | 
							case GTPIE_CAUSE:	/* TV GTPIE types with value length 1 */
 | 
				
			||||||
 | 
							case GTPIE_REORDER:
 | 
				
			||||||
 | 
							case GTPIE_MAP_CAUSE:
 | 
				
			||||||
 | 
							case GTPIE_MS_VALIDATED:
 | 
				
			||||||
 | 
							case GTPIE_RECOVERY:
 | 
				
			||||||
 | 
							case GTPIE_SELECTION_MODE:
 | 
				
			||||||
 | 
							case GTPIE_TEARDOWN:
 | 
				
			||||||
 | 
							case GTPIE_NSAPI:
 | 
				
			||||||
 | 
							case GTPIE_RANAP_CAUSE:
 | 
				
			||||||
 | 
							case GTPIE_RP_SMS:
 | 
				
			||||||
 | 
							case GTPIE_RP:
 | 
				
			||||||
 | 
							case GTPIE_MS_NOT_REACH:
 | 
				
			||||||
 | 
							case GTPIE_BCM:
 | 
				
			||||||
 | 
								iesize = 2;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_PFI:	/* TV GTPIE types with value length 2 */
 | 
				
			||||||
 | 
							case GTPIE_CHARGING_C:
 | 
				
			||||||
 | 
							case GTPIE_TRACE_REF:
 | 
				
			||||||
 | 
							case GTPIE_TRACE_TYPE:
 | 
				
			||||||
 | 
								iesize = 3;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_QOS_PROFILE0:	/* TV GTPIE types with value length 3 */
 | 
				
			||||||
 | 
							case GTPIE_P_TMSI_S:
 | 
				
			||||||
 | 
								iesize = 4;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_TLLI:	/* TV GTPIE types with value length 4 */
 | 
				
			||||||
 | 
							case GTPIE_P_TMSI:
 | 
				
			||||||
 | 
							case GTPIE_TEI_DI:
 | 
				
			||||||
 | 
							case GTPIE_TEI_C:
 | 
				
			||||||
 | 
							case GTPIE_CHARGING_ID:
 | 
				
			||||||
 | 
								iesize = 5;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_TEI_DII:	/* TV GTPIE types with value length 5 */
 | 
				
			||||||
 | 
								iesize = 6;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_RAI:		/* TV GTPIE types with value length 6 */
 | 
				
			||||||
 | 
								iesize = 7;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_RAB_CONTEXT:	/* TV GTPIE types with value length 7 */
 | 
				
			||||||
 | 
								iesize = 8;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_IMSI:	/* TV GTPIE types with value length 8 */
 | 
				
			||||||
 | 
								iesize = 9;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_AUTH_TRIPLET:	/* TV GTPIE types with value length 28 */
 | 
				
			||||||
 | 
								iesize = 29;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_EXT_HEADER_T:	/* GTP extension header */
 | 
				
			||||||
 | 
								iesize = 2 + hton8(ie->ext.l);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case GTPIE_EUA:	/* TLV GTPIE types with length length 2 */
 | 
				
			||||||
 | 
							case GTPIE_MM_CONTEXT:
 | 
				
			||||||
 | 
							case GTPIE_PDP_CONTEXT:
 | 
				
			||||||
 | 
							case GTPIE_APN:
 | 
				
			||||||
 | 
							case GTPIE_PCO:
 | 
				
			||||||
 | 
							case GTPIE_GSN_ADDR:
 | 
				
			||||||
 | 
							case GTPIE_MSISDN:
 | 
				
			||||||
 | 
							case GTPIE_QOS_PROFILE:
 | 
				
			||||||
 | 
							case GTPIE_AUTH_QUINTUP:
 | 
				
			||||||
 | 
							case GTPIE_TFT:
 | 
				
			||||||
 | 
							case GTPIE_TARGET_INF:
 | 
				
			||||||
 | 
							case GTPIE_UTRAN_TRANS:
 | 
				
			||||||
 | 
							case GTPIE_RAB_SETUP:
 | 
				
			||||||
 | 
							case GTPIE_TRIGGER_ID:
 | 
				
			||||||
 | 
							case GTPIE_OMC_ID:
 | 
				
			||||||
 | 
							case GTPIE_RAN_T_CONTAIN:
 | 
				
			||||||
 | 
							case GTPIE_PDP_CTX_PRIO:
 | 
				
			||||||
 | 
							case GTPIE_ADDL_RAB_S_I:
 | 
				
			||||||
 | 
							case GTPIE_SGSN_NUMBER:
 | 
				
			||||||
 | 
							case GTPIE_COMMON_FLAGS:
 | 
				
			||||||
 | 
							case GTPIE_APN_RESTR:
 | 
				
			||||||
 | 
							case GTPIE_R_PRIO_LCS:
 | 
				
			||||||
 | 
							case GTPIE_RAT_TYPE:
 | 
				
			||||||
 | 
							case GTPIE_USER_LOC:
 | 
				
			||||||
 | 
							case GTPIE_MS_TZ:
 | 
				
			||||||
 | 
							case GTPIE_IMEI_SV:
 | 
				
			||||||
 | 
							case GTPIE_CML_CHG_I_CT:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_UE_CTX:
 | 
				
			||||||
 | 
							case GTPIE_TMGI:
 | 
				
			||||||
 | 
							case GTPIE_RIM_ROUT_ADDR:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_PCO:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_SA:
 | 
				
			||||||
 | 
							case GTPIE_SRNC_PDCP_CTX:
 | 
				
			||||||
 | 
							case GTPIE_ADDL_TRACE:
 | 
				
			||||||
 | 
							case GTPIE_HOP_CTR:
 | 
				
			||||||
 | 
							case GTPIE_SEL_PLMN_ID:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_SESS_ID:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_2_3G_IND:
 | 
				
			||||||
 | 
							case GTPIE_ENH_NSAPI:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_SESS_DUR:
 | 
				
			||||||
 | 
							case GTPIE_A_MBMS_TRAC_I:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_S_REP_N:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_TTDT:
 | 
				
			||||||
 | 
							case GTPIE_PS_HO_REQ_CTX:
 | 
				
			||||||
 | 
							case GTPIE_BSS_CONTAINER:
 | 
				
			||||||
 | 
							case GTPIE_CELL_ID:
 | 
				
			||||||
 | 
							case GTPIE_PDU_NUMBERS:
 | 
				
			||||||
 | 
							case GTPIE_BSSGP_CAUSE:
 | 
				
			||||||
 | 
							case GTPIE_RQD_MBMS_BCAP:
 | 
				
			||||||
 | 
							case GTPIE_RIM_RA_DISCR:
 | 
				
			||||||
 | 
							case GTPIE_L_SETUP_PFCS:
 | 
				
			||||||
 | 
							case GTPIE_PS_HO_XID_PAR:
 | 
				
			||||||
 | 
							case GTPIE_MS_CHG_REP_A:
 | 
				
			||||||
 | 
							case GTPIE_DIR_TUN_FLAGS:
 | 
				
			||||||
 | 
							case GTPIE_CORREL_ID:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_FLOWI:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_MC_DIST:
 | 
				
			||||||
 | 
							case GTPIE_MBMS_DIST_ACK:
 | 
				
			||||||
 | 
							case GTPIE_R_IRAT_HO_INF:
 | 
				
			||||||
 | 
							case GTPIE_RFSP_IDX:
 | 
				
			||||||
 | 
							case GTPIE_FQDN:
 | 
				
			||||||
 | 
							case GTPIE_E_ALL_PRIO_1:
 | 
				
			||||||
 | 
							case GTPIE_E_ALL_PRIO_2:
 | 
				
			||||||
 | 
							case GTPIE_E_CMN_FLAGS:
 | 
				
			||||||
 | 
							case GTPIE_U_CSG_INFO:
 | 
				
			||||||
 | 
							case GTPIE_CSG_I_REP_ACT:
 | 
				
			||||||
 | 
							case GTPIE_CSG_ID:
 | 
				
			||||||
 | 
							case GTPIE_CSG_MEMB_IND:
 | 
				
			||||||
 | 
							case GTPIE_AMBR:
 | 
				
			||||||
 | 
							case GTPIE_UE_NET_CAPA:
 | 
				
			||||||
 | 
							case GTPIE_UE_AMBR:
 | 
				
			||||||
 | 
							case GTPIE_APN_AMBR_NS:
 | 
				
			||||||
 | 
							case GTPIE_GGSN_BACKOFF:
 | 
				
			||||||
 | 
							case GTPIE_S_PRIO_IND:
 | 
				
			||||||
 | 
							case GTPIE_S_PRIO_IND_NS:
 | 
				
			||||||
 | 
							case GTPIE_H_BR_16MBPS_F:
 | 
				
			||||||
 | 
							case GTPIE_A_MMCTX_SRVCC:
 | 
				
			||||||
 | 
							case GTPIE_A_FLAGS_SRVCC:
 | 
				
			||||||
 | 
							case GTPIE_STN_SR:
 | 
				
			||||||
 | 
							case GTPIE_C_MSISDN:
 | 
				
			||||||
 | 
							case GTPIE_E_RANAP_CAUSE:
 | 
				
			||||||
 | 
							case GTPIE_ENODEB_ID:
 | 
				
			||||||
 | 
							case GTPIE_SEL_MODE_NS:
 | 
				
			||||||
 | 
							case GTPIE_ULI_TIMESTAMP:
 | 
				
			||||||
 | 
							case GTPIE_CHARGING_ADDR:
 | 
				
			||||||
 | 
							case GTPIE_PRIVATE:
 | 
				
			||||||
 | 
								iesize = 3 + hton16(ie->tlv.l);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return 2;	/* We received something unknown */
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (p + iesize < end) {
 | 
				
			||||||
 | 
								memcpy(p, ie, iesize);
 | 
				
			||||||
 | 
								p += iesize;
 | 
				
			||||||
 | 
								*encoded_len += iesize;
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								return 2;	/* Out of space */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										248
									
								
								gtp/pdp.c
									
									
									
									
									
								
							
							
						
						
									
										248
									
								
								gtp/pdp.c
									
									
									
									
									
								
							@@ -1,16 +1,17 @@
 | 
				
			|||||||
/* 
 | 
					/*
 | 
				
			||||||
 *  OpenGGSN - Gateway GPRS Support Node
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
					 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
				
			||||||
 * 
 | 
					 *  Copyright (C) 2017 Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 *  The contents of this file may be used under the terms of the GNU
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 *  General Public License Version 2, provided that the above copyright
 | 
					 *  General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 *  notice and this permission notice is included in all copies or
 | 
					 *  notice and this permission notice is included in all copies or
 | 
				
			||||||
 *  substantial portions of the software.
 | 
					 *  substantial portions of the software.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * pdp.c: 
 | 
					 * pdp.c:
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,32 +27,29 @@
 | 
				
			|||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include "pdp.h"
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "lookupa.h"
 | 
					#include "lookupa.h"
 | 
				
			||||||
 | 
					#include "queue.h"
 | 
				
			||||||
/* ***********************************************************
 | 
					 | 
				
			||||||
 * Global variables TODO: most should be moved to gsn_t
 | 
					 | 
				
			||||||
 *************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct pdp_t pdpa[PDP_MAX];	/* PDP storage */
 | 
					 | 
				
			||||||
static struct pdp_t *hashtid[PDP_MAX];	/* Hash table for IMSI + NSAPI */
 | 
					 | 
				
			||||||
/* struct pdp_t* haship[PDP_MAX];  Hash table for IP and network interface */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ***********************************************************
 | 
					/* ***********************************************************
 | 
				
			||||||
 * Functions related to PDP storage
 | 
					 * Functions related to PDP storage
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Lifecycle
 | 
					 * Lifecycle
 | 
				
			||||||
 * For a GGSN pdp context life begins with the reception of a 
 | 
					 * For a GGSN pdp context life begins with the reception of a
 | 
				
			||||||
 * create pdp context request. It normally ends with the reception
 | 
					 * create pdp context request. It normally ends with the reception
 | 
				
			||||||
 * of a delete pdp context request, but will also end with the
 | 
					 * of a delete pdp context request, but will also end with the
 | 
				
			||||||
 * reception of an error indication message. 
 | 
					 * reception of an error indication message.
 | 
				
			||||||
 * Provisions should probably be made for terminating pdp contexts
 | 
					 * Provisions should probably be made for terminating pdp contexts
 | 
				
			||||||
 * based on either idle timeout, or by sending downlink probe 
 | 
					 * based on either idle timeout, or by sending downlink probe
 | 
				
			||||||
 * messages (ping?) to see if the MS is still responding.
 | 
					 * messages (ping?) to see if the MS is still responding.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 * For an SGSN pdp context life begins with the application just
 | 
					 * For an SGSN pdp context life begins with the application just
 | 
				
			||||||
 * before sending off a create pdp context request. It normally
 | 
					 * before sending off a create pdp context request. It normally
 | 
				
			||||||
 * ends when a delete pdp context response message is received 
 | 
					 * ends when a delete pdp context response message is received
 | 
				
			||||||
 * from the GGSN, but should also end when with the reception of
 | 
					 * from the GGSN, but should also end when with the reception of
 | 
				
			||||||
 * an error indication message.
 | 
					 * an error indication message.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -61,15 +59,15 @@ static struct pdp_t *hashtid[PDP_MAX];	/* Hash table for IMSI + NSAPI */
 | 
				
			|||||||
 * Downlink packets received in the GGSN are identified only by their
 | 
					 * Downlink packets received in the GGSN are identified only by their
 | 
				
			||||||
 * network interface together with their destination IP address (Two
 | 
					 * network interface together with their destination IP address (Two
 | 
				
			||||||
 * network interfaces can use the same private IP address). Each IMSI
 | 
					 * network interfaces can use the same private IP address). Each IMSI
 | 
				
			||||||
 * (mobile station) can have several PDP contexts using the same IP 
 | 
					 * (mobile station) can have several PDP contexts using the same IP
 | 
				
			||||||
 * address. In this case the traffic flow template (TFT) is used to
 | 
					 * address. In this case the traffic flow template (TFT) is used to
 | 
				
			||||||
 * determine the correct PDP context for a particular IMSI. Also it 
 | 
					 * determine the correct PDP context for a particular IMSI. Also it
 | 
				
			||||||
 * should be possible for each PDP context to use several IP adresses
 | 
					 * should be possible for each PDP context to use several IP adresses
 | 
				
			||||||
 * For fixed wireless access a mobile station might need a full class
 | 
					 * For fixed wireless access a mobile station might need a full class
 | 
				
			||||||
 * C network. Even in the case of several IP adresses the PDP context
 | 
					 * C network. Even in the case of several IP adresses the PDP context
 | 
				
			||||||
 * should be determined on the basis of the network IP address.
 | 
					 * should be determined on the basis of the network IP address.
 | 
				
			||||||
 * Thus we need a hash table based on network interface + IP address.
 | 
					 * Thus we need a hash table based on network interface + IP address.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 * Uplink packets are for GTP0 identified by their IMSI and NSAPI, which
 | 
					 * Uplink packets are for GTP0 identified by their IMSI and NSAPI, which
 | 
				
			||||||
 * is collectively called the tunnel identifier. There is also a 16 bit
 | 
					 * is collectively called the tunnel identifier. There is also a 16 bit
 | 
				
			||||||
 * flow label that can be used for identification of uplink packets. This
 | 
					 * flow label that can be used for identification of uplink packets. This
 | 
				
			||||||
@@ -82,7 +80,7 @@ static struct pdp_t *hashtid[PDP_MAX];	/* Hash table for IMSI + NSAPI */
 | 
				
			|||||||
 * Thus we need a hash table based on TID (IMSI and NSAPI). The TEID will
 | 
					 * Thus we need a hash table based on TID (IMSI and NSAPI). The TEID will
 | 
				
			||||||
 * be used for directly addressing the PDP context.
 | 
					 * be used for directly addressing the PDP context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 * pdp_newpdp 
 | 
					 * pdp_newpdp
 | 
				
			||||||
 * Gives you a pdp context with no hash references In some way
 | 
					 * Gives you a pdp context with no hash references In some way
 | 
				
			||||||
 * this should have a limited lifetime.
 | 
					 * this should have a limited lifetime.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -109,11 +107,16 @@ static struct pdp_t *hashtid[PDP_MAX];	/* Hash table for IMSI + NSAPI */
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *************************************************************/
 | 
					 *************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pdp_init()
 | 
					static struct gsn_t *g_gsn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pdp_init(struct gsn_t *gsn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	memset(&pdpa, 0, sizeof(pdpa));
 | 
						if (!g_gsn) {
 | 
				
			||||||
	memset(&hashtid, 0, sizeof(hashtid));
 | 
							g_gsn = gsn;
 | 
				
			||||||
	/*  memset(&haship, 0, sizeof(haship)); */
 | 
						} else {
 | 
				
			||||||
 | 
							LOGP(DLGTP, LOGL_FATAL, "This interface is depreacted and doesn't support multiple GGSN!");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -121,6 +124,13 @@ int pdp_init()
 | 
				
			|||||||
int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
 | 
					int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
 | 
				
			||||||
	       struct pdp_t *pdp_old)
 | 
						       struct pdp_t *pdp_old)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						return gtp_pdp_newpdp(g_gsn, pdp, imsi, nsapi, pdp_old);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_pdp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
 | 
				
			||||||
 | 
						       struct pdp_t *pdp_old)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pdp_t *pdpa = gsn->pdpa;
 | 
				
			||||||
	int n;
 | 
						int n;
 | 
				
			||||||
	for (n = 0; n < PDP_MAX; n++) {	/* TODO: Need to do better than linear search */
 | 
						for (n = 0; n < PDP_MAX; n++) {	/* TODO: Need to do better than linear search */
 | 
				
			||||||
		if (pdpa[n].inuse == 0) {
 | 
							if (pdpa[n].inuse == 0) {
 | 
				
			||||||
@@ -130,6 +140,7 @@ int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
 | 
				
			|||||||
			else
 | 
								else
 | 
				
			||||||
				memset(*pdp, 0, sizeof(struct pdp_t));
 | 
									memset(*pdp, 0, sizeof(struct pdp_t));
 | 
				
			||||||
			(*pdp)->inuse = 1;
 | 
								(*pdp)->inuse = 1;
 | 
				
			||||||
 | 
								(*pdp)->gsn = gsn;
 | 
				
			||||||
			(*pdp)->imsi = imsi;
 | 
								(*pdp)->imsi = imsi;
 | 
				
			||||||
			(*pdp)->nsapi = nsapi;
 | 
								(*pdp)->nsapi = nsapi;
 | 
				
			||||||
			(*pdp)->fllc = (uint16_t) n + 1;
 | 
								(*pdp)->fllc = (uint16_t) n + 1;
 | 
				
			||||||
@@ -146,7 +157,9 @@ int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
 | 
				
			|||||||
				     1].secondary_tei[(*pdp)->nsapi & 0x0f] =
 | 
									     1].secondary_tei[(*pdp)->nsapi & 0x0f] =
 | 
				
			||||||
				    (*pdp)->teid_own;
 | 
									    (*pdp)->teid_own;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								/* Default: Generate G-PDU sequence numbers on Tx */
 | 
				
			||||||
 | 
								(*pdp)->tx_gpdu_seq = true;
 | 
				
			||||||
 | 
								INIT_LLIST_HEAD(&(*pdp)->qmsg_list_req);
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -155,6 +168,18 @@ int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int pdp_freepdp(struct pdp_t *pdp)
 | 
					int pdp_freepdp(struct pdp_t *pdp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct qmsg_t *qmsg, *qmsg2;
 | 
				
			||||||
 | 
						struct pdp_t *pdpa = pdp->gsn->pdpa;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Remove all enqueued messages belonging to this pdp from req tx transmit
 | 
				
			||||||
 | 
						   queue. queue_freemsg will call llist_del(). */
 | 
				
			||||||
 | 
						llist_for_each_entry_safe(qmsg, qmsg2, &pdp->qmsg_list_req, entry) {
 | 
				
			||||||
 | 
							if ((rc = queue_freemsg(pdp->gsn->queue_req, qmsg)))
 | 
				
			||||||
 | 
								LOGP(DLGTP, LOGL_ERROR,
 | 
				
			||||||
 | 
								     "Failed freeing qmsg from qmsg_list_req during pdp_freepdp()! %d\n", rc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pdp_tiddel(pdp);
 | 
						pdp_tiddel(pdp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Remove any references in primary context */
 | 
						/* Remove any references in primary context */
 | 
				
			||||||
@@ -169,12 +194,20 @@ int pdp_freepdp(struct pdp_t *pdp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int pdp_getpdp(struct pdp_t **pdp)
 | 
					int pdp_getpdp(struct pdp_t **pdp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	*pdp = &pdpa[0];
 | 
						*pdp = &g_gsn->pdpa[0];
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl)
 | 
					int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						return gtp_pdp_getgtp0(g_gsn, pdp, fl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_pdp_getgtp0(struct gsn_t *gsn, struct pdp_t **pdp, uint16_t fl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pdp_t *pdpa = gsn->pdpa;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((fl > PDP_MAX) || (fl < 1)) {
 | 
						if ((fl > PDP_MAX) || (fl < 1)) {
 | 
				
			||||||
		return EOF;	/* Not found */
 | 
							return EOF;	/* Not found */
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@@ -189,6 +222,13 @@ int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei)
 | 
					int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						return gtp_pdp_getgtp1(g_gsn, pdp, tei);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_pdp_getgtp1(struct gsn_t *gsn, struct pdp_t **pdp, uint32_t tei)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pdp_t *pdpa = gsn->pdpa;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((tei > PDP_MAX) || (tei < 1)) {
 | 
						if ((tei > PDP_MAX) || (tei < 1)) {
 | 
				
			||||||
		return EOF;	/* Not found */
 | 
							return EOF;	/* Not found */
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@@ -201,6 +241,30 @@ int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* get a PDP based on the *peer* address + TEI-Data.  Used for matching inbound Error Ind */
 | 
				
			||||||
 | 
					int pdp_getgtp1_peer_d(struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return gtp_pdp_getgtp1_peer_d(g_gsn, pdp, peer, teid_gn);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_pdp_getgtp1_peer_d(struct gsn_t *gsn, struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pdp_t *pdpa = gsn->pdpa;
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* this is O(n) but we don't have (nor want) another hash... */
 | 
				
			||||||
 | 
						for (i = 0; i < PDP_MAX; i++) {
 | 
				
			||||||
 | 
							struct pdp_t *candidate = &pdpa[i];
 | 
				
			||||||
 | 
							if (candidate->inuse && candidate->teid_gn == teid_gn &&
 | 
				
			||||||
 | 
							    candidate->gsnru.l == sizeof(peer->sin_addr) &&
 | 
				
			||||||
 | 
							    !memcmp(&peer->sin_addr, candidate->gsnru.v, sizeof(peer->sin_addr))) {
 | 
				
			||||||
 | 
								*pdp = &pdpa[i];
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return EOF;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pdp_tidhash(uint64_t tid)
 | 
					int pdp_tidhash(uint64_t tid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (lookup(&tid, sizeof(tid), 0) % PDP_MAX);
 | 
						return (lookup(&tid, sizeof(tid), 0) % PDP_MAX);
 | 
				
			||||||
@@ -208,10 +272,11 @@ int pdp_tidhash(uint64_t tid)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int pdp_tidset(struct pdp_t *pdp, uint64_t tid)
 | 
					int pdp_tidset(struct pdp_t *pdp, uint64_t tid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct pdp_t **hashtid = pdp->gsn->hashtid;
 | 
				
			||||||
	int hash = pdp_tidhash(tid);
 | 
						int hash = pdp_tidhash(tid);
 | 
				
			||||||
	struct pdp_t *pdp2;
 | 
						struct pdp_t *pdp2;
 | 
				
			||||||
	struct pdp_t *pdp_prev = NULL;
 | 
						struct pdp_t *pdp_prev = NULL;
 | 
				
			||||||
	DEBUGP(DLGTP, "Begin pdp_tidset tid = %llx\n", tid);
 | 
						DEBUGP(DLGTP, "Begin pdp_tidset tid = %"PRIx64"\n", tid);
 | 
				
			||||||
	pdp->tidnext = NULL;
 | 
						pdp->tidnext = NULL;
 | 
				
			||||||
	pdp->tid = tid;
 | 
						pdp->tid = tid;
 | 
				
			||||||
	for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext)
 | 
						for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext)
 | 
				
			||||||
@@ -226,10 +291,11 @@ int pdp_tidset(struct pdp_t *pdp, uint64_t tid)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int pdp_tiddel(struct pdp_t *pdp)
 | 
					int pdp_tiddel(struct pdp_t *pdp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct pdp_t **hashtid = pdp->gsn->hashtid;
 | 
				
			||||||
	int hash = pdp_tidhash(pdp->tid);
 | 
						int hash = pdp_tidhash(pdp->tid);
 | 
				
			||||||
	struct pdp_t *pdp2;
 | 
						struct pdp_t *pdp2;
 | 
				
			||||||
	struct pdp_t *pdp_prev = NULL;
 | 
						struct pdp_t *pdp_prev = NULL;
 | 
				
			||||||
	DEBUGP(DLGTP, "Begin pdp_tiddel tid = %llx\n", pdp->tid);
 | 
						DEBUGP(DLGTP, "Begin pdp_tiddel tid = %"PRIx64"\n", pdp->tid);
 | 
				
			||||||
	for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
 | 
						for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
 | 
				
			||||||
		if (pdp2 == pdp) {
 | 
							if (pdp2 == pdp) {
 | 
				
			||||||
			if (!pdp_prev)
 | 
								if (!pdp_prev)
 | 
				
			||||||
@@ -247,9 +313,15 @@ int pdp_tiddel(struct pdp_t *pdp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int pdp_tidget(struct pdp_t **pdp, uint64_t tid)
 | 
					int pdp_tidget(struct pdp_t **pdp, uint64_t tid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						return gtp_pdp_tidget(g_gsn, pdp, tid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_pdp_tidget(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t tid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pdp_t **hashtid = gsn->hashtid;
 | 
				
			||||||
	int hash = pdp_tidhash(tid);
 | 
						int hash = pdp_tidhash(tid);
 | 
				
			||||||
	struct pdp_t *pdp2;
 | 
						struct pdp_t *pdp2;
 | 
				
			||||||
	DEBUGP(DLGTP, "Begin pdp_tidget tid = %llx\n", tid);
 | 
						DEBUGP(DLGTP, "Begin pdp_tidget tid = %"PRIx64"\n", tid);
 | 
				
			||||||
	for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
 | 
						for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
 | 
				
			||||||
		if (pdp2->tid == tid) {
 | 
							if (pdp2->tid == tid) {
 | 
				
			||||||
			*pdp = pdp2;
 | 
								*pdp = pdp2;
 | 
				
			||||||
@@ -263,102 +335,17 @@ int pdp_tidget(struct pdp_t **pdp, uint64_t tid)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi)
 | 
					int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return pdp_tidget(pdp,
 | 
						return gtp_pdp_getimsi(g_gsn, pdp, imsi, nsapi);
 | 
				
			||||||
			  (imsi & 0x0fffffffffffffffull) +
 | 
					 | 
				
			||||||
			  ((uint64_t) nsapi << 60));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					int gtp_pdp_getimsi(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi)
 | 
				
			||||||
int pdp_iphash(void* ipif, struct ul66_t *eua) {
 | 
					{
 | 
				
			||||||
  /#printf("IPhash %ld\n", lookup(eua->v, eua->l, ipif) % PDP_MAX);#/
 | 
						return gtp_pdp_tidget(gsn, pdp, pdp_gettid(imsi, nsapi));
 | 
				
			||||||
  return (lookup(eua->v, eua->l, ipif) % PDP_MAX);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
int pdp_ipset(struct pdp_t *pdp, void* ipif, struct ul66_t *eua) {
 | 
					 | 
				
			||||||
  int hash;
 | 
					 | 
				
			||||||
  struct pdp_t *pdp2;
 | 
					 | 
				
			||||||
  struct pdp_t *pdp_prev = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (PDP_DEBUG) printf("Begin pdp_ipset %d %d %2x%2x%2x%2x\n",
 | 
					 | 
				
			||||||
			(unsigned) ipif, eua->l,
 | 
					 | 
				
			||||||
			eua->v[2], eua->v[3], 
 | 
					 | 
				
			||||||
			eua->v[4], eua->v[5]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pdp->ipnext = NULL;
 | 
					 | 
				
			||||||
  pdp->ipif = ipif;
 | 
					 | 
				
			||||||
  pdp->eua.l = eua->l;
 | 
					 | 
				
			||||||
  memcpy(pdp->eua.v, eua->v, eua->l);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  hash = pdp_iphash(pdp->ipif, &pdp->eua);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (pdp2 = haship[hash]; pdp2; pdp2 = pdp2->ipnext)
 | 
					 | 
				
			||||||
    pdp_prev = pdp2;
 | 
					 | 
				
			||||||
  if (!pdp_prev) 
 | 
					 | 
				
			||||||
    haship[hash] = pdp;
 | 
					 | 
				
			||||||
  else 
 | 
					 | 
				
			||||||
    pdp_prev->ipnext = pdp;
 | 
					 | 
				
			||||||
  if (PDP_DEBUG) printf("End pdp_ipset\n");
 | 
					 | 
				
			||||||
  return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pdp_ipdel(struct pdp_t *pdp) {
 | 
					 | 
				
			||||||
  int hash = pdp_iphash(pdp->ipif, &pdp->eua);
 | 
					 | 
				
			||||||
  struct pdp_t *pdp2;
 | 
					 | 
				
			||||||
  struct pdp_t *pdp_prev = NULL;
 | 
					 | 
				
			||||||
  if (PDP_DEBUG) printf("Begin pdp_ipdel\n");
 | 
					 | 
				
			||||||
  for (pdp2 = haship[hash]; pdp2; pdp2 = pdp2->ipnext) {
 | 
					 | 
				
			||||||
    if (pdp2 == pdp) {
 | 
					 | 
				
			||||||
      if (!pdp_prev) 
 | 
					 | 
				
			||||||
	haship[hash] = pdp2->ipnext;
 | 
					 | 
				
			||||||
      else 
 | 
					 | 
				
			||||||
	pdp_prev->ipnext = pdp2->ipnext;
 | 
					 | 
				
			||||||
      if (PDP_DEBUG) printf("End pdp_ipdel: PDP found\n");
 | 
					 | 
				
			||||||
      return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    pdp_prev = pdp2;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (PDP_DEBUG) printf("End pdp_ipdel: PDP not found\n");
 | 
					 | 
				
			||||||
  return EOF; /# End of linked list and not found #/
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pdp_ipget(struct pdp_t **pdp, void* ipif, struct ul66_t *eua) {
 | 
					 | 
				
			||||||
  int hash = pdp_iphash(ipif, eua);
 | 
					 | 
				
			||||||
  struct pdp_t *pdp2;
 | 
					 | 
				
			||||||
  /#printf("Begin pdp_ipget %d %d %2x%2x%2x%2x\n", (unsigned)ipif, eua->l, 
 | 
					 | 
				
			||||||
    eua->v[2],eua->v[3],eua->v[4],eua->v[5]);#/
 | 
					 | 
				
			||||||
  for (pdp2 = haship[hash]; pdp2; pdp2 = pdp2->ipnext) {
 | 
					 | 
				
			||||||
    if ((pdp2->ipif == ipif) && (pdp2->eua.l == eua->l) && 
 | 
					 | 
				
			||||||
	(memcmp(&pdp2->eua.v, &eua->v, eua->l) == 0)) {
 | 
					 | 
				
			||||||
      *pdp = pdp2;
 | 
					 | 
				
			||||||
      /#printf("End pdp_ipget. Found\n");#/
 | 
					 | 
				
			||||||
      return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (PDP_DEBUG) printf("End pdp_ipget Notfound %d %d %2x%2x%2x%2x\n", 
 | 
					 | 
				
			||||||
	 (unsigned)ipif, eua->l, eua->v[2],eua->v[3],eua->v[4],eua->v[5]);
 | 
					 | 
				
			||||||
  return EOF; /# End of linked list and not found #/
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
/* Various conversion functions */
 | 
					/* Various conversion functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pdp_ntoeua(struct in_addr *src, struct ul66_t *eua)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	eua->l = 6;
 | 
					 | 
				
			||||||
	eua->v[0] = 0xf1;	/* IETF */
 | 
					 | 
				
			||||||
	eua->v[1] = 0x21;	/* IPv4 */
 | 
					 | 
				
			||||||
	memcpy(&eua->v[2], src, 4);	/* Copy a 4 byte address */
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int pdp_euaton(struct ul66_t *eua, struct in_addr *dst)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ((eua->l != 6) || (eua->v[0] != 0xf1) || (eua->v[1] != 0x21)) {
 | 
					 | 
				
			||||||
		return EOF;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	memcpy(dst, &eua->v[2], 4);	/* Copy a 4 byte address */
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi)
 | 
					uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (imsi & 0x0fffffffffffffffull) + ((uint64_t) nsapi << 60);
 | 
						return (imsi & 0x0fffffffffffffffull) + ((uint64_t) nsapi << 60);
 | 
				
			||||||
@@ -370,13 +357,16 @@ void pdp_set_imsi_nsapi(struct pdp_t *pdp, uint64_t teid)
 | 
				
			|||||||
	pdp->nsapi = (teid & 0xf000000000000000ull) >> 60;
 | 
						pdp->nsapi = (teid & 0xf000000000000000ull) >> 60;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ulcpy(void *dst, void *src, size_t size)
 | 
					/* Count amount of secondary PDP contexts linked to this primary PDP context
 | 
				
			||||||
 | 
					 * (itself included). Must be called on a primary PDP context. */
 | 
				
			||||||
 | 
					unsigned int pdp_count_secondary(const struct pdp_t *pdp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (((struct ul255_t *)src)->l <= size) {
 | 
						unsigned int n;
 | 
				
			||||||
		((struct ul255_t *)dst)->l = ((struct ul255_t *)src)->l;
 | 
						unsigned int count = 0;
 | 
				
			||||||
		memcpy(((struct ul255_t *)dst)->v, ((struct ul255_t *)src)->v,
 | 
						OSMO_ASSERT(!pdp->secondary);
 | 
				
			||||||
		       ((struct ul255_t *)dst)->l);
 | 
					
 | 
				
			||||||
		return 0;
 | 
						for (n = 0; n < PDP_MAXNSAPI; n++)
 | 
				
			||||||
	} else
 | 
							if (pdp->secondary_tei[n])
 | 
				
			||||||
		return EOF;
 | 
								count++;
 | 
				
			||||||
 | 
						return count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										105
									
								
								gtp/queue.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								gtp/queue.c
									
									
									
									
									
								
							@@ -1,13 +1,14 @@
 | 
				
			|||||||
/* 
 | 
					/*
 | 
				
			||||||
 *  OpenGGSN - Gateway GPRS Support Node
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
					 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
				
			||||||
 *  Copyright (C) 2011 Harald Welte <laforge@gnumonks.org>
 | 
					 *  Copyright (C) 2011 Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 * 
 | 
					 *  Copyright (C) 2016 sysmocom - s.f.m.c. GmbH
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 *  The contents of this file may be used under the terms of the GNU
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 *  General Public License Version 2, provided that the above copyright
 | 
					 *  General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 *  notice and this permission notice is included in all copies or
 | 
					 *  notice and this permission notice is included in all copies or
 | 
				
			||||||
 *  substantial portions of the software.
 | 
					 *  substantial portions of the software.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -26,8 +27,10 @@
 | 
				
			|||||||
#include <sys/time.h>
 | 
					#include <sys/time.h>
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include "pdp.h"
 | 
					
 | 
				
			||||||
#include "gtp.h"
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "queue.h"
 | 
					#include "queue.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief dump a queue_t to stdout */
 | 
					/*! \brief dump a queue_t to stdout */
 | 
				
			||||||
@@ -61,7 +64,7 @@ static int queue_seqhash(struct sockaddr_in *peer, uint16_t seq)
 | 
				
			|||||||
	return seq % QUEUE_HASH_SIZE;
 | 
						return seq % QUEUE_HASH_SIZE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief Insert a message with given sequence number into the hash
 | 
					/*! \brief Insert a message with given sequence number into the hash.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This function sets the peer and the seq of the qmsg and then inserts
 | 
					 * This function sets the peer and the seq of the qmsg and then inserts
 | 
				
			||||||
 * the qmsg into the queue hash.  To do so, it does a hashtable lookup
 | 
					 * the qmsg into the queue hash.  To do so, it does a hashtable lookup
 | 
				
			||||||
@@ -78,7 +81,7 @@ static int queue_seqset(struct queue_t *queue, struct qmsg_t *qmsg,
 | 
				
			|||||||
	if (QUEUE_DEBUG)
 | 
						if (QUEUE_DEBUG)
 | 
				
			||||||
		printf("Begin queue_seqset seq = %d\n", (int)seq);
 | 
							printf("Begin queue_seqset seq = %d\n", (int)seq);
 | 
				
			||||||
	if (QUEUE_DEBUG)
 | 
						if (QUEUE_DEBUG)
 | 
				
			||||||
		printf("SIZEOF PEER %d, *PEER %d\n", sizeof(peer),
 | 
							printf("SIZEOF PEER %zu, *PEER %zu\n", sizeof(peer),
 | 
				
			||||||
		       sizeof(*peer));
 | 
							       sizeof(*peer));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qmsg->seq = seq;
 | 
						qmsg->seq = seq;
 | 
				
			||||||
@@ -105,8 +108,7 @@ static int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg)
 | 
				
			|||||||
		printf("Begin queue_seqdel seq = %d\n", (int)qmsg->seq);
 | 
							printf("Begin queue_seqdel seq = %d\n", (int)qmsg->seq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
 | 
						for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
 | 
				
			||||||
		/* FIXME: this is always true !?! */
 | 
							if (qmsg == qmsg2) {
 | 
				
			||||||
		if (qmsg == qmsg) {
 | 
					 | 
				
			||||||
			if (!qmsg_prev)
 | 
								if (!qmsg_prev)
 | 
				
			||||||
				queue->hashseq[hash] = qmsg2->seqnext;
 | 
									queue->hashseq[hash] = qmsg2->seqnext;
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
@@ -121,25 +123,30 @@ static int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg)
 | 
				
			|||||||
	return EOF;		/* End of linked list and not found */
 | 
						return EOF;		/* End of linked list and not found */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief Allocates and initialises new queue structure */
 | 
					/*! Allocates and initialises new queue structure.
 | 
				
			||||||
 | 
					 *  \param[out] queue pointer where to store the allocated object. Must be freed with queue_free
 | 
				
			||||||
 | 
					 *  \returns zero on success, non-zero on error
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int queue_new(struct queue_t **queue)
 | 
					int queue_new(struct queue_t **queue)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (QUEUE_DEBUG)
 | 
						if (QUEUE_DEBUG)
 | 
				
			||||||
		printf("queue_new\n");
 | 
							printf("queue_new\n");
 | 
				
			||||||
	*queue = calloc(1, sizeof(struct queue_t));
 | 
						*queue = calloc(1, sizeof(struct queue_t));
 | 
				
			||||||
 | 
						if (!(*queue))
 | 
				
			||||||
 | 
							return EOF;
 | 
				
			||||||
	(*queue)->next = 0;
 | 
						(*queue)->next = 0;
 | 
				
			||||||
	(*queue)->first = -1;
 | 
						(*queue)->first = -1;
 | 
				
			||||||
	(*queue)->last = -1;
 | 
						(*queue)->last = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (QUEUE_DEBUG)
 | 
						if (QUEUE_DEBUG)
 | 
				
			||||||
		queue_print(*queue);
 | 
							queue_print(*queue);
 | 
				
			||||||
	if (*queue)
 | 
						return 0;
 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return EOF;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief Deallocates queue structure */
 | 
					/*! Deallocates queue structure.
 | 
				
			||||||
 | 
					 *  \param[in] queue pointer previously allocated by queue_new
 | 
				
			||||||
 | 
					 *  \returns zero on success, non-zero on error.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int queue_free(struct queue_t *queue)
 | 
					int queue_free(struct queue_t *queue)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (QUEUE_DEBUG)
 | 
						if (QUEUE_DEBUG)
 | 
				
			||||||
@@ -150,7 +157,13 @@ int queue_free(struct queue_t *queue)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief Add a new message to the queue */
 | 
					/*! Add a new message to the queue.
 | 
				
			||||||
 | 
					 *  \param[in] queue pointer previously allocated by queue_new
 | 
				
			||||||
 | 
					 *  \param[out] qmsg first message from the queue (if succeeds)
 | 
				
			||||||
 | 
					 *  \param[in] peer who sent the message to add
 | 
				
			||||||
 | 
					 *  \param[in] seq sequence number of the message to add
 | 
				
			||||||
 | 
					 *  \returns zero on success, non-zero on error.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
 | 
					int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
 | 
				
			||||||
		 struct sockaddr_in *peer, uint16_t seq)
 | 
							 struct sockaddr_in *peer, uint16_t seq)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -161,6 +174,7 @@ int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		*qmsg = &queue->qmsga[queue->next];
 | 
							*qmsg = &queue->qmsga[queue->next];
 | 
				
			||||||
		queue_seqset(queue, *qmsg, peer, seq);
 | 
							queue_seqset(queue, *qmsg, peer, seq);
 | 
				
			||||||
 | 
							INIT_LLIST_HEAD(&(*qmsg)->entry);
 | 
				
			||||||
		(*qmsg)->state = 1;	/* Space taken */
 | 
							(*qmsg)->state = 1;	/* Space taken */
 | 
				
			||||||
		(*qmsg)->this = queue->next;
 | 
							(*qmsg)->this = queue->next;
 | 
				
			||||||
		(*qmsg)->next = -1;	/* End of the queue */
 | 
							(*qmsg)->next = -1;	/* End of the queue */
 | 
				
			||||||
@@ -177,7 +191,11 @@ int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief Simply remoev a given qmsg_t from the queue
 | 
					
 | 
				
			||||||
 | 
					/*! Remove an element from the queue.
 | 
				
			||||||
 | 
					 *  \param[in] queue pointer previously allocated by queue_new
 | 
				
			||||||
 | 
					 *  \param[in] qmsg message to free
 | 
				
			||||||
 | 
					 *  \returns zero on success, non-zero on error.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Internally, we first delete the entry from the queue, and then update
 | 
					 * Internally, we first delete the entry from the queue, and then update
 | 
				
			||||||
 * up our global queue->first / queue->last pointers.  Finally,
 | 
					 * up our global queue->first / queue->last pointers.  Finally,
 | 
				
			||||||
@@ -191,6 +209,8 @@ int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg)
 | 
				
			|||||||
		return EOF;	/* Not in queue */
 | 
							return EOF;	/* Not in queue */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						llist_del(&qmsg->entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	queue_seqdel(queue, qmsg);
 | 
						queue_seqdel(queue, qmsg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (qmsg->next == -1)	/* Are we the last in queue? */
 | 
						if (qmsg->next == -1)	/* Are we the last in queue? */
 | 
				
			||||||
@@ -211,7 +231,11 @@ int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief Move a given qmsg_t to the end of the queue ?!? */
 | 
					/*! Move a given qmsg_t to the end of the queue.
 | 
				
			||||||
 | 
					 *  \param[in] queue pointer previously allocated by queue_new
 | 
				
			||||||
 | 
					 *  \param[in] qmsg message to move to the end of the queue
 | 
				
			||||||
 | 
					 *  \returns zero on success, non-zero on error.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int queue_back(struct queue_t *queue, struct qmsg_t *qmsg)
 | 
					int queue_back(struct queue_t *queue, struct qmsg_t *qmsg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (QUEUE_DEBUG)
 | 
						if (QUEUE_DEBUG)
 | 
				
			||||||
@@ -237,7 +261,11 @@ int queue_back(struct queue_t *queue, struct qmsg_t *qmsg)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief Get the first element in the entire queue */
 | 
					/*! Get the first element in the entire queue.
 | 
				
			||||||
 | 
					 *  \param[in] queue pointer previously allocated by queue_new
 | 
				
			||||||
 | 
					 *  \param[out] qmsg first message from the queue (if succeeds)
 | 
				
			||||||
 | 
					 *  \returns zero on success, non-zero on error.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg)
 | 
					int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*printf("queue_getfirst\n"); */
 | 
						/*printf("queue_getfirst\n"); */
 | 
				
			||||||
@@ -251,27 +279,13 @@ int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief Linear search over entire queue to get given peer + seq*/
 | 
					/*! Get a queue entry for a given peer + seq.
 | 
				
			||||||
/* FIXME: unused, dead code! */
 | 
					 *  \param[in] queue pointer previously allocated by queue_new
 | 
				
			||||||
int queue_getseqx(struct queue_t *queue, struct qmsg_t **qmsg,
 | 
					 *  \param[out] qmsg first message from the queue (if succeeds)
 | 
				
			||||||
		  struct sockaddr_in *peer, uint16_t seq)
 | 
					 *  \param[in] peer who sent the message to retrieve
 | 
				
			||||||
{
 | 
					 *  \param[in] seq sequence number of the message to retrive
 | 
				
			||||||
	int n;
 | 
					 *  \returns zero on success, non-zero on error.
 | 
				
			||||||
	if (QUEUE_DEBUG)
 | 
					 */
 | 
				
			||||||
		printf("queue_getseq, %d\n", (int)seq);
 | 
					 | 
				
			||||||
	if (QUEUE_DEBUG)
 | 
					 | 
				
			||||||
		queue_print(queue);
 | 
					 | 
				
			||||||
	for (n = 0; n < QUEUE_SIZE; n++) {
 | 
					 | 
				
			||||||
		if ((queue->qmsga[n].seq == seq) &&
 | 
					 | 
				
			||||||
		    (!memcmp(&queue->qmsga[n].peer, peer, sizeof(*peer)))) {
 | 
					 | 
				
			||||||
			*qmsg = &queue->qmsga[n];
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return EOF;		/* Not found */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*! \brief Get a queue entry for a given peer + seq */
 | 
					 | 
				
			||||||
int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
 | 
					int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
 | 
				
			||||||
		 struct sockaddr_in *peer, uint16_t seq)
 | 
							 struct sockaddr_in *peer, uint16_t seq)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -293,7 +307,14 @@ int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
 | 
				
			|||||||
	return EOF;		/* End of linked list and not found */
 | 
						return EOF;		/* End of linked list and not found */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! \brief look-up a given seq/peer, return cbp + type and free entry */
 | 
					/*! look-up a given seq/peer, return cbp + type and free entry.
 | 
				
			||||||
 | 
					 *  \param[in] queue pointer previously allocated by queue_new
 | 
				
			||||||
 | 
					 *  \param[in] peer who sent the message to retrieve
 | 
				
			||||||
 | 
					 *  \param[in] seq sequence number of the message to retrive
 | 
				
			||||||
 | 
					 *  \param[out] type GTP message type
 | 
				
			||||||
 | 
					 *  \param[out] type callback pointer of the message
 | 
				
			||||||
 | 
					 *  \returns zero on success, non-zero on error.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
 | 
					int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
 | 
				
			||||||
		      uint16_t seq, uint8_t * type, void **cbp)
 | 
							      uint16_t seq, uint8_t * type, void **cbp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								gtp/queue.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								gtp/queue.h
									
									
									
									
									
								
							@@ -1,12 +1,12 @@
 | 
				
			|||||||
/* 
 | 
					/*
 | 
				
			||||||
 *  OpenGGSN - Gateway GPRS Support Node
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 *  Copyright (C) 2002 Mondru AB.
 | 
					 *  Copyright (C) 2002 Mondru AB.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 *  The contents of this file may be used under the terms of the GNU
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 *  General Public License Version 2, provided that the above copyright
 | 
					 *  General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 *  notice and this permission notice is included in all copies or
 | 
					 *  notice and this permission notice is included in all copies or
 | 
				
			||||||
 *  substantial portions of the software.
 | 
					 *  substantial portions of the software.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -17,9 +17,13 @@
 | 
				
			|||||||
#ifndef _QUEUE_H
 | 
					#ifndef _QUEUE_H
 | 
				
			||||||
#define _QUEUE_H
 | 
					#define _QUEUE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/linuxlist.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QUEUE_DEBUG 0		/* Print debug information */
 | 
					#define QUEUE_DEBUG 0		/* Print debug information */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QUEUE_SIZE 1024		/* Size of retransmission queue */
 | 
					#define QUEUE_SIZE (PDP_MAX*2)	/* Size of retransmission queue */
 | 
				
			||||||
#define QUEUE_HASH_SIZE 65536	/* Size of hash table (2^16) */
 | 
					#define QUEUE_HASH_SIZE 65536	/* Size of hash table (2^16) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct qmsg_t {			/* Holder for queued packets */
 | 
					struct qmsg_t {			/* Holder for queued packets */
 | 
				
			||||||
@@ -37,6 +41,7 @@ struct qmsg_t {			/* Holder for queued packets */
 | 
				
			|||||||
	int this;		/* Pointer to myself */
 | 
						int this;		/* Pointer to myself */
 | 
				
			||||||
	time_t timeout;		/* When do we retransmit this packet? */
 | 
						time_t timeout;		/* When do we retransmit this packet? */
 | 
				
			||||||
	int retrans;		/* How many times did we retransmit this? */
 | 
						int retrans;		/* How many times did we retransmit this? */
 | 
				
			||||||
 | 
						struct llist_head entry; /* Listed with other qmsg_t belonging to a pdp_t->qmsg_list_req */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct queue_t {
 | 
					struct queue_t {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								include/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								include/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					SUBDIRS = \
 | 
				
			||||||
 | 
						osmocom \
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
							
								
								
									
										3
									
								
								include/osmocom/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								include/osmocom/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					SUBDIRS = \
 | 
				
			||||||
 | 
						gtp \
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
							
								
								
									
										8
									
								
								include/osmocom/gtp/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								include/osmocom/gtp/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					libgtp_HEADERS = \
 | 
				
			||||||
 | 
						gsn.h \
 | 
				
			||||||
 | 
						gtp.h \
 | 
				
			||||||
 | 
						gtpie.h \
 | 
				
			||||||
 | 
						pdp.h \
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libgtpdir = $(includedir)/osmocom/gtp
 | 
				
			||||||
							
								
								
									
										181
									
								
								include/osmocom/gtp/gsn.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								include/osmocom/gtp/gsn.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,181 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 | 
					 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 | 
					 *  General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 | 
					 *  notice and this permission notice is included in all copies or
 | 
				
			||||||
 | 
					 *  substantial portions of the software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _GSN_H
 | 
				
			||||||
 | 
					#define _GSN_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/utils.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/defs.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/timer.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/tdef.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/rate_ctr.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pdp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GTP_MODE_GGSN 1
 | 
				
			||||||
 | 
					#define GTP_MODE_SGSN 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RESTART_FILE "gsn_restart"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct osmo_tdef gtp_T_defs[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ***********************************************************
 | 
				
			||||||
 | 
					 * Information storage for each gsn instance
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Normally each instance of the application corresponds to
 | 
				
			||||||
 | 
					 * one instance of a gsn.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * In order to avoid global variables in the application, and
 | 
				
			||||||
 | 
					 * also in order to allow several instances of a gsn in the same
 | 
				
			||||||
 | 
					 * application this struct is provided in order to store all
 | 
				
			||||||
 | 
					 * relevant information related to the gsn.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note that this does not include information storage for '
 | 
				
			||||||
 | 
					 * each pdp context. This is stored in another struct.
 | 
				
			||||||
 | 
					 *************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsn_rate_ctr_keys {
 | 
				
			||||||
 | 
						GSN_CTR_ERR_SOCKET,
 | 
				
			||||||
 | 
						GSN_CTR_ERR_READFROM,	/* Number of readfrom errors */
 | 
				
			||||||
 | 
						GSN_CTR_ERR_SENDTO,	/* Number of sendto errors */
 | 
				
			||||||
 | 
						GSN_CTR_ERR_QUEUEFULL,	/* Number of times queue was full */
 | 
				
			||||||
 | 
						GSN_CTR_ERR_SEQ,	/* Number of seq out of range */
 | 
				
			||||||
 | 
						GSN_CTR_ERR_ADDRESS,	/* GSN address conversion failed */
 | 
				
			||||||
 | 
						GSN_CTR_ERR_UNKNOWN_PDP,	/* GSN address conversion failed */
 | 
				
			||||||
 | 
						GSN_CTR_ERR_UNEXPECTED_CAUSE,	/* Unexpected cause value received */
 | 
				
			||||||
 | 
						GSN_CTR_ERR_OUT_OF_PDP,	/* Out of storage for PDP contexts */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_EMPTY,		/* Number of empty packets */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_UNSUP,		/* Number of unsupported version 29.60 11.1.1 */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_TOOSHORT,	/* Number of too short headers 29.60 11.1.2 */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_UNKNOWN,	/* Number of unknown messages 29.60 11.1.3 */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_UNEXPECT,	/* Number of unexpected messages 29.60 11.1.4 */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_DUPLICATE,	/* Number of duplicate or unsolicited replies */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_MISSING,	/* Number of missing information field messages */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_INCORRECT,	/* Number of incorrect information field messages */
 | 
				
			||||||
 | 
						GSN_CTR_PKT_INVALID,	/* Number of invalid message format messages */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 3GPP TS 29.006 14.1, 14,2 */
 | 
				
			||||||
 | 
					enum gtp_gsn_timers {
 | 
				
			||||||
 | 
						GTP_GSN_TIMER_T3_RESPONSE = 3,
 | 
				
			||||||
 | 
						GTP_GSN_TIMER_N3_REQUESTS = 1003,
 | 
				
			||||||
 | 
						GTP_GSN_TIMER_T3_HOLD_RESPONSE = -3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsn_t {
 | 
				
			||||||
 | 
						/* Parameters related to the network interface */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int fd0;		/* GTP0 file descriptor */
 | 
				
			||||||
 | 
						int fd1c;		/* GTP1 control plane file descriptor */
 | 
				
			||||||
 | 
						int fd1u;		/* GTP0 user plane file descriptor */
 | 
				
			||||||
 | 
						int mode;		/* Mode of operation: GGSN or SGSN */
 | 
				
			||||||
 | 
						struct in_addr gsnc;	/* IP address of this gsn for signalling */
 | 
				
			||||||
 | 
						struct in_addr gsnu;	/* IP address of this gsn for user traffic */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Parameters related to signalling messages */
 | 
				
			||||||
 | 
						uint16_t seq_next;	/* Next sequence number to use */
 | 
				
			||||||
 | 
						int seq_first;		/* First packet in queue (oldest timeout) */
 | 
				
			||||||
 | 
						int seq_last;		/* Last packet in queue (youngest timeout) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned char restart_counter;	/* Increment on restart. Stored on disk */
 | 
				
			||||||
 | 
						char *statedir;		/* Disk location for permanent storage */
 | 
				
			||||||
 | 
						void *priv;		/* used by libgtp users to attach their own state) */
 | 
				
			||||||
 | 
						struct queue_t *queue_req;	/* Request queue */
 | 
				
			||||||
 | 
						struct queue_t *queue_resp;	/* Response queue */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct pdp_t pdpa[PDP_MAX];	/* PDP storage */
 | 
				
			||||||
 | 
						struct pdp_t *hashtid[PDP_MAX];	/* Hash table for IMSI + NSAPI */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct osmo_timer_list queue_timer; /* internal queue_{req,resp} timer */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Call back functions */
 | 
				
			||||||
 | 
						int (*cb_delete_context) (struct pdp_t *);
 | 
				
			||||||
 | 
						int (*cb_create_context_ind) (struct pdp_t *);
 | 
				
			||||||
 | 
						int (*cb_update_context_ind)(struct pdp_t *pdp);
 | 
				
			||||||
 | 
						int (*cb_unsup_ind) (struct sockaddr_in * peer);
 | 
				
			||||||
 | 
						int (*cb_extheader_ind) (struct sockaddr_in * peer);
 | 
				
			||||||
 | 
						int (*cb_ran_info_relay_ind) (struct sockaddr_in *peer, union gtpie_member **ie);
 | 
				
			||||||
 | 
						int (*cb_conf) (int type, int cause, struct pdp_t * pdp, void *cbp);
 | 
				
			||||||
 | 
						int (*cb_data_ind) (struct pdp_t * pdp, void *pack, unsigned len);
 | 
				
			||||||
 | 
						int (*cb_recovery) (struct sockaddr_in * peer, uint8_t recovery);
 | 
				
			||||||
 | 
						int (*cb_recovery2) (struct sockaddr_in * peer, struct pdp_t * pdp, uint8_t recovery);
 | 
				
			||||||
 | 
						int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer, struct pdp_t *pdp, uint8_t recovery);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Counters */
 | 
				
			||||||
 | 
						struct rate_ctr_group *ctrg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Timers: */
 | 
				
			||||||
 | 
						struct osmo_tdef *tdef;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* External API functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
 | 
				
			||||||
 | 
							   int mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_free(struct gsn_t *gsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
 | 
				
			||||||
 | 
							      uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead");
 | 
				
			||||||
 | 
					extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
 | 
				
			||||||
 | 
					extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
 | 
									  void *cbp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
										 int (*cb_create_context_ind) (struct
 | 
				
			||||||
 | 
													       pdp_t *
 | 
				
			||||||
 | 
													       pdp));
 | 
				
			||||||
 | 
					extern int gtp_set_cb_update_context_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
										 int (*cb_update_context_ind)(struct pdp_t *pdp));
 | 
				
			||||||
 | 
					extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								       int (*cb_data_ind) (struct pdp_t * pdp,
 | 
				
			||||||
 | 
											   void *pack, unsigned len));
 | 
				
			||||||
 | 
					extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
 | 
				
			||||||
 | 
									     int (*cb_delete_context) (struct pdp_t *
 | 
				
			||||||
 | 
												       pdp));
 | 
				
			||||||
 | 
					/*extern int gtp_set_cb_create_context(struct gsn_t *gsn,
 | 
				
			||||||
 | 
					  int (*cb_create_context) (struct pdp_t* pdp)); */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
									int (*cb) (struct sockaddr_in * peer));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
									    int (*cb) (struct sockaddr_in * peer));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_set_cb_ran_info_relay_ind(struct gsn_t *gsn,
 | 
				
			||||||
 | 
									    int (*cb) (struct sockaddr_in * peer, union gtpie_member **ie));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_set_cb_conf(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								   int (*cb) (int type, int cause, struct pdp_t * pdp,
 | 
				
			||||||
 | 
									      void *cbp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_set_cb_recovery(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								int (*cb) (struct sockaddr_in * peer,
 | 
				
			||||||
 | 
									   uint8_t recovery))
 | 
				
			||||||
 | 
						OSMO_DEPRECATED("Use gtp_set_cb_recovery2() instead, to obtain pdp ctx originating the recovery");
 | 
				
			||||||
 | 
					int gtp_set_cb_recovery2(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								int (*cb) (struct sockaddr_in * peer,
 | 
				
			||||||
 | 
									   struct pdp_t * pdp,
 | 
				
			||||||
 | 
									   uint8_t recovery))
 | 
				
			||||||
 | 
						OSMO_DEPRECATED("Use gtp_set_cb_recovery3() instead, to obtain gsn handling the recovery");
 | 
				
			||||||
 | 
					int gtp_set_cb_recovery3(struct gsn_t *gsn,
 | 
				
			||||||
 | 
								int (*cb) (struct gsn_t * gsn, struct sockaddr_in * peer,
 | 
				
			||||||
 | 
									   struct pdp_t * pdp,
 | 
				
			||||||
 | 
									   uint8_t recovery));
 | 
				
			||||||
 | 
					void gtp_clear_queues(struct gsn_t *gsn);
 | 
				
			||||||
 | 
					extern int gtp_fd(struct gsn_t *gsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_retrans(struct gsn_t *gsn) OSMO_DEPRECATED("This API is a no-op, libgtp already does the job internally");
 | 
				
			||||||
 | 
					extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) OSMO_DEPRECATED("This API is a no-op and will return a 1 day timeout");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* !_GSN_H */
 | 
				
			||||||
@@ -1,19 +1,22 @@
 | 
				
			|||||||
/* 
 | 
					/*
 | 
				
			||||||
 *  OpenGGSN - Gateway GPRS Support Node
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
					 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 *  The contents of this file may be used under the terms of the GNU
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 *  General Public License Version 2, provided that the above copyright
 | 
					 *  General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 *  notice and this permission notice is included in all copies or
 | 
					 *  notice and this permission notice is included in all copies or
 | 
				
			||||||
 *  substantial portions of the software.
 | 
					 *  substantial portions of the software.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef _GTP_H
 | 
					#ifndef _GTP_H
 | 
				
			||||||
#define _GTP_H
 | 
					#define _GTP_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GTP_MODE_GGSN 1
 | 
					#include <osmocom/core/utils.h>
 | 
				
			||||||
#define GTP_MODE_SGSN 2
 | 
					
 | 
				
			||||||
 | 
					#include "gtpie.h"
 | 
				
			||||||
 | 
					#include "pdp.h"
 | 
				
			||||||
 | 
					#include "gsn.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GTP0_PORT	3386
 | 
					#define GTP0_PORT	3386
 | 
				
			||||||
#define GTP1C_PORT	2123
 | 
					#define GTP1C_PORT	2123
 | 
				
			||||||
@@ -25,12 +28,10 @@
 | 
				
			|||||||
#define GTP1_HEADER_SIZE_SHORT  8
 | 
					#define GTP1_HEADER_SIZE_SHORT  8
 | 
				
			||||||
#define GTP1_HEADER_SIZE_LONG  12
 | 
					#define GTP1_HEADER_SIZE_LONG  12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NAMESIZE 1024
 | 
				
			||||||
#define SYSLOG_PRINTSIZE 255
 | 
					#define SYSLOG_PRINTSIZE 255
 | 
				
			||||||
#define ERRMSG_SIZE 255
 | 
					#define ERRMSG_SIZE 255
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RESTART_FILE "gsn_restart"
 | 
					 | 
				
			||||||
#define NAMESIZE 1024
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* GTP version 1 extension header type definitions. */
 | 
					/* GTP version 1 extension header type definitions. */
 | 
				
			||||||
#define GTP_EXT_PDCP_PDU    0xC0	/* PDCP PDU Number */
 | 
					#define GTP_EXT_PDCP_PDU    0xC0	/* PDCP PDU Number */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,7 +53,7 @@
 | 
				
			|||||||
#define GTP_UPDATE_PDP_RSP   19	/* Update PDP Context Response */
 | 
					#define GTP_UPDATE_PDP_RSP   19	/* Update PDP Context Response */
 | 
				
			||||||
#define GTP_DELETE_PDP_REQ   20	/* Delete PDP Context Request */
 | 
					#define GTP_DELETE_PDP_REQ   20	/* Delete PDP Context Request */
 | 
				
			||||||
#define GTP_DELETE_PDP_RSP   21	/* Delete PDP Context Response */
 | 
					#define GTP_DELETE_PDP_RSP   21	/* Delete PDP Context Response */
 | 
				
			||||||
						       /* 22-25 For future use. *//* In version GTP 1 anonomous PDP context */
 | 
					/* 22-25 For future use. *//* In version GTP 1 anonomous PDP context */
 | 
				
			||||||
#define GTP_ERROR            26	/* Error Indication */
 | 
					#define GTP_ERROR            26	/* Error Indication */
 | 
				
			||||||
#define GTP_PDU_NOT_REQ      27	/* PDU Notification Request */
 | 
					#define GTP_PDU_NOT_REQ      27	/* PDU Notification Request */
 | 
				
			||||||
#define GTP_PDU_NOT_RSP      28	/* PDU Notification Response */
 | 
					#define GTP_PDU_NOT_RSP      28	/* PDU Notification Response */
 | 
				
			||||||
@@ -79,13 +80,18 @@
 | 
				
			|||||||
#define GTP_FWD_SRNS         58	/* Forward SRNS Context */
 | 
					#define GTP_FWD_SRNS         58	/* Forward SRNS Context */
 | 
				
			||||||
#define GTP_FWD_RELOC_ACK    59	/* Forward Relocation Complete Acknowledge */
 | 
					#define GTP_FWD_RELOC_ACK    59	/* Forward Relocation Complete Acknowledge */
 | 
				
			||||||
#define GTP_FWD_SRNS_ACK     60	/* Forward SRNS Context Acknowledge */
 | 
					#define GTP_FWD_SRNS_ACK     60	/* Forward SRNS Context Acknowledge */
 | 
				
			||||||
 | 
					#define GTP_RAN_INFO_RELAY   70	/* RAN Information Relay */
 | 
				
			||||||
/* 61-239 For future use. */
 | 
					/* 61-239 For future use. */
 | 
				
			||||||
#define GTP_DATA_TRAN_REQ   240	/* Data Record Transfer Request */
 | 
					#define GTP_DATA_TRAN_REQ   240	/* Data Record Transfer Request */
 | 
				
			||||||
#define GTP_DATA_TRAN_RSP   241	/* Data Record Transfer Response */
 | 
					#define GTP_DATA_TRAN_RSP   241	/* Data Record Transfer Response */
 | 
				
			||||||
/* 242-254 For future use. */
 | 
					/* 242-254 For future use. */
 | 
				
			||||||
#define GTP_GPDU            255	/* G-PDU */
 | 
					#define GTP_GPDU            255	/* G-PDU */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* GTP information element cause codes from 29.060 v3.9.0 7.7 */
 | 
					extern const struct value_string gtp_type_names[];
 | 
				
			||||||
 | 
					static inline const char *gtp_type_name(uint8_t val)
 | 
				
			||||||
 | 
					{ return get_value_string(gtp_type_names, val); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GTP information element cause codes from 29.060 v15.3.0 7.7.1 */
 | 
				
			||||||
/*                                                            */
 | 
					/*                                                            */
 | 
				
			||||||
#define GTPCAUSE_REQ_IMSI                   0	/* Request IMSI */
 | 
					#define GTPCAUSE_REQ_IMSI                   0	/* Request IMSI */
 | 
				
			||||||
#define GTPCAUSE_REQ_IMEI                   1	/* Request IMEI */
 | 
					#define GTPCAUSE_REQ_IMEI                   1	/* Request IMEI */
 | 
				
			||||||
@@ -93,19 +99,26 @@
 | 
				
			|||||||
#define GTPCAUSE_NO_ID_NEEDED               3	/* No identity needed */
 | 
					#define GTPCAUSE_NO_ID_NEEDED               3	/* No identity needed */
 | 
				
			||||||
#define GTPCAUSE_MS_REFUSES_X               4	/* MS refuses */
 | 
					#define GTPCAUSE_MS_REFUSES_X               4	/* MS refuses */
 | 
				
			||||||
#define GTPCAUSE_MS_NOT_RESP_X              5	/* MS is not GPRS responding */
 | 
					#define GTPCAUSE_MS_NOT_RESP_X              5	/* MS is not GPRS responding */
 | 
				
			||||||
#define GTPCAUSE_006                        6	/* For future use 6-48 */
 | 
					#define GTPCAUSE_REACTIVATION_REQ           6	/* Reactivation Requested */
 | 
				
			||||||
#define GTPCAUSE_049                       49	/* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */
 | 
					#define GTPCAUSE_PDP_ADDR_INACT             7	/* PDP address inactivity timer expires */
 | 
				
			||||||
#define GTPCAUSE_064                       64	/* For future use 64-127 */
 | 
					#define GTPCAUSE_NET_FAILURE                8	/* Network failure */
 | 
				
			||||||
 | 
					#define GTPCAUSE_QOS_MISMATCH               9	/* QoS parameter mismatch */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 10-48 For future use */
 | 
				
			||||||
 | 
					/* 49-63 Cause values reserved for GPRS charging protocol use (See GTP' 3GPP TS 32.295) */
 | 
				
			||||||
 | 
					/* 64-127 For future use */
 | 
				
			||||||
#define GTPCAUSE_ACC_REQ                  128	/* Request accepted */
 | 
					#define GTPCAUSE_ACC_REQ                  128	/* Request accepted */
 | 
				
			||||||
#define GTPCAUSE_129                      129	/* For future use 129-176 */
 | 
					#define GTPCAUSE_NEW_PDP_NET_PREF         129	/* New PDP type due to network preference */
 | 
				
			||||||
#define GTPCAUSE_177                      177	/* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */
 | 
					#define GTPCAUSE_NEW_PDP_ADDR_BEAR        130	/* New PDP type due to single address bearer only */
 | 
				
			||||||
 | 
					/* 131-176 For future use */
 | 
				
			||||||
 | 
					/* 177-191 Cause values reserved for GPRS charging protocol use (See GTP' 3GPP TS 32.295) */
 | 
				
			||||||
#define GTPCAUSE_NON_EXIST                192	/* Non-existent */
 | 
					#define GTPCAUSE_NON_EXIST                192	/* Non-existent */
 | 
				
			||||||
#define GTPCAUSE_INVALID_MESSAGE          193	/* Invalid message format */
 | 
					#define GTPCAUSE_INVALID_MESSAGE          193	/* Invalid message format */
 | 
				
			||||||
#define GTPCAUSE_IMSI_NOT_KNOWN           194	/* IMSI not known */
 | 
					#define GTPCAUSE_IMSI_NOT_KNOWN           194	/* IMSI not known */
 | 
				
			||||||
#define GTPCAUSE_MS_DETACHED              195	/* MS is GPRS detached */
 | 
					#define GTPCAUSE_MS_DETACHED              195	/* MS is GPRS detached */
 | 
				
			||||||
#define GTPCAUSE_MS_NOT_RESP              196	/* MS is not GPRS responding */
 | 
					#define GTPCAUSE_MS_NOT_RESP              196	/* MS is not GPRS responding */
 | 
				
			||||||
#define GTPCAUSE_MS_REFUSES               197	/* MS refuses */
 | 
					#define GTPCAUSE_MS_REFUSES               197	/* MS refuses */
 | 
				
			||||||
#define GTPCAUSE_198                      198	/* For future use */
 | 
					#define GTPCAUSE_VERSION_NOT_SUPPORTED    198	/* Version not supported */
 | 
				
			||||||
#define GTPCAUSE_NO_RESOURCES             199	/* No resources available */
 | 
					#define GTPCAUSE_NO_RESOURCES             199	/* No resources available */
 | 
				
			||||||
#define GTPCAUSE_NOT_SUPPORTED            200	/* Service not supported */
 | 
					#define GTPCAUSE_NOT_SUPPORTED            200	/* Service not supported */
 | 
				
			||||||
#define GTPCAUSE_MAN_IE_INCORRECT         201	/* Mandatory IE incorrect */
 | 
					#define GTPCAUSE_MAN_IE_INCORRECT         201	/* Mandatory IE incorrect */
 | 
				
			||||||
@@ -128,13 +141,21 @@
 | 
				
			|||||||
#define GTPCAUSE_SYN_ERR_FILTER           218	/* Syntactic errors in packet filter(s) */
 | 
					#define GTPCAUSE_SYN_ERR_FILTER           218	/* Syntactic errors in packet filter(s) */
 | 
				
			||||||
#define GTPCAUSE_MISSING_APN              219	/* Missing or unknown APN */
 | 
					#define GTPCAUSE_MISSING_APN              219	/* Missing or unknown APN */
 | 
				
			||||||
#define GTPCAUSE_UNKNOWN_PDP              220	/* Unknown PDP address or PDP type */
 | 
					#define GTPCAUSE_UNKNOWN_PDP              220	/* Unknown PDP address or PDP type */
 | 
				
			||||||
#define GTPCAUSE_221                      221	/* For Future Use 221-240 */
 | 
					/* 234-240 For future use */
 | 
				
			||||||
#define GTPCAUSE_241                      241	/* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */
 | 
					/* 241-255 Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' 3GPP TS 32.295) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool gtp_cause_successful(uint8_t cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return cause == GTPCAUSE_ACC_REQ ||
 | 
				
			||||||
 | 
							cause == GTPCAUSE_NEW_PDP_NET_PREF ||
 | 
				
			||||||
 | 
							cause == GTPCAUSE_NEW_PDP_ADDR_BEAR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ul66_t;
 | 
					struct ul66_t;
 | 
				
			||||||
struct ul16_t;
 | 
					struct ul16_t;
 | 
				
			||||||
 | 
					struct pdp_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* GTP 0 header. 
 | 
					/* GTP 0 header.
 | 
				
			||||||
 * Explanation to some of the fields:
 | 
					 * Explanation to some of the fields:
 | 
				
			||||||
 * SNDCP NPDU Number flag = 0 except for inter SGSN handover situations
 | 
					 * SNDCP NPDU Number flag = 0 except for inter SGSN handover situations
 | 
				
			||||||
 * SNDCP N-PDU LCC Number 0 = 0xff except for inter SGSN handover situations
 | 
					 * SNDCP N-PDU LCC Number 0 = 0xff except for inter SGSN handover situations
 | 
				
			||||||
@@ -161,6 +182,13 @@ struct gtp0_header {		/*    Descriptions from 3GPP 09.60 */
 | 
				
			|||||||
	uint64_t tid;		/* 13 Tunnel ID */
 | 
						uint64_t tid;		/* 13 Tunnel ID */
 | 
				
			||||||
} __attribute__((packed));	/* 20 */
 | 
					} __attribute__((packed));	/* 20 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GTP1HDR_F_NPDU	0x01
 | 
				
			||||||
 | 
					#define GTP1HDR_F_SEQ	0x02
 | 
				
			||||||
 | 
					#define GTP1HDR_F_EXT	0x04
 | 
				
			||||||
 | 
					#define GTP1HDR_F_GTP1	0x10
 | 
				
			||||||
 | 
					#define GTPHDR_F_VER(n)	((n) << 5)
 | 
				
			||||||
 | 
					#define GTPHDR_F_GET_VER(flags) ((flags)>>5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gtp1_header_short {	/*    Descriptions from 3GPP 29060 */
 | 
					struct gtp1_header_short {	/*    Descriptions from 3GPP 29060 */
 | 
				
			||||||
	uint8_t flags;		/* 01 bitfield, with typical values */
 | 
						uint8_t flags;		/* 01 bitfield, with typical values */
 | 
				
			||||||
	/*    001..... Version: 1 */
 | 
						/*    001..... Version: 1 */
 | 
				
			||||||
@@ -212,192 +240,48 @@ union gtp_packet {
 | 
				
			|||||||
	struct gtp1_packet_long gtp1l;
 | 
						struct gtp1_packet_long gtp1l;
 | 
				
			||||||
} __attribute__ ((packed));
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ***********************************************************
 | 
					 | 
				
			||||||
 * Information storage for each gsn instance
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Normally each instance of the application corresponds to
 | 
					 | 
				
			||||||
 * one instance of a gsn. 
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * In order to avoid global variables in the application, and
 | 
					 | 
				
			||||||
 * also in order to allow several instances of a gsn in the same
 | 
					 | 
				
			||||||
 * application this struct is provided in order to store all
 | 
					 | 
				
			||||||
 * relevant information related to the gsn.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * Note that this does not include information storage for '
 | 
					 | 
				
			||||||
 * each pdp context. This is stored in another struct.
 | 
					 | 
				
			||||||
 *************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsn_t {
 | 
					 | 
				
			||||||
	/* Parameters related to the network interface */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int fd0;		/* GTP0 file descriptor */
 | 
					 | 
				
			||||||
	int fd1c;		/* GTP1 control plane file descriptor */
 | 
					 | 
				
			||||||
	int fd1u;		/* GTP0 user plane file descriptor */
 | 
					 | 
				
			||||||
	int mode;		/* Mode of operation: GGSN or SGSN */
 | 
					 | 
				
			||||||
	struct in_addr gsnc;	/* IP address of this gsn for signalling */
 | 
					 | 
				
			||||||
	struct in_addr gsnu;	/* IP address of this gsn for user traffic */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Parameters related to signalling messages */
 | 
					 | 
				
			||||||
	uint16_t seq_next;	/* Next sequence number to use */
 | 
					 | 
				
			||||||
	int seq_first;		/* First packet in queue (oldest timeout) */
 | 
					 | 
				
			||||||
	int seq_last;		/* Last packet in queue (youngest timeout) */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	unsigned char restart_counter;	/* Increment on restart. Stored on disk */
 | 
					 | 
				
			||||||
	char *statedir;		/* Disk location for permanent storage */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct queue_t *queue_req;	/* Request queue */
 | 
					 | 
				
			||||||
	struct queue_t *queue_resp;	/* Response queue */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Call back functions */
 | 
					 | 
				
			||||||
	int (*cb_delete_context) (struct pdp_t *);
 | 
					 | 
				
			||||||
	int (*cb_create_context_ind) (struct pdp_t *);
 | 
					 | 
				
			||||||
	int (*cb_unsup_ind) (struct sockaddr_in * peer);
 | 
					 | 
				
			||||||
	int (*cb_extheader_ind) (struct sockaddr_in * peer);
 | 
					 | 
				
			||||||
	int (*cb_conf) (int type, int cause, struct pdp_t * pdp, void *cbp);
 | 
					 | 
				
			||||||
	int (*cb_data_ind) (struct pdp_t * pdp, void *pack, unsigned len);
 | 
					 | 
				
			||||||
	int (*cb_recovery) (struct sockaddr_in * peer, uint8_t recovery);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Counters */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint64_t err_socket;	/* Number of socket errors */
 | 
					 | 
				
			||||||
	uint64_t err_readfrom;	/* Number of readfrom errors */
 | 
					 | 
				
			||||||
	uint64_t err_sendto;	/* Number of sendto errors */
 | 
					 | 
				
			||||||
	uint64_t err_memcpy;	/* Number of memcpy */
 | 
					 | 
				
			||||||
	uint64_t err_queuefull;	/* Number of times queue was full */
 | 
					 | 
				
			||||||
	uint64_t err_seq;	/* Number of seq out of range */
 | 
					 | 
				
			||||||
	uint64_t err_address;	/* GSN address conversion failed */
 | 
					 | 
				
			||||||
	uint64_t err_unknownpdp;	/* GSN address conversion failed */
 | 
					 | 
				
			||||||
	uint64_t err_unknowntid;	/* Application supplied unknown imsi+nsapi */
 | 
					 | 
				
			||||||
	uint64_t err_cause;	/* Unexpected cause value received */
 | 
					 | 
				
			||||||
	uint64_t err_outofpdp;	/* Out of storage for PDP contexts */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint64_t empty;		/* Number of empty packets */
 | 
					 | 
				
			||||||
	uint64_t unsup;		/* Number of unsupported version 29.60 11.1.1 */
 | 
					 | 
				
			||||||
	uint64_t tooshort;	/* Number of too short headers 29.60 11.1.2 */
 | 
					 | 
				
			||||||
	uint64_t unknown;	/* Number of unknown messages 29.60 11.1.3 */
 | 
					 | 
				
			||||||
	uint64_t unexpect;	/* Number of unexpected messages 29.60 11.1.4 */
 | 
					 | 
				
			||||||
	uint64_t duplicate;	/* Number of duplicate or unsolicited replies */
 | 
					 | 
				
			||||||
	uint64_t missing;	/* Number of missing information field messages */
 | 
					 | 
				
			||||||
	uint64_t incorrect;	/* Number of incorrect information field messages */
 | 
					 | 
				
			||||||
	uint64_t invalid;	/* Number of invalid message format messages */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* External API functions */
 | 
					/* External API functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const char *gtp_version();
 | 
					extern const char *gtp_version();
 | 
				
			||||||
extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
 | 
					 | 
				
			||||||
		   int mode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_free(struct gsn_t *gsn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
 | 
					 | 
				
			||||||
		      uint64_t imsi, uint8_t nsapi);
 | 
					 | 
				
			||||||
extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
					extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
				  void *cbp);
 | 
									  void *cbp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
 | 
					 | 
				
			||||||
					 int (*cb_create_context_ind) (struct
 | 
					 | 
				
			||||||
								       pdp_t *
 | 
					 | 
				
			||||||
								       pdp));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
					extern int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
				   int cause);
 | 
									   int cause);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
					extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
			      void *cbp, struct in_addr *inetaddr);
 | 
								      void *cbp, struct in_addr *inetaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int gtp_update_context_resp(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
 | 
									   int cause);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
					extern int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
				  void *cbp, int teardown);
 | 
									  void *cbp, int teardown)
 | 
				
			||||||
 | 
							OSMO_DEPRECATED("Use gtp_delete_context_req2() instead, to avoid freeing pdp ctx before reply");
 | 
				
			||||||
 | 
					extern int gtp_delete_context_req2(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
 | 
									   void *cbp, int teardown);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
					extern int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
			void *pack, unsigned len);
 | 
								void *pack, unsigned len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
 | 
					extern int gtp_ran_info_relay_req(struct gsn_t *gsn, const struct sockaddr_in *peer,
 | 
				
			||||||
			       int (*cb_data_ind) (struct pdp_t * pdp,
 | 
									  const uint8_t *ran_container, size_t ran_container_len,
 | 
				
			||||||
						   void *pack, unsigned len));
 | 
									  const uint8_t *rim_route_addr, size_t rim_route_addr_len,
 | 
				
			||||||
 | 
									  uint8_t rim_route_addr_discr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_fd(struct gsn_t *gsn);
 | 
					 | 
				
			||||||
extern int gtp_decaps0(struct gsn_t *gsn);
 | 
					extern int gtp_decaps0(struct gsn_t *gsn);
 | 
				
			||||||
extern int gtp_decaps1c(struct gsn_t *gsn);
 | 
					extern int gtp_decaps1c(struct gsn_t *gsn);
 | 
				
			||||||
extern int gtp_decaps1u(struct gsn_t *gsn);
 | 
					extern int gtp_decaps1u(struct gsn_t *gsn);
 | 
				
			||||||
extern int gtp_retrans(struct gsn_t *gsn);
 | 
					 | 
				
			||||||
extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
 | 
					 | 
				
			||||||
				     int (*cb_delete_context) (struct pdp_t *
 | 
					 | 
				
			||||||
							       pdp));
 | 
					 | 
				
			||||||
/*extern int gtp_set_cb_create_context(struct gsn_t *gsn,
 | 
					 | 
				
			||||||
  int (*cb_create_context) (struct pdp_t* pdp)); */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
 | 
					 | 
				
			||||||
				int (*cb) (struct sockaddr_in * peer));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
 | 
					 | 
				
			||||||
				    int (*cb) (struct sockaddr_in * peer));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_set_cb_conf(struct gsn_t *gsn,
 | 
					 | 
				
			||||||
			   int (*cb) (int type, int cause, struct pdp_t * pdp,
 | 
					 | 
				
			||||||
				      void *cbp));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gtp_set_cb_recovery(struct gsn_t *gsn,
 | 
					 | 
				
			||||||
			int (*cb) (struct sockaddr_in * peer,
 | 
					 | 
				
			||||||
				   uint8_t recovery));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Internal functions (not part of the API */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp,
 | 
					extern int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp,
 | 
				
			||||||
			struct in_addr *inetaddrs);
 | 
								struct in_addr *inetaddrs);
 | 
				
			||||||
extern int gtp_echo_resp(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			 struct sockaddr_in *peer, int fd,
 | 
					 | 
				
			||||||
			 void *pack, unsigned len);
 | 
					 | 
				
			||||||
extern int gtp_echo_ind(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			struct sockaddr_in *peer, int fd,
 | 
					 | 
				
			||||||
			void *pack, unsigned len);
 | 
					 | 
				
			||||||
extern int gtp_echo_conf(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			 struct sockaddr_in *peer, void *pack, unsigned len);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtp_unsup_req(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			 struct sockaddr_in *peer,
 | 
					 | 
				
			||||||
			 int fd, void *pack, unsigned len);
 | 
					 | 
				
			||||||
extern int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
 | 
					 | 
				
			||||||
			 void *pack, unsigned len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			       struct pdp_t *pdp, uint8_t cause);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			      struct sockaddr_in *peer, int fd,
 | 
					 | 
				
			||||||
			      void *pack, unsigned len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			       struct sockaddr_in *peer,
 | 
					 | 
				
			||||||
			       void *pack, unsigned len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *cbp,
 | 
					 | 
				
			||||||
			      struct in_addr *inetaddr, struct pdp_t *pdp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *cbp,
 | 
					 | 
				
			||||||
			      struct pdp_t *pdp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			       struct sockaddr_in *peer, int fd,
 | 
					 | 
				
			||||||
			       void *pack, unsigned len,
 | 
					 | 
				
			||||||
			       struct pdp_t *pdp, struct pdp_t *linked_pdp,
 | 
					 | 
				
			||||||
			       uint8_t cause, int teardown);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			      struct sockaddr_in *peer, int fd,
 | 
					 | 
				
			||||||
			      void *pack, unsigned len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
 | 
					 | 
				
			||||||
			       struct sockaddr_in *peer,
 | 
					 | 
				
			||||||
			       void *pack, unsigned len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int ipv42eua(struct ul66_t *eua, struct in_addr *src);
 | 
					 | 
				
			||||||
extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua);
 | 
					 | 
				
			||||||
extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna);
 | 
					extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna);
 | 
				
			||||||
extern int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src);
 | 
					
 | 
				
			||||||
 | 
					extern const char *imsi_gtp2str(const uint64_t *imsi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Set the talloc context for internal objects */
 | 
				
			||||||
 | 
					void gtp_set_talloc_ctx(void *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !_GTP_H */
 | 
					#endif /* !_GTP_H */
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/* 
 | 
					/* 
 | 
				
			||||||
 *  OpenGGSN - Gateway GPRS Support Node
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
					 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 | 
				
			||||||
 * 
 | 
					 * 
 | 
				
			||||||
 *  The contents of this file may be used under the terms of the GNU
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
@@ -12,6 +12,8 @@
 | 
				
			|||||||
#ifndef _GTPIE_H
 | 
					#ifndef _GTPIE_H
 | 
				
			||||||
#define _GTPIE_H
 | 
					#define _GTPIE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Macroes for conversion between host and network byte order */
 | 
					/* Macroes for conversion between host and network byte order */
 | 
				
			||||||
#define hton8(x)  (x)
 | 
					#define hton8(x)  (x)
 | 
				
			||||||
#define ntoh8(x)  (x)
 | 
					#define ntoh8(x)  (x)
 | 
				
			||||||
@@ -48,7 +50,7 @@ static __inline uint64_t hton64(uint64_t q)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define GTPIE_DEBUG 0		/* Print debug information */
 | 
					#define GTPIE_DEBUG 0		/* Print debug information */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* GTP Information elements from 29.060 v3.9.0 7.7 Information Elements */
 | 
					/* GTP Information elements from 29.060 v11.8.0 7.7 Information Elements */
 | 
				
			||||||
/* Also covers version 0. Note that version 0 6: QOS Profile was superceded *
 | 
					/* Also covers version 0. Note that version 0 6: QOS Profile was superceded *
 | 
				
			||||||
 * by 135: QOS Profile in version 1 */
 | 
					 * by 135: QOS Profile in version 1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,7 +86,7 @@ static __inline uint64_t hton64(uint64_t q)
 | 
				
			|||||||
#define GTPIE_TRACE_TYPE     28	/* Trace Type 2 */
 | 
					#define GTPIE_TRACE_TYPE     28	/* Trace Type 2 */
 | 
				
			||||||
#define GTPIE_MS_NOT_REACH   29	/* MS Not Reachable Reason 1 */
 | 
					#define GTPIE_MS_NOT_REACH   29	/* MS Not Reachable Reason 1 */
 | 
				
			||||||
				/* 30-116 UNUSED */
 | 
									/* 30-116 UNUSED */
 | 
				
			||||||
/* 117-126 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
 | 
					/* 117-126 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15 / 32.295) */
 | 
				
			||||||
#define GTPIE_CHARGING_ID   127	/* Charging ID 4 */
 | 
					#define GTPIE_CHARGING_ID   127	/* Charging ID 4 */
 | 
				
			||||||
#define GTPIE_EUA           128	/* End User Address */
 | 
					#define GTPIE_EUA           128	/* End User Address */
 | 
				
			||||||
#define GTPIE_MM_CONTEXT    129	/* MM Context */
 | 
					#define GTPIE_MM_CONTEXT    129	/* MM Context */
 | 
				
			||||||
@@ -102,13 +104,81 @@ static __inline uint64_t hton64(uint64_t q)
 | 
				
			|||||||
#define GTPIE_EXT_HEADER_T  141	/* Extension Header Type List */
 | 
					#define GTPIE_EXT_HEADER_T  141	/* Extension Header Type List */
 | 
				
			||||||
#define GTPIE_TRIGGER_ID    142	/* Trigger Id */
 | 
					#define GTPIE_TRIGGER_ID    142	/* Trigger Id */
 | 
				
			||||||
#define GTPIE_OMC_ID        143	/* OMC Identity */
 | 
					#define GTPIE_OMC_ID        143	/* OMC Identity */
 | 
				
			||||||
 | 
					#define GTPIE_RAN_T_CONTAIN 144	/* RAN Transparent Container */
 | 
				
			||||||
 | 
					#define GTPIE_PDP_CTX_PRIO  145	/* PDP Context Prioritization */
 | 
				
			||||||
 | 
					#define GTPIE_ADDL_RAB_S_I  146	/* Additional RAB Setup Information */
 | 
				
			||||||
 | 
					#define GTPIE_SGSN_NUMBER   147	/* SGSN Number */
 | 
				
			||||||
 | 
					#define GTPIE_COMMON_FLAGS  148	/* Common Flags */
 | 
				
			||||||
 | 
					#define GTPIE_APN_RESTR     149	/* APN Restriction */
 | 
				
			||||||
 | 
					#define GTPIE_R_PRIO_LCS    150	/* Radio Priority LCS */
 | 
				
			||||||
#define GTPIE_RAT_TYPE      151	/* Radio Access Technology Type */
 | 
					#define GTPIE_RAT_TYPE      151	/* Radio Access Technology Type */
 | 
				
			||||||
#define GTPIE_USER_LOC      152	/* User Location Information  */
 | 
					#define GTPIE_USER_LOC      152	/* User Location Information  */
 | 
				
			||||||
#define GTPIE_MS_TZ         153	/* MS Time Zone */
 | 
					#define GTPIE_MS_TZ         153	/* MS Time Zone */
 | 
				
			||||||
#define GTPIE_IMEI_SV       154	/* IMEI Software Version */
 | 
					#define GTPIE_IMEI_SV       154	/* IMEI Software Version */
 | 
				
			||||||
/* 239-250 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
 | 
					#define GTPIE_CML_CHG_I_CT  155	/* CAMEL Charging Information Container */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_UE_CTX   156	/* MSMS UE Context */
 | 
				
			||||||
 | 
					#define GTPIE_TMGI          157	/* Temporary Mobile Group Identity (TMGI) */
 | 
				
			||||||
 | 
					#define GTPIE_RIM_ROUT_ADDR 158	/* RIM Routing Address */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_PCO      159	/* MBMS Protocol Configuratin Options */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_SA       160	/* MBMS Service Area */
 | 
				
			||||||
 | 
					#define GTPIE_SRNC_PDCP_CTX 161	/* Source RNC PDCP Context Info */
 | 
				
			||||||
 | 
					#define GTPIE_ADDL_TRACE    162	/* Additional Trace Info */
 | 
				
			||||||
 | 
					#define GTPIE_HOP_CTR       163	/* Hop Counter */
 | 
				
			||||||
 | 
					#define GTPIE_SEL_PLMN_ID   164	/* Selected PLMN ID */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_SESS_ID  165	/* MBMS Session Identifier */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_2_3G_IND 166	/* MBMS 2G/3G Indicator */
 | 
				
			||||||
 | 
					#define GTPIE_ENH_NSAPI     167	/* Enhanced NSAPI */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_SESS_DUR 168	/* MBMS Session Duration */
 | 
				
			||||||
 | 
					#define GTPIE_A_MBMS_TRAC_I 169	/* Additional MBMS Trace Info */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_S_REP_N  170	/* MBMS Session Repetition Number */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_TTDT     171	/* MBMS Time To Data Transfer */
 | 
				
			||||||
 | 
					#define GTPIE_PS_HO_REQ_CTX 172	/* PS Handover Request Context */
 | 
				
			||||||
 | 
					#define GTPIE_BSS_CONTAINER 173	/* BSS Container */
 | 
				
			||||||
 | 
					#define GTPIE_CELL_ID       174	/* Cell Identification */
 | 
				
			||||||
 | 
					#define GTPIE_PDU_NUMBERS   175	/* PDU Numbers */
 | 
				
			||||||
 | 
					#define GTPIE_BSSGP_CAUSE   176	/* BSSGP Cause */
 | 
				
			||||||
 | 
					#define GTPIE_RQD_MBMS_BCAP 177	/* Required MBMS Bearer Capabilities */
 | 
				
			||||||
 | 
					#define GTPIE_RIM_RA_DISCR  178	/* RIM Routing Address Discriminator */
 | 
				
			||||||
 | 
					#define GTPIE_L_SETUP_PFCS  179	/* List of set-up PFCs */
 | 
				
			||||||
 | 
					#define GTPIE_PS_HO_XID_PAR 180	/* PS Handover XID Parameters */
 | 
				
			||||||
 | 
					#define GTPIE_MS_CHG_REP_A  181	/* MS Info Change Reporting Action */
 | 
				
			||||||
 | 
					#define GTPIE_DIR_TUN_FLAGS 182	/* Direct Tunnel Flags */
 | 
				
			||||||
 | 
					#define GTPIE_CORREL_ID     183	/* Correlation-ID */
 | 
				
			||||||
 | 
					#define GTPIE_BCM           184	/* Bearer control mode */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_FLOWI    185	/* MBMS Flow Identifier */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_MC_DIST  186	/* MBMS IP Multicast Distribution */
 | 
				
			||||||
 | 
					#define GTPIE_MBMS_DIST_ACK 187	/* MBMS Distribution Acknowledgement */
 | 
				
			||||||
 | 
					#define GTPIE_R_IRAT_HO_INF 188	/* Reliable INTER RAT HANDOVER INFO */
 | 
				
			||||||
 | 
					#define GTPIE_RFSP_IDX      189	/* RFSP Index */
 | 
				
			||||||
 | 
					#define GTPIE_FQDN          190	/* FQDN */
 | 
				
			||||||
 | 
					#define GTPIE_E_ALL_PRIO_1  191	/* Evolvd Allocation/Retention Priority I */
 | 
				
			||||||
 | 
					#define GTPIE_E_ALL_PRIO_2  192	/* Evolvd Allocation/Retention Priority II */
 | 
				
			||||||
 | 
					#define GTPIE_E_CMN_FLAGS   193	/* Extended Common Flags */
 | 
				
			||||||
 | 
					#define GTPIE_U_CSG_INFO    194	/* User CSG Information (UCI) */
 | 
				
			||||||
 | 
					#define GTPIE_CSG_I_REP_ACT 195	/* CSG Information Reporting Action */
 | 
				
			||||||
 | 
					#define GTPIE_CSG_ID        196	/* CSG ID */
 | 
				
			||||||
 | 
					#define GTPIE_CSG_MEMB_IND  197	/* CSG Membership Indication (CMI) */
 | 
				
			||||||
 | 
					#define GTPIE_AMBR          198	/* Aggregate Maximum Bit Rate (AMBR) */
 | 
				
			||||||
 | 
					#define GTPIE_UE_NET_CAPA   199	/* UE Network Capability */
 | 
				
			||||||
 | 
					#define GTPIE_UE_AMBR       200	/* UE-AMBR */
 | 
				
			||||||
 | 
					#define GTPIE_APN_AMBR_NS   201	/* APN-AMBR with NSAPI */
 | 
				
			||||||
 | 
					#define GTPIE_GGSN_BACKOFF  202	/* GGSN Back-Off Time */
 | 
				
			||||||
 | 
					#define GTPIE_S_PRIO_IND    203	/* Signalling Priority Indication */
 | 
				
			||||||
 | 
					#define GTPIE_S_PRIO_IND_NS 204	/* Signalling Priority Indication with NSAPI */
 | 
				
			||||||
 | 
					#define GTPIE_H_BR_16MBPS_F 205	/* Higher Bitrates than 16 Mbps flag */
 | 
				
			||||||
 | 
					/* 206: Reserved */
 | 
				
			||||||
 | 
					#define GTPIE_A_MMCTX_SRVCC 207	/* Additional MM context for SRVCC */
 | 
				
			||||||
 | 
					#define GTPIE_A_FLAGS_SRVCC 208	/* Additional flags fro SRVC */
 | 
				
			||||||
 | 
					#define GTPIE_STN_SR        209	/* STN-SR */
 | 
				
			||||||
 | 
					#define GTPIE_C_MSISDN      210	/* C-MSISDN */
 | 
				
			||||||
 | 
					#define GTPIE_E_RANAP_CAUSE 211	/* Extended RANAP Cause */
 | 
				
			||||||
 | 
					#define GTPIE_ENODEB_ID     212	/* eNodeB ID */
 | 
				
			||||||
 | 
					#define GTPIE_SEL_MODE_NS   213	/* Selection Mode with NSAPI */
 | 
				
			||||||
 | 
					#define GTPIE_ULI_TIMESTAMP 214	/* ULI Timestamp */
 | 
				
			||||||
 | 
					/* 215-238 Spare. For future use */
 | 
				
			||||||
 | 
					/* 239-250 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15 / 32.295) */
 | 
				
			||||||
#define GTPIE_CHARGING_ADDR 251	/* Charging Gateway Address */
 | 
					#define GTPIE_CHARGING_ADDR 251	/* Charging Gateway Address */
 | 
				
			||||||
/* 252-254 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
 | 
					/* 252-254 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15 / 32.295) */
 | 
				
			||||||
#define GTPIE_PRIVATE       255	/* Private Extension */
 | 
					#define GTPIE_PRIVATE       255	/* Private Extension */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* GTP information element structs in network order */
 | 
					/* GTP information element structs in network order */
 | 
				
			||||||
@@ -220,9 +290,9 @@ struct tlv2 {
 | 
				
			|||||||
} __attribute__ ((packed));
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtpie_tlv(void *p, unsigned int *length, unsigned int size,
 | 
					extern int gtpie_tlv(void *p, unsigned int *length, unsigned int size,
 | 
				
			||||||
		     uint8_t t, int l, void *v);
 | 
							     uint8_t t, int l, const void *v);
 | 
				
			||||||
extern int gtpie_tv0(void *p, unsigned int *length, unsigned int size,
 | 
					extern int gtpie_tv0(void *p, unsigned int *length, unsigned int size,
 | 
				
			||||||
		     uint8_t t, int l, uint8_t * v);
 | 
							     uint8_t t, int l, const uint8_t * v);
 | 
				
			||||||
extern int gtpie_tv1(void *p, unsigned int *length, unsigned int size,
 | 
					extern int gtpie_tv1(void *p, unsigned int *length, unsigned int size,
 | 
				
			||||||
		     uint8_t t, uint8_t v);
 | 
							     uint8_t t, uint8_t v);
 | 
				
			||||||
extern int gtpie_tv2(void *p, unsigned int *length, unsigned int size,
 | 
					extern int gtpie_tv2(void *p, unsigned int *length, unsigned int size,
 | 
				
			||||||
@@ -247,9 +317,11 @@ extern int gtpie_gettv8(union gtpie_member *ie[], int type, int instance,
 | 
				
			|||||||
			uint64_t * dst);
 | 
								uint64_t * dst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int gtpie_decaps(union gtpie_member *ie[], int version,
 | 
					extern int gtpie_decaps(union gtpie_member *ie[], int version,
 | 
				
			||||||
			void *pack, unsigned len);
 | 
								const void *pack, unsigned len);
 | 
				
			||||||
extern int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len);
 | 
					extern int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len);
 | 
				
			||||||
extern int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
					extern int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
 | 
				
			||||||
			 void *pack, unsigned *len);
 | 
								 void *pack, unsigned *len);
 | 
				
			||||||
 | 
					extern int gtpie_encaps3(union gtpie_member *ie[], unsigned int ie_len,
 | 
				
			||||||
 | 
							  void *pack, unsigned pack_len, unsigned *encoded_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !_GTPIE_H */
 | 
					#endif /* !_GTPIE_H */
 | 
				
			||||||
@@ -1,20 +1,37 @@
 | 
				
			|||||||
/* 
 | 
					/*
 | 
				
			||||||
 *  OpenGGSN - Gateway GPRS Support Node
 | 
					 *  OsmoGGSN - Gateway GPRS Support Node
 | 
				
			||||||
 *  Copyright (C) 2002, 2003 Mondru AB.
 | 
					 *  Copyright (C) 2002, 2003 Mondru AB.
 | 
				
			||||||
 * 
 | 
					 *  Copyright (C) 2017 Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 *  The contents of this file may be used under the terms of the GNU
 | 
					 *  The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 *  General Public License Version 2, provided that the above copyright
 | 
					 *  General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 *  notice and this permission notice is included in all copies or
 | 
					 *  notice and this permission notice is included in all copies or
 | 
				
			||||||
 *  substantial portions of the software.
 | 
					 *  substantial portions of the software.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef _PDP_H
 | 
					#ifndef _PDP_H
 | 
				
			||||||
#define _PDP_H
 | 
					#define _PDP_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/defs.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/linuxlist.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsn_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LOGPDPX(ss, level, pdp, fmt, args...)				\
 | 
				
			||||||
 | 
						LOGP(ss, level, "PDP(%s:%u): " fmt, imsi_gtp2str(&(pdp)->imsi), (pdp)->nsapi, ## args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PDP_MAX 1024		/* Max number of PDP contexts */
 | 
					#define PDP_MAX 1024		/* Max number of PDP contexts */
 | 
				
			||||||
#define PDP_MAXNSAPI 16		/* Max number of NSAPI */
 | 
					#define PDP_MAXNSAPI 16		/* Max number of NSAPI */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PDP_EUA_ORG_IETF	0xF1
 | 
				
			||||||
 | 
					#define PDP_EUA_TYPE_v4		0x21
 | 
				
			||||||
 | 
					#define PDP_EUA_TYPE_v6		0x57
 | 
				
			||||||
 | 
					#define PDP_EUA_TYPE_v4v6	0x8D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* GTP Information elements from 29.060 v3.9.0 7.7 Information Elements */
 | 
					/* GTP Information elements from 29.060 v3.9.0 7.7 Information Elements */
 | 
				
			||||||
/* Also covers version 0. Note that version 0 6: QOS Profile was superceded *
 | 
					/* Also covers version 0. Note that version 0 6: QOS Profile was superceded *
 | 
				
			||||||
 * by 135: QOS Profile in version 1 */
 | 
					 * by 135: QOS Profile in version 1 */
 | 
				
			||||||
@@ -29,6 +46,11 @@ struct ul_t {
 | 
				
			|||||||
	unsigned char *v;
 | 
						unsigned char *v;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ul1_t {
 | 
				
			||||||
 | 
						unsigned int l;
 | 
				
			||||||
 | 
						unsigned char v[1];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ul16_t {
 | 
					struct ul16_t {
 | 
				
			||||||
	unsigned int l;
 | 
						unsigned int l;
 | 
				
			||||||
	unsigned char v[16];
 | 
						unsigned char v[16];
 | 
				
			||||||
@@ -59,16 +81,16 @@ struct ul255_t {
 | 
				
			|||||||
 * and 09.60.
 | 
					 * and 09.60.
 | 
				
			||||||
 * 31 * 4 + 15 structs +  = 120 + 15 structs ~ 2k / context
 | 
					 * 31 * 4 + 15 structs +  = 120 + 15 structs ~ 2k / context
 | 
				
			||||||
 * Structs: IP address 16+4 bytes (6), APN 255 bytes (2)
 | 
					 * Structs: IP address 16+4 bytes (6), APN 255 bytes (2)
 | 
				
			||||||
 * QOS: 255 bytes (3), msisdn 16 bytes (1), 
 | 
					 * QOS: 255 bytes (3), msisdn 16 bytes (1),
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * TODO: We need to consider who manages the pdp_t hash tables
 | 
					 * TODO: We need to consider who manages the pdp_t hash tables
 | 
				
			||||||
 * Is it gtp_lib, or is it the application?
 | 
					 * Is it gtp_lib, or is it the application?
 | 
				
			||||||
 * I suppose that it will be gtp_lib. 
 | 
					 * I suppose that it will be gtp_lib.
 | 
				
			||||||
 * SGSN will ask gtplib for new pdp_t. Fill out the fields,
 | 
					 * SGSN will ask gtplib for new pdp_t. Fill out the fields,
 | 
				
			||||||
 * and pass it on to gtp_create_pdp_req.
 | 
					 * and pass it on to gtp_create_pdp_req.
 | 
				
			||||||
 * GGSN will receive gtp_create_pdp_ind, create new pdp_t and
 | 
					 * GGSN will receive gtp_create_pdp_ind, create new pdp_t and
 | 
				
			||||||
 * send responce to SGSN.
 | 
					 * send responce to SGSN.
 | 
				
			||||||
 * SGSN will receive response and gtplib will find the 
 | 
					 * SGSN will receive response and gtplib will find the
 | 
				
			||||||
 * original pdp_t corresponding to the request. This will be
 | 
					 * original pdp_t corresponding to the request. This will be
 | 
				
			||||||
 * passed on to the application.
 | 
					 * passed on to the application.
 | 
				
			||||||
 * Eventually the SGSN will close the connection, and the
 | 
					 * Eventually the SGSN will close the connection, and the
 | 
				
			||||||
@@ -76,10 +98,10 @@ struct ul255_t {
 | 
				
			|||||||
 * This means that gtplib need to have functions to
 | 
					 * This means that gtplib need to have functions to
 | 
				
			||||||
 * allocate, free, sort and find pdp_t
 | 
					 * allocate, free, sort and find pdp_t
 | 
				
			||||||
 * (newpdp, freepdp, getpdp)
 | 
					 * (newpdp, freepdp, getpdp)
 | 
				
			||||||
 * Hash tables: TID, IMSI, IP etc.) 
 | 
					 * Hash tables: TID, IMSI, IP etc.)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Secondary PDP Context Activation Procedure 
 | 
					 * Secondary PDP Context Activation Procedure
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * With GTP version 1 it is possible to establish multiple PDP
 | 
					 * With GTP version 1 it is possible to establish multiple PDP
 | 
				
			||||||
 * contexts with the same IP address. With this scheme the first
 | 
					 * contexts with the same IP address. With this scheme the first
 | 
				
			||||||
@@ -109,7 +131,7 @@ struct pdp_t {
 | 
				
			|||||||
	/* Parameters shared by all PDP context belonging to the same MS */
 | 
						/* Parameters shared by all PDP context belonging to the same MS */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void *ipif;		/* IP network interface */
 | 
						void *ipif;		/* IP network interface */
 | 
				
			||||||
	void *peer;		/* Pointer to peer protocol */
 | 
						void *peer[2];		/* Pointer to peer protocol */
 | 
				
			||||||
	void *asap;		/* Application specific service access point */
 | 
						void *asap;		/* Application specific service access point */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t imsi;		/* International Mobile Subscriber Identity. */
 | 
						uint64_t imsi;		/* International Mobile Subscriber Identity. */
 | 
				
			||||||
@@ -221,37 +243,45 @@ struct pdp_t {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* to be used by libgtp callers/users (to attach their own private state) */
 | 
						/* to be used by libgtp callers/users (to attach their own private state) */
 | 
				
			||||||
	void *priv;
 | 
						void *priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct gsn_t *gsn; /* Back pointer to GSN where this pdp ctx belongs to */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool tx_gpdu_seq;		/* Transmit (true) or suppress G-PDU sequence numbers */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct llist_head qmsg_list_req; /* list of req qmsg_t in retrans queue belonging this pdp ctx */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct ul1_t dir_tun_flags; /* Direct Tunnel Flags, TS 29.060 7.7.81 */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* functions related to pdp_t management */
 | 
					/* functions related to pdp_t management */
 | 
				
			||||||
int pdp_init();
 | 
					int gtp_pdp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi,
 | 
				
			||||||
int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
 | 
							   uint8_t nsapi, struct pdp_t *pdp_old);
 | 
				
			||||||
	       struct pdp_t *pdp_old);
 | 
					 | 
				
			||||||
int pdp_freepdp(struct pdp_t *pdp);
 | 
					int pdp_freepdp(struct pdp_t *pdp);
 | 
				
			||||||
int pdp_getpdp(struct pdp_t **pdp);
 | 
					int gtp_pdp_getgtp0(struct gsn_t *gsn, struct pdp_t **pdp, uint16_t fl);
 | 
				
			||||||
 | 
					int gtp_pdp_getgtp1(struct gsn_t *gsn, struct pdp_t **pdp, uint32_t tei);
 | 
				
			||||||
int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl);
 | 
					int gtp_pdp_getgtp1_peer_d(struct gsn_t *gsn, struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn);
 | 
				
			||||||
int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei);
 | 
					int gtp_pdp_getimsi(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi);
 | 
				
			||||||
 | 
					int gtp_pdp_tidget(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t tid);
 | 
				
			||||||
int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pdp_tidhash(uint64_t tid);
 | 
					int pdp_tidhash(uint64_t tid);
 | 
				
			||||||
int pdp_tidset(struct pdp_t *pdp, uint64_t tid);
 | 
					int pdp_tidset(struct pdp_t *pdp, uint64_t tid);
 | 
				
			||||||
int pdp_tiddel(struct pdp_t *pdp);
 | 
					int pdp_tiddel(struct pdp_t *pdp);
 | 
				
			||||||
int pdp_tidget(struct pdp_t **pdp, uint64_t tid);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi);
 | 
				
			||||||
void pdp_set_imsi_nsapi(struct pdp_t *pdp, uint64_t teid);
 | 
					void pdp_set_imsi_nsapi(struct pdp_t *pdp, uint64_t teid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					unsigned int pdp_count_secondary(const struct pdp_t *pdp);
 | 
				
			||||||
int pdp_iphash(void* ipif, struct ul66_t *eua);
 | 
					
 | 
				
			||||||
int pdp_ipset(struct pdp_t *pdp, void* ipif, struct ul66_t *eua);
 | 
					/* Deprecated APIs (support for only 1 GSN per process). Must be used only after first call to gtp_new() and until it is freed. */
 | 
				
			||||||
int pdp_ipdel(struct pdp_t *pdp);
 | 
					int pdp_init(struct gsn_t *gsn); /* Use only allowed inside libgtp to keep compatiblity with deprecated APIs defined here. */
 | 
				
			||||||
int pdp_ipget(struct pdp_t **pdp, void* ipif, struct ul66_t *eua);
 | 
					int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
 | 
				
			||||||
*/
 | 
						       struct pdp_t *pdp_old) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead");
 | 
				
			||||||
 | 
					int pdp_getpdp(struct pdp_t **pdp) OSMO_DEPRECATED("Use gsn_t->pdpa field instead");
 | 
				
			||||||
 | 
					int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl) OSMO_DEPRECATED("Use gtp_pdp_getgtp0() instead");
 | 
				
			||||||
 | 
					int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei) OSMO_DEPRECATED("Use gtp_pdp_getgtp1() instead");
 | 
				
			||||||
 | 
					int pdp_getgtp1_peer_d(struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn) OSMO_DEPRECATED("Use gtp_pdp_getgtp1_peer_d() instead");
 | 
				
			||||||
 | 
					int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_getimsi() instead");
 | 
				
			||||||
 | 
					int pdp_tidget(struct pdp_t **pdp, uint64_t tid) OSMO_DEPRECATED("Use gtp_pdp_tidget() instead");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pdp_ntoeua(struct in_addr *src, struct ul66_t *eua);
 | 
					 | 
				
			||||||
int pdp_euaton(struct ul66_t *eua, struct in_addr *dst);
 | 
					 | 
				
			||||||
uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi);
 | 
					 | 
				
			||||||
int ulcpy(void *dst, void *src, size_t size);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !_PDP_H */
 | 
					#endif /* !_PDP_H */
 | 
				
			||||||
@@ -1,7 +1,44 @@
 | 
				
			|||||||
noinst_LIBRARIES = libmisc.a
 | 
					noinst_LIBRARIES = libmisc.a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
noinst_HEADERS = gnugetopt.h ippool.h lookup.h syserr.h tun.h
 | 
					noinst_HEADERS = \
 | 
				
			||||||
 | 
							 checksum.h \
 | 
				
			||||||
 | 
							 gnugetopt.h \
 | 
				
			||||||
 | 
							 gtp-kernel.h \
 | 
				
			||||||
 | 
							 icmpv6.h \
 | 
				
			||||||
 | 
							 in46_addr.h \
 | 
				
			||||||
 | 
							 ippool.h \
 | 
				
			||||||
 | 
							 lookup.h \
 | 
				
			||||||
 | 
							 netdev.h \
 | 
				
			||||||
 | 
							 netns.h \
 | 
				
			||||||
 | 
							 syserr.h \
 | 
				
			||||||
 | 
							 tun.h \
 | 
				
			||||||
 | 
							 util.h \
 | 
				
			||||||
 | 
							 $(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AM_CFLAGS = -O2 -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
 | 
					AM_CFLAGS = \
 | 
				
			||||||
 | 
						    -fno-builtin \
 | 
				
			||||||
 | 
						    -Wall \
 | 
				
			||||||
 | 
						    -DSBINDIR='"$(sbindir)"' \
 | 
				
			||||||
 | 
						    -I$(top_srcdir)/include \
 | 
				
			||||||
 | 
						    $(LIBOSMOCORE_CFLAGS) \
 | 
				
			||||||
 | 
						    $(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libmisc_a_SOURCES = getopt1.c getopt.c ippool.c lookup.c tun.c debug.c
 | 
					libmisc_a_SOURCES = \
 | 
				
			||||||
 | 
							    checksum.c \
 | 
				
			||||||
 | 
							    debug.c \
 | 
				
			||||||
 | 
							    getopt.c \
 | 
				
			||||||
 | 
							    getopt1.c \
 | 
				
			||||||
 | 
							    icmpv6.c \
 | 
				
			||||||
 | 
							    in46_addr.c \
 | 
				
			||||||
 | 
							    ippool.c \
 | 
				
			||||||
 | 
							    lookup.c \
 | 
				
			||||||
 | 
							    netdev.c \
 | 
				
			||||||
 | 
							    netns.c \
 | 
				
			||||||
 | 
							    tun.c \
 | 
				
			||||||
 | 
							    util.c \
 | 
				
			||||||
 | 
							    $(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ENABLE_GTP_KERNEL
 | 
				
			||||||
 | 
					AM_CFLAGS += -DGTP_KERNEL $(LIBGTPNL_CFLAGS)
 | 
				
			||||||
 | 
					libmisc_a_SOURCES += gtp-kernel.c
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										211
									
								
								lib/checksum.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								lib/checksum.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * INET		An implementation of the TCP/IP protocol suite for the LINUX
 | 
				
			||||||
 | 
					 *		operating system.  INET is implemented using the  BSD Socket
 | 
				
			||||||
 | 
					 *		interface as the means of communication with the user level.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		IP/TCP/UDP checksumming routines
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
 | 
				
			||||||
 | 
					 *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
 | 
				
			||||||
 | 
					 *		Tom May, <ftom@netcom.com>
 | 
				
			||||||
 | 
					 *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
 | 
				
			||||||
 | 
					 *		Lots of code moved from tcp.c and ip.c; see those files
 | 
				
			||||||
 | 
					 *		for more names.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
 | 
				
			||||||
 | 
					 *		Fixed some nasty bugs, causing some horrible crashes.
 | 
				
			||||||
 | 
					 *		A: At some points, the sum (%0) was used as
 | 
				
			||||||
 | 
					 *		length-counter instead of the length counter
 | 
				
			||||||
 | 
					 *		(%1). Thanks to Roman Hodek for pointing this out.
 | 
				
			||||||
 | 
					 *		B: GCC seems to mess up if one uses too many
 | 
				
			||||||
 | 
					 *		data-registers to hold input values and one tries to
 | 
				
			||||||
 | 
					 *		specify d0 and d1 as scratch registers. Letting gcc
 | 
				
			||||||
 | 
					 *		choose these registers itself solves the problem.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 *		modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 *		as published by the Free Software Foundation; either version
 | 
				
			||||||
 | 
					 *		2 of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
 | 
				
			||||||
 | 
					 kills, so most of the assembly has to go. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__FreeBSD__)
 | 
				
			||||||
 | 
					#define _KERNEL	/* needed on FreeBSD 10.x for s6_addr32 */
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <sys/endian.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "checksum.h"
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned short from32to16(unsigned int x)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* add up 16-bit and 16-bit for 16+c bit */
 | 
				
			||||||
 | 
						x = (x & 0xffff) + (x >> 16);
 | 
				
			||||||
 | 
						/* add up carry.. */
 | 
				
			||||||
 | 
						x = (x & 0xffff) + (x >> 16);
 | 
				
			||||||
 | 
						return x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned int do_csum(const unsigned char *buff, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int odd;
 | 
				
			||||||
 | 
						unsigned int result = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len <= 0)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						odd = 1 & (unsigned long) buff;
 | 
				
			||||||
 | 
						if (odd) {
 | 
				
			||||||
 | 
					#if BYTE_ORDER == LITTLE_ENDIAN
 | 
				
			||||||
 | 
							result += (*buff << 8);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							result = *buff;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							len--;
 | 
				
			||||||
 | 
							buff++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (len >= 2) {
 | 
				
			||||||
 | 
							if (2 & (unsigned long) buff) {
 | 
				
			||||||
 | 
								result += *(unsigned short *) buff;
 | 
				
			||||||
 | 
								len -= 2;
 | 
				
			||||||
 | 
								buff += 2;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (len >= 4) {
 | 
				
			||||||
 | 
								const unsigned char *end = buff + ((unsigned)len & ~3);
 | 
				
			||||||
 | 
								unsigned int carry = 0;
 | 
				
			||||||
 | 
								do {
 | 
				
			||||||
 | 
									unsigned int w = *(unsigned int *) buff;
 | 
				
			||||||
 | 
									buff += 4;
 | 
				
			||||||
 | 
									result += carry;
 | 
				
			||||||
 | 
									result += w;
 | 
				
			||||||
 | 
									carry = (w > result);
 | 
				
			||||||
 | 
								} while (buff < end);
 | 
				
			||||||
 | 
								result += carry;
 | 
				
			||||||
 | 
								result = (result & 0xffff) + (result >> 16);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (len & 2) {
 | 
				
			||||||
 | 
								result += *(unsigned short *) buff;
 | 
				
			||||||
 | 
								buff += 2;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (len & 1)
 | 
				
			||||||
 | 
					#if BYTE_ORDER == LITTLE_ENDIAN
 | 
				
			||||||
 | 
							result += *buff;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							result += (*buff << 8);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						result = from32to16(result);
 | 
				
			||||||
 | 
						if (odd)
 | 
				
			||||||
 | 
							result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *	This is a version of ip_compute_csum() optimized for IP headers,
 | 
				
			||||||
 | 
					 *	which always checksum on 4 octet boundaries.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t ip_fast_csum(const void *iph, unsigned int ihl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (uint16_t)~do_csum(iph, ihl*4);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * computes the checksum of a memory block at buff, length len,
 | 
				
			||||||
 | 
					 * and adds in "sum" (32-bit)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * returns a 32-bit number suitable for feeding into itself
 | 
				
			||||||
 | 
					 * or csum_tcpudp_magic
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * this function must be called with even lengths, except
 | 
				
			||||||
 | 
					 * for the last fragment, which may be odd
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * it's best to have buff aligned on a 32-bit boundary
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t csum_partial(const void *buff, int len, uint32_t wsum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int sum = (unsigned int)wsum;
 | 
				
			||||||
 | 
						unsigned int result = do_csum(buff, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* add in old sum, and carry.. */
 | 
				
			||||||
 | 
						result += sum;
 | 
				
			||||||
 | 
						if (sum > result)
 | 
				
			||||||
 | 
							result += 1;
 | 
				
			||||||
 | 
						return (uint32_t)result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * this routine is used for miscellaneous IP-like checksums, mainly
 | 
				
			||||||
 | 
					 * in icmp.c
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t ip_compute_csum(const void *buff, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (uint16_t)~do_csum(buff, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t csum_ipv6_magic(const struct in6_addr *saddr,
 | 
				
			||||||
 | 
								const struct in6_addr *daddr,
 | 
				
			||||||
 | 
								uint32_t len, uint8_t proto, uint32_t csum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int carry;
 | 
				
			||||||
 | 
						uint32_t ulen;
 | 
				
			||||||
 | 
						uint32_t uproto;
 | 
				
			||||||
 | 
						uint32_t sum = (uint32_t)csum;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum += (uint32_t)saddr->s6_addr32[0];
 | 
				
			||||||
 | 
						carry = (sum < (uint32_t)saddr->s6_addr32[0]);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum += (uint32_t)saddr->s6_addr32[1];
 | 
				
			||||||
 | 
						carry = (sum < (uint32_t)saddr->s6_addr32[1]);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum += (uint32_t)saddr->s6_addr32[2];
 | 
				
			||||||
 | 
						carry = (sum < (uint32_t)saddr->s6_addr32[2]);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum += (uint32_t)saddr->s6_addr32[3];
 | 
				
			||||||
 | 
						carry = (sum < (uint32_t)saddr->s6_addr32[3]);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum += (uint32_t)daddr->s6_addr32[0];
 | 
				
			||||||
 | 
						carry = (sum < (uint32_t)daddr->s6_addr32[0]);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum += (uint32_t)daddr->s6_addr32[1];
 | 
				
			||||||
 | 
						carry = (sum < (uint32_t)daddr->s6_addr32[1]);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum += (uint32_t)daddr->s6_addr32[2];
 | 
				
			||||||
 | 
						carry = (sum < (uint32_t)daddr->s6_addr32[2]);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum += (uint32_t)daddr->s6_addr32[3];
 | 
				
			||||||
 | 
						carry = (sum < (uint32_t)daddr->s6_addr32[3]);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ulen = (uint32_t)htonl((uint32_t) len);
 | 
				
			||||||
 | 
						sum += ulen;
 | 
				
			||||||
 | 
						carry = (sum < ulen);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uproto = (uint32_t)htonl(proto);
 | 
				
			||||||
 | 
						sum += uproto;
 | 
				
			||||||
 | 
						carry = (sum < uproto);
 | 
				
			||||||
 | 
						sum += carry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return csum_fold((uint32_t)sum);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* fold a partial checksum */
 | 
				
			||||||
 | 
					uint16_t csum_fold(uint32_t csum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t sum = (uint32_t)csum;
 | 
				
			||||||
 | 
						sum = (sum & 0xffff) + (sum >> 16);
 | 
				
			||||||
 | 
						sum = (sum & 0xffff) + (sum >> 16);
 | 
				
			||||||
 | 
						return (uint16_t)~sum;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								lib/checksum.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								lib/checksum.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t ip_fast_csum(const void *iph, unsigned int ihl);
 | 
				
			||||||
 | 
					uint32_t csum_partial(const void *buff, int len, uint32_t wsum);
 | 
				
			||||||
 | 
					uint16_t ip_compute_csum(const void *buff, int len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t csum_ipv6_magic(const struct in6_addr *saddr,
 | 
				
			||||||
 | 
								const struct in6_addr *daddr,
 | 
				
			||||||
 | 
								uint32_t len, uint8_t proto, uint32_t csum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t csum_fold(uint32_t csum);
 | 
				
			||||||
@@ -24,6 +24,11 @@ static const struct log_info_cat default_categories[] = {
 | 
				
			|||||||
	[DSGSN] = {
 | 
						[DSGSN] = {
 | 
				
			||||||
		.name = "DSGSN",
 | 
							.name = "DSGSN",
 | 
				
			||||||
		.description = "SGSN Emulator",
 | 
							.description = "SGSN Emulator",
 | 
				
			||||||
 | 
							.enabled = 1, .loglevel = LOGL_INFO,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						[DICMP6] = {
 | 
				
			||||||
 | 
							.name = "DICMP6",
 | 
				
			||||||
 | 
							.description = "ICMPv6",
 | 
				
			||||||
		.enabled = 1, .loglevel = LOGL_NOTICE,
 | 
							.enabled = 1, .loglevel = LOGL_NOTICE,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										201
									
								
								lib/gtp-kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								lib/gtp-kernel.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
				
			|||||||
 | 
					#ifdef __linux__
 | 
				
			||||||
 | 
					#define _GNU_SOURCE 1		/* strdup() prototype, broken arpa/inet.h */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_STDINT_H
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					#include <net/if.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <libgtpnl/gtp.h>
 | 
				
			||||||
 | 
					#include <libgtpnl/gtpnl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../lib/tun.h"
 | 
				
			||||||
 | 
					#include "../lib/syserr.h"
 | 
				
			||||||
 | 
					#include "../lib/util.h"
 | 
				
			||||||
 | 
					#include "../lib/ippool.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gtp-kernel.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void pdp_debug(const char *prefix, const char *devname, struct pdp_t *pdp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char buf4[INET_ADDRSTRLEN], buf6[INET6_ADDRSTRLEN];
 | 
				
			||||||
 | 
						struct ippoolm_t *peer;
 | 
				
			||||||
 | 
						struct in_addr ia;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buf4[0] = '\0';
 | 
				
			||||||
 | 
						if ((peer = pdp_get_peer_ipv(pdp, false)))
 | 
				
			||||||
 | 
							in46a_ntop(&peer->addr, buf4, sizeof(buf4));
 | 
				
			||||||
 | 
						buf6[0] = '\0';
 | 
				
			||||||
 | 
						if ((peer = pdp_get_peer_ipv(pdp, true)))
 | 
				
			||||||
 | 
							in46a_ntop(&peer->addr, buf6, sizeof(buf6));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gsna2in_addr(&ia, &pdp->gsnrc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						LOGPDPX(DGGSN, LOGL_DEBUG, pdp, "%s %s v%u TEID %"PRIx64" EUA=(%s,%s) SGSN=%s\n", prefix,
 | 
				
			||||||
 | 
							devname, pdp->version,
 | 
				
			||||||
 | 
							pdp->version == 0 ? pdp_gettid(pdp->imsi, pdp->nsapi) : pdp->teid_gn,
 | 
				
			||||||
 | 
							buf4, buf6, inet_ntoa(ia));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct {
 | 
				
			||||||
 | 
						int			genl_id;
 | 
				
			||||||
 | 
						struct mnl_socket	*nl;
 | 
				
			||||||
 | 
					} gtp_nl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int gtp_kernel_init_once(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* only initialize once */
 | 
				
			||||||
 | 
						if (gtp_nl.nl)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gtp_nl.nl = genl_socket_open();
 | 
				
			||||||
 | 
						if (gtp_nl.nl == NULL) {
 | 
				
			||||||
 | 
							LOGP(DGGSN, LOGL_ERROR, "cannot create genetlink socket\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						gtp_nl.genl_id = genl_lookup_family(gtp_nl.nl, "gtp");
 | 
				
			||||||
 | 
						if (gtp_nl.genl_id < 0) {
 | 
				
			||||||
 | 
							LOGP(DGGSN, LOGL_ERROR, "cannot lookup GTP genetlink ID\n");
 | 
				
			||||||
 | 
							genl_socket_close(gtp_nl.nl);
 | 
				
			||||||
 | 
							gtp_nl.nl = NULL;
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						LOGP(DGGSN, LOGL_NOTICE, "Initialized GTP kernel mode (genl ID is %d)\n", gtp_nl.genl_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_kernel_create(int dest_ns, const char *devname, int fd0, int fd1u)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (gtp_kernel_init_once() < 0)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return gtp_dev_create(dest_ns, devname, fd0, fd1u);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_kernel_create_sgsn(int dest_ns, const char *devname, int fd0, int fd1u)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (gtp_kernel_init_once() < 0)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return gtp_dev_create_sgsn(dest_ns, devname, fd0, fd1u);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void gtp_kernel_stop(const char *devname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gtp_dev_destroy(devname);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_kernel_tunnel_add(struct pdp_t *pdp, const char *devname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ms_addr_count;
 | 
				
			||||||
 | 
						struct in46_addr ms[2];
 | 
				
			||||||
 | 
						struct in46_addr sgsn;
 | 
				
			||||||
 | 
						struct gtp_tunnel *t;
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pdp_debug(__func__, devname, pdp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						in46a_from_gsna(&pdp->gsnrc, &sgsn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ms_addr_count = in46a_from_eua(&pdp->eua, ms);
 | 
				
			||||||
 | 
						if (ms_addr_count < 0)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < ms_addr_count; i++) {
 | 
				
			||||||
 | 
							t = gtp_tunnel_alloc();
 | 
				
			||||||
 | 
							if (t == NULL)
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
 | 
				
			||||||
 | 
							gtp_tunnel_set_version(t, pdp->version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (in46a_to_af(&ms[i]) == AF_INET)
 | 
				
			||||||
 | 
								gtp_tunnel_set_ms_ip4(t, &ms[i].v4);
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								/* In IPv6, EUA doesn't contain the actual IP
 | 
				
			||||||
 | 
								 * addr/prefix. Set higher bits to 0 to get the 64 bit
 | 
				
			||||||
 | 
								 * netmask. */
 | 
				
			||||||
 | 
								memset(((void *)&ms[i].v6) + 8, 0, 8);
 | 
				
			||||||
 | 
								gtp_tunnel_set_ms_ip6(t, &ms[i].v6);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (in46a_to_af(&sgsn) == AF_INET)
 | 
				
			||||||
 | 
								gtp_tunnel_set_sgsn_ip4(t, &sgsn.v4);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								gtp_tunnel_set_sgsn_ip6(t, &sgsn.v6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pdp->version == 0) {
 | 
				
			||||||
 | 
								gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
 | 
				
			||||||
 | 
								gtp_tunnel_set_flowid(t, pdp->flru);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								gtp_tunnel_set_i_tei(t, pdp->teid_own);
 | 
				
			||||||
 | 
								/* use the TEI advertised by SGSN when sending packets
 | 
				
			||||||
 | 
								 * towards the SGSN */
 | 
				
			||||||
 | 
								gtp_tunnel_set_o_tei(t, pdp->teid_gn);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ret = gtp_add_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
 | 
				
			||||||
 | 
							gtp_tunnel_free(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ret != 0)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_kernel_tunnel_del(struct pdp_t *pdp, const char *devname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ms_addr_count;
 | 
				
			||||||
 | 
						struct in46_addr ms[2];
 | 
				
			||||||
 | 
						struct gtp_tunnel *t;
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pdp_debug(__func__, devname, pdp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ms_addr_count = in46a_from_eua(&pdp->eua, ms);
 | 
				
			||||||
 | 
						if (ms_addr_count < 0)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < ms_addr_count; i++) {
 | 
				
			||||||
 | 
							t = gtp_tunnel_alloc();
 | 
				
			||||||
 | 
							if (t == NULL)
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
 | 
				
			||||||
 | 
							gtp_tunnel_set_family(t, in46a_to_af(&ms[i]));
 | 
				
			||||||
 | 
							gtp_tunnel_set_version(t, pdp->version);
 | 
				
			||||||
 | 
							if (pdp->version == 0) {
 | 
				
			||||||
 | 
								gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
 | 
				
			||||||
 | 
								gtp_tunnel_set_flowid(t, pdp->flru);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								gtp_tunnel_set_i_tei(t, pdp->teid_own);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ret = gtp_del_tunnel(gtp_nl.genl_id, gtp_nl.nl, t);
 | 
				
			||||||
 | 
							gtp_tunnel_free(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ret != 0)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								lib/gtp-kernel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								lib/gtp-kernel.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					#ifndef _GTP_KERNEL_H_
 | 
				
			||||||
 | 
					#define _GTP_KERNEL_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gengetopt_args_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int debug;
 | 
				
			||||||
 | 
					extern char *ipup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef GTP_KERNEL
 | 
				
			||||||
 | 
					int gtp_kernel_create(int dest_ns, const char *devname, int fd0, int fd1u);
 | 
				
			||||||
 | 
					int gtp_kernel_create_sgsn(int dest_ns, const char *devname, int fd0, int fd1u);
 | 
				
			||||||
 | 
					void gtp_kernel_stop(const char *devname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gtp_kernel_tunnel_add(struct pdp_t *pdp, const char *devname);
 | 
				
			||||||
 | 
					int gtp_kernel_tunnel_del(struct pdp_t *pdp, const char *devname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static inline int gtp_kernel_create(int dest_ns, const char *devname, int fd0, int fd1u)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SYS_ERR(DGGSN, LOGL_ERROR, 0, "ggsn compiled without GTP kernel support!\n");
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#define gtp_kernel_create_sgsn gtp_kernel_create
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gtp_kernel_stop(const char *devname) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int gtp_kernel_tunnel_add(struct pdp_t *pdp, const char *devname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int gtp_kernel_tunnel_del(struct pdp_t *pdp, const char *devname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif /* _GTP_KERNEL_H_ */
 | 
				
			||||||
							
								
								
									
										335
									
								
								lib/icmpv6.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								lib/icmpv6.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,335 @@
 | 
				
			|||||||
 | 
					/* Minimal ICMPv6 code for generating router advertisements as required by
 | 
				
			||||||
 | 
					 * relevant 3GPP specs for a GGSN with IPv6 PDP contexts */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* (C) 2017 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 | 
					 * General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 | 
					 * notice and this permission notice is included in all copies or
 | 
				
			||||||
 | 
					 * substantial portions of the software.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#if defined(__FreeBSD__)
 | 
				
			||||||
 | 
					#include <sys/types.h>	/* FreeBSD 10.x needs this before ip6.h */
 | 
				
			||||||
 | 
					#include <sys/endian.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#include <netinet/ip6.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/msgb.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/utils.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtp.h>
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "checksum.h"
 | 
				
			||||||
 | 
					#include "ippool.h"
 | 
				
			||||||
 | 
					#include "syserr.h"
 | 
				
			||||||
 | 
					#include "icmpv6.h"
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 29.061 11.2.1.3.4 IPv6 Router Configuration Variables in GGSN */
 | 
				
			||||||
 | 
					#define GGSN_MaxRtrAdvInterval	21600		/* 6 hours */
 | 
				
			||||||
 | 
					#define GGSN_MinRtrAdvInterval 16200		/* 4.5 hours */
 | 
				
			||||||
 | 
					#define GGSN_AdvValidLifetime	0xffffffff	/* infinite */
 | 
				
			||||||
 | 
					#define GGSN_AdvPreferredLifetime 0xffffffff	/* infinite */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC3307 link-local scope multicast address */
 | 
				
			||||||
 | 
					const struct in6_addr all_router_mcast_addr = {
 | 
				
			||||||
 | 
						.s6_addr = { 0xff,0x02,0,0,  0,0,0,0, 0,0,0,0,  0,0,0,2 }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC4291  link-local solicited-node multicast address, FF02:0:0:0:0:1:FF, 104 bits = 13 bytes */
 | 
				
			||||||
 | 
					const uint8_t solicited_node_mcast_addr_prefix[13] = {
 | 
				
			||||||
 | 
						0xff, 0x02, 0x00, 0x00,
 | 
				
			||||||
 | 
						0x00, 0x00, 0x00, 0x00,
 | 
				
			||||||
 | 
						0x00, 0x00, 0x00, 0x01,
 | 
				
			||||||
 | 
						0xFF
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Prepends the ipv6 header and returns checksum content */
 | 
				
			||||||
 | 
					uint16_t icmpv6_prepend_ip6hdr(struct msgb *msg, const struct in6_addr *saddr,
 | 
				
			||||||
 | 
									  const struct in6_addr *daddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t len;
 | 
				
			||||||
 | 
						uint16_t skb_csum;
 | 
				
			||||||
 | 
						struct ip6_hdr *i6h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* checksum */
 | 
				
			||||||
 | 
						skb_csum = csum_partial(msgb_data(msg), msgb_length(msg), 0);
 | 
				
			||||||
 | 
						len = msgb_length(msg);
 | 
				
			||||||
 | 
						skb_csum = csum_ipv6_magic(saddr, daddr, len, IPPROTO_ICMPV6, skb_csum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Push IPv6 header in front of ICMPv6 packet */
 | 
				
			||||||
 | 
						i6h = (struct ip6_hdr *) msgb_push(msg, sizeof(*i6h));
 | 
				
			||||||
 | 
						/* 4 bits version, 8 bits TC, 20 bits flow-ID */
 | 
				
			||||||
 | 
						i6h->ip6_ctlun.ip6_un1.ip6_un1_flow = htonl(0x60000000);
 | 
				
			||||||
 | 
						i6h->ip6_ctlun.ip6_un1.ip6_un1_plen = htons(len);
 | 
				
			||||||
 | 
						i6h->ip6_ctlun.ip6_un1.ip6_un1_nxt = IPPROTO_ICMPV6;
 | 
				
			||||||
 | 
						i6h->ip6_ctlun.ip6_un1.ip6_un1_hlim = 255;
 | 
				
			||||||
 | 
						i6h->ip6_src = *saddr;
 | 
				
			||||||
 | 
						i6h->ip6_dst = *daddr;
 | 
				
			||||||
 | 
						return skb_csum;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! construct a RFC4861 compliant ICMPv6 router soliciation
 | 
				
			||||||
 | 
					 *  \param[in] saddr Source IPv6 address for router advertisement
 | 
				
			||||||
 | 
					 *  \param[in] daddr Destination IPv6 address for router advertisement IPv6 header
 | 
				
			||||||
 | 
					 *  \param[in] prefix The single prefix to be advertised (/64 implied!)
 | 
				
			||||||
 | 
					 *  \returns callee-allocated message buffer containing router advertisement */
 | 
				
			||||||
 | 
					struct msgb *icmpv6_construct_rs(const struct in6_addr *saddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct msgb *msg = msgb_alloc_headroom(512,128, "IPv6 RS");
 | 
				
			||||||
 | 
						struct icmpv6_rsol_hdr *rs;
 | 
				
			||||||
 | 
						OSMO_ASSERT(msg);
 | 
				
			||||||
 | 
						rs = (struct icmpv6_rsol_hdr *) msgb_put(msg, sizeof(*rs));
 | 
				
			||||||
 | 
						rs->hdr.type = 133;	/* see RFC4861 4.1 */
 | 
				
			||||||
 | 
						rs->hdr.code = 0;	/* see RFC4861 4.1 */
 | 
				
			||||||
 | 
						rs->hdr.csum = 0;	/* updated below */
 | 
				
			||||||
 | 
						rs->reserved = 0;	/* see RFC4861 4.1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rs->hdr.csum = icmpv6_prepend_ip6hdr(msg, saddr, &all_router_mcast_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return msg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/*! construct a 3GPP 29.061 compliant router advertisement for a given prefix
 | 
				
			||||||
 | 
					 *  \param[in] saddr Source IPv6 address for router advertisement
 | 
				
			||||||
 | 
					 *  \param[in] daddr Destination IPv6 address for router advertisement IPv6 header
 | 
				
			||||||
 | 
					 *  \param[in] prefix The single prefix to be advertised (/64 implied!)
 | 
				
			||||||
 | 
					 *  \returns callee-allocated message buffer containing router advertisement */
 | 
				
			||||||
 | 
					static struct msgb *icmpv6_construct_ra(const struct in6_addr *saddr,
 | 
				
			||||||
 | 
									 const struct in6_addr *daddr,
 | 
				
			||||||
 | 
									 const struct in6_addr *prefix,
 | 
				
			||||||
 | 
									 uint32_t mtu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct msgb *msg = msgb_alloc_headroom(512,128, "IPv6 RA");
 | 
				
			||||||
 | 
						struct icmpv6_radv_hdr *ra;
 | 
				
			||||||
 | 
						struct icmpv6_opt_prefix *ra_opt_pref;
 | 
				
			||||||
 | 
						struct icmpv6_opt_mtu *ra_opt_mtu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OSMO_ASSERT(msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ra = (struct icmpv6_radv_hdr *) msgb_put(msg, sizeof(*ra));
 | 
				
			||||||
 | 
						ra->hdr.type = 134;	/* see RFC4861 4.2 */
 | 
				
			||||||
 | 
						ra->hdr.code = 0;	/* see RFC4861 4.2 */
 | 
				
			||||||
 | 
						ra->hdr.csum = 0;	/* updated below */
 | 
				
			||||||
 | 
						ra->cur_ho_limit = 64;	/* seems reasonable? */
 | 
				
			||||||
 | 
						/* the GGSN shall leave the M-flag cleared in the Router
 | 
				
			||||||
 | 
						 * Advertisement messages */
 | 
				
			||||||
 | 
						ra->m = 0;
 | 
				
			||||||
 | 
						/* The GGSN may set the O-flag if there are additional
 | 
				
			||||||
 | 
						 * configuration parameters that need to be fetched by the MS */
 | 
				
			||||||
 | 
						ra->o = 0;		/* no DHCPv6 */
 | 
				
			||||||
 | 
						ra->res = 0;
 | 
				
			||||||
 | 
						/* RFC4861 Default: 3 * MaxRtrAdvInterval */
 | 
				
			||||||
 | 
						ra->router_lifetime = htons(3*GGSN_MaxRtrAdvInterval);
 | 
				
			||||||
 | 
						ra->reachable_time = 0;	/* Unspecified */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* RFC4861 Section 4.6.2 */
 | 
				
			||||||
 | 
						ra_opt_pref = (struct icmpv6_opt_prefix *) msgb_put(msg, sizeof(*ra_opt_pref));
 | 
				
			||||||
 | 
						ra_opt_pref->hdr.type = 3;	/* RFC4861 4.6.2 */
 | 
				
			||||||
 | 
						ra_opt_pref->hdr.len = 4;	/* RFC4861 4.6.2 */
 | 
				
			||||||
 | 
						ra_opt_pref->prefix_len = 64;	/* only prefix length as per 3GPP */
 | 
				
			||||||
 | 
						/* The Prefix is contained in the Prefix Information Option of
 | 
				
			||||||
 | 
						 * the Router Advertisements and shall have the A-flag set
 | 
				
			||||||
 | 
						 * and the L-flag cleared */
 | 
				
			||||||
 | 
						ra_opt_pref->a = 1;
 | 
				
			||||||
 | 
						ra_opt_pref->l = 0;
 | 
				
			||||||
 | 
						ra_opt_pref->res = 0;
 | 
				
			||||||
 | 
						/*  The lifetime of the prefix shall be set to infinity */
 | 
				
			||||||
 | 
						ra_opt_pref->valid_lifetime = htonl(GGSN_AdvValidLifetime);
 | 
				
			||||||
 | 
						ra_opt_pref->preferred_lifetime = htonl(GGSN_AdvPreferredLifetime);
 | 
				
			||||||
 | 
						ra_opt_pref->res2 = 0;
 | 
				
			||||||
 | 
						memcpy(ra_opt_pref->prefix, prefix, sizeof(ra_opt_pref->prefix));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* RFC4861 Section 4.6.4, MTU */
 | 
				
			||||||
 | 
						ra_opt_mtu = (struct icmpv6_opt_mtu *) msgb_put(msg, sizeof(*ra_opt_mtu));
 | 
				
			||||||
 | 
						ra_opt_mtu->hdr.type = 5;	/* RFC4861 4.6.4 */
 | 
				
			||||||
 | 
						ra_opt_mtu->hdr.len = 1;	/* RFC4861 4.6.4 */
 | 
				
			||||||
 | 
						ra_opt_mtu->reserved = 0;
 | 
				
			||||||
 | 
						ra_opt_mtu->mtu = htonl(mtu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The Prefix is contained in the Prefix Information Option of
 | 
				
			||||||
 | 
						 * the Router Advertisements and shall have the A-flag set
 | 
				
			||||||
 | 
						 * and the L-flag cleared */
 | 
				
			||||||
 | 
						ra_opt_pref->a = 1;
 | 
				
			||||||
 | 
						ra_opt_pref->l = 0;
 | 
				
			||||||
 | 
						ra_opt_pref->res = 0;
 | 
				
			||||||
 | 
						/*  The lifetime of the prefix shall be set to infinity */
 | 
				
			||||||
 | 
						ra_opt_pref->valid_lifetime = htonl(GGSN_AdvValidLifetime);
 | 
				
			||||||
 | 
						ra_opt_pref->preferred_lifetime = htonl(GGSN_AdvPreferredLifetime);
 | 
				
			||||||
 | 
						ra_opt_pref->res2 = 0;
 | 
				
			||||||
 | 
						memcpy(ra_opt_pref->prefix, prefix, sizeof(ra_opt_pref->prefix));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* checksum */
 | 
				
			||||||
 | 
						ra->hdr.csum = icmpv6_prepend_ip6hdr(msg, saddr, daddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return msg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Validate an ICMPv6 router solicitation according to RFC4861 6.1.1 */
 | 
				
			||||||
 | 
					static bool icmpv6_validate_router_solicit(const uint8_t *pack, unsigned len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
 | 
				
			||||||
 | 
						//const struct icmpv6_hdr *ic6h = (struct icmpv6_hdr *) (pack + sizeof(*ip6h));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Hop limit field must have 255 */
 | 
				
			||||||
 | 
						if (ip6h->ip6_ctlun.ip6_un1.ip6_un1_hlim != 255)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						/* FIXME: ICMP checksum is valid */
 | 
				
			||||||
 | 
						/* ICMP length (derived from IP length) is 8 or more octets */
 | 
				
			||||||
 | 
						if (ip6h->ip6_ctlun.ip6_un1.ip6_un1_plen < 8)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						/* FIXME: All included options have a length > 0 */
 | 
				
			||||||
 | 
						/* FIXME: If IP source is unspecified, no source link-layer addr option */
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Validate an ICMPv6 neighbor solicitation according to RFC4861 7.1.1 */
 | 
				
			||||||
 | 
					static bool icmpv6_validate_neigh_solicit(const uint8_t *pack, unsigned len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Hop limit field must have 255 */
 | 
				
			||||||
 | 
						if (ip6h->ip6_ctlun.ip6_un1.ip6_un1_hlim != 255)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						/* FIXME: ICMP checksum is valid */
 | 
				
			||||||
 | 
						/* ICMP length (derived from IP length) is 24 or more octets */
 | 
				
			||||||
 | 
						if (ip6h->ip6_ctlun.ip6_un1.ip6_un1_plen < 24)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						/* FIXME: All included options have a length > 0 */
 | 
				
			||||||
 | 
						/* FIXME: If the IP source address is the unspecified address, the IP
 | 
				
			||||||
 | 
						 * destination address is a solicited-node multicast address. */
 | 
				
			||||||
 | 
						/* FIXME: If IP source is unspecified, no source link-layer addr option */
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Validate an ICMPv6 router advertisement according to RFC4861 6.1.2.
 | 
				
			||||||
 | 
					   Returns pointer packet header on success, NULL otherwise. */
 | 
				
			||||||
 | 
					struct icmpv6_radv_hdr *icmpv6_validate_router_adv(const uint8_t *pack, unsigned len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
 | 
				
			||||||
 | 
						const struct icmpv6_hdr *ic6h = (struct icmpv6_hdr *) (pack + sizeof(*ip6h));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ICMP length (derived from IP length) is 16 or more octets */
 | 
				
			||||||
 | 
						if (len < sizeof(*ip6h) + 16)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ic6h->type != 134) /* router advertismenet type */
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*Routers must use their link-local address */
 | 
				
			||||||
 | 
						if (!IN6_IS_ADDR_LINKLOCAL(&ip6h->ip6_src))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						/* Hop limit field must have 255 */
 | 
				
			||||||
 | 
						if (ip6h->ip6_ctlun.ip6_un1.ip6_un1_hlim != 255)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						/* ICMP Code is 0 */
 | 
				
			||||||
 | 
						if (ic6h->code != 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						/* ICMP length (derived from IP length) is 16 or more octets */
 | 
				
			||||||
 | 
						if (ip6h->ip6_ctlun.ip6_un1.ip6_un1_plen < 16)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						/* FIXME: All included options have a length > 0 */
 | 
				
			||||||
 | 
						/* FIXME: If IP source is unspecified, no source link-layer addr option */
 | 
				
			||||||
 | 
						return (struct icmpv6_radv_hdr *)ic6h;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* handle incoming packets to the all-routers multicast address */
 | 
				
			||||||
 | 
					int handle_router_mcast(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
 | 
								const struct in6_addr *pdp_prefix,
 | 
				
			||||||
 | 
								const struct in6_addr *own_ll_addr,
 | 
				
			||||||
 | 
								uint32_t mtu,
 | 
				
			||||||
 | 
								const uint8_t *pack, unsigned len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
 | 
				
			||||||
 | 
						const struct icmpv6_hdr *ic6h = (struct icmpv6_hdr *) (pack + sizeof(*ip6h));
 | 
				
			||||||
 | 
						struct msgb *msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len < sizeof(*ip6h)) {
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_NOTICE, "Packet too short: %u bytes\n", len);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* we only treat ICMPv6 here */
 | 
				
			||||||
 | 
						if (ip6h->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_ICMPV6) {
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_DEBUG, "Ignoring non-ICMP to all-routers mcast\n");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len < sizeof(*ip6h) + sizeof(*ic6h)) {
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_NOTICE, "Short ICMPv6 packet: %s\n", osmo_hexdump(pack, len));
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (ic6h->type) {
 | 
				
			||||||
 | 
						case 133:	/* router solicitation */
 | 
				
			||||||
 | 
							if (ic6h->code != 0) {
 | 
				
			||||||
 | 
								LOGP(DICMP6, LOGL_NOTICE, "ICMPv6 type 133 but code %d\n", ic6h->code);
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!icmpv6_validate_router_solicit(pack, len)) {
 | 
				
			||||||
 | 
								LOGP(DICMP6, LOGL_NOTICE, "Invalid Router Solicitation: %s\n",
 | 
				
			||||||
 | 
									osmo_hexdump(pack, len));
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/* Send router advertisement from GGSN link-local
 | 
				
			||||||
 | 
							 * address to MS link-local address, including prefix
 | 
				
			||||||
 | 
							 * allocated to this PDP context */
 | 
				
			||||||
 | 
							msg = icmpv6_construct_ra(own_ll_addr, &ip6h->ip6_src, pdp_prefix, mtu);
 | 
				
			||||||
 | 
							/* Send the constructed RA to the MS */
 | 
				
			||||||
 | 
							gtp_data_req(gsn, pdp, msgb_data(msg), msgb_length(msg));
 | 
				
			||||||
 | 
							msgb_free(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_DEBUG, "Unknown ICMPv6 type %u\n", ic6h->type);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* handle incoming packets to the solicited-node multicast address */
 | 
				
			||||||
 | 
					int handle_solicited_node_mcast(const uint8_t *pack, unsigned len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
 | 
				
			||||||
 | 
						const struct icmpv6_hdr *ic6h = (struct icmpv6_hdr *) (pack + sizeof(*ip6h));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len < sizeof(*ip6h)) {
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_NOTICE, "Packet too short: %u bytes\n", len);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* we only treat ICMPv6 here */
 | 
				
			||||||
 | 
						if (ip6h->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_ICMPV6) {
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_DEBUG, "Ignoring non-ICMP solicited-node mcast\n");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len < sizeof(*ip6h) + sizeof(*ic6h)) {
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_NOTICE, "Short ICMPv6 packet: %s\n", osmo_hexdump(pack, len));
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (ic6h->type) {
 | 
				
			||||||
 | 
						case 135: /* Neighbor Solicitation. RFC2461, RFC2462 */
 | 
				
			||||||
 | 
							if (ic6h->code != 0) {
 | 
				
			||||||
 | 
								LOGP(DICMP6, LOGL_NOTICE, "ICMPv6 type 135 but code %d\n", ic6h->code);
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!icmpv6_validate_neigh_solicit(pack, len)) {
 | 
				
			||||||
 | 
								LOGP(DICMP6, LOGL_NOTICE, "Invalid Neighbor Solicitation: %s\n",
 | 
				
			||||||
 | 
									osmo_hexdump(pack, len));
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/* RFC 2462: Ignore Neighbor (Duplicate Address Detection) */
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_DEBUG, "Ignoring Rx ICMPv6 Neighbor Soliciation: %s\n", osmo_hexdump(pack, len));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							LOGP(DICMP6, LOGL_DEBUG, "Unknown ICMPv6 type %u\n", ic6h->type);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										109
									
								
								lib/icmpv6.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								lib/icmpv6.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/msgb.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/endian.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/gtp.h>
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ICMPv6_OPT_TYPE_PREFIX_INFO 0x03
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define foreach_icmpv6_opt(icmpv6_pkt, icmpv6_len, opt_hdr) \
 | 
				
			||||||
 | 
							for (opt_hdr = (struct icmpv6_opt_hdr *)(icmpv6_pkt)->options; \
 | 
				
			||||||
 | 
							     (uint8_t*)(opt_hdr) + sizeof(struct icmpv6_opt_hdr) <= (((uint8_t*)(icmpv6_pkt)) + (icmpv6_len)); \
 | 
				
			||||||
 | 
							     opt_hdr = (struct icmpv6_opt_hdr*)((uint8_t*)(opt_hdr) + (opt_hdr)->len) \
 | 
				
			||||||
 | 
							    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct icmpv6_hdr {
 | 
				
			||||||
 | 
						uint8_t type;
 | 
				
			||||||
 | 
						uint8_t code;
 | 
				
			||||||
 | 
						uint16_t csum;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct icmpv6_echo_hdr {
 | 
				
			||||||
 | 
						struct icmpv6_hdr hdr;
 | 
				
			||||||
 | 
						uint16_t ident;		/* Identifier */
 | 
				
			||||||
 | 
						uint16_t seq;		/* Sequence number */
 | 
				
			||||||
 | 
						uint8_t data[0];	/* Data */
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC4861 Section 4.1 */
 | 
				
			||||||
 | 
					struct icmpv6_rsol_hdr {
 | 
				
			||||||
 | 
						struct icmpv6_hdr hdr;
 | 
				
			||||||
 | 
						uint32_t reserved;
 | 
				
			||||||
 | 
						uint8_t options[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC4861 Section 4.2 */
 | 
				
			||||||
 | 
					struct icmpv6_radv_hdr {
 | 
				
			||||||
 | 
						struct icmpv6_hdr hdr;
 | 
				
			||||||
 | 
						uint8_t cur_ho_limit;
 | 
				
			||||||
 | 
					#if OSMO_IS_LITTLE_ENDIAN
 | 
				
			||||||
 | 
						uint8_t res:6,
 | 
				
			||||||
 | 
							m:1,
 | 
				
			||||||
 | 
							o:1;
 | 
				
			||||||
 | 
					#elif OSMO_IS_BIG_ENDIAN
 | 
				
			||||||
 | 
					/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
 | 
				
			||||||
 | 
						uint8_t o:1, m:1, res:6;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						uint16_t router_lifetime;
 | 
				
			||||||
 | 
						uint32_t reachable_time;
 | 
				
			||||||
 | 
						uint32_t retrans_timer;
 | 
				
			||||||
 | 
						uint8_t options[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC4861 Section 4.6 */
 | 
				
			||||||
 | 
					struct icmpv6_opt_hdr {
 | 
				
			||||||
 | 
						uint8_t type;
 | 
				
			||||||
 | 
						/* length in units of 8 octets, including type+len! */
 | 
				
			||||||
 | 
						uint8_t len;
 | 
				
			||||||
 | 
						uint8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC4861 Section 4.6.2 */
 | 
				
			||||||
 | 
					struct icmpv6_opt_prefix {
 | 
				
			||||||
 | 
						struct icmpv6_opt_hdr hdr;
 | 
				
			||||||
 | 
						uint8_t prefix_len;
 | 
				
			||||||
 | 
					#if OSMO_IS_LITTLE_ENDIAN
 | 
				
			||||||
 | 
						uint8_t res:6,
 | 
				
			||||||
 | 
							a:1,
 | 
				
			||||||
 | 
							l:1;
 | 
				
			||||||
 | 
					#elif OSMO_IS_BIG_ENDIAN
 | 
				
			||||||
 | 
					/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
 | 
				
			||||||
 | 
						uint8_t l:1, a:1, res:6;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						uint32_t valid_lifetime;
 | 
				
			||||||
 | 
						uint32_t preferred_lifetime;
 | 
				
			||||||
 | 
						uint32_t res2;
 | 
				
			||||||
 | 
						uint8_t prefix[16];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC4861 Section 4.6.4 */
 | 
				
			||||||
 | 
					struct icmpv6_opt_mtu {
 | 
				
			||||||
 | 
						struct icmpv6_opt_hdr hdr;
 | 
				
			||||||
 | 
						uint16_t reserved;
 | 
				
			||||||
 | 
						uint32_t mtu;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t icmpv6_prepend_ip6hdr(struct msgb *msg, const struct in6_addr *saddr,
 | 
				
			||||||
 | 
									  const struct in6_addr *daddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct msgb *icmpv6_construct_rs(const struct in6_addr *saddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int handle_router_mcast(struct gsn_t *gsn, struct pdp_t *pdp,
 | 
				
			||||||
 | 
								const struct in6_addr *pdp_prefix,
 | 
				
			||||||
 | 
								const struct in6_addr *own_ll_addr,
 | 
				
			||||||
 | 
								uint32_t mtu,
 | 
				
			||||||
 | 
								const uint8_t *pack, unsigned len);
 | 
				
			||||||
 | 
					int handle_solicited_node_mcast(const uint8_t *pack, unsigned len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct icmpv6_radv_hdr *icmpv6_validate_router_adv(const uint8_t *pack, unsigned len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RFC3307 link-local scope multicast address */
 | 
				
			||||||
 | 
					extern const struct in6_addr all_router_mcast_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const uint8_t solicited_node_mcast_addr_prefix[13];
 | 
				
			||||||
							
								
								
									
										384
									
								
								lib/in46_addr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										384
									
								
								lib/in46_addr.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,384 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * IPv4/v6 address functions.
 | 
				
			||||||
 | 
					 * Copyright (C) 2017 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The contents of this file may be used under the terms of the GNU
 | 
				
			||||||
 | 
					 * General Public License Version 2, provided that the above copyright
 | 
				
			||||||
 | 
					 * notice and this permission notice is included in all copies or
 | 
				
			||||||
 | 
					 * substantial portions of the software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../lib/in46_addr.h"
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/core/utils.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					#include <netdb.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Return the address family of given \reff in46_addr argument */
 | 
				
			||||||
 | 
					int in46a_to_af(const struct in46_addr *in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (in->len) {
 | 
				
			||||||
 | 
						case 4:
 | 
				
			||||||
 | 
							return AF_INET;
 | 
				
			||||||
 | 
						case 8:
 | 
				
			||||||
 | 
						case 16:
 | 
				
			||||||
 | 
							return AF_INET6;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							OSMO_ASSERT(0);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Convert \ref in46_addr to sockaddr_storage */
 | 
				
			||||||
 | 
					int in46a_to_sas(struct sockaddr_storage *out, const struct in46_addr *in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sockaddr_in *sin = (struct sockaddr_in *)out;
 | 
				
			||||||
 | 
						struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (in->len) {
 | 
				
			||||||
 | 
						case 4:
 | 
				
			||||||
 | 
							sin->sin_family = AF_INET;
 | 
				
			||||||
 | 
							sin->sin_addr = in->v4;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 16:
 | 
				
			||||||
 | 
							sin6->sin6_family = AF_INET6;
 | 
				
			||||||
 | 
							sin6->sin6_addr = in->v6;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							OSMO_ASSERT(0);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Convenience wrapper around inet_ntop() for in46_addr.
 | 
				
			||||||
 | 
					 *  \param[in] in the in46_addr to print
 | 
				
			||||||
 | 
					 *  \param[out] dst destination buffer where string representation of the address is stored
 | 
				
			||||||
 | 
					 *  \param[out] dst_size size dst. Usually it should be at least INET6_ADDRSTRLEN.
 | 
				
			||||||
 | 
					 *  \return address of dst on success, NULL on error */
 | 
				
			||||||
 | 
					const char *in46a_ntop(const struct in46_addr *in, char *dst, socklen_t dst_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int af;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!in || in->len == 0) {
 | 
				
			||||||
 | 
							strncpy(dst, "UNDEFINED", dst_size);
 | 
				
			||||||
 | 
							return dst;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						af = in46a_to_af(in);
 | 
				
			||||||
 | 
						if (af < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return inet_ntop(af, (const void *) &in->v4, dst, dst_size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* like inet_ntoa() */
 | 
				
			||||||
 | 
					const char *in46a_ntoa(const struct in46_addr *in46)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char addrstr_buf[256];
 | 
				
			||||||
 | 
						if (in46a_ntop(in46, addrstr_buf, sizeof(addrstr_buf)) < 0)
 | 
				
			||||||
 | 
							return "INVALID";
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return addrstr_buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *in46p_ntoa(const struct in46_prefix *in46p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char addrstr_buf[256];
 | 
				
			||||||
 | 
						snprintf(addrstr_buf, sizeof(addrstr_buf), "%s/%u", in46a_ntoa(&in46p->addr), in46p->prefixlen);
 | 
				
			||||||
 | 
						return addrstr_buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Determine if two in46_addr are equal or not
 | 
				
			||||||
 | 
					 *  \returns 1 in case they are equal; 0 otherwise */
 | 
				
			||||||
 | 
					int in46a_equal(const struct in46_addr *a, const struct in46_addr *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (a->len == b->len && !memcmp(&a->v6, &b->v6, a->len))
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Determine if two in46_addr prefix are equal or not
 | 
				
			||||||
 | 
					 *  The prefix length is determined by the shortest of the prefixes of a and b
 | 
				
			||||||
 | 
					 *  \returns 1 in case the common prefix are equal; 0 otherwise */
 | 
				
			||||||
 | 
					int in46a_prefix_equal(const struct in46_addr *a, const struct in46_addr *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int len;
 | 
				
			||||||
 | 
						if (a->len > b->len)
 | 
				
			||||||
 | 
							len = b->len;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							len = a->len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!memcmp(&a->v6, &b->v6, len))
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Match if IPv6 addr1 + addr2 are within same \a mask */
 | 
				
			||||||
 | 
					static int ipv6_within_mask(const struct in6_addr *addr1, const struct in6_addr *addr2,
 | 
				
			||||||
 | 
								    const struct in6_addr *mask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct in6_addr masked = *addr2;
 | 
				
			||||||
 | 
					#if defined(__linux__)
 | 
				
			||||||
 | 
						masked.s6_addr32[0] &= mask->s6_addr32[0];
 | 
				
			||||||
 | 
						masked.s6_addr32[1] &= mask->s6_addr32[1];
 | 
				
			||||||
 | 
						masked.s6_addr32[2] &= mask->s6_addr32[2];
 | 
				
			||||||
 | 
						masked.s6_addr32[3] &= mask->s6_addr32[3];
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						masked.__u6_addr.__u6_addr32[0] &= mask->__u6_addr.__u6_addr32[0];
 | 
				
			||||||
 | 
						masked.__u6_addr.__u6_addr32[1] &= mask->__u6_addr.__u6_addr32[1];
 | 
				
			||||||
 | 
						masked.__u6_addr.__u6_addr32[2] &= mask->__u6_addr.__u6_addr32[2];
 | 
				
			||||||
 | 
						masked.__u6_addr.__u6_addr32[3] &= mask->__u6_addr.__u6_addr32[3];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						if (!memcmp(addr1, &masked, sizeof(struct in6_addr)))
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Create an IPv6 netmask from the given prefix length */
 | 
				
			||||||
 | 
					static void create_ipv6_netmask(struct in6_addr *netmask, int prefixlen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t *p_netmask;
 | 
				
			||||||
 | 
						memset(netmask, 0, sizeof(struct in6_addr));
 | 
				
			||||||
 | 
						if (prefixlen < 0)
 | 
				
			||||||
 | 
							prefixlen = 0;
 | 
				
			||||||
 | 
						else if (128 < prefixlen)
 | 
				
			||||||
 | 
							prefixlen = 128;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__linux__)
 | 
				
			||||||
 | 
						p_netmask = &netmask->s6_addr32[0];
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						p_netmask = &netmask->__u6_addr.__u6_addr32[0];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						while (32 < prefixlen) {
 | 
				
			||||||
 | 
							*p_netmask = 0xffffffff;
 | 
				
			||||||
 | 
							p_netmask++;
 | 
				
			||||||
 | 
							prefixlen -= 32;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (prefixlen != 0) {
 | 
				
			||||||
 | 
							*p_netmask = htonl(0xFFFFFFFF << (32 - prefixlen));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Determine if given \a addr is within given \a net + \a prefixlen
 | 
				
			||||||
 | 
					 *  Builds the netmask from \a net + \a prefixlen and matches it to \a addr
 | 
				
			||||||
 | 
					 *  \returns 1 in case of a match, 0 otherwise */
 | 
				
			||||||
 | 
					int in46a_within_mask(const struct in46_addr *addr, const struct in46_addr *net, size_t prefixlen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct in_addr netmask;
 | 
				
			||||||
 | 
						struct in6_addr netmask6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (addr->len != net->len)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (addr->len) {
 | 
				
			||||||
 | 
						case 4:
 | 
				
			||||||
 | 
							netmask.s_addr = htonl(0xFFFFFFFF << (32 - prefixlen));
 | 
				
			||||||
 | 
							if ((addr->v4.s_addr & netmask.s_addr) == net->v4.s_addr)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
						case 16:
 | 
				
			||||||
 | 
							create_ipv6_netmask(&netmask6, prefixlen);
 | 
				
			||||||
 | 
							return ipv6_within_mask(&addr->v6, &net->v6, &netmask6);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							OSMO_ASSERT(0);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned int ipv4_netmasklen(const struct in_addr *netmask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t bits = netmask->s_addr;
 | 
				
			||||||
 | 
						uint8_t *b = (uint8_t*) &bits;
 | 
				
			||||||
 | 
						unsigned int i, prefix = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < 4; i++) {
 | 
				
			||||||
 | 
							while (b[i] & 0x80) {
 | 
				
			||||||
 | 
								prefix++;
 | 
				
			||||||
 | 
								b[i] = b[i] << 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return prefix;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned int ipv6_netmasklen(const struct in6_addr *netmask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#if defined(__linux__)
 | 
				
			||||||
 | 
							#define ADDRFIELD(i) s6_addr32[i]
 | 
				
			||||||
 | 
						#else
 | 
				
			||||||
 | 
							#define ADDRFIELD(i) __u6_addr.__u6_addr32[i]
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int i, j, prefix = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (j = 0; j < 4; j++) {
 | 
				
			||||||
 | 
							uint32_t bits = netmask->ADDRFIELD(j);
 | 
				
			||||||
 | 
							uint8_t *b = (uint8_t*) &bits;
 | 
				
			||||||
 | 
							for (i = 0; i < 4; i++) {
 | 
				
			||||||
 | 
								while (b[i] & 0x80) {
 | 
				
			||||||
 | 
									prefix++;
 | 
				
			||||||
 | 
									b[i] = b[i] << 1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#undef ADDRFIELD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return prefix;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Convert netmask to prefix length representation
 | 
				
			||||||
 | 
					 *  \param[in] netmask in46_addr containing a netmask (consecutive list of 1-bit followed by consecutive list of 0-bit)
 | 
				
			||||||
 | 
					 *  \returns prefix length representation of the netmask (count of 1-bit from the start of the netmask)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					unsigned int in46a_netmasklen(const struct in46_addr *netmask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (netmask->len) {
 | 
				
			||||||
 | 
						case 4:
 | 
				
			||||||
 | 
							return ipv4_netmasklen(&netmask->v4);
 | 
				
			||||||
 | 
						case 16:
 | 
				
			||||||
 | 
							return ipv6_netmasklen(&netmask->v6);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							OSMO_ASSERT(0);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Convert given array of in46_addr to PDP End User Address
 | 
				
			||||||
 | 
					 *  \param[in] src Array containing 1 or 2 in46_addr
 | 
				
			||||||
 | 
					 *  \param[out] eua End User Address structure to fill
 | 
				
			||||||
 | 
					 *  \returns 0 on success; negative on error
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * In case size is 2, this function expects to find exactly one IPv4 and one
 | 
				
			||||||
 | 
					 * IPv6 addresses in src. */
 | 
				
			||||||
 | 
					int in46a_to_eua(const struct in46_addr *src, unsigned int size, struct ul66_t *eua)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct in46_addr *src_v4, *src_v6;
 | 
				
			||||||
 | 
						if (size == 1) {
 | 
				
			||||||
 | 
							switch (src->len) {
 | 
				
			||||||
 | 
							case 4:
 | 
				
			||||||
 | 
								eua->l = 6;
 | 
				
			||||||
 | 
								eua->v[0] = PDP_EUA_ORG_IETF;
 | 
				
			||||||
 | 
								eua->v[1] = PDP_EUA_TYPE_v4;
 | 
				
			||||||
 | 
								memcpy(&eua->v[2], &src->v4, 4);	/* Copy a 4 byte address */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 8:
 | 
				
			||||||
 | 
							case 16:
 | 
				
			||||||
 | 
								eua->l = 18;
 | 
				
			||||||
 | 
								eua->v[0] = PDP_EUA_ORG_IETF;
 | 
				
			||||||
 | 
								eua->v[1] = PDP_EUA_TYPE_v6;
 | 
				
			||||||
 | 
								memcpy(&eua->v[2], &src->v6, 16);	/* Copy a 16 byte address */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								OSMO_ASSERT(0);
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (src[0].len == src[1].len)
 | 
				
			||||||
 | 
							return -1; /* we should have a v4 and a v6 address */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						src_v4 = (src[0].len == 4) ? &src[0] : &src[1];
 | 
				
			||||||
 | 
						src_v6 = (src[0].len == 4) ? &src[1] : &src[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						eua->l = 22;
 | 
				
			||||||
 | 
						eua->v[0] = PDP_EUA_ORG_IETF;
 | 
				
			||||||
 | 
						eua->v[1] = PDP_EUA_TYPE_v4v6;
 | 
				
			||||||
 | 
						memcpy(&eua->v[2], &src_v4->v4, 4);
 | 
				
			||||||
 | 
						memcpy(&eua->v[6], &src_v6->v6, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! Convert given PDP End User Address to an array of in46_addr
 | 
				
			||||||
 | 
					 *  \param[in] eua End User Address structure to parse
 | 
				
			||||||
 | 
					 *  \param[out] dst Array containing 2 in46_addr
 | 
				
			||||||
 | 
					 *  \returns number of parsed addresses (1 or 2) on success; negative on error
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function expects to receive an End User Address struct together with an
 | 
				
			||||||
 | 
					 * array of 2 zeroed in46_addr structs. The in46_addr structs are filled in
 | 
				
			||||||
 | 
					 * order, hence if the function returns 1 the parsed address will be stored in
 | 
				
			||||||
 | 
					 * the first struct and the second one will be left intact. If 2 is returned, it
 | 
				
			||||||
 | 
					 * is guaranteed that one of them is an IPv4 and the other one is an IPv6, but
 | 
				
			||||||
 | 
					 * the order in which they are presented is not specified and must be
 | 
				
			||||||
 | 
					 * discovered for instance by checking the len field of each address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int in46a_from_eua(const struct ul66_t *eua, struct in46_addr *dst)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (eua->l < 2)
 | 
				
			||||||
 | 
							goto default_to_dyn_v4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (eua->v[0] != 0xf1)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (eua->v[1]) {
 | 
				
			||||||
 | 
						case PDP_EUA_TYPE_v4:
 | 
				
			||||||
 | 
							dst->len = 4;
 | 
				
			||||||
 | 
							if (eua->l >= 6)
 | 
				
			||||||
 | 
								memcpy(&dst->v4, &eua->v[2], 4);	/* Copy a 4 byte address */
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								dst->v4.s_addr = 0;
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						case PDP_EUA_TYPE_v6:
 | 
				
			||||||
 | 
							dst->len = 16;
 | 
				
			||||||
 | 
							if (eua->l >= 18)
 | 
				
			||||||
 | 
								memcpy(&dst->v6, &eua->v[2], 16);	/* Copy a 16 byte address */
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								memset(&dst->v6, 0, 16);
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						case PDP_EUA_TYPE_v4v6:
 | 
				
			||||||
 | 
							/* 3GPP TS 29.060, section 7.7.27 */
 | 
				
			||||||
 | 
							switch (eua->l) {
 | 
				
			||||||
 | 
								case 2: /* v4 & v6 dynamic */
 | 
				
			||||||
 | 
									dst[0].v4.s_addr = 0;
 | 
				
			||||||
 | 
									memset(&dst[1].v6, 0, 16);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case 6: /* v4 static, v6 dynamic */
 | 
				
			||||||
 | 
									memcpy(&dst[0].v4, &eua->v[2], 4);
 | 
				
			||||||
 | 
									memset(&dst[1].v6, 0, 16);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case 18: /* v4 dynamic, v6 static */
 | 
				
			||||||
 | 
									dst[0].v4.s_addr = 0;
 | 
				
			||||||
 | 
									memcpy(&dst[1].v6, &eua->v[2], 16);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case 22:  /* v4 & v6 static */
 | 
				
			||||||
 | 
									memcpy(&dst[0].v4, &eua->v[2], 4);
 | 
				
			||||||
 | 
									memcpy(&dst[1].v6, &eua->v[6], 16);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							dst[0].len = 4;
 | 
				
			||||||
 | 
							dst[1].len = 16;
 | 
				
			||||||
 | 
							return 2;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					default_to_dyn_v4:
 | 
				
			||||||
 | 
						/* assume dynamic IPv4 by default */
 | 
				
			||||||
 | 
						dst->len = 4;
 | 
				
			||||||
 | 
						dst->v4.s_addr = 0;
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void in46a_from_gsna(const struct ul16_t *in, struct in46_addr *dst)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dst->len = in->l;
 | 
				
			||||||
 | 
						OSMO_ASSERT(in->l <= sizeof(dst->v6));
 | 
				
			||||||
 | 
						memcpy(&dst->v6, in->v, in->l);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										43
									
								
								lib/in46_addr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								lib/in46_addr.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <osmocom/gtp/pdp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* a simple wrapper around an in6_addr to also contain the length of the address,
 | 
				
			||||||
 | 
					 * thereby implicitly indicating the address family of the address */
 | 
				
			||||||
 | 
					struct in46_addr {
 | 
				
			||||||
 | 
						uint8_t len;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct in_addr v4;
 | 
				
			||||||
 | 
							struct in6_addr v6;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct in46_prefix {
 | 
				
			||||||
 | 
						struct in46_addr addr;
 | 
				
			||||||
 | 
						uint8_t prefixlen;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int in46a_to_af(const struct in46_addr *in);
 | 
				
			||||||
 | 
					extern int in46a_to_sas(struct sockaddr_storage *out, const struct in46_addr *in);
 | 
				
			||||||
 | 
					extern const char *in46a_ntop(const struct in46_addr *in, char *dst, socklen_t dst_size);
 | 
				
			||||||
 | 
					extern const char *in46a_ntoa(const struct in46_addr *in46);
 | 
				
			||||||
 | 
					extern const char *in46p_ntoa(const struct in46_prefix *in46p);
 | 
				
			||||||
 | 
					extern int in46a_equal(const struct in46_addr *a, const struct in46_addr *b);
 | 
				
			||||||
 | 
					extern int in46a_prefix_equal(const struct in46_addr *a, const struct in46_addr *b);
 | 
				
			||||||
 | 
					extern int in46a_within_mask(const struct in46_addr *addr, const struct in46_addr *net, size_t prefixlen);
 | 
				
			||||||
 | 
					unsigned int in46a_netmasklen(const struct in46_addr *netmask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int in46a_to_eua(const struct in46_addr *src, unsigned int size, struct ul66_t *eua);
 | 
				
			||||||
 | 
					int in46a_from_eua(const struct ul66_t *eua, struct in46_addr *dst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool in46a_is_v6(const struct in46_addr *addr) {
 | 
				
			||||||
 | 
						return addr->len == 8 || addr->len == 16;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool in46a_is_v4(const struct in46_addr *addr) {
 | 
				
			||||||
 | 
						return addr->len == sizeof(struct in_addr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void in46a_from_gsna(const struct ul16_t *in, struct in46_addr *dst);
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user