├── .gitignore ├── COPYING ├── INSTALL ├── Makefile.am ├── README ├── README.md ├── Socket ├── Errno.cxx ├── Errno.hxx ├── Makefile.am ├── SockAddr.cxx ├── SockAddr.hxx ├── Socket.cxx ├── Socket.hxx └── test │ ├── Makefile.am │ └── getifaddrs.cxx ├── configure.ac ├── debian ├── changelog ├── compat ├── control ├── copyright ├── docs ├── init.d.in ├── po │ └── POTFILES.in ├── postinst ├── rules ├── source │ └── format ├── tcp-intercept.config └── tcp-intercept.templates ├── m4 └── as-ac-expand.m4 ├── po ├── LINGUAS ├── Makevars ├── POTFILES.in └── nl.po ├── src ├── Makefile.am ├── gettext.h └── tcp-intercept.cxx └── test ├── Makefile.am └── simply-run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | Makefile.in 3 | *.o 4 | *.a 5 | .deps 6 | /ABOUT-NLS 7 | /config.h 8 | /config.h.in 9 | /config.status 10 | /config.log 11 | /configure 12 | /aclocal.m4 13 | /autom4te.cache 14 | /compile 15 | /depcomp 16 | /install-sh 17 | /missing 18 | /config.guess 19 | /config.sub 20 | /config.rpath 21 | /libtool 22 | /ltmain.sh 23 | /stamp-h1 24 | /GITREVISION 25 | /m4 26 | /Socket/.libs/* 27 | /Socket/*.lo 28 | /Socket/*.la 29 | /src/tcp-intercept 30 | /po/*.pot 31 | /po/*.gmo 32 | /po/Makefile.in.in 33 | /po/Makevars.template 34 | /po/POTFILES 35 | /po/Rules-quot 36 | /po/boldquot.sed 37 | /po/en@boldquot.header 38 | /po/en@quot.header 39 | /po/insert-header.sin 40 | /po/quot.sed 41 | /po/remove-potcdate.sed 42 | /po/remove-potcdate.sin 43 | /po/stamp-po 44 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published by 637 | the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006 Free Software Foundation, Inc. 6 | 7 | This file is free documentation; the Free Software Foundation gives 8 | unlimited permission to copy, distribute and modify it. 9 | 10 | Basic Installation 11 | ================== 12 | 13 | Briefly, the shell commands `./configure; make; make install' should 14 | configure, build, and install this package. The following 15 | more-detailed instructions are generic; see the `README' file for 16 | instructions specific to this package. 17 | 18 | The `configure' shell script attempts to guess correct values for 19 | various system-dependent variables used during compilation. It uses 20 | those values to create a `Makefile' in each directory of the package. 21 | It may also create one or more `.h' files containing system-dependent 22 | definitions. Finally, it creates a shell script `config.status' that 23 | you can run in the future to recreate the current configuration, and a 24 | file `config.log' containing compiler output (useful mainly for 25 | debugging `configure'). 26 | 27 | It can also use an optional file (typically called `config.cache' 28 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 29 | the results of its tests to speed up reconfiguring. Caching is 30 | disabled by default to prevent problems with accidental use of stale 31 | cache files. 32 | 33 | If you need to do unusual things to compile the package, please try 34 | to figure out how `configure' could check whether to do them, and mail 35 | diffs or instructions to the address given in the `README' so they can 36 | be considered for the next release. If you are using the cache, and at 37 | some point `config.cache' contains results you don't want to keep, you 38 | may remove or edit it. 39 | 40 | The file `configure.ac' (or `configure.in') is used to create 41 | `configure' by a program called `autoconf'. You need `configure.ac' if 42 | you want to change it or regenerate `configure' using a newer version 43 | of `autoconf'. 44 | 45 | The simplest way to compile this package is: 46 | 47 | 1. `cd' to the directory containing the package's source code and type 48 | `./configure' to configure the package for your system. 49 | 50 | Running `configure' might take a while. While running, it prints 51 | some messages telling which features it is checking for. 52 | 53 | 2. Type `make' to compile the package. 54 | 55 | 3. Optionally, type `make check' to run any self-tests that come with 56 | the package. 57 | 58 | 4. Type `make install' to install the programs and any data files and 59 | documentation. 60 | 61 | 5. You can remove the program binaries and object files from the 62 | source code directory by typing `make clean'. To also remove the 63 | files that `configure' created (so you can compile the package for 64 | a different kind of computer), type `make distclean'. There is 65 | also a `make maintainer-clean' target, but that is intended mainly 66 | for the package's developers. If you use it, you may have to get 67 | all sorts of other programs in order to regenerate files that came 68 | with the distribution. 69 | 70 | Compilers and Options 71 | ===================== 72 | 73 | Some systems require unusual options for compilation or linking that the 74 | `configure' script does not know about. Run `./configure --help' for 75 | details on some of the pertinent environment variables. 76 | 77 | You can give `configure' initial values for configuration parameters 78 | by setting variables in the command line or in the environment. Here 79 | is an example: 80 | 81 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 82 | 83 | *Note Defining Variables::, for more details. 84 | 85 | Compiling For Multiple Architectures 86 | ==================================== 87 | 88 | You can compile the package for more than one kind of computer at the 89 | same time, by placing the object files for each architecture in their 90 | own directory. To do this, you can use GNU `make'. `cd' to the 91 | directory where you want the object files and executables to go and run 92 | the `configure' script. `configure' automatically checks for the 93 | source code in the directory that `configure' is in and in `..'. 94 | 95 | With a non-GNU `make', it is safer to compile the package for one 96 | architecture at a time in the source code directory. After you have 97 | installed the package for one architecture, use `make distclean' before 98 | reconfiguring for another architecture. 99 | 100 | Installation Names 101 | ================== 102 | 103 | By default, `make install' installs the package's commands under 104 | `/usr/local/bin', include files under `/usr/local/include', etc. You 105 | can specify an installation prefix other than `/usr/local' by giving 106 | `configure' the option `--prefix=PREFIX'. 107 | 108 | You can specify separate installation prefixes for 109 | architecture-specific files and architecture-independent files. If you 110 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 111 | PREFIX as the prefix for installing programs and libraries. 112 | Documentation and other data files still use the regular prefix. 113 | 114 | In addition, if you use an unusual directory layout you can give 115 | options like `--bindir=DIR' to specify different values for particular 116 | kinds of files. Run `configure --help' for a list of the directories 117 | you can set and what kinds of files go in them. 118 | 119 | If the package supports it, you can cause programs to be installed 120 | with an extra prefix or suffix on their names by giving `configure' the 121 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 122 | 123 | Optional Features 124 | ================= 125 | 126 | Some packages pay attention to `--enable-FEATURE' options to 127 | `configure', where FEATURE indicates an optional part of the package. 128 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 129 | is something like `gnu-as' or `x' (for the X Window System). The 130 | `README' should mention any `--enable-' and `--with-' options that the 131 | package recognizes. 132 | 133 | For packages that use the X Window System, `configure' can usually 134 | find the X include and library files automatically, but if it doesn't, 135 | you can use the `configure' options `--x-includes=DIR' and 136 | `--x-libraries=DIR' to specify their locations. 137 | 138 | Specifying the System Type 139 | ========================== 140 | 141 | There may be some features `configure' cannot figure out automatically, 142 | but needs to determine by the type of machine the package will run on. 143 | Usually, assuming the package is built to be run on the _same_ 144 | architectures, `configure' can figure that out, but if it prints a 145 | message saying it cannot guess the machine type, give it the 146 | `--build=TYPE' option. TYPE can either be a short name for the system 147 | type, such as `sun4', or a canonical name which has the form: 148 | 149 | CPU-COMPANY-SYSTEM 150 | 151 | where SYSTEM can have one of these forms: 152 | 153 | OS KERNEL-OS 154 | 155 | See the file `config.sub' for the possible values of each field. If 156 | `config.sub' isn't included in this package, then this package doesn't 157 | need to know the machine type. 158 | 159 | If you are _building_ compiler tools for cross-compiling, you should 160 | use the option `--target=TYPE' to select the type of system they will 161 | produce code for. 162 | 163 | If you want to _use_ a cross compiler, that generates code for a 164 | platform different from the build platform, you should specify the 165 | "host" platform (i.e., that on which the generated programs will 166 | eventually be run) with `--host=TYPE'. 167 | 168 | Sharing Defaults 169 | ================ 170 | 171 | If you want to set default values for `configure' scripts to share, you 172 | can create a site shell script called `config.site' that gives default 173 | values for variables like `CC', `cache_file', and `prefix'. 174 | `configure' looks for `PREFIX/share/config.site' if it exists, then 175 | `PREFIX/etc/config.site' if it exists. Or, you can set the 176 | `CONFIG_SITE' environment variable to the location of the site script. 177 | A warning: not all `configure' scripts look for a site script. 178 | 179 | Defining Variables 180 | ================== 181 | 182 | Variables not defined in a site shell script can be set in the 183 | environment passed to `configure'. However, some packages may run 184 | configure again during the build, and the customized values of these 185 | variables may be lost. In order to avoid this problem, you should set 186 | them in the `configure' command line, using `VAR=value'. For example: 187 | 188 | ./configure CC=/usr/local2/bin/gcc 189 | 190 | causes the specified `gcc' to be used as the C compiler (unless it is 191 | overridden in the site shell script). 192 | 193 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 194 | an Autoconf bug. Until the bug is fixed you can use this workaround: 195 | 196 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 197 | 198 | `configure' Invocation 199 | ====================== 200 | 201 | `configure' recognizes the following options to control how it operates. 202 | 203 | `--help' 204 | `-h' 205 | Print a summary of the options to `configure', and exit. 206 | 207 | `--version' 208 | `-V' 209 | Print the version of Autoconf used to generate the `configure' 210 | script, and exit. 211 | 212 | `--cache-file=FILE' 213 | Enable the cache: use and save the results of the tests in FILE, 214 | traditionally `config.cache'. FILE defaults to `/dev/null' to 215 | disable caching. 216 | 217 | `--config-cache' 218 | `-C' 219 | Alias for `--cache-file=config.cache'. 220 | 221 | `--quiet' 222 | `--silent' 223 | `-q' 224 | Do not print messages saying which checks are being made. To 225 | suppress all normal output, redirect it to `/dev/null' (any error 226 | messages will still be shown). 227 | 228 | `--srcdir=DIR' 229 | Look for the package's source code in directory DIR. Usually 230 | `configure' can determine that directory automatically. 231 | 232 | `configure' also accepts some other, not widely useful, options. Run 233 | `configure --help' for more details. 234 | 235 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = config.rpath GITREVISION 2 | SUBDIRS = Socket src test po 3 | 4 | ACLOCAL_AMFLAGS = -I m4 5 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tcp-intercept 2 | ============= 3 | 4 | This program is designed to intercept TCP connections passing through this box. 5 | This can be set up using the TPROXY-target of iptables, together with the 6 | appropriate `ip route` setup. See kernel/Documentation/networking/tproxy.txt for 7 | details. 8 | 9 | 10 | Rationale 11 | --------- 12 | 13 | The idea is to perform TCP-acceleration on unaware endpoints. This acceleration 14 | can consist of using MultiPath-TCP, using another congestion control algorithm, 15 | or both. 16 | 17 | Other projects exist to simply add MPTCP-support to existing connections on the 18 | netfilter-layer (e.g. 19 | http://www.ietf.org/mail-archive/web/multipathtcp/current/msg01934.html). This 20 | is more performant, since it doesn't maintain any buffers. 21 | In order to change the congestion control however, intermediate buffers are 22 | needed. 23 | 24 | 25 | Compiling and installing 26 | ------------------------ 27 | 28 | If you use a Debian-based system, you can build a `.deb` file by running 29 | `dpkg-buildpackage -us -uc`, and install it with `dpkg -i generated-file.deb`. 30 | You need to have the dependencies installed before you can build. 31 | 32 | Dependencies: 33 | 34 | * libev (`libev-dev` on debian-based systems) 35 | * libdaemon (`libdaemon-dev` on debian-based systems) 36 | * ptr_list from libboost (`libboost-dev` on debian-based systems) 37 | * libsimplelog (https://github.com/VRT-onderzoek-en-innovatie/libsimplelog) 38 | 39 | Instructions: 40 | 41 | ``` 42 | autopoint 43 | autoreconf -i 44 | ./configure 45 | make 46 | sudo make install 47 | ``` 48 | 49 | TCP keepalive support 50 | ------------------------ 51 | Inorder to benefit from the TCP-keepalive functionality, you need to enable 52 | kernel support. Without this functionality, tcp-intercept has no way of 53 | cleaning up connections that hang becasue one of the peers lost connectivity 54 | without tcp-inntercept being aware of it. Should you wish to have this feature 55 | enabled (default is disabled), please start tcp-intercept with the keepalive 56 | option (-k). 57 | 58 | You may use the procfs or sysctl interface to configure the kernel parameters. 59 | 60 | procfs: 61 | * /proc/sys/net/ipv4/tcp_keepalive_time 62 | * /proc/sys/net/ipv4/tcp_keepalive_intvl 63 | * /proc/sys/net/ipv4/tcp_keepalive_probes 64 | 65 | sysctl: 66 | * net.ipv4.tcp_keepalive_time 67 | * net.ipv4.tcp_keepalive_intvl 68 | * net.ipv4.tcp_keepalive_probes 69 | 70 | 71 | TCP_NODELAY (no Nagel) support 72 | ----------------------- 73 | tcp-intercept can disable (optionally) the Nagel-Algorithm used by TCP. TCP by default 74 | tries to optimise utilization of the network. In doing so, it buffers data segments 75 | (smaller than an MSS), until it reaches the MSS or it receives an ACK message for its 76 | sent data segments, and sends them out as one big segment. This way it avoids the 77 | frequent sending of small segments that could waste bandwidth. On the contrary, this 78 | could have a negative effect on latency/jitter sensitive applications (real time apps). 79 | Should you wish to have this feature enabled (default is disabled), please start 80 | tcp-intercept with the TCP_NODELAY option (-n). 81 | 82 | iptables setup 83 | ------------- 84 | ``` 85 | IP_ROUTE_TABLE_NUMBER=5 # free routing table number to use 86 | FWMARK="0x01/0x01" # Distinguishing FWmark bit to use 87 | LISTEN_PORT=5000 # Port where tcp-intercept is listening on 88 | 89 | # First add a custom route table that delivers everything locally 90 | ip rule add fwmark $FWMARK table $IP_ROUTE_TABLE_NUMBER 91 | ip route add local 0.0.0.0/0 dev lo table $IP_ROUTE_TABLE_NUMBER 92 | 93 | iptables -t mangle -N tproxy 94 | 95 | # If this packet matches an existing, open local socket, deliver it locally 96 | iptables -t mangle -A tproxy -p tcp -m socket -j MARK --set-mark $FWMARK 97 | iptables -t mangle -A tproxy -p tcp -m socket -j RETURN 98 | # If it is a packet with a local destination, don't touch it 99 | iptables -t mangle -A tproxy -p tcp -m addrtype --dst-type LOCAL -j RETURN 100 | # Intercept all other TCP-connections 101 | iptables -t mangle -A tproxy -p tcp -j TPROXY \ 102 | --on-port $LISTEN_PORT --tproxy-mark $FWMARK 103 | 104 | iptables -t mangle -A PREROUTING -j tproxy 105 | ``` 106 | -------------------------------------------------------------------------------- /Socket/Errno.cxx: -------------------------------------------------------------------------------- 1 | #include "Errno.hxx" 2 | 3 | #include 4 | #include 5 | 6 | Errno::Errno(std::string what, int errno_value) throw() : 7 | std::runtime_error(what), 8 | m_errno(errno_value) 9 | { 10 | } 11 | 12 | const char* Errno::what() const throw() { 13 | std::ostringstream e; 14 | e << std::runtime_error::what() 15 | << ": " << strerror(m_errno); 16 | return e.str().c_str(); 17 | } 18 | -------------------------------------------------------------------------------- /Socket/Errno.hxx: -------------------------------------------------------------------------------- 1 | #ifndef __ERRNO_HXX_INCLUDED__ 2 | #define __ERRNO_HXX_INCLUDED__ 3 | 4 | #include 5 | #include 6 | 7 | class Errno : public std::runtime_error { 8 | public: 9 | Errno(std::string what, int errno_value) throw(); 10 | virtual const char* what() const throw(); 11 | 12 | virtual int error_number() const throw() { return m_errno; } 13 | 14 | protected: 15 | int m_errno; 16 | 17 | }; 18 | 19 | #endif // __ERRNO_HXX_INCLUDED__ 20 | -------------------------------------------------------------------------------- /Socket/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = test 2 | 3 | noinst_LTLIBRARIES = libSocket.la 4 | 5 | libSocket_la_SOURCES = Socket.cxx Socket.hxx \ 6 | SockAddr.cxx SockAddr.hxx \ 7 | Errno.cxx Errno.hxx 8 | -------------------------------------------------------------------------------- /Socket/SockAddr.cxx: -------------------------------------------------------------------------------- 1 | #include "SockAddr.hxx" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace SockAddr { 14 | 15 | bool SockAddr::address_equal(SockAddr const &b) const throw() { 16 | if( this->addr_family() != b.addr_family() ) return false; 17 | switch( this->addr_family() ) { 18 | case AF_INET: 19 | return dynamic_cast(this)->address_equal( dynamic_cast(b) ); 20 | case AF_INET6: 21 | return dynamic_cast(this)->address_equal( dynamic_cast(b) ); 22 | } 23 | } 24 | 25 | std::auto_ptr create(struct sockaddr_storage const *addr) throw(std::invalid_argument) { 26 | if( addr == NULL ) throw std::invalid_argument("Empty address"); 27 | 28 | switch( addr->ss_family ) { 29 | case AF_INET: 30 | return std::auto_ptr( new Inet4( *reinterpret_cast(addr) ) ); 31 | case AF_INET6: 32 | return std::auto_ptr( new Inet6( *reinterpret_cast(addr) ) ); 33 | default: 34 | throw(std::invalid_argument("Unknown address family")); 35 | } 36 | } 37 | 38 | std::auto_ptr translate(std::string const &host, unsigned short const port) throw(std::invalid_argument) { 39 | bool looks_like_v4 = ( host.find('.') != std::string::npos ); 40 | bool looks_like_v6 = ( host.find(':') != std::string::npos ); 41 | if( ( !looks_like_v4 && !looks_like_v6 ) || ( looks_like_v4 && looks_like_v6 ) ) { 42 | std::string e("\""); 43 | e.append(host); 44 | e.append("\" does not look like an IP address"); 45 | throw std::invalid_argument(e); 46 | } 47 | if( looks_like_v4 ) { 48 | struct sockaddr_in sa; 49 | bzero(&sa, sizeof(sa)); 50 | #ifdef SOCKADDR_HAS_LEN_FIELD 51 | sa.sin_len = sizeof(sa); 52 | #endif 53 | sa.sin_family = AF_INET; 54 | if( inet_pton(AF_INET, host.c_str(), &sa.sin_addr) <= 0 ) { 55 | std::string e("\""); 56 | e.append(host); 57 | e.append("\" is not an IPv4 address"); 58 | throw std::invalid_argument(e); 59 | } 60 | sa.sin_port = htons(port); 61 | 62 | return create(&sa); 63 | } else { // looks_like_v6 64 | struct sockaddr_in6 sa; 65 | bzero(&sa, sizeof(sa)); 66 | #ifdef SOCKADDR_HAS_LEN_FIELD 67 | sa.sin6_len = sizeof(sa); 68 | #endif 69 | sa.sin6_family = AF_INET6; 70 | if( inet_pton(AF_INET6, host.c_str(), &sa.sin6_addr) <= 0 ) { 71 | std::string e("\""); 72 | e.append(host); 73 | e.append("\" is not an IPv6 address"); 74 | throw std::invalid_argument(e); 75 | } 76 | sa.sin6_port = htons(port); 77 | 78 | return create(&sa); 79 | } 80 | } 81 | 82 | std::auto_ptr< boost::ptr_vector< SockAddr > > resolve(std::string const &host, std::string const &port, int const family, int const socktype, int const protocol, bool const v4_mapped) { 83 | struct addrinfo hints; 84 | hints.ai_family = family; 85 | hints.ai_socktype = socktype; 86 | hints.ai_protocol = protocol; 87 | hints.ai_flags = AI_ADDRCONFIG; 88 | if( v4_mapped ) hints.ai_flags = AI_V4MAPPED; 89 | 90 | int hstart = 0, hend = host.length(); 91 | if( host[0] == '[' && host[ host.length()-1 ] == ']' ) { 92 | hstart = 1; 93 | hend -= 2; 94 | hints.ai_flags |= AI_NUMERICHOST; 95 | } 96 | 97 | int pstart = 0, pend = port.length(); 98 | if( port[0] == '[' && port[ port.length()-1 ] == ']' ) { 99 | pstart = 1; 100 | pend -= 2; 101 | hints.ai_flags |= AI_NUMERICSERV; 102 | } 103 | 104 | struct addrinfo *res; 105 | int rv = getaddrinfo(host.substr(hstart,hend).c_str(), port.substr(pstart,pend).c_str(), &hints, &res); 106 | if( rv != 0 ) { 107 | std::ostringstream e; 108 | e << "Could not getaddrinfo(\"" << host << "\", \"" << port << "\"): "; 109 | e << gai_strerror(rv); 110 | throw std::runtime_error(e.str()); 111 | } 112 | 113 | struct addrinfo *p = res; 114 | std::auto_ptr< boost::ptr_vector< SockAddr > > ret( new boost::ptr_vector< SockAddr> ); 115 | while( p != NULL ) { 116 | std::auto_ptr a( create( reinterpret_cast(p->ai_addr) ) ); 117 | ret->push_back( a.release() ); 118 | 119 | p = p->ai_next; 120 | } 121 | 122 | freeaddrinfo(res); 123 | 124 | return ret; 125 | } 126 | 127 | std::auto_ptr< boost::ptr_vector< SockAddr > > getifaddrs() { 128 | std::auto_ptr< boost::ptr_vector< SockAddr > > ret( new boost::ptr_vector< SockAddr> ); 129 | 130 | struct ifaddrs *ifap; 131 | int rv = ::getifaddrs(&ifap); 132 | 133 | while( ifap != NULL ) { 134 | try { 135 | std::auto_ptr a( create( reinterpret_cast(ifap->ifa_addr) ) ); 136 | ret->push_back( a.release() ); 137 | } catch( std::invalid_argument &e ) { 138 | // Unknown address family, ignore 139 | } 140 | 141 | ifap = ifap->ifa_next; 142 | } 143 | 144 | freeifaddrs(ifap); 145 | 146 | return ret; 147 | } 148 | 149 | Inet4::Inet4(struct sockaddr_in const &addr) throw() { 150 | bzero(&m_addr, sizeof(m_addr)); 151 | #ifdef SOCKADDR_HAS_LEN_FIELD 152 | m_addr.sin_len = sizeof(m_addr); 153 | #endif 154 | m_addr.sin_family = addr.sin_family; 155 | m_addr.sin_port = addr.sin_port; 156 | m_addr.sin_addr.s_addr = addr.sin_addr.s_addr; 157 | } 158 | 159 | std::string Inet4::string() const throw(Errno) { 160 | std::string a("["); 161 | { 162 | char address[INET_ADDRSTRLEN]; 163 | if( inet_ntop(AF_INET, &m_addr.sin_addr, address, sizeof(address)) == NULL ) { 164 | throw Errno("Could not convert IPv4 address to text", errno); 165 | } 166 | a.append(address); 167 | } 168 | 169 | a.append("]:"); 170 | 171 | { 172 | char port[6]; 173 | int rv = snprintf(port, sizeof(port), "%d", ntohs(m_addr.sin_port)); 174 | assert( rv < (signed)sizeof(port) ); // unsigned shorts are always 5 digits or less 175 | if( rv == -1 ) { 176 | throw Errno("Could not convert IPv4 address to text", errno); 177 | } 178 | a.append(port); 179 | } 180 | return a; 181 | } 182 | 183 | Inet6::Inet6(struct sockaddr_in6 const &addr) throw() { 184 | bzero(&m_addr, sizeof(m_addr)); 185 | #ifdef SOCKADDR_HAS_LEN_FIELD 186 | m_addr.sin6_len = sizeof(m_addr); 187 | #endif 188 | m_addr.sin6_family = AF_INET6; 189 | m_addr.sin6_port = addr.sin6_port; 190 | m_addr.sin6_flowinfo = addr.sin6_flowinfo; 191 | for( unsigned int i = 0; i < sizeof(addr.sin6_addr.s6_addr); i++) m_addr.sin6_addr.s6_addr[i] = addr.sin6_addr.s6_addr[i]; 192 | m_addr.sin6_scope_id = addr.sin6_scope_id; 193 | } 194 | 195 | std::string Inet6::string() const throw(std::runtime_error) { 196 | std::string a("["); 197 | { 198 | char address[INET6_ADDRSTRLEN]; 199 | if( inet_ntop(AF_INET6, &m_addr.sin6_addr, address, sizeof(address)) == NULL ) { 200 | throw Errno("Could not convert IPv6 address to text", errno); 201 | } 202 | a.append(address); 203 | } 204 | 205 | a.append("]:"); 206 | 207 | { 208 | char port[6]; 209 | int rv = snprintf(port, sizeof(port), "%d", ntohs(m_addr.sin6_port)); 210 | assert( rv < (signed)sizeof(port) ); // unsigned shorts are always 5 digits or less 211 | if( rv == -1 ) { 212 | throw Errno("Could not convert IPv6 address to text", errno); 213 | } 214 | a.append(port); 215 | } 216 | return a; 217 | } 218 | 219 | } // namespace 220 | -------------------------------------------------------------------------------- /Socket/SockAddr.hxx: -------------------------------------------------------------------------------- 1 | #ifndef __SOCKADDR_HPP__ 2 | #define __SOCKADDR_HPP__ 3 | 4 | #include "../config.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "Errno.hxx" 11 | 12 | namespace SockAddr { 13 | 14 | class SockAddr { 15 | protected: 16 | SockAddr() throw() {} 17 | 18 | public: 19 | virtual ~SockAddr() throw() {}; 20 | 21 | virtual operator struct sockaddr const*() const throw() =0; 22 | virtual socklen_t const addr_len() const throw() =0; 23 | 24 | virtual bool operator ==(SockAddr const &b) const throw() { 25 | return this->port_equal(b) && this->address_equal(b); 26 | } 27 | virtual bool address_equal(SockAddr const &b) const throw(); 28 | virtual bool port_equal(SockAddr const &b) const throw() { 29 | return this->port_number() == b.port_number(); 30 | } 31 | 32 | virtual std::string string() const throw(std::runtime_error) = 0; 33 | 34 | virtual int const proto_family() const throw() =0; 35 | virtual int const addr_family() const throw() =0; 36 | 37 | virtual int const port_number() const throw() =0; 38 | 39 | virtual bool is_any() const throw() =0; 40 | virtual bool is_loopback() const throw() =0; 41 | }; 42 | 43 | std::auto_ptr create(struct sockaddr_storage const *addr) throw(std::invalid_argument); 44 | inline std::auto_ptr create(struct sockaddr_in const *addr) throw(std::invalid_argument) { 45 | return create( reinterpret_cast(addr) ); 46 | } 47 | inline std::auto_ptr create(struct sockaddr_in6 const *addr) throw(std::invalid_argument) { 48 | return create( reinterpret_cast(addr) ); 49 | } 50 | 51 | std::auto_ptr translate(std::string const &host, unsigned short const port) throw(std::invalid_argument); 52 | 53 | std::auto_ptr< boost::ptr_vector< SockAddr > > resolve(std::string const &host, std::string const &service, int const family = 0, int const socktype = 0, int const protocol = 0, bool const v4_mapped = false); 54 | 55 | std::auto_ptr< boost::ptr_vector< SockAddr > > getifaddrs(); 56 | 57 | 58 | class Inet4 : public SockAddr { 59 | protected: 60 | struct sockaddr_in m_addr; 61 | 62 | public: 63 | Inet4(struct sockaddr_in const &addr) throw(); 64 | virtual ~Inet4() throw() {}; 65 | 66 | socklen_t const addr_len() const throw() { return sizeof(m_addr); } 67 | 68 | virtual operator struct sockaddr const*() const throw() { return reinterpret_cast(&m_addr); } 69 | virtual bool address_equal(Inet4 const &b) const throw() { 70 | return (m_addr.sin_addr.s_addr == b.m_addr.sin_addr.s_addr); 71 | } 72 | 73 | virtual std::string string() const throw(Errno); 74 | 75 | virtual int const proto_family() const throw() { return PF_INET; } 76 | virtual int const addr_family() const throw() { return AF_INET; } 77 | 78 | virtual int const port_number() const throw() { return ntohs(m_addr.sin_port); } 79 | 80 | virtual bool is_any() const throw() { return m_addr.sin_addr.s_addr == INADDR_ANY; } 81 | virtual bool is_loopback() const throw() { return m_addr.sin_addr.s_addr == INADDR_LOOPBACK; } 82 | }; 83 | 84 | 85 | class Inet6 : public SockAddr { 86 | protected: 87 | struct sockaddr_in6 m_addr; 88 | 89 | public: 90 | Inet6(struct sockaddr_in6 const &addr) throw(); 91 | virtual ~Inet6() throw() {} 92 | 93 | socklen_t const addr_len() const throw() { return sizeof(m_addr); } 94 | 95 | virtual operator struct sockaddr const*() const throw() { return reinterpret_cast(&m_addr); } 96 | virtual bool address_equal(Inet6 const &b) const throw() { 97 | for( unsigned int i = 0; i < sizeof(m_addr.sin6_addr.s6_addr); i++) { 98 | if( m_addr.sin6_addr.s6_addr[i] != b.m_addr.sin6_addr.s6_addr[i] ) return false; 99 | } 100 | return true; 101 | } 102 | 103 | virtual std::string string() const throw(std::runtime_error); 104 | 105 | virtual int const proto_family() const throw() { return PF_INET6; } 106 | virtual int const addr_family() const throw() { return AF_INET6; } 107 | 108 | virtual int const port_number() const throw() { return ntohs(m_addr.sin6_port); } 109 | 110 | virtual bool is_any() const throw() { return memcmp(&m_addr.sin6_addr, &in6addr_any, 16); } 111 | virtual bool is_loopback() const throw() { return memcmp(&m_addr.sin6_addr, &in6addr_loopback, 16); } 112 | }; 113 | 114 | } // namespace 115 | 116 | #endif // __SOCKADDR_HPP__ 117 | -------------------------------------------------------------------------------- /Socket/Socket.cxx: -------------------------------------------------------------------------------- 1 | #include "Socket.hxx" 2 | #include 3 | #include 4 | #include 5 | 6 | Socket Socket::socket(int const domain, int const type, int const protocol) throw(Errno) { 7 | int s = ::socket(domain, type, protocol); 8 | if( s == -1 ) { 9 | throw Errno("Could not create socket", errno); 10 | } 11 | return Socket(s); 12 | } 13 | 14 | void Socket::bind(struct sockaddr const *address, socklen_t const address_len) throw(Errno) { 15 | if( ::bind(m_socket, address, address_len) == -1 ) { 16 | throw Errno("Could not bind", errno); 17 | } 18 | } 19 | 20 | void Socket::connect(struct sockaddr const *address, socklen_t const address_len) throw(Errno) { 21 | if( ::connect(m_socket, address, address_len) ) { 22 | throw Errno("Could not connect", errno); 23 | } 24 | } 25 | 26 | void Socket::listen(int const backlog) throw(Errno) { 27 | if( ::listen(m_socket, backlog) == -1 ) { 28 | throw Errno("Could not listen", errno); 29 | } 30 | } 31 | 32 | Socket Socket::accept(int const socket, struct sockaddr *address, socklen_t *address_len) throw(Errno) { 33 | int s = ::accept(socket, address, address_len); 34 | if( s == -1 ) { 35 | throw Errno("Could not accept()", errno); 36 | } 37 | return Socket(s); 38 | } 39 | 40 | Socket Socket::accept(std::auto_ptr *client_address) throw(Errno) { 41 | struct sockaddr_storage a; 42 | socklen_t a_len = sizeof(a); 43 | Socket s( accept(m_socket, reinterpret_cast(&a), &a_len) ); 44 | if( client_address != NULL ) { 45 | *client_address = SockAddr::create(&a); 46 | } 47 | return s; 48 | } 49 | 50 | std::auto_ptr Socket::getsockname() const throw(Errno) { 51 | struct sockaddr_storage a; 52 | socklen_t a_len = sizeof(a); 53 | if( -1 == ::getsockname(m_socket, reinterpret_cast(&a), &a_len) ) { 54 | throw Errno("Could not getsockname()", errno); 55 | } 56 | std::auto_ptr addr( SockAddr::create(&a) ); 57 | return addr; 58 | } 59 | 60 | std::auto_ptr Socket::getpeername() const throw(Errno) { 61 | struct sockaddr_storage a; 62 | socklen_t a_len = sizeof(a); 63 | if( -1 == ::getpeername(m_socket, reinterpret_cast(&a), &a_len) ) { 64 | throw Errno("Could not getpeername()", errno); 65 | } 66 | std::auto_ptr addr( SockAddr::create(&a) ); 67 | return addr; 68 | } 69 | 70 | std::string Socket::recv(size_t const max_length ) throw(Errno) { 71 | std::auto_ptr buf( new char[max_length] ); 72 | ssize_t length = ::recv(m_socket, buf.get(), max_length, 0); 73 | if( length == -1 ) { 74 | throw Errno("Could not recv()", errno); 75 | } 76 | return std::string(buf.get(), length); // TODO: avoid needless copy of data 77 | } 78 | 79 | ssize_t Socket::send(char const *data, size_t len) throw(Errno) { 80 | ssize_t rv = ::send(m_socket, data, len, 0); 81 | if( rv == -1 ) { 82 | throw Errno("Could not send()", errno); 83 | } 84 | return rv; 85 | } 86 | void Socket::send(std::string const &data) throw(Errno,std::runtime_error) { 87 | ssize_t rv = this->send(data.data(), data.length()); 88 | if( rv != (signed)data.length() ) { 89 | std::ostringstream e; 90 | e << "Could not send(): Not enough bytes sent: " << rv << " < " << data.length(); 91 | throw std::runtime_error(e.str()); 92 | } 93 | } 94 | 95 | void Socket::shutdown(int how) throw(Errno) { 96 | if( ::shutdown(m_socket, how) == -1 ) { 97 | throw Errno("Could not shutdown()", errno); 98 | } 99 | } 100 | 101 | void Socket::setsockopt(int const level, int const optname, const void *optval, socklen_t optlen) throw(Errno) { 102 | if( ::setsockopt(m_socket, level, optname, optval, optlen) == -1 ) { 103 | throw Errno("Could not setsockopt()", errno); 104 | } 105 | } 106 | 107 | void Socket::getsockopt(int const level, int const optname, void *optval, socklen_t *optlen) throw(Errno) { 108 | if( ::getsockopt(m_socket, level, optname, optval, optlen) == -1 ) { 109 | throw Errno("Could not getsockopt()", errno); 110 | } 111 | } 112 | 113 | bool Socket::non_blocking() throw(Errno) { 114 | int flags = fcntl(m_socket, F_GETFL); 115 | if( flags == -1 ) { 116 | throw Errno("Could not fcntl(, F_GETFL)", errno); 117 | } 118 | return flags | O_NONBLOCK; 119 | } 120 | bool Socket::non_blocking(bool new_state) throw(Errno) { 121 | int flags = fcntl(m_socket, F_GETFL); 122 | if( flags == -1 ) { 123 | throw Errno("Could not fcntl(, F_GETFL)", errno); 124 | } 125 | bool non_block_state = flags | O_NONBLOCK; 126 | 127 | if( new_state ) { 128 | flags |= O_NONBLOCK; 129 | } else { 130 | flags &= ~O_NONBLOCK; 131 | } 132 | 133 | int rv = fcntl(m_socket, F_SETFL, flags); 134 | if( rv == -1 ) { 135 | throw Errno("Could not fcntl(, F_SETFL)", errno); 136 | } 137 | 138 | return non_block_state; 139 | } 140 | -------------------------------------------------------------------------------- /Socket/Socket.hxx: -------------------------------------------------------------------------------- 1 | #ifndef __SOCKET_HPP__ 2 | #define __SOCKET_HPP__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Errno.hxx" 10 | #include "SockAddr.hxx" 11 | 12 | class Socket { 13 | private: 14 | int m_socket; 15 | 16 | public: 17 | /** 18 | * Take responsibility of a socket 19 | * Will close when this object is destroyed 20 | */ 21 | Socket(int const socket = -1) throw() : m_socket(socket) {} 22 | 23 | ~Socket() throw() { this->reset(); } 24 | 25 | /** 26 | * Release responsibility of the socket 27 | * The socket FD is returned. 28 | */ 29 | int release() throw() { int tmp = m_socket; m_socket = -1; return tmp; } 30 | 31 | void reset(int const socket = -1) { if( m_socket != -1 ) close(m_socket); m_socket = socket; } 32 | Socket & operator =(Socket &rhs) { this->reset( rhs.m_socket ); rhs.release(); return *this; } 33 | Socket & operator =(Socket rhs) { this->reset( rhs.m_socket ); rhs.release(); return *this; } 34 | 35 | /* 36 | * Factory methods 37 | */ 38 | static Socket socket(int const domain, int const type, int const protocol) throw(Errno); 39 | static Socket accept(int const socket, struct sockaddr *address, socklen_t *address_len) throw(Errno); 40 | 41 | operator int() throw() { return m_socket; } 42 | 43 | void bind(struct sockaddr const *address, socklen_t const address_len) throw(Errno); 44 | void bind(SockAddr::SockAddr const &addr) throw(Errno) { 45 | return this->bind(static_cast(addr), addr.addr_len()); } 46 | 47 | void connect(struct sockaddr const *address, socklen_t const address_len) throw(Errno); 48 | void connect(SockAddr::SockAddr const &addr) throw(Errno) { 49 | return this->connect(static_cast(addr), addr.addr_len()); } 50 | 51 | void listen(int const backlog) throw(Errno); 52 | 53 | /** 54 | * Accept a new connection on this socket (must be in listening mode) 55 | * The new socket FD is returned 56 | * if client_address is not NULL, the target auto_ptr is reassigned to 57 | * own the SockAddr of the client. 58 | */ 59 | Socket accept(std::auto_ptr *client_address) throw(Errno); 60 | 61 | std::string recv(size_t const max_length = 4096) throw(Errno); 62 | ssize_t send(char const *data, size_t len) throw(Errno); 63 | void send(std::string const &data) throw(Errno,std::runtime_error); 64 | 65 | void shutdown(int how) throw(Errno); 66 | 67 | std::auto_ptr getsockname() const throw(Errno); 68 | std::auto_ptr getpeername() const throw(Errno); 69 | 70 | /** 71 | * {set,get}sockopt calls 72 | */ 73 | void setsockopt(int const level, int const optname, const void *optval, socklen_t optlen) throw(Errno); 74 | void getsockopt(int const level, int const optname, void *optval, socklen_t *optlen) throw(Errno); 75 | 76 | void set_reuseaddr(bool state = true) throw(Errno) { 77 | int optval = state; 78 | return this->setsockopt(SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); 79 | } 80 | 81 | int getsockopt_so_error() throw(Errno) { 82 | int error; 83 | socklen_t error_len = sizeof(error); 84 | this->getsockopt(SOL_SOCKET, SO_ERROR, &error, &error_len); 85 | return error; 86 | } 87 | 88 | 89 | /** 90 | * Get or set the non-blocking state of the socket 91 | * Both functions return the non-blocking state at the moment of the call 92 | * (i.e. before it is changed) 93 | */ 94 | bool non_blocking() throw(Errno); 95 | bool non_blocking(bool new_state) throw(Errno); 96 | }; 97 | 98 | #endif // __SOCKET_HPP__ 99 | -------------------------------------------------------------------------------- /Socket/test/Makefile.am: -------------------------------------------------------------------------------- 1 | check_PROGRAMS = getifaddrs 2 | TESTS = $(check_PROGRAMS) 3 | 4 | getifaddrs_SOURCES = getifaddrs.cxx 5 | getifaddrs_LDADD = ../libSocket.la 6 | -------------------------------------------------------------------------------- /Socket/test/getifaddrs.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../SockAddr.hxx" 3 | 4 | int main() { 5 | std::auto_ptr< boost::ptr_vector< SockAddr::SockAddr> > local_addrs 6 | = SockAddr::getifaddrs(); 7 | for( typeof(local_addrs->begin()) i = local_addrs->begin(); i != local_addrs->end(); i++ ) { 8 | printf("%s\n", i->string().c_str() ); 9 | } 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ(2.61) 2 | AC_INIT([tcp-intercept], m4_esyscmd_s([dpkg-parsechangelog | sed -n 's/^Version: //p']), []) 3 | AM_INIT_AUTOMAKE([foreign dist-bzip2 -Wall]) 4 | LT_INIT 5 | 6 | AC_MSG_CHECKING([whether this is a Git repository]) 7 | PACKAGE_GITREVISION=`git describe --tags --always HEAD 2>/dev/null` 8 | which git > /dev/null; \ 9 | if test $? -ne 0 || test "x$PACKAGE_GITREVISION" = "x"; then 10 | PACKAGE_GITREVISION="`cat $srcdir/GITREVISION`-cached" 11 | AC_MSG_RESULT([no, using stored version info: $PACKAGE_GITREVISION]) 12 | else 13 | echo $PACKAGE_GITREVISION > $srcdir/GITREVISION 14 | AC_MSG_RESULT([yes, current version info: $PACKAGE_GITREVISION]) 15 | fi 16 | AC_SUBST(PACKAGE_GITREVISION) 17 | AC_DEFINE_UNQUOTED([PACKAGE_GITREVISION],["$PACKAGE_GITREVISION"],[Package version with Git revision info]) 18 | 19 | AC_CONFIG_SRCDIR([src/tcp-intercept.cxx]) 20 | AC_CONFIG_HEADERS([config.h]) 21 | AC_LANG([C++]) 22 | 23 | # Check for options. 24 | #################### 25 | AC_ARG_ENABLE([useless], 26 | AC_HELP_STRING([--enable-useless],[Enable useless build. When some features are missing, this build becomes useless. Normally ./configure will bail out with an error. This option turns these errors into warnings.]), 27 | [enable_useless=$enableval],[enable_useless=no]) 28 | 29 | AC_ARG_ENABLE([ipv6], 30 | AC_HELP_STRING([--disable-ipv6],[Disable IPv6 support]), 31 | [enable_ipv6=$enableval],[enable_ipv6=yes]) 32 | AS_IF([test x$enable_ipv6 == xyes], [AC_DEFINE([ENABLE_IPV6],[1],[Define to 1 to enable IPv6 support])] ) 33 | 34 | # Checks for programs. 35 | ###################### 36 | AC_PROG_CXX 37 | AC_PROG_CXXCPP 38 | AM_PROG_CC_C_O # per product options in Makefile.am 39 | AM_GNU_GETTEXT_VERSION([0.18.1]) 40 | AM_GNU_GETTEXT([external]) 41 | 42 | # Checks for libraries. 43 | ####################### 44 | AC_CHECK_LIB(ev, ev_run, , [AC_MSG_ERROR([Couldn't find libev])]) dnl ' 45 | AC_CHECK_LIB(simplelog, LogAtLevel_nodebug, , [AC_MSG_ERROR([Couldn't find libsimplelog])]) dnl ' 46 | AC_CHECK_LIB(daemon, daemon_fork, [: do nothing yet, wait for more detailed test below], [AC_MSG_ERROR([Couldn't find libdaemon])]) dnl ' 47 | AC_CHECK_LIB(daemon, daemon_close_all, , [AC_MSG_ERROR([Couldn't find a recent enough libdaemon])]) dnl ' 48 | 49 | # Checks for header files. 50 | ########################## 51 | AC_HEADER_STDC 52 | AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h string.h strings.h sys/socket.h unistd.h fcntl.h sys/time.h]) 53 | AC_CHECK_HEADER([boost/ptr_container/ptr_list.hpp], [], [AC_MSG_ERROR([Couldn't find boost library])], []) dnl ' 54 | AC_HEADER_TIME 55 | 56 | 57 | # Checks for typedefs, structures, and compiler characteristics. 58 | ################################################################ 59 | AC_HEADER_STDBOOL 60 | AC_C_CONST 61 | AC_C_INLINE 62 | AC_TYPE_SIZE_T 63 | AC_TYPE_SSIZE_T 64 | 65 | # Check for the sin_len field in sockaddr_in 66 | AC_CHECK_MEMBER([struct sockaddr_in.sin_len], 67 | [AC_DEFINE([SOCKADDR_IN_HAS_LEN_FIELD], [1], [struct sockaddr_in has sin_len field])], 68 | [], 69 | [#include ]) 70 | AS_IF([test x$enable_ipv6 == xyes], [ 71 | AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len], 72 | [AC_DEFINE([SOCKADDR_IN6_HAS_LEN_FIELD], [1], [struct sockaddr_in6 has sin6_len field])], 73 | [], 74 | [#include ]) 75 | ]) 76 | 77 | AC_CHECK_DECL([IP_TRANSPARENT], [AC_DEFINE([HAVE_DECL_IP_TRANSPARENT], [1], [IP_TRANSPARENT is defined])], 78 | AS_IF([test x$enable_useless == xyes],[AC_MSG_WARN([Couldn't find IP_TRANSPARENT option]);have_useful_build=no], 79 | [AC_MSG_ERROR([Couldn't find IP_TRANSPARENT option])]), [ 80 | #include ]) 81 | 82 | AC_CHECK_DECL([SOL_IP], [], [AC_DEFINE([SOL_IP], [IPPROTO_IP], [Workaround for OSes that don't support SOL_IP])], [ 83 | #include ]) dnl ' 84 | 85 | #AC_STRUCT_TM 86 | # This macro is obsolescent, as time.h defines struct tm in current systems. New 87 | # programs need not use this macro. 88 | # source: http://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Particular-Structures.html#index-AC_005fSTRUCT_005fTM-685 89 | 90 | 91 | # Checks for library functions. 92 | ############################### 93 | AC_CHECK_FUNCS([bzero socket strerror gettimeofday]) 94 | 95 | # AC_FUNC_STRFTIME 96 | # This macro is obsolescent, as no current systems require the intl library for 97 | # strftime. New programs need not use this macro. 98 | # source: http://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Particular-Functions.html#AC_FUNC_STRFTIME 99 | 100 | 101 | # Add some info to config.h 102 | AC_DEFINE_UNQUOTED([CONFIGURE_ARGS],["$ac_configure_args"],[Configure flags]) 103 | AC_DEFINE_UNQUOTED([CFLAGS],["$CFLAGS"],[Used C flags]) 104 | AC_DEFINE_UNQUOTED([CXXFLAGS],["$CXXFLAGS"],[Used C++ flags]) 105 | AC_DEFINE_UNQUOTED([CPPFLAGS],["$CPPFLAGS"],[Used C-preprocessor flags]) 106 | 107 | # Output 108 | ######## 109 | AS_AC_EXPAND(EXPANDED_sbindir, "$sbindir") 110 | AC_CONFIG_FILES([ 111 | debian/init.d 112 | Makefile 113 | Socket/Makefile 114 | Socket/test/Makefile 115 | src/Makefile 116 | test/Makefile 117 | po/Makefile.in 118 | ]) 119 | AC_OUTPUT 120 | 121 | echo " 122 | -------------------------------------------------------------------------------- 123 | ${PACKAGE_NAME} version ${PACKAGE_VERSION} (${PACKAGE_GITREVISION}) 124 | 125 | Prefix: '${prefix}' 126 | C Compiler: '${CC} ${CFLAGS} ${CPPFLAGS}' 127 | C++ Compiler: '${CXX} ${CXXFLAGS} ${CPPFLAGS}' 128 | Linker: '${LD} ${LDFLAGS}' 129 | Libraries: '${LIBS}' 130 | 131 | Configured with: 132 | IPv6: $enable_ipv6 133 | -------------------------------------------------------------------------------- 134 | " 135 | 136 | AS_IF([test x$have_useful_build == xno], [ 137 | echo 138 | echo "WARNING: THIS WILL RESULT IN A USELESS BUILD!!!" 139 | echo 140 | ]) 141 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | tcp-intercept (1.1.1) UNRELEASED; urgency=low 2 | 3 | * 4 | 5 | -- Niels Laukens Mon, 13 Feb 2017 11:25:03 +0100 6 | 7 | tcp-intercept (1.1.0) unstable; urgency=low 8 | 9 | * Add option to use TCP_NODELAY and SO_KEEPALIVE (by Maedot Desta) 10 | 11 | -- Niels Laukens Mon, 13 Feb 2017 11:25:03 +0100 12 | 13 | tcp-intercept (1.0.2) unstable; urgency=low 14 | 15 | * Enhanced IPv6 compatibility 16 | 17 | -- Niels Laukens Mon, 5 Oct 2015 10:17:03 +0200 18 | 19 | tcp-intercept (1.0.1) unstable; urgency=low 20 | 21 | * Minor bugfixes of corner cases 22 | 23 | -- Niels Laukens Tue, 13 May 2014 12:18:52 +0200 24 | 25 | tcp-intercept (1.0.0) unstable; urgency=low 26 | 27 | * Initial Release. 28 | 29 | -- Niels Laukens Fri, 18 Apr 2014 14:38:00 +0200 30 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: tcp-intercept 2 | Section: net 3 | Priority: optional 4 | Maintainer: Niels Laukens 5 | Build-Depends: debhelper (>= 9.0.0), autotools-dev, dh-autoreconf, 6 | libsimplelog-dev, libev-dev, libdaemon-dev, libboost-dev 7 | Standards-Version: 3.9.3 8 | Homepage: https://github.com/VRT-onderzoek-en-innovatie/tcp-intercept 9 | Vcs-Git: git://github.com/VRT-onderzoek-en-innovatie/tcp-intercept.git 10 | Vcs-Browser: https://github.com/VRT-onderzoek-en-innovatie/tcp-intercept 11 | 12 | Package: tcp-intercept 13 | Architecture: linux-any 14 | Depends: ${shlibs:Depends}, ${misc:Depends} 15 | Description: Intercept TCP-sessions with help of tproxy 16 | This program is designed to intercept TCP connections passing through this 17 | box. This can be set up using the TPROXY-target of iptables, together with the 18 | appropriate ip route setup. See kernel/Documentation/networking/tproxy.txt 19 | for details. 20 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://dep.debian.net/deps/dep5 2 | Upstream-Name: tcp-intercept 3 | Source: https://github.com/VRT-onderzoek-en-innovatie/tcp-intercept 4 | 5 | Files: * 6 | Copyright: 2013 Niels Laukens 7 | License: AGPL-3.0 8 | 9 | Files: debian/* 10 | Copyright: 2013 Niels Laukens 11 | License: GPL-3.0+ 12 | 13 | License: GPL-3.0+ 14 | This program is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | . 19 | This package is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | . 24 | You should have received a copy of the GNU General Public License 25 | along with this program. If not, see . 26 | . 27 | On Debian systems, the complete text of the GNU General 28 | Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". 29 | 30 | License: AGPL-3.0 31 | GNU AFFERO GENERAL PUBLIC LICENSE 32 | Version 3, 19 November 2007 33 | . 34 | Copyright (C) 2007 Free Software Foundation, Inc. 35 | Everyone is permitted to copy and distribute verbatim copies 36 | of this license document, but changing it is not allowed. 37 | . 38 | Preamble 39 | . 40 | The GNU Affero General Public License is a free, copyleft license for 41 | software and other kinds of works, specifically designed to ensure 42 | cooperation with the community in the case of network server software. 43 | . 44 | The licenses for most software and other practical works are designed 45 | to take away your freedom to share and change the works. By contrast, 46 | our General Public Licenses are intended to guarantee your freedom to 47 | share and change all versions of a program--to make sure it remains free 48 | software for all its users. 49 | . 50 | When we speak of free software, we are referring to freedom, not 51 | price. Our General Public Licenses are designed to make sure that you 52 | have the freedom to distribute copies of free software (and charge for 53 | them if you wish), that you receive source code or can get it if you 54 | want it, that you can change the software or use pieces of it in new 55 | free programs, and that you know you can do these things. 56 | . 57 | Developers that use our General Public Licenses protect your rights 58 | with two steps: (1) assert copyright on the software, and (2) offer 59 | you this License which gives you legal permission to copy, distribute 60 | and/or modify the software. 61 | . 62 | A secondary benefit of defending all users' freedom is that 63 | improvements made in alternate versions of the program, if they 64 | receive widespread use, become available for other developers to 65 | incorporate. Many developers of free software are heartened and 66 | encouraged by the resulting cooperation. However, in the case of 67 | software used on network servers, this result may fail to come about. 68 | The GNU General Public License permits making a modified version and 69 | letting the public access it on a server without ever releasing its 70 | source code to the public. 71 | . 72 | The GNU Affero General Public License is designed specifically to 73 | ensure that, in such cases, the modified source code becomes available 74 | to the community. It requires the operator of a network server to 75 | provide the source code of the modified version running there to the 76 | users of that server. Therefore, public use of a modified version, on 77 | a publicly accessible server, gives the public access to the source 78 | code of the modified version. 79 | . 80 | An older license, called the Affero General Public License and 81 | published by Affero, was designed to accomplish similar goals. This is 82 | a different license, not a version of the Affero GPL, but Affero has 83 | released a new version of the Affero GPL which permits relicensing under 84 | this license. 85 | . 86 | The precise terms and conditions for copying, distribution and 87 | modification follow. 88 | . 89 | TERMS AND CONDITIONS 90 | . 91 | 0. Definitions. 92 | . 93 | "This License" refers to version 3 of the GNU Affero General Public License. 94 | . 95 | "Copyright" also means copyright-like laws that apply to other kinds of 96 | works, such as semiconductor masks. 97 | . 98 | "The Program" refers to any copyrightable work licensed under this 99 | License. Each licensee is addressed as "you". "Licensees" and 100 | "recipients" may be individuals or organizations. 101 | . 102 | To "modify" a work means to copy from or adapt all or part of the work 103 | in a fashion requiring copyright permission, other than the making of an 104 | exact copy. The resulting work is called a "modified version" of the 105 | earlier work or a work "based on" the earlier work. 106 | . 107 | A "covered work" means either the unmodified Program or a work based 108 | on the Program. 109 | . 110 | To "propagate" a work means to do anything with it that, without 111 | permission, would make you directly or secondarily liable for 112 | infringement under applicable copyright law, except executing it on a 113 | computer or modifying a private copy. Propagation includes copying, 114 | distribution (with or without modification), making available to the 115 | public, and in some countries other activities as well. 116 | . 117 | To "convey" a work means any kind of propagation that enables other 118 | parties to make or receive copies. Mere interaction with a user through 119 | a computer network, with no transfer of a copy, is not conveying. 120 | . 121 | An interactive user interface displays "Appropriate Legal Notices" 122 | to the extent that it includes a convenient and prominently visible 123 | feature that (1) displays an appropriate copyright notice, and (2) 124 | tells the user that there is no warranty for the work (except to the 125 | extent that warranties are provided), that licensees may convey the 126 | work under this License, and how to view a copy of this License. If 127 | the interface presents a list of user commands or options, such as a 128 | menu, a prominent item in the list meets this criterion. 129 | . 130 | 1. Source Code. 131 | . 132 | The "source code" for a work means the preferred form of the work 133 | for making modifications to it. "Object code" means any non-source 134 | form of a work. 135 | . 136 | A "Standard Interface" means an interface that either is an official 137 | standard defined by a recognized standards body, or, in the case of 138 | interfaces specified for a particular programming language, one that 139 | is widely used among developers working in that language. 140 | . 141 | The "System Libraries" of an executable work include anything, other 142 | than the work as a whole, that (a) is included in the normal form of 143 | packaging a Major Component, but which is not part of that Major 144 | Component, and (b) serves only to enable use of the work with that 145 | Major Component, or to implement a Standard Interface for which an 146 | implementation is available to the public in source code form. A 147 | "Major Component", in this context, means a major essential component 148 | (kernel, window system, and so on) of the specific operating system 149 | (if any) on which the executable work runs, or a compiler used to 150 | produce the work, or an object code interpreter used to run it. 151 | . 152 | The "Corresponding Source" for a work in object code form means all 153 | the source code needed to generate, install, and (for an executable 154 | work) run the object code and to modify the work, including scripts to 155 | control those activities. However, it does not include the work's 156 | System Libraries, or general-purpose tools or generally available free 157 | programs which are used unmodified in performing those activities but 158 | which are not part of the work. For example, Corresponding Source 159 | includes interface definition files associated with source files for 160 | the work, and the source code for shared libraries and dynamically 161 | linked subprograms that the work is specifically designed to require, 162 | such as by intimate data communication or control flow between those 163 | subprograms and other parts of the work. 164 | . 165 | The Corresponding Source need not include anything that users 166 | can regenerate automatically from other parts of the Corresponding 167 | Source. 168 | . 169 | The Corresponding Source for a work in source code form is that 170 | same work. 171 | . 172 | 2. Basic Permissions. 173 | . 174 | All rights granted under this License are granted for the term of 175 | copyright on the Program, and are irrevocable provided the stated 176 | conditions are met. This License explicitly affirms your unlimited 177 | permission to run the unmodified Program. The output from running a 178 | covered work is covered by this License only if the output, given its 179 | content, constitutes a covered work. This License acknowledges your 180 | rights of fair use or other equivalent, as provided by copyright law. 181 | . 182 | You may make, run and propagate covered works that you do not 183 | convey, without conditions so long as your license otherwise remains 184 | in force. You may convey covered works to others for the sole purpose 185 | of having them make modifications exclusively for you, or provide you 186 | with facilities for running those works, provided that you comply with 187 | the terms of this License in conveying all material for which you do 188 | not control copyright. Those thus making or running the covered works 189 | for you must do so exclusively on your behalf, under your direction 190 | and control, on terms that prohibit them from making any copies of 191 | your copyrighted material outside their relationship with you. 192 | . 193 | Conveying under any other circumstances is permitted solely under 194 | the conditions stated below. Sublicensing is not allowed; section 10 195 | makes it unnecessary. 196 | . 197 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 198 | . 199 | No covered work shall be deemed part of an effective technological 200 | measure under any applicable law fulfilling obligations under article 201 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 202 | similar laws prohibiting or restricting circumvention of such 203 | measures. 204 | . 205 | When you convey a covered work, you waive any legal power to forbid 206 | circumvention of technological measures to the extent such circumvention 207 | is effected by exercising rights under this License with respect to 208 | the covered work, and you disclaim any intention to limit operation or 209 | modification of the work as a means of enforcing, against the work's 210 | users, your or third parties' legal rights to forbid circumvention of 211 | technological measures. 212 | . 213 | 4. Conveying Verbatim Copies. 214 | . 215 | You may convey verbatim copies of the Program's source code as you 216 | receive it, in any medium, provided that you conspicuously and 217 | appropriately publish on each copy an appropriate copyright notice; 218 | keep intact all notices stating that this License and any 219 | non-permissive terms added in accord with section 7 apply to the code; 220 | keep intact all notices of the absence of any warranty; and give all 221 | recipients a copy of this License along with the Program. 222 | . 223 | You may charge any price or no price for each copy that you convey, 224 | and you may offer support or warranty protection for a fee. 225 | . 226 | 5. Conveying Modified Source Versions. 227 | . 228 | You may convey a work based on the Program, or the modifications to 229 | produce it from the Program, in the form of source code under the 230 | terms of section 4, provided that you also meet all of these conditions: 231 | . 232 | a) The work must carry prominent notices stating that you modified 233 | it, and giving a relevant date. 234 | . 235 | b) The work must carry prominent notices stating that it is 236 | released under this License and any conditions added under section 237 | 7. This requirement modifies the requirement in section 4 to 238 | "keep intact all notices". 239 | . 240 | c) You must license the entire work, as a whole, under this 241 | License to anyone who comes into possession of a copy. This 242 | License will therefore apply, along with any applicable section 7 243 | additional terms, to the whole of the work, and all its parts, 244 | regardless of how they are packaged. This License gives no 245 | permission to license the work in any other way, but it does not 246 | invalidate such permission if you have separately received it. 247 | . 248 | d) If the work has interactive user interfaces, each must display 249 | Appropriate Legal Notices; however, if the Program has interactive 250 | interfaces that do not display Appropriate Legal Notices, your 251 | work need not make them do so. 252 | . 253 | A compilation of a covered work with other separate and independent 254 | works, which are not by their nature extensions of the covered work, 255 | and which are not combined with it such as to form a larger program, 256 | in or on a volume of a storage or distribution medium, is called an 257 | "aggregate" if the compilation and its resulting copyright are not 258 | used to limit the access or legal rights of the compilation's users 259 | beyond what the individual works permit. Inclusion of a covered work 260 | in an aggregate does not cause this License to apply to the other 261 | parts of the aggregate. 262 | . 263 | 6. Conveying Non-Source Forms. 264 | . 265 | You may convey a covered work in object code form under the terms 266 | of sections 4 and 5, provided that you also convey the 267 | machine-readable Corresponding Source under the terms of this License, 268 | in one of these ways: 269 | . 270 | a) Convey the object code in, or embodied in, a physical product 271 | (including a physical distribution medium), accompanied by the 272 | Corresponding Source fixed on a durable physical medium 273 | customarily used for software interchange. 274 | . 275 | b) Convey the object code in, or embodied in, a physical product 276 | (including a physical distribution medium), accompanied by a 277 | written offer, valid for at least three years and valid for as 278 | long as you offer spare parts or customer support for that product 279 | model, to give anyone who possesses the object code either (1) a 280 | copy of the Corresponding Source for all the software in the 281 | product that is covered by this License, on a durable physical 282 | medium customarily used for software interchange, for a price no 283 | more than your reasonable cost of physically performing this 284 | conveying of source, or (2) access to copy the 285 | Corresponding Source from a network server at no charge. 286 | . 287 | c) Convey individual copies of the object code with a copy of the 288 | written offer to provide the Corresponding Source. This 289 | alternative is allowed only occasionally and noncommercially, and 290 | only if you received the object code with such an offer, in accord 291 | with subsection 6b. 292 | . 293 | d) Convey the object code by offering access from a designated 294 | place (gratis or for a charge), and offer equivalent access to the 295 | Corresponding Source in the same way through the same place at no 296 | further charge. You need not require recipients to copy the 297 | Corresponding Source along with the object code. If the place to 298 | copy the object code is a network server, the Corresponding Source 299 | may be on a different server (operated by you or a third party) 300 | that supports equivalent copying facilities, provided you maintain 301 | clear directions next to the object code saying where to find the 302 | Corresponding Source. Regardless of what server hosts the 303 | Corresponding Source, you remain obligated to ensure that it is 304 | available for as long as needed to satisfy these requirements. 305 | . 306 | e) Convey the object code using peer-to-peer transmission, provided 307 | you inform other peers where the object code and Corresponding 308 | Source of the work are being offered to the general public at no 309 | charge under subsection 6d. 310 | . 311 | A separable portion of the object code, whose source code is excluded 312 | from the Corresponding Source as a System Library, need not be 313 | included in conveying the object code work. 314 | . 315 | A "User Product" is either (1) a "consumer product", which means any 316 | tangible personal property which is normally used for personal, family, 317 | or household purposes, or (2) anything designed or sold for incorporation 318 | into a dwelling. In determining whether a product is a consumer product, 319 | doubtful cases shall be resolved in favor of coverage. For a particular 320 | product received by a particular user, "normally used" refers to a 321 | typical or common use of that class of product, regardless of the status 322 | of the particular user or of the way in which the particular user 323 | actually uses, or expects or is expected to use, the product. A product 324 | is a consumer product regardless of whether the product has substantial 325 | commercial, industrial or non-consumer uses, unless such uses represent 326 | the only significant mode of use of the product. 327 | . 328 | "Installation Information" for a User Product means any methods, 329 | procedures, authorization keys, or other information required to install 330 | and execute modified versions of a covered work in that User Product from 331 | a modified version of its Corresponding Source. The information must 332 | suffice to ensure that the continued functioning of the modified object 333 | code is in no case prevented or interfered with solely because 334 | modification has been made. 335 | . 336 | If you convey an object code work under this section in, or with, or 337 | specifically for use in, a User Product, and the conveying occurs as 338 | part of a transaction in which the right of possession and use of the 339 | User Product is transferred to the recipient in perpetuity or for a 340 | fixed term (regardless of how the transaction is characterized), the 341 | Corresponding Source conveyed under this section must be accompanied 342 | by the Installation Information. But this requirement does not apply 343 | if neither you nor any third party retains the ability to install 344 | modified object code on the User Product (for example, the work has 345 | been installed in ROM). 346 | . 347 | The requirement to provide Installation Information does not include a 348 | requirement to continue to provide support service, warranty, or updates 349 | for a work that has been modified or installed by the recipient, or for 350 | the User Product in which it has been modified or installed. Access to a 351 | network may be denied when the modification itself materially and 352 | adversely affects the operation of the network or violates the rules and 353 | protocols for communication across the network. 354 | . 355 | Corresponding Source conveyed, and Installation Information provided, 356 | in accord with this section must be in a format that is publicly 357 | documented (and with an implementation available to the public in 358 | source code form), and must require no special password or key for 359 | unpacking, reading or copying. 360 | . 361 | 7. Additional Terms. 362 | . 363 | "Additional permissions" are terms that supplement the terms of this 364 | License by making exceptions from one or more of its conditions. 365 | Additional permissions that are applicable to the entire Program shall 366 | be treated as though they were included in this License, to the extent 367 | that they are valid under applicable law. If additional permissions 368 | apply only to part of the Program, that part may be used separately 369 | under those permissions, but the entire Program remains governed by 370 | this License without regard to the additional permissions. 371 | . 372 | When you convey a copy of a covered work, you may at your option 373 | remove any additional permissions from that copy, or from any part of 374 | it. (Additional permissions may be written to require their own 375 | removal in certain cases when you modify the work.) You may place 376 | additional permissions on material, added by you to a covered work, 377 | for which you have or can give appropriate copyright permission. 378 | . 379 | Notwithstanding any other provision of this License, for material you 380 | add to a covered work, you may (if authorized by the copyright holders of 381 | that material) supplement the terms of this License with terms: 382 | . 383 | a) Disclaiming warranty or limiting liability differently from the 384 | terms of sections 15 and 16 of this License; or 385 | . 386 | b) Requiring preservation of specified reasonable legal notices or 387 | author attributions in that material or in the Appropriate Legal 388 | Notices displayed by works containing it; or 389 | . 390 | c) Prohibiting misrepresentation of the origin of that material, or 391 | requiring that modified versions of such material be marked in 392 | reasonable ways as different from the original version; or 393 | . 394 | d) Limiting the use for publicity purposes of names of licensors or 395 | authors of the material; or 396 | . 397 | e) Declining to grant rights under trademark law for use of some 398 | trade names, trademarks, or service marks; or 399 | . 400 | f) Requiring indemnification of licensors and authors of that 401 | material by anyone who conveys the material (or modified versions of 402 | it) with contractual assumptions of liability to the recipient, for 403 | any liability that these contractual assumptions directly impose on 404 | those licensors and authors. 405 | . 406 | All other non-permissive additional terms are considered "further 407 | restrictions" within the meaning of section 10. If the Program as you 408 | received it, or any part of it, contains a notice stating that it is 409 | governed by this License along with a term that is a further 410 | restriction, you may remove that term. If a license document contains 411 | a further restriction but permits relicensing or conveying under this 412 | License, you may add to a covered work material governed by the terms 413 | of that license document, provided that the further restriction does 414 | not survive such relicensing or conveying. 415 | . 416 | If you add terms to a covered work in accord with this section, you 417 | must place, in the relevant source files, a statement of the 418 | additional terms that apply to those files, or a notice indicating 419 | where to find the applicable terms. 420 | . 421 | Additional terms, permissive or non-permissive, may be stated in the 422 | form of a separately written license, or stated as exceptions; 423 | the above requirements apply either way. 424 | . 425 | 8. Termination. 426 | . 427 | You may not propagate or modify a covered work except as expressly 428 | provided under this License. Any attempt otherwise to propagate or 429 | modify it is void, and will automatically terminate your rights under 430 | this License (including any patent licenses granted under the third 431 | paragraph of section 11). 432 | . 433 | However, if you cease all violation of this License, then your 434 | license from a particular copyright holder is reinstated (a) 435 | provisionally, unless and until the copyright holder explicitly and 436 | finally terminates your license, and (b) permanently, if the copyright 437 | holder fails to notify you of the violation by some reasonable means 438 | prior to 60 days after the cessation. 439 | . 440 | Moreover, your license from a particular copyright holder is 441 | reinstated permanently if the copyright holder notifies you of the 442 | violation by some reasonable means, this is the first time you have 443 | received notice of violation of this License (for any work) from that 444 | copyright holder, and you cure the violation prior to 30 days after 445 | your receipt of the notice. 446 | . 447 | Termination of your rights under this section does not terminate the 448 | licenses of parties who have received copies or rights from you under 449 | this License. If your rights have been terminated and not permanently 450 | reinstated, you do not qualify to receive new licenses for the same 451 | material under section 10. 452 | . 453 | 9. Acceptance Not Required for Having Copies. 454 | . 455 | You are not required to accept this License in order to receive or 456 | run a copy of the Program. Ancillary propagation of a covered work 457 | occurring solely as a consequence of using peer-to-peer transmission 458 | to receive a copy likewise does not require acceptance. However, 459 | nothing other than this License grants you permission to propagate or 460 | modify any covered work. These actions infringe copyright if you do 461 | not accept this License. Therefore, by modifying or propagating a 462 | covered work, you indicate your acceptance of this License to do so. 463 | . 464 | 10. Automatic Licensing of Downstream Recipients. 465 | . 466 | Each time you convey a covered work, the recipient automatically 467 | receives a license from the original licensors, to run, modify and 468 | propagate that work, subject to this License. You are not responsible 469 | for enforcing compliance by third parties with this License. 470 | . 471 | An "entity transaction" is a transaction transferring control of an 472 | organization, or substantially all assets of one, or subdividing an 473 | organization, or merging organizations. If propagation of a covered 474 | work results from an entity transaction, each party to that 475 | transaction who receives a copy of the work also receives whatever 476 | licenses to the work the party's predecessor in interest had or could 477 | give under the previous paragraph, plus a right to possession of the 478 | Corresponding Source of the work from the predecessor in interest, if 479 | the predecessor has it or can get it with reasonable efforts. 480 | . 481 | You may not impose any further restrictions on the exercise of the 482 | rights granted or affirmed under this License. For example, you may 483 | not impose a license fee, royalty, or other charge for exercise of 484 | rights granted under this License, and you may not initiate litigation 485 | (including a cross-claim or counterclaim in a lawsuit) alleging that 486 | any patent claim is infringed by making, using, selling, offering for 487 | sale, or importing the Program or any portion of it. 488 | . 489 | 11. Patents. 490 | . 491 | A "contributor" is a copyright holder who authorizes use under this 492 | License of the Program or a work on which the Program is based. The 493 | work thus licensed is called the contributor's "contributor version". 494 | . 495 | A contributor's "essential patent claims" are all patent claims 496 | owned or controlled by the contributor, whether already acquired or 497 | hereafter acquired, that would be infringed by some manner, permitted 498 | by this License, of making, using, or selling its contributor version, 499 | but do not include claims that would be infringed only as a 500 | consequence of further modification of the contributor version. For 501 | purposes of this definition, "control" includes the right to grant 502 | patent sublicenses in a manner consistent with the requirements of 503 | this License. 504 | . 505 | Each contributor grants you a non-exclusive, worldwide, royalty-free 506 | patent license under the contributor's essential patent claims, to 507 | make, use, sell, offer for sale, import and otherwise run, modify and 508 | propagate the contents of its contributor version. 509 | . 510 | In the following three paragraphs, a "patent license" is any express 511 | agreement or commitment, however denominated, not to enforce a patent 512 | (such as an express permission to practice a patent or covenant not to 513 | sue for patent infringement). To "grant" such a patent license to a 514 | party means to make such an agreement or commitment not to enforce a 515 | patent against the party. 516 | . 517 | If you convey a covered work, knowingly relying on a patent license, 518 | and the Corresponding Source of the work is not available for anyone 519 | to copy, free of charge and under the terms of this License, through a 520 | publicly available network server or other readily accessible means, 521 | then you must either (1) cause the Corresponding Source to be so 522 | available, or (2) arrange to deprive yourself of the benefit of the 523 | patent license for this particular work, or (3) arrange, in a manner 524 | consistent with the requirements of this License, to extend the patent 525 | license to downstream recipients. "Knowingly relying" means you have 526 | actual knowledge that, but for the patent license, your conveying the 527 | covered work in a country, or your recipient's use of the covered work 528 | in a country, would infringe one or more identifiable patents in that 529 | country that you have reason to believe are valid. 530 | . 531 | If, pursuant to or in connection with a single transaction or 532 | arrangement, you convey, or propagate by procuring conveyance of, a 533 | covered work, and grant a patent license to some of the parties 534 | receiving the covered work authorizing them to use, propagate, modify 535 | or convey a specific copy of the covered work, then the patent license 536 | you grant is automatically extended to all recipients of the covered 537 | work and works based on it. 538 | . 539 | A patent license is "discriminatory" if it does not include within 540 | the scope of its coverage, prohibits the exercise of, or is 541 | conditioned on the non-exercise of one or more of the rights that are 542 | specifically granted under this License. You may not convey a covered 543 | work if you are a party to an arrangement with a third party that is 544 | in the business of distributing software, under which you make payment 545 | to the third party based on the extent of your activity of conveying 546 | the work, and under which the third party grants, to any of the 547 | parties who would receive the covered work from you, a discriminatory 548 | patent license (a) in connection with copies of the covered work 549 | conveyed by you (or copies made from those copies), or (b) primarily 550 | for and in connection with specific products or compilations that 551 | contain the covered work, unless you entered into that arrangement, 552 | or that patent license was granted, prior to 28 March 2007. 553 | . 554 | Nothing in this License shall be construed as excluding or limiting 555 | any implied license or other defenses to infringement that may 556 | otherwise be available to you under applicable patent law. 557 | . 558 | 12. No Surrender of Others' Freedom. 559 | . 560 | If conditions are imposed on you (whether by court order, agreement or 561 | otherwise) that contradict the conditions of this License, they do not 562 | excuse you from the conditions of this License. If you cannot convey a 563 | covered work so as to satisfy simultaneously your obligations under this 564 | License and any other pertinent obligations, then as a consequence you may 565 | not convey it at all. For example, if you agree to terms that obligate you 566 | to collect a royalty for further conveying from those to whom you convey 567 | the Program, the only way you could satisfy both those terms and this 568 | License would be to refrain entirely from conveying the Program. 569 | . 570 | 13. Remote Network Interaction; Use with the GNU General Public License. 571 | . 572 | Notwithstanding any other provision of this License, if you modify the 573 | Program, your modified version must prominently offer all users 574 | interacting with it remotely through a computer network (if your version 575 | supports such interaction) an opportunity to receive the Corresponding 576 | Source of your version by providing access to the Corresponding Source 577 | from a network server at no charge, through some standard or customary 578 | means of facilitating copying of software. This Corresponding Source 579 | shall include the Corresponding Source for any work covered by version 3 580 | of the GNU General Public License that is incorporated pursuant to the 581 | following paragraph. 582 | . 583 | Notwithstanding any other provision of this License, you have 584 | permission to link or combine any covered work with a work licensed 585 | under version 3 of the GNU General Public License into a single 586 | combined work, and to convey the resulting work. The terms of this 587 | License will continue to apply to the part which is the covered work, 588 | but the work with which it is combined will remain governed by version 589 | 3 of the GNU General Public License. 590 | . 591 | 14. Revised Versions of this License. 592 | . 593 | The Free Software Foundation may publish revised and/or new versions of 594 | the GNU Affero General Public License from time to time. Such new versions 595 | will be similar in spirit to the present version, but may differ in detail to 596 | address new problems or concerns. 597 | . 598 | Each version is given a distinguishing version number. If the 599 | Program specifies that a certain numbered version of the GNU Affero General 600 | Public License "or any later version" applies to it, you have the 601 | option of following the terms and conditions either of that numbered 602 | version or of any later version published by the Free Software 603 | Foundation. If the Program does not specify a version number of the 604 | GNU Affero General Public License, you may choose any version ever published 605 | by the Free Software Foundation. 606 | . 607 | If the Program specifies that a proxy can decide which future 608 | versions of the GNU Affero General Public License can be used, that proxy's 609 | public statement of acceptance of a version permanently authorizes you 610 | to choose that version for the Program. 611 | . 612 | Later license versions may give you additional or different 613 | permissions. However, no additional obligations are imposed on any 614 | author or copyright holder as a result of your choosing to follow a 615 | later version. 616 | . 617 | 15. Disclaimer of Warranty. 618 | . 619 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 620 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 621 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 622 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 623 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 624 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 625 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 626 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 627 | . 628 | 16. Limitation of Liability. 629 | . 630 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 631 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 632 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 633 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 634 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 635 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 636 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 637 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 638 | SUCH DAMAGES. 639 | . 640 | 17. Interpretation of Sections 15 and 16. 641 | . 642 | If the disclaimer of warranty and limitation of liability provided 643 | above cannot be given local legal effect according to their terms, 644 | reviewing courts shall apply local law that most closely approximates 645 | an absolute waiver of all civil liability in connection with the 646 | Program, unless a warranty or assumption of liability accompanies a 647 | copy of the Program in return for a fee. 648 | 649 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README.md 2 | -------------------------------------------------------------------------------- /debian/init.d.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: tcp-intercept 4 | # Required-Start: $network $remote_fs 5 | # Required-Stop: $remote_fs 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: TCP intercepting daemon 9 | # Description: TCP intercepting daemon that receives diverted TCP- 10 | # connections from TPROXY iptables rules. 11 | ### END INIT INFO 12 | 13 | # Author: Niels Laukens 14 | 15 | # PATH should only include /usr/* if it runs after the mountnfs.sh script 16 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 17 | DESC=tcp-intercept # Introduce a short description here 18 | NAME=tcp-intercept # Introduce the short server's name here 19 | DAEMON=@EXPANDED_sbindir@/tcp-intercept # Introduce the server's location here 20 | DAEMON_ARGS="" # Arguments to run the daemon with 21 | PIDFILE=@localstatedir@/run/$NAME.pid 22 | SCRIPTNAME=/etc/init.d/$NAME 23 | 24 | # Exit if the package is not installed 25 | [ -x $DAEMON ] || exit 0 26 | 27 | # Default values of the configuration variables 28 | CONTROL_NETWORK=0 # this scripts configures routes 29 | CONTROL_IPTABLES=0 # this scripts configures iptables 30 | IP_ROUTE_TABLE_NUMBER=5 # free routing table number to use 31 | FWMARK="0x1/0x1" # Distinguishing FWmark bit to use 32 | LISTEN_PORT=5000 # Port where tcp-intercept is listening on 33 | 34 | # Read configuration variable file if it is present 35 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 36 | 37 | # Load the VERBOSE setting and other rcS variables 38 | . /lib/init/vars.sh 39 | 40 | # Define LSB log_* functions. 41 | # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. 42 | . /lib/lsb/init-functions 43 | 44 | # 45 | # Function that starts the daemon/service 46 | # 47 | do_start() 48 | { 49 | # Return 50 | # 0 if daemon has been started 51 | # 1 if daemon was already running 52 | # 2 if daemon could not be started 53 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ 54 | || return 1 55 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ 56 | -p "$PIDFILE" -b "$BIND_LISTEN" -B "$BIND_OUTGOING" -l "$LOGFILE" \ 57 | $DAEMON_ARGS \ 58 | || return 2 59 | } 60 | 61 | network_start() 62 | { 63 | if ! ip rule show | grep "fwmark $FWMARK" >/dev/null; then 64 | ip rule add fwmark $FWMARK table $IP_ROUTE_TABLE_NUMBER 65 | fi 66 | ip route add local 0.0.0.0/0 dev lo table $IP_ROUTE_TABLE_NUMBER 2>/dev/null 67 | } 68 | 69 | firewall_start() 70 | { 71 | iptables -t mangle -N tproxy 2>/dev/null 72 | iptables -t mangle -F tproxy 73 | iptables -t mangle -A tproxy -p tcp -m socket -j MARK --set-mark $FWMARK 74 | iptables -t mangle -A tproxy -p tcp -m socket -j RETURN 75 | iptables -t mangle -A tproxy -p tcp -m addrtype --dst-type LOCAL -j RETURN 76 | iptables -t mangle -A tproxy -p tcp -j TPROXY --on-port $LISTEN_PORT \ 77 | --tproxy-mark $FWMARK 78 | if ! iptables -t mangle -nL PREROUTING | grep tproxy >/dev/null; then 79 | iptables -t mangle -A PREROUTING -j tproxy 80 | fi 81 | } 82 | 83 | # 84 | # Function that stops the daemon/service 85 | # 86 | do_stop() 87 | { 88 | # Return 89 | # 0 if daemon has been stopped 90 | # 1 if daemon was already stopped 91 | # 2 if daemon could not be stopped 92 | # other if a failure occurred 93 | start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME 94 | RETVAL="$?" 95 | [ "$RETVAL" = 2 ] && return 2 96 | # Wait for children to finish too if this is a daemon that forks 97 | # and if the daemon is only ever run from this initscript. 98 | # If the above conditions are not satisfied then add some other code 99 | # that waits for the process to drop all resources that could be 100 | # needed by services started subsequently. A last resort is to 101 | # sleep for some time. 102 | start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON 103 | [ "$?" = 2 ] && return 2 104 | # Many daemons don't delete their pidfiles when they exit. 105 | rm -f $PIDFILE 106 | return "$RETVAL" 107 | } 108 | 109 | network_stop() 110 | { 111 | ip rule del fwmark $FWMARK table $IP_ROUTE_TABLE_NUMBER 2>/dev/null 112 | ip route flush table $IP_ROUTE_TABLE_NUMBER 113 | } 114 | 115 | firewall_stop() 116 | { 117 | if iptables -t mangle -nL PREROUTING --line-numbers | grep tproxy >/dev/null; then 118 | line=`iptables -t mangle -nL PREROUTING --line-numbers | grep tproxy | cut -f 1 -d " "` 119 | iptables -t mangle -D PREROUTING $line 120 | iptables -t mangle -F tproxy 121 | iptables -t mangle -X tproxy 122 | fi 123 | } 124 | 125 | # 126 | # Function that sends a SIGHUP to the daemon/service 127 | # 128 | do_reload() { 129 | # 130 | # If the daemon can reload its configuration without 131 | # restarting (for example, when it is sent a SIGHUP), 132 | # then implement that here. 133 | # 134 | start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME 135 | return 0 136 | } 137 | 138 | case "$1" in 139 | start) 140 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME" 141 | do_start 142 | [ $CONTROL_NETWORK = 1 ] && network_start 143 | [ $CONTROL_IPTABLES = 1 ] && firewall_start 144 | case "$?" in 145 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 146 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 147 | esac 148 | ;; 149 | stop) 150 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 151 | [ $CONTROL_IPTABLES = 1 ] && firewall_stop 152 | [ $CONTROL_NETWORK = 1 ] && network_stop 153 | do_stop 154 | case "$?" in 155 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 156 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 157 | esac 158 | ;; 159 | status) 160 | status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? 161 | ;; 162 | reload|force-reload) 163 | log_daemon_msg "Reloading $DESC" "$NAME" 164 | do_reload 165 | log_end_msg $? 166 | ;; 167 | restart) 168 | log_daemon_msg "Restarting $DESC" "$NAME" 169 | do_stop 170 | case "$?" in 171 | 0|1) 172 | do_start 173 | case "$?" in 174 | 0) log_end_msg 0 ;; 175 | 1) log_end_msg 1 ;; # Old process is still running 176 | *) log_end_msg 1 ;; # Failed to start 177 | esac 178 | ;; 179 | *) 180 | # Failed to stop 181 | log_end_msg 1 182 | ;; 183 | esac 184 | ;; 185 | *) 186 | echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 187 | exit 3 188 | ;; 189 | esac 190 | 191 | : 192 | -------------------------------------------------------------------------------- /debian/po/POTFILES.in: -------------------------------------------------------------------------------- 1 | [type: gettext/rfc822deb] tcp-intercept.templates 2 | -------------------------------------------------------------------------------- /debian/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # Source debconf library. 6 | . /usr/share/debconf/confmodule 7 | 8 | TMPFILE=`mktemp -t tcp-intercept.XXXXXX` 9 | if [ -f "/etc/default/tcp-intercept" ]; then 10 | cat "/etc/default/tcp-intercept" > "$TMPFILE" 11 | else 12 | cat > "$TMPFILE" <<-EOT 13 | # Defaults for tcp-intercept initscript 14 | # sourced by /etc/init.d/tcp-intercept 15 | # installed at /etc/default/tcp-intercept by the maintainer scripts 16 | 17 | # 18 | # This is a POSIX shell fragment 19 | # 20 | 21 | # Use square brackets to supress name lookup 22 | BIND_LISTEN="will be filled in below" 23 | BIND_OUTGOING="will be filled in below" 24 | LOGFILE="/var/log/tcp-intercept.log" 25 | 26 | # Additional options that are passed to the Daemon. 27 | DAEMON_OPTS="" 28 | EOT 29 | fi 30 | 31 | subst () { # VAR newvalue 32 | if ! grep -q "^\s*$1=" "$TMPFILE"; then 33 | echo "$1=" >> "$TMPFILE" 34 | fi 35 | sed -i -e "s/^\s*$1=.*/$1=\"$2\"/" "$TMPFILE" 36 | } 37 | 38 | db_get tcp-intercept/bind-listen 39 | subst BIND_LISTEN $RET 40 | 41 | db_get tcp-intercept/bind-outgoing 42 | subst BIND_OUTGOING $RET 43 | 44 | mv "$TMPFILE" /etc/default/tcp-intercept 45 | 46 | 47 | # dh_installdeb will replace this with shell code automatically 48 | # generated by other debhelper scripts. 49 | 50 | #DEBHELPER# 51 | 52 | exit 0 53 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | %: 13 | dh $@ --parallel --with autotools_dev --with autoreconf 14 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /debian/tcp-intercept.config: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | . /usr/share/debconf/confmodule 6 | 7 | db_version 2.0 8 | 9 | # Load our configuration file, if it exists 10 | [ -e /etc/default/tcp-intercept ] && . /etc/default/tcp-intercept 11 | 12 | # Use current values as default 13 | if [ -n "$BIND_LISTEN" ]; then 14 | db_set tcp-intercept/bind-listen "$BIND_LISTEN" 15 | fi 16 | if [ -n "$BIND_OUTGOING" ]; then 17 | db_set tcp-intercept/bind-outgoing "$BIND_OUTGOING" 18 | fi 19 | 20 | db_input medium tcp-intercept/bind-listen || true 21 | db_input medium tcp-intercept/bind-outgoing || true 22 | db_go 23 | -------------------------------------------------------------------------------- /debian/tcp-intercept.templates: -------------------------------------------------------------------------------- 1 | Template: tcp-intercept/bind-listen 2 | Type: string 3 | Default: [0.0.0.0]:[5000] 4 | _Description: Address and port to listen on: 5 | The address and port the tcp-intercept daemon listens on. Use square brackets 6 | to suppress name-resolving. 7 | . 8 | You should keep the 0.0.0.0-part, but you can change the port number if this 9 | conflicts. Be sure to change the iptables-rules accordingly 10 | 11 | 12 | Template: tcp-intercept/bind-outgoing 13 | Type: string 14 | Default: [0.0.0.0]:[0] 15 | _Description: Address (and port) to bind to for outgoing connections: 16 | The address and port the tcp-intercept daemon uses for outgoing connections. 17 | Use square brackets to suppress name-resolving. 18 | . 19 | You can use the special string "client" (without quotes) to spoof the original 20 | source address. 21 | -------------------------------------------------------------------------------- /m4/as-ac-expand.m4: -------------------------------------------------------------------------------- 1 | dnl as-ac-expand.m4 0.2.1 2 | dnl autostars m4 macro for expanding directories using configure's prefix 3 | dnl thomas@apestaart.org 4 | 5 | dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR) 6 | dnl example 7 | dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) 8 | dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local 9 | dnl Note: when using $prefix or $exec_prefix, avoid it expanding to NONE 10 | dnl by calling it like this: 11 | dnl AS_AC_EXPAND(PYTHONLIBDIR, "\${exec_prefix}/lib/python$PYVER/site-packages") 12 | 13 | AC_DEFUN([AS_AC_EXPAND], 14 | [ 15 | EXP_VAR=[$1] 16 | FROM_VAR=[$2] 17 | 18 | dnl echo DEBUG: expand FROM_VAR $FROM_VAR 19 | 20 | dnl first expand prefix and exec_prefix if necessary 21 | prefix_save=$prefix 22 | exec_prefix_save=$exec_prefix 23 | 24 | dnl if no prefix given, then use /usr/local, the default prefix 25 | if test "x$prefix" = "xNONE"; then 26 | prefix="$ac_default_prefix" 27 | fi 28 | dnl if no exec_prefix given, then use prefix 29 | if test "x$exec_prefix" = "xNONE"; then 30 | exec_prefix=$prefix 31 | fi 32 | 33 | full_var="$FROM_VAR" 34 | dnl loop until it doesn't change anymore 35 | while true; do 36 | dnl echo DEBUG: full_var: $full_var 37 | new_full_var="`eval echo $full_var`" 38 | if test "x$new_full_var" = "x$full_var"; then break; fi 39 | full_var=$new_full_var 40 | done 41 | 42 | dnl clean up 43 | full_var=$new_full_var 44 | AC_SUBST([$1], "$full_var") 45 | 46 | dnl restore prefix and exec_prefix 47 | prefix=$prefix_save 48 | exec_prefix=$exec_prefix_save 49 | ]) 50 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | nl 2 | -------------------------------------------------------------------------------- /po/Makevars: -------------------------------------------------------------------------------- 1 | # Makefile variables for PO directory in any package using GNU gettext. 2 | 3 | # Usually the message domain is the same as the package name. 4 | DOMAIN = $(PACKAGE) 5 | 6 | # These two variables depend on the location of this directory. 7 | subdir = po 8 | top_builddir = .. 9 | 10 | # These options get passed to xgettext. 11 | XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ 12 | 13 | # This is the copyright holder that gets inserted into the header of the 14 | # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding 15 | # package. (Note that the msgstr strings, extracted from the package's 16 | # sources, belong to the copyright holder of the package.) Translators are 17 | # expected to transfer the copyright for their translations to this person 18 | # or entity, or to disclaim their copyright. The empty string stands for 19 | # the public domain; in this case the translators are expected to disclaim 20 | # their copyright. 21 | COPYRIGHT_HOLDER = Free Software Foundation, Inc. 22 | 23 | # This is the email address or URL to which the translators shall report 24 | # bugs in the untranslated strings: 25 | # - Strings which are not entire sentences, see the maintainer guidelines 26 | # in the GNU gettext documentation, section 'Preparing Strings'. 27 | # - Strings which use unclear terms or require additional context to be 28 | # understood. 29 | # - Strings which make invalid assumptions about notation of date, time or 30 | # money. 31 | # - Pluralisation problems. 32 | # - Incorrect English spelling. 33 | # - Incorrect formatting. 34 | # It can be your email address, or a mailing list address where translators 35 | # can write to without being subscribed, or the URL of a web page through 36 | # which the translators can contact you. 37 | MSGID_BUGS_ADDRESS = 38 | 39 | # This is the list of locale categories, beyond LC_MESSAGES, for which the 40 | # message catalogs shall be used. It is usually empty. 41 | EXTRA_LOCALE_CATEGORIES = 42 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | # List of source files which contain translatable strings. 2 | src/tcp-intercept.cxx 3 | -------------------------------------------------------------------------------- /po/nl.po: -------------------------------------------------------------------------------- 1 | # Dutch translations for tcp-intercept package. 2 | # Copyright (C) 2014 Free Software Foundation, Inc. 3 | # This file is distributed under the same license as the tcp-intercept package. 4 | # Niels Laukens , 2014. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: tcp-intercept 0.0.3\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2014-07-02 13:59+0200\n" 11 | "PO-Revision-Date: 2014-02-28 10:41+0100\n" 12 | "Last-Translator: Niels Laukens \n" 13 | "Language-Team: Dutch\n" 14 | "Language: nl\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 19 | 20 | #: src/tcp-intercept.cxx:45 21 | msgid "Received SIGINT, exiting" 22 | msgstr "" 23 | 24 | #: src/tcp-intercept.cxx:49 25 | msgid "Received SIGTERM, exiting" 26 | msgstr "" 27 | 28 | #: src/tcp-intercept.cxx:54 29 | msgid "Received SIGHUP, closing this logfile" 30 | msgstr "" 31 | 32 | #: src/tcp-intercept.cxx:60 33 | msgid "Received SIGHUP, (re)opening this logfile" 34 | msgstr "" 35 | 36 | #: src/tcp-intercept.cxx:64 37 | msgid "Received SIGPIPE, ignoring" 38 | msgstr "" 39 | 40 | #. TRANSLATORS: %1$s contains the connection ID that was just closed 41 | #: src/tcp-intercept.cxx:76 42 | #, c-format 43 | msgid "%1$s: closed" 44 | msgstr "" 45 | 46 | #. TRANSLATORS: %1$s contains the connection ID, 47 | #. %2$s the error message 48 | #: src/tcp-intercept.cxx:97 49 | #, c-format 50 | msgid "%1$s: connect to server failed: %2$s" 51 | msgstr "" 52 | 53 | #. TRANSLATORS: %1$s contains the connection ID 54 | #: src/tcp-intercept.cxx:105 55 | #, c-format 56 | msgid "%1$s: server accepted connection, splicing" 57 | msgstr "" 58 | 59 | #: src/tcp-intercept.cxx:128 60 | #, c-format 61 | msgid "%1$s %2$s: could not send(), but was ready for write" 62 | msgstr "" 63 | 64 | #. TRANSLATORS: %1$s contains the connection ID, 65 | #. %2$s contains the direction (separately translated), 66 | #. %3$s contains the error 67 | #. 68 | #: src/tcp-intercept.cxx:138 src/tcp-intercept.cxx:172 69 | #, c-format 70 | msgid "%1$s %2$s: Error: %3$s)" 71 | msgstr "" 72 | 73 | #. TRANSLATORS: %1$s contains the connection ID, 74 | #. %2$s contains the direction (separately translated) 75 | #. 76 | #: src/tcp-intercept.cxx:157 77 | #, c-format 78 | msgid "%1$s %2$s: EOF" 79 | msgstr "" 80 | 81 | #: src/tcp-intercept.cxx:180 src/tcp-intercept.cxx:205 82 | msgid "S>C" 83 | msgstr "" 84 | 85 | #: src/tcp-intercept.cxx:188 src/tcp-intercept.cxx:197 86 | msgid "C>S" 87 | msgstr "" 88 | 89 | #. TRANSLATORS: %1$s contains the connection ID 90 | #. 91 | #: src/tcp-intercept.cxx:257 92 | #, c-format 93 | msgid "%1$s: Connection directly to us, dropping" 94 | msgstr "" 95 | 96 | #. TRANSLATORS: %1$s contains the connection ID 97 | #. 98 | #: src/tcp-intercept.cxx:264 99 | #, c-format 100 | msgid "%1$s: Connection intercepted" 101 | msgstr "" 102 | 103 | #: src/tcp-intercept.cxx:281 src/tcp-intercept.cxx:311 104 | #, c-format 105 | msgid "Error: %s" 106 | msgstr "" 107 | 108 | #. TRANSLATORS: %1$s contains the connection ID, 109 | #. %2$s the source address of the new connection, 110 | #. %3$s the destination address of the new connection 111 | #. 112 | #: src/tcp-intercept.cxx:323 113 | #, c-format 114 | msgid "%1$s: Connecting %2$s-->%3$s" 115 | msgstr "" 116 | 117 | #: src/tcp-intercept.cxx:370 118 | msgid "" 119 | "Options:\n" 120 | " -h --help Displays this help message and exits\n" 121 | " -V --version Displays the version and exits\n" 122 | " -f --foreground Don't fork and detach\n" 123 | " --pid-file -p file The file to write the PID to, especially\n" 124 | " usefull when running as a daemon. Must be " 125 | "an\n" 126 | " absolute path.\n" 127 | " --bind-listen -b host:port Bind to the specified address for " 128 | "incomming\n" 129 | " connections.\n" 130 | " host and port resolving can be bypassed " 131 | "by\n" 132 | " placing [] around them\n" 133 | " --bind-outgoing -B host:port Bind to the specified address for " 134 | "outgoing\n" 135 | " connections.\n" 136 | " host and port resolving can be bypassed " 137 | "by\n" 138 | " placing [] around them\n" 139 | " the special string \"client\" can be used " 140 | "to\n" 141 | " reuse the client's source address. Note " 142 | "that\n" 143 | " you should take care that the return " 144 | "packets\n" 145 | " pass through this process again!\n" 146 | " --log -l file Log to file\n" 147 | msgstr "" 148 | 149 | #: src/tcp-intercept.cxx:394 150 | #, c-format 151 | msgid "" 152 | "%1$s version %2$s\n" 153 | " configured with: %3$s\n" 154 | " CFLAGS=\"%4$s\" CXXFLAGS=\"%5$s\" CPPFLAGS=\"%6$s\"\n" 155 | " Options:\n" 156 | " IPv6: %7$s\n" 157 | "\n" 158 | msgstr "" 159 | 160 | #: src/tcp-intercept.cxx:404 161 | msgid "yes" 162 | msgstr "" 163 | 164 | #: src/tcp-intercept.cxx:406 165 | msgid "no" 166 | msgstr "" 167 | 168 | #: src/tcp-intercept.cxx:434 169 | #, c-format 170 | msgid "%1$s version %2$s starting up" 171 | msgstr "%1$s versie %2$s start op" 172 | 173 | #. TRANSLATORS: %1$s contains the string passed as option 174 | #. 175 | #: src/tcp-intercept.cxx:450 src/tcp-intercept.cxx:502 176 | #, c-format 177 | msgid "Invalid bind string \"%1$s\": could not find ':'\n" 178 | msgstr "" 179 | 180 | #: src/tcp-intercept.cxx:459 src/tcp-intercept.cxx:511 181 | #, c-format 182 | msgid "Can not bind to \"%1$s\": Could not resolve\n" 183 | msgstr "" 184 | 185 | #: src/tcp-intercept.cxx:463 src/tcp-intercept.cxx:514 186 | #, c-format 187 | msgid "Can not bind to \"%1$s\": Resolves to multiple entries:\n" 188 | msgstr "" 189 | 190 | #. TRANSLATORS: %1$s contains the listening address 191 | #. 192 | #: src/tcp-intercept.cxx:481 193 | #, c-format 194 | msgid "Listening on %s" 195 | msgstr "" 196 | 197 | #: src/tcp-intercept.cxx:488 198 | msgid "Outgoing connections will connect from original source address" 199 | msgstr "" 200 | 201 | #: src/tcp-intercept.cxx:522 202 | #, c-format 203 | msgid "Outgoing connections will connect from %1$s" 204 | msgstr "" 205 | 206 | #: src/tcp-intercept.cxx:528 207 | msgid "Failed to create pipe." 208 | msgstr "" 209 | 210 | #: src/tcp-intercept.cxx:534 211 | #, c-format 212 | msgid "Could not fork(): %s" 213 | msgstr "" 214 | 215 | #: src/tcp-intercept.cxx:541 216 | #, c-format 217 | msgid "Could not recieve return value from daemon process: %s" 218 | msgstr "" 219 | 220 | #: src/tcp-intercept.cxx:544 221 | #, c-format 222 | msgid "Child process [%1$d] forked succesfully, it signaled %2$d" 223 | msgstr "" 224 | 225 | #: src/tcp-intercept.cxx:588 226 | msgid "Setup done, starting event loop" 227 | msgstr "" 228 | 229 | #: src/tcp-intercept.cxx:597 230 | msgid "Exiting cleanly..." 231 | msgstr "" 232 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | sbin_PROGRAMS = tcp-intercept 2 | 3 | tcp_intercept_SOURCES = tcp-intercept.cxx gettext.h 4 | tcp_intercept_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" 5 | tcp_intercept_LDADD = ../Socket/libSocket.la $(LIBINTL) 6 | -------------------------------------------------------------------------------- /src/gettext.h: -------------------------------------------------------------------------------- 1 | /* Convenience header for conditional use of GNU . 2 | Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU General Public License as published 6 | by the Free Software Foundation; either version 3, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Library General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public 15 | License along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 17 | USA. */ 18 | 19 | #ifndef _LIBGETTEXT_H 20 | #define _LIBGETTEXT_H 1 21 | 22 | /* NLS can be disabled through the configure --disable-nls option. */ 23 | #if ENABLE_NLS 24 | 25 | /* Get declarations of GNU message catalog functions. */ 26 | # include 27 | 28 | /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by 29 | the gettext() and ngettext() macros. This is an alternative to calling 30 | textdomain(), and is useful for libraries. */ 31 | # ifdef DEFAULT_TEXT_DOMAIN 32 | # undef gettext 33 | # define gettext(Msgid) \ 34 | dgettext (DEFAULT_TEXT_DOMAIN, Msgid) 35 | # undef ngettext 36 | # define ngettext(Msgid1, Msgid2, N) \ 37 | dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) 38 | # endif 39 | 40 | #else 41 | 42 | /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which 43 | chokes if dcgettext is defined as a macro. So include it now, to make 44 | later inclusions of a NOP. We don't include 45 | as well because people using "gettext.h" will not include , 46 | and also including would fail on SunOS 4, whereas 47 | is OK. */ 48 | #if defined(__sun) 49 | # include 50 | #endif 51 | 52 | /* Many header files from the libstdc++ coming with g++ 3.3 or newer include 53 | , which chokes if dcgettext is defined as a macro. So include 54 | it now, to make later inclusions of a NOP. */ 55 | #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) 56 | # include 57 | # if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H 58 | # include 59 | # endif 60 | #endif 61 | 62 | /* Disabled NLS. 63 | The casts to 'const char *' serve the purpose of producing warnings 64 | for invalid uses of the value returned from these functions. 65 | On pre-ANSI systems without 'const', the config.h file is supposed to 66 | contain "#define const". */ 67 | # undef gettext 68 | # define gettext(Msgid) ((const char *) (Msgid)) 69 | # undef dgettext 70 | # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) 71 | # undef dcgettext 72 | # define dcgettext(Domainname, Msgid, Category) \ 73 | ((void) (Category), dgettext (Domainname, Msgid)) 74 | # undef ngettext 75 | # define ngettext(Msgid1, Msgid2, N) \ 76 | ((N) == 1 \ 77 | ? ((void) (Msgid2), (const char *) (Msgid1)) \ 78 | : ((void) (Msgid1), (const char *) (Msgid2))) 79 | # undef dngettext 80 | # define dngettext(Domainname, Msgid1, Msgid2, N) \ 81 | ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) 82 | # undef dcngettext 83 | # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ 84 | ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) 85 | # undef textdomain 86 | # define textdomain(Domainname) ((const char *) (Domainname)) 87 | # undef bindtextdomain 88 | # define bindtextdomain(Domainname, Dirname) \ 89 | ((void) (Domainname), (const char *) (Dirname)) 90 | # undef bind_textdomain_codeset 91 | # define bind_textdomain_codeset(Domainname, Codeset) \ 92 | ((void) (Domainname), (const char *) (Codeset)) 93 | 94 | #endif 95 | 96 | /* A pseudo function call that serves as a marker for the automated 97 | extraction of messages, but does not call gettext(). The run-time 98 | translation is done at a different place in the code. 99 | The argument, String, should be a literal string. Concatenated strings 100 | and other string expressions won't work. 101 | The macro's expansion is not parenthesized, so that it is suitable as 102 | initializer for static 'char[]' or 'const char[]' variables. */ 103 | #define gettext_noop(String) String 104 | 105 | /* The separator between msgctxt and msgid in a .mo file. */ 106 | #define GETTEXT_CONTEXT_GLUE "\004" 107 | 108 | /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a 109 | MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be 110 | short and rarely need to change. 111 | The letter 'p' stands for 'particular' or 'special'. */ 112 | #ifdef DEFAULT_TEXT_DOMAIN 113 | # define pgettext(Msgctxt, Msgid) \ 114 | pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) 115 | #else 116 | # define pgettext(Msgctxt, Msgid) \ 117 | pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) 118 | #endif 119 | #define dpgettext(Domainname, Msgctxt, Msgid) \ 120 | pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) 121 | #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ 122 | pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) 123 | #ifdef DEFAULT_TEXT_DOMAIN 124 | # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ 125 | npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) 126 | #else 127 | # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ 128 | npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) 129 | #endif 130 | #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ 131 | npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) 132 | #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ 133 | npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) 134 | 135 | #ifdef __GNUC__ 136 | __inline 137 | #else 138 | #ifdef __cplusplus 139 | inline 140 | #endif 141 | #endif 142 | static const char * 143 | pgettext_aux (const char *domain, 144 | const char *msg_ctxt_id, const char *msgid, 145 | int category) 146 | { 147 | const char *translation = dcgettext (domain, msg_ctxt_id, category); 148 | if (translation == msg_ctxt_id) 149 | return msgid; 150 | else 151 | return translation; 152 | } 153 | 154 | #ifdef __GNUC__ 155 | __inline 156 | #else 157 | #ifdef __cplusplus 158 | inline 159 | #endif 160 | #endif 161 | static const char * 162 | npgettext_aux (const char *domain, 163 | const char *msg_ctxt_id, const char *msgid, 164 | const char *msgid_plural, unsigned long int n, 165 | int category) 166 | { 167 | const char *translation = 168 | dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); 169 | if (translation == msg_ctxt_id || translation == msgid_plural) 170 | return (n == 1 ? msgid : msgid_plural); 171 | else 172 | return translation; 173 | } 174 | 175 | /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID 176 | can be arbitrary expressions. But for string literals these macros are 177 | less efficient than those above. */ 178 | 179 | #include 180 | 181 | #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ 182 | (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ 183 | /* || __STDC_VERSION__ >= 199901L */ ) 184 | 185 | #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 186 | #include 187 | #endif 188 | 189 | #define pgettext_expr(Msgctxt, Msgid) \ 190 | dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) 191 | #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ 192 | dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) 193 | 194 | #ifdef __GNUC__ 195 | __inline 196 | #else 197 | #ifdef __cplusplus 198 | inline 199 | #endif 200 | #endif 201 | static const char * 202 | dcpgettext_expr (const char *domain, 203 | const char *msgctxt, const char *msgid, 204 | int category) 205 | { 206 | size_t msgctxt_len = strlen (msgctxt) + 1; 207 | size_t msgid_len = strlen (msgid) + 1; 208 | const char *translation; 209 | #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 210 | char msg_ctxt_id[msgctxt_len + msgid_len]; 211 | #else 212 | char buf[1024]; 213 | char *msg_ctxt_id = 214 | (msgctxt_len + msgid_len <= sizeof (buf) 215 | ? buf 216 | : (char *) malloc (msgctxt_len + msgid_len)); 217 | if (msg_ctxt_id != NULL) 218 | #endif 219 | { 220 | memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); 221 | msg_ctxt_id[msgctxt_len - 1] = '\004'; 222 | memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); 223 | translation = dcgettext (domain, msg_ctxt_id, category); 224 | #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 225 | if (msg_ctxt_id != buf) 226 | free (msg_ctxt_id); 227 | #endif 228 | if (translation != msg_ctxt_id) 229 | return translation; 230 | } 231 | return msgid; 232 | } 233 | 234 | #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ 235 | dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) 236 | #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ 237 | dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) 238 | 239 | #ifdef __GNUC__ 240 | __inline 241 | #else 242 | #ifdef __cplusplus 243 | inline 244 | #endif 245 | #endif 246 | static const char * 247 | dcnpgettext_expr (const char *domain, 248 | const char *msgctxt, const char *msgid, 249 | const char *msgid_plural, unsigned long int n, 250 | int category) 251 | { 252 | size_t msgctxt_len = strlen (msgctxt) + 1; 253 | size_t msgid_len = strlen (msgid) + 1; 254 | const char *translation; 255 | #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 256 | char msg_ctxt_id[msgctxt_len + msgid_len]; 257 | #else 258 | char buf[1024]; 259 | char *msg_ctxt_id = 260 | (msgctxt_len + msgid_len <= sizeof (buf) 261 | ? buf 262 | : (char *) malloc (msgctxt_len + msgid_len)); 263 | if (msg_ctxt_id != NULL) 264 | #endif 265 | { 266 | memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); 267 | msg_ctxt_id[msgctxt_len - 1] = '\004'; 268 | memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); 269 | translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); 270 | #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 271 | if (msg_ctxt_id != buf) 272 | free (msg_ctxt_id); 273 | #endif 274 | if (!(translation == msg_ctxt_id || translation == msgid_plural)) 275 | return translation; 276 | } 277 | return (n == 1 ? msgid : msgid_plural); 278 | } 279 | 280 | #endif /* _LIBGETTEXT_H */ 281 | -------------------------------------------------------------------------------- /src/tcp-intercept.cxx: -------------------------------------------------------------------------------- 1 | #include "../config.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "gettext.h" 13 | #define _(String) gettext(String) 14 | #define N_(String) String 15 | 16 | #include "../Socket/Socket.hxx" 17 | #include 18 | #include 19 | #include 20 | 21 | std::string logfilename; 22 | FILE *logfile; 23 | 24 | static const int MAX_CONN_BACKLOG = 32; 25 | 26 | std::auto_ptr bind_listen_addr; 27 | std::auto_ptr bind_addr_outgoing; 28 | bool keepalive = false; 29 | bool nodelay = false; 30 | 31 | struct connection { 32 | std::string id; 33 | 34 | Socket s_client; 35 | Socket s_server; 36 | 37 | ev_io e_s_connect; 38 | ev_io e_c_read, e_c_write; 39 | ev_io e_s_read, e_s_write; 40 | 41 | std::string buf_c_to_s, buf_s_to_c; 42 | bool con_open_c_to_s, con_open_s_to_c; 43 | }; 44 | boost::ptr_list< struct connection > connections; 45 | 46 | 47 | void received_sigint(EV_P_ ev_signal *w, int revents) throw() { 48 | LogInfo(_("Received SIGINT, exiting")); 49 | ev_break(EV_A_ EVUNLOOP_ALL); 50 | } 51 | void received_sigterm(EV_P_ ev_signal *w, int revents) throw() { 52 | LogInfo(_("Received SIGTERM, exiting")); 53 | ev_break(EV_A_ EVUNLOOP_ALL); 54 | } 55 | 56 | void received_sighup(EV_P_ ev_signal *w, int revents) throw() { 57 | LogInfo(_("Received SIGHUP, closing this logfile")); 58 | if( logfilename.size() > 0 ) { 59 | fclose(logfile); 60 | logfile = fopen(logfilename.c_str(), "a"); 61 | LogSetOutputFile(NULL, logfile); 62 | } /* else we're still logging to stderr, which doesn't need reopening */ 63 | LogInfo(_("Received SIGHUP, (re)opening this logfile")); 64 | } 65 | 66 | void received_sigpipe(EV_P_ ev_signal *w, int revents) throw() { 67 | LogDebug(_("Received SIGPIPE, ignoring")); 68 | } 69 | 70 | 71 | void kill_connection(EV_P_ struct connection *con) { 72 | // Remove from event loops 73 | ev_io_stop(EV_A_ &con->e_c_read ); 74 | ev_io_stop(EV_A_ &con->e_c_write ); 75 | ev_io_stop(EV_A_ &con->e_s_read ); 76 | ev_io_stop(EV_A_ &con->e_s_write ); 77 | 78 | /* TRANSLATORS: %1$s contains the connection ID that was just closed */ 79 | LogInfo(_("%1$s: closed"), con->id.c_str()); 80 | 81 | // Find and erase this connection in the list 82 | // TODO scaling issue: this is O(n) with the number of connections. 83 | for( typeof(connections.begin()) i = connections.begin(); i != connections.end(); ++i ) { 84 | if( &(*i) == con ) { 85 | connections.erase(i); 86 | break; // Stop searching 87 | } 88 | } 89 | } 90 | 91 | static void server_socket_connect_done(EV_P_ ev_io *w, int revents) { 92 | struct connection* con = reinterpret_cast( w->data ); 93 | 94 | ev_io_stop(EV_A_ &con->e_s_connect); // We connect only once 95 | 96 | Errno connect_error("connect()", con->s_server.getsockopt_so_error()); 97 | if( connect_error.error_number() != 0 ) { 98 | /* TRANSLATORS: %1$s contains the connection ID, 99 | %2$s the error message */ 100 | LogWarn(_("%1$s: connect to server failed: %2$s"), 101 | con->id.c_str(), 102 | connect_error.what() ); 103 | kill_connection(EV_A_ con); 104 | return; 105 | } 106 | 107 | /* TRANSLATORS: %1$s contains the connection ID */ 108 | LogInfo(_("%1$s: server accepted connection, splicing"), con->id.c_str()); 109 | ev_io_start(EV_A_ &con->e_c_write); 110 | ev_io_start(EV_A_ &con->e_s_write); 111 | } 112 | 113 | inline static void peer_ready_write(EV_P_ struct connection* con, 114 | std::string const &dir, 115 | bool &con_open, 116 | Socket &rx, ev_io *e_rx_read, 117 | std::string &buf, 118 | Socket &tx, ev_io *e_tx_write ) { 119 | if( buf.length() == 0 ) { 120 | // All is written, and we're still ready to write, read some more 121 | ev_io_start( EV_A_ e_rx_read ); 122 | ev_io_stop( EV_A_ e_tx_write ); 123 | return; 124 | } 125 | // buf.length() > 0 126 | try { 127 | ssize_t rv = tx.send(buf.data(), buf.length()); 128 | if( rv == 0 ) { 129 | // Weird situation. FD was ready for write, but send() returned 0 130 | // anyway... Retry later 131 | LogWarn(_("%1$s %2$s: could not send(), but was ready for write"), 132 | con->id.c_str(), dir.c_str()); 133 | return; 134 | } 135 | buf = buf.substr( rv ); 136 | } catch( Errno &e ) { 137 | /* TRANSLATORS: %1$s contains the connection ID, 138 | %2$s contains the direction (separately translated), 139 | %3$s contains the error 140 | */ 141 | LogError(_("%1$s %2$s: Error: %3$s)"), con->id.c_str(), dir.c_str(), e.what()); 142 | kill_connection(EV_A_ con); 143 | } 144 | } 145 | inline static void peer_ready_read(EV_P_ struct connection* con, 146 | std::string const &dir, 147 | bool &con_open, 148 | Socket &rx, ev_io *e_rx_read, 149 | std::string &buf, 150 | Socket &tx, ev_io *e_tx_write ) { 151 | // TODO allow read when we still have data in the buffer to streamline things 152 | assert( buf.length() == 0 ); 153 | try { 154 | buf = rx.recv(); 155 | ev_io_stop( EV_A_ e_rx_read ); 156 | if( buf.length() == 0 ) { // EOF has been read 157 | /* TRANSLATORS: %1$s contains the connection ID, 158 | %2$s contains the direction (separately translated) 159 | */ 160 | LogInfo(_("%1$s %2$s: EOF"), con->id.c_str(), dir.c_str()); 161 | tx.shutdown(SHUT_WR); // shutdown() does not block 162 | con_open = false; 163 | if( !con->con_open_s_to_c && !con->con_open_c_to_s ) { 164 | // Connection fully closed, clean up 165 | kill_connection(EV_A_ con); 166 | } 167 | } else { // data has been read 168 | ev_io_start( EV_A_ e_tx_write ); 169 | } 170 | } catch( Errno &e ) { 171 | /* TRANSLATORS: %1$s contains the connection ID, 172 | %2$s contains the direction (separately translated), 173 | %3$s contains the error 174 | */ 175 | LogError(_("%1$s %2$s: Error: %3$s)"), con->id.c_str(), dir.c_str(), e.what()); 176 | kill_connection(EV_A_ con); 177 | } 178 | } 179 | 180 | static void client_ready_write(EV_P_ ev_io *w, int revents) { 181 | struct connection* con = reinterpret_cast( w->data ); 182 | assert( w == &con->e_c_write ); 183 | return peer_ready_write(EV_A_ con, _("S>C"), con->con_open_s_to_c, 184 | con->s_server, &con->e_s_read, 185 | con->buf_s_to_c, 186 | con->s_client, &con->e_c_write); 187 | } 188 | static void server_ready_write(EV_P_ ev_io *w, int revents) { 189 | struct connection* con = reinterpret_cast( w->data ); 190 | assert( w == &con->e_s_write ); 191 | return peer_ready_write(EV_A_ con, _("C>S"), con->con_open_c_to_s, 192 | con->s_client, &con->e_c_read, 193 | con->buf_c_to_s, 194 | con->s_server, &con->e_s_write); 195 | } 196 | 197 | static void client_ready_read(EV_P_ ev_io *w, int revents) { 198 | struct connection* con = reinterpret_cast( w->data ); 199 | assert( w == &con->e_c_read ); 200 | return peer_ready_read(EV_A_ con, _("C>S"), con->con_open_c_to_s, 201 | con->s_client, &con->e_c_read, 202 | con->buf_c_to_s, 203 | con->s_server, &con->e_s_write); 204 | } 205 | static void server_ready_read(EV_P_ ev_io *w, int revents) { 206 | struct connection* con = reinterpret_cast( w->data ); 207 | assert( w == &con->e_s_read ); 208 | return peer_ready_read(EV_A_ con, _("S>C"), con->con_open_s_to_c, 209 | con->s_server, &con->e_s_read, 210 | con->buf_s_to_c, 211 | con->s_client, &con->e_c_write); 212 | } 213 | 214 | 215 | static bool our_sockaddr(SockAddr::SockAddr const *destination) throw(Errno) { 216 | // Begin with quick checks 217 | if( destination->port_number() != bind_listen_addr->port_number() ) { 218 | return false; 219 | } 220 | 221 | if( ! bind_listen_addr->is_any() ) { 222 | if( *destination == *bind_listen_addr ) { 223 | // We've "intercepted" a connection that was directed to us 224 | return true; 225 | } 226 | } else { 227 | // Iterate over all local IPs 228 | // This can't be cached, since local IPs change over time 229 | std::auto_ptr< boost::ptr_vector< SockAddr::SockAddr> > local_addrs 230 | = SockAddr::getifaddrs(); 231 | for( typeof(local_addrs->begin()) i = local_addrs->begin(); i != local_addrs->end(); i++ ) { 232 | if( destination->address_equal(*i) ) return true; 233 | } 234 | } 235 | return false; 236 | } 237 | 238 | 239 | static void listening_socket_ready_for_read(EV_P_ ev_io *w, int revents) { 240 | Socket* s_listen = reinterpret_cast( w->data ); 241 | 242 | std::auto_ptr new_con( new struct connection ); 243 | 244 | std::auto_ptr client_addr; 245 | std::auto_ptr server_addr; 246 | try { 247 | new_con->s_client = s_listen->accept(&client_addr); 248 | //We do not want to buffer small packets, which could increase latency/jitter 249 | //for real time applications. Let them go out as they came in!! 250 | if(nodelay){ 251 | int val = 1; 252 | new_con->s_client.setsockopt(IPPROTO_TCP, TCP_NODELAY, (char *) &val, sizeof(val)); 253 | } 254 | //Take care of socks hanging in ESTABLISHED/CLOSE_WAIT/FIN_WAIT2 states 255 | if(keepalive){ 256 | int val = 1; 257 | new_con->s_client.setsockopt(SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); 258 | //LogInfo(_("%1$s: Enabling keepalive on s_client"), new_con->id.c_str()); 259 | } 260 | 261 | server_addr = new_con->s_client.getsockname(); 262 | 263 | new_con->id.assign( client_addr->string() ); 264 | new_con->id.append( "-->" ); 265 | new_con->id.append( server_addr->string() ); 266 | 267 | new_con->s_client.non_blocking(true); 268 | 269 | if( our_sockaddr(server_addr.get()) ) { 270 | /* TRANSLATORS: %1$s contains the connection ID 271 | */ 272 | LogWarn(_("%1$s: Connection directly to us, dropping"), new_con->id.c_str()); 273 | return; 274 | // Sockets will go out of scope, and close() themselves 275 | } 276 | 277 | /* TRANSLATORS: %1$s contains the connection ID 278 | */ 279 | LogInfo(_("%1$s: Connection intercepted"), new_con->id.c_str()); 280 | 281 | new_con->s_server = Socket::socket(server_addr->addr_family(), SOCK_STREAM, 0); 282 | if(nodelay){ 283 | int val = 1; 284 | new_con->s_server.setsockopt(IPPROTO_TCP, TCP_NODELAY, (char *) &val, sizeof(val)); 285 | } 286 | if(keepalive){ 287 | int val = 1; 288 | new_con->s_server.setsockopt(SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); 289 | //LogInfo(_("%1$s: Enabling keepalive on s_server"), new_con->id.c_str()); 290 | } 291 | 292 | if( bind_addr_outgoing.get() != NULL ) { 293 | new_con->s_server.bind( *bind_addr_outgoing ); 294 | } else { 295 | #if HAVE_DECL_IP_TRANSPARENT 296 | int value = 1; 297 | new_con->s_server.setsockopt(SOL_IP, IP_TRANSPARENT, &value, sizeof(value)); 298 | #endif 299 | new_con->s_server.bind( *client_addr ); 300 | } 301 | new_con->s_server.non_blocking(true); 302 | } catch( Errno &e ) { 303 | LogError(_("Error: %s"), e.what()); 304 | return; 305 | // Sockets will go out of scope, and close() themselves 306 | } 307 | 308 | ev_io_init( &new_con->e_s_connect, server_socket_connect_done, new_con->s_server, EV_WRITE ); 309 | ev_io_init( &new_con->e_c_read, client_ready_read, new_con->s_client, EV_READ ); 310 | ev_io_init( &new_con->e_c_write, client_ready_write, new_con->s_client, EV_WRITE ); 311 | ev_io_init( &new_con->e_s_read, server_ready_read, new_con->s_server, EV_READ ); 312 | ev_io_init( &new_con->e_s_write, server_ready_write, new_con->s_server, EV_WRITE ); 313 | new_con->e_s_connect.data = 314 | new_con->e_c_read.data = 315 | new_con->e_c_write.data = 316 | new_con->e_s_read.data = 317 | new_con->e_s_write.data = 318 | new_con.get(); 319 | new_con->con_open_c_to_s = new_con->con_open_s_to_c = true; 320 | 321 | try { 322 | new_con->s_server.connect( *server_addr ); 323 | // Connection succeeded right away, flag the callback right away 324 | ev_feed_event(EV_A_ &new_con->e_s_connect, 0); 325 | 326 | } catch( Errno &e ) { 327 | if( e.error_number() == EINPROGRESS ) { 328 | // connect() is started, wait for socket to become write-ready 329 | // Have libev call the callback 330 | ev_io_start( EV_A_ &new_con->e_s_connect ); 331 | 332 | } else { 333 | LogError(_("Error: %s"), e.what()); 334 | return; 335 | // Sockets will go out of scope, and close() themselves 336 | } 337 | } 338 | 339 | std::auto_ptr my_addr; 340 | my_addr = new_con->s_server.getsockname(); 341 | /* TRANSLATORS: %1$s contains the connection ID, 342 | %2$s the source address of the new connection, 343 | %3$s the destination address of the new connection 344 | */ 345 | LogInfo(_("%1$s: Connecting %2$s-->%3$s"), new_con->id.c_str(), 346 | my_addr->string().c_str(), server_addr->string().c_str()); 347 | 348 | connections.push_back( new_con.release() ); 349 | } 350 | 351 | const char* pidfile = NULL; 352 | const char* return_pidfile() { 353 | return pidfile; 354 | } 355 | 356 | int main(int argc, char* argv[]) { 357 | setlocale (LC_ALL, ""); 358 | bindtextdomain(PACKAGE, LOCALEDIR); 359 | textdomain(PACKAGE); 360 | 361 | // Default options 362 | struct { 363 | bool fork; 364 | std::string bind_addr_listen; 365 | std::string bind_addr_outgoing; 366 | } options = { 367 | /* fork = */ true, 368 | /* bind_addr_listen = */ "[0.0.0.0]:[5000]", 369 | /* bind_addr_outgoing = */ "[0.0.0.0]:[0]" 370 | }; 371 | 372 | { // Parse options 373 | char optstring[] = "hVknfp:b:B:l:"; 374 | struct option longopts[] = { 375 | {"help", no_argument, NULL, 'h'}, 376 | {"version", no_argument, NULL, 'V'}, 377 | {"keepalive", no_argument, NULL, 'k'}, 378 | {"tcp_nodelay", no_argument, NULL, 'n'}, 379 | {"foreground", no_argument, NULL, 'f'}, 380 | {"pid-file", required_argument, NULL, 'p'}, 381 | {"bind-listen", required_argument, NULL, 'b'}, 382 | {"bind-outgoing", required_argument, NULL, 'B'}, 383 | {"log", required_argument, NULL, 'l'}, 384 | {NULL, 0, 0, 0} 385 | }; 386 | int longindex; 387 | int opt; 388 | while( (opt = getopt_long(argc, argv, optstring, longopts, &longindex)) != -1 ) { 389 | switch(opt) { 390 | case 'h': 391 | case '?': 392 | std::cerr << _( 393 | // >---------------------- Standard terminal width ---------------------------------< 394 | "Options:\n" 395 | " -h --help Displays this help message and exits\n" 396 | " -V --version Displays the version and exits\n" 397 | " -k --keepalive Enable keepalive on the sockets\n" 398 | " -n --tcp_nodelay Disable Nagel's Algorithm on the sockets\n" 399 | " -f --foreground Don't fork and detach\n" 400 | " --pid-file -p file The file to write the PID to, especially\n" 401 | " usefull when running as a daemon. Must be an\n" 402 | " absolute path.\n" 403 | " --bind-listen -b host:port Bind to the specified address for incomming\n" 404 | " connections.\n" 405 | " host and port resolving can be bypassed by\n" 406 | " placing [] around them\n" 407 | " --bind-outgoing -B host:port Bind to the specified address for outgoing\n" 408 | " connections.\n" 409 | " host and port resolving can be bypassed by\n" 410 | " placing [] around them\n" 411 | " the special string \"client\" can be used to\n" 412 | " reuse the client's source address. Note that\n" 413 | " you should take care that the return packets\n" 414 | " pass through this process again!\n" 415 | " --log -l file Log to file\n" 416 | ); 417 | if( opt == '?' ) exit(EX_USAGE); 418 | exit(EX_OK); 419 | case 'V': 420 | printf(_("%1$s version %2$s\n" 421 | " configured with: %3$s\n" 422 | " CFLAGS=\"%4$s\" CXXFLAGS=\"%5$s\" CPPFLAGS=\"%6$s\"\n" 423 | " Options:\n" 424 | " IPv6: %7$s\n" 425 | "\n"), 426 | PACKAGE_NAME, PACKAGE_VERSION " (" PACKAGE_GITREVISION ")", 427 | CONFIGURE_ARGS, 428 | CFLAGS, CXXFLAGS, CPPFLAGS, 429 | #ifdef ENABLE_IPV6 430 | _("yes") 431 | #else 432 | _("no") 433 | #endif 434 | ); 435 | exit(EX_OK); 436 | case 'k': 437 | keepalive = true; 438 | break; 439 | case 'n': 440 | nodelay = true; 441 | break; 442 | case 'f': 443 | options.fork = false; 444 | break; 445 | case 'p': 446 | pidfile = optarg; 447 | break; 448 | case 'b': 449 | options.bind_addr_listen = optarg; 450 | break; 451 | case 'B': 452 | options.bind_addr_outgoing = optarg; 453 | break; 454 | case 'l': 455 | logfilename = optarg; 456 | logfile = fopen(logfilename.c_str(), "a"); 457 | LogSetOutputFile(NULL, logfile); 458 | break; 459 | } 460 | } 461 | } 462 | 463 | /* Set indetification string for the daemon for both syslog and PID file */ 464 | daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]); 465 | 466 | LogInfo(_("%1$s version %2$s starting up"), PACKAGE_NAME, PACKAGE_VERSION " (" PACKAGE_GITREVISION ")"); 467 | 468 | Socket s_listen; 469 | { // Open listening socket 470 | std::string host, port; 471 | 472 | /* Address format is 473 | * - hostname:portname 474 | * - [numeric ip]:portname 475 | * - hostname:[portnumber] 476 | * - [numeric ip]:[portnumber] 477 | */ 478 | size_t c = options.bind_addr_listen.rfind(":"); 479 | if( c == std::string::npos ) { 480 | /* TRANSLATORS: %1$s contains the string passed as option 481 | */ 482 | fprintf(stderr, _("Invalid bind string \"%1$s\": could not find ':'\n"), options.bind_addr_listen.c_str()); 483 | exit(EX_DATAERR); 484 | } 485 | host = options.bind_addr_listen.substr(0, c); 486 | port = options.bind_addr_listen.substr(c+1); 487 | 488 | std::auto_ptr< boost::ptr_vector< SockAddr::SockAddr> > bind_sa 489 | = SockAddr::resolve( host, port, 0, SOCK_STREAM, 0); 490 | if( bind_sa->size() == 0 ) { 491 | fprintf(stderr, _("Can not bind to \"%1$s\": Could not resolve\n"), options.bind_addr_listen.c_str()); 492 | exit(EX_DATAERR); 493 | } else if( bind_sa->size() > 1 ) { 494 | // TODO: allow this 495 | fprintf(stderr, _("Can not bind to \"%1$s\": Resolves to multiple entries:\n"), options.bind_addr_listen.c_str()); 496 | for( typeof(bind_sa->begin()) i = bind_sa->begin(); i != bind_sa->end(); i++ ) { 497 | std::cerr << " " << i->string() << "\n"; 498 | } 499 | exit(EX_DATAERR); 500 | } 501 | s_listen = Socket::socket( (*bind_sa)[0].proto_family() , SOCK_STREAM, 0); 502 | s_listen.set_reuseaddr(); 503 | s_listen.bind((*bind_sa)[0]); 504 | s_listen.listen(MAX_CONN_BACKLOG); 505 | 506 | #if HAVE_DECL_IP_TRANSPARENT 507 | int value = 1; 508 | s_listen.setsockopt(SOL_IP, IP_TRANSPARENT, &value, sizeof(value)); 509 | #endif 510 | 511 | /* TRANSLATORS: %1$s contains the listening address 512 | */ 513 | LogInfo(_("Listening on %s"), (*bind_sa)[0].string().c_str()); 514 | 515 | bind_listen_addr.reset( bind_sa->release(bind_sa->begin()).release() ); // Transfer ownership; TODO: this should be simpeler that double release() 516 | } 517 | 518 | if( options.bind_addr_outgoing == "client" ) { 519 | bind_addr_outgoing.reset(NULL); 520 | LogInfo(_("Outgoing connections will connect from original source address")); 521 | } else { // Resolve client address 522 | std::string host, port; 523 | 524 | /* Address format is 525 | * - hostname:portname 526 | * - [numeric ip]:portname 527 | * - hostname:[portnumber] 528 | * - [numeric ip]:[portnumber] 529 | */ 530 | size_t c = options.bind_addr_outgoing.rfind(":"); 531 | if( c == std::string::npos ) { 532 | /* TRANSLATORS: %1$s contains the string passed as option 533 | */ 534 | fprintf(stderr, _("Invalid bind string \"%1$s\": could not find ':'\n"), options.bind_addr_outgoing.c_str()); 535 | exit(EX_DATAERR); 536 | } 537 | host = options.bind_addr_outgoing.substr(0, c); 538 | port = options.bind_addr_outgoing.substr(c+1); 539 | 540 | std::auto_ptr< boost::ptr_vector< SockAddr::SockAddr> > bind_sa 541 | = SockAddr::resolve( host, port, 0, SOCK_STREAM, 0); 542 | if( bind_sa->size() == 0 ) { 543 | fprintf(stderr, _("Can not bind to \"%1$s\": Could not resolve\n"), options.bind_addr_outgoing.c_str()); 544 | exit(EX_DATAERR); 545 | } else if( bind_sa->size() > 1 ) { 546 | fprintf(stderr, _("Can not bind to \"%1$s\": Resolves to multiple entries:\n"), options.bind_addr_outgoing.c_str()); 547 | for( typeof(bind_sa->begin()) i = bind_sa->begin(); i != bind_sa->end(); i++ ) { 548 | std::cerr << " " << i->string() << "\n"; 549 | } 550 | exit(EX_DATAERR); 551 | } 552 | bind_addr_outgoing.reset( bind_sa->release(bind_sa->begin()).release() ); // Transfer ownership; TODO: this should be simpeler that double release() 553 | 554 | LogInfo(_("Outgoing connections will connect from %1$s"), bind_addr_outgoing->string().c_str()); 555 | } 556 | 557 | if( options.fork ) { 558 | /* Prepare for return value passing from the initialization procedure of the daemon process */ 559 | if (daemon_retval_init() < 0) { 560 | LogError(_("Failed to create pipe.")); 561 | exit(EX_OSERR); 562 | } 563 | 564 | pid_t child = daemon_fork(); 565 | if( child < 0 ) { 566 | LogError(_("Could not fork(): %s"), strerror(errno)); 567 | daemon_retval_done(); 568 | exit(EX_OSERR); 569 | } else if( child > 0 ) { // parent 570 | int ret; 571 | /* Wait for 20 seconds for the return value passed from the daemon process */ 572 | if ((ret = daemon_retval_wait(20)) < 0) { 573 | LogError(_("Could not recieve return value from daemon process: %s"), strerror(errno)); 574 | exit(EX_OSERR); 575 | } 576 | LogInfo(_("Child process [%1$d] forked succesfully, it signaled %2$d"), child, ret); 577 | exit(ret); 578 | } 579 | // Child continues 580 | 581 | /* Close all FDs; 0, 1 and 2 are kept open anyway and point to 582 | * /dev/null (done by daemon_fork()) */ 583 | daemon_close_all(s_listen, fileno(logfile), -1); 584 | } 585 | 586 | if( pidfile != NULL ) { // PID-file 587 | daemon_pid_file_proc = return_pidfile; 588 | if( daemon_pid_file_create() ) { 589 | daemon_retval_send(EX_OSERR); 590 | exit(EX_OSERR); 591 | } 592 | } 593 | 594 | // Let our parent know that we're doing fine 595 | daemon_retval_send(0); 596 | 597 | { 598 | ev_signal ev_sigint_watcher; 599 | ev_signal_init( &ev_sigint_watcher, received_sigint, SIGINT); 600 | ev_signal_start( EV_DEFAULT_ &ev_sigint_watcher); 601 | 602 | ev_signal ev_sigterm_watcher; 603 | ev_signal_init( &ev_sigterm_watcher, received_sigterm, SIGTERM); 604 | ev_signal_start( EV_DEFAULT_ &ev_sigterm_watcher); 605 | 606 | ev_signal ev_sighup_watcher; 607 | ev_signal_init( &ev_sighup_watcher, received_sighup, SIGHUP); 608 | ev_signal_start( EV_DEFAULT_ &ev_sighup_watcher); 609 | 610 | ev_signal ev_sigpipe_watcher; 611 | ev_signal_init( &ev_sigpipe_watcher, received_sigpipe, SIGPIPE); 612 | ev_signal_start( EV_DEFAULT_ &ev_sigpipe_watcher); 613 | 614 | 615 | ev_io e_listen; 616 | e_listen.data = &s_listen; 617 | ev_io_init( &e_listen, listening_socket_ready_for_read, s_listen, EV_READ ); 618 | ev_io_start( EV_DEFAULT_ &e_listen ); 619 | 620 | LogInfo(_("Setup done, starting event loop")); 621 | try { 622 | ev_run(EV_DEFAULT_ 0); 623 | } catch( std::exception &e ) { 624 | std::cerr << e.what() << "\n"; 625 | return EX_SOFTWARE; 626 | } 627 | } 628 | 629 | LogInfo(_("Exiting cleanly...")); 630 | daemon_pid_file_remove(); 631 | return EX_OK; 632 | } 633 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | dist_check_SCRIPTS = simply-run.sh 2 | 3 | check_PROGRAMS = 4 | TESTS = simply-run.sh $(check_PROGRAMS) 5 | -------------------------------------------------------------------------------- /test/simply-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # fail fast 4 | 5 | ../src/tcp-intercept -V 6 | --------------------------------------------------------------------------------