1 2 /*-------------------------------------------------------------*/ 3 /*************************************************************** 4 * A netwib_io is the main way to exchange data in netwib. * 5 * * 6 * A concrete example first : * 7 * ----. ,-----. ,-------. ,----. ,------ * 8 * file >---->readl >---( program )---->conv >---->socket * 9 * ----' `-----' `-------' `----' `------ * 10 * * 11 * It works like this : * 12 * - read data from a file * 13 * - read only line by line * 14 * - treat it in the program * 15 * - write data for output * 16 * - convert data, for example replacing '\' by "\\" * 17 * - write data to socket * 18 * * 19 * This example contains 3 types of netwib_io : * 20 * - file and socket are "io final link" * 21 * - readl and conv are "io link" * 22 * - file and socket are also "io link" (because a * 23 * "io final link" is a special kind of "io link") * 24 * - conv is a "io chain" composed of conv+socket * 25 * - readl is a "io chain" composed of readl+file * 26 * - socket is a "io chain" composed of only socket * 27 * - file is a "io chain" composed of only file * 28 * * 29 * Using the same program, we might for example read data * 30 * from a file and write them back to a socket. This can be * 31 * represented as : * 32 * ------. ,-------. ,--------- * 33 * file >----( program )-----> socket * 34 * ------' `-------' `--------- * 35 * Another variant would be to plug readl or conv to other * 36 * "io chain", such as : * 37 * ----. ,-----. ,-------. ,----. ,------ * 38 * ipc >---->readl >---( program )---->conv >---->record * 39 * ----' `-----' `-------' `----' `------ * 40 * An "io chain" can be bi-directional. For example : * 41 * --------. ,--. ,-------. * 42 * socket >------>l5 >----( program )-. * 43 * <------< <--. `-------' | * 44 * --------' `--' `-------------' * 45 * * 46 * Note : you can find other examples at the end of this file * 47 * * 48 * The main ideas to remember is : * 49 * - a "io chain" is composed of one or more "io link" * 50 * - a "io link" might be intermediary or "io final link" * 51 * - those 3 types use the same structure : netwib_io * 52 ***************************************************************/ 53 54 /*-------------------------------------------------------------*/ 55 typedef struct netwib_io netwib_io; 56 57 /*-------------------------------------------------------------*/ 58 /* direction */ 59 typedef enum { 60 NETWIB_IO_WAYTYPE_READ = 1, /* read */ 61 NETWIB_IO_WAYTYPE_WRITE, /* write */ 62 NETWIB_IO_WAYTYPE_RDWR, /* read and write */ 63 NETWIB_IO_WAYTYPE_NONE, /* nor read nor write */ 64 NETWIB_IO_WAYTYPE_SUPPORTED /* every way supported by the io */ 65 } netwib_io_waytype; 66 67 /*-------------------------------------------------------------*/ 68 /*************************************************************** 69 * Currently, system "io final link" are : * 70 * Name Definition Read/Write * 71 * FILE : regular file : read/write * 72 * FD : file desc : read/write * 73 * HANDLE : Windows HANDLE : read/write * 74 * KBD : keyboard : read * 75 * RECORD : record : read/write * 76 * SOCK : socket : read/write * 77 * SNIFF : sniff : read * 78 * SPOOF : spoof : write * 79 * They are initialized by : * 80 * - netwib_io_init_file * 81 * - netwib_io_init_fd * 82 * - etc. * 83 ***************************************************************/ 84 85 /*-------------------------------------------------------------*/ 86 /*************************************************************** 87 * Those five functions permits to create and to navigate * 88 * through a "io chain". * 89 ***************************************************************/ 90 91 /*-------------------------------------------------------------*/ 92 /* Name : netwib_io_plug 93 Description : 94 Create a chain by pluging one link/chain to another. 95 Input parameter(s) : 96 *piowheretoplug : io where to plug 97 typeofplug : type of plug 98 Input/output parameter(s) : 99 *pio : current io 100 Output parameter(s) : 101 Normal return values : 102 NETWIB_ERR_OK : ok 103 */ 104 netwib_err netwib_io_plug(netwib_io *pio, 105 netwib_io_waytype typeofplug, 106 netwib_io *piowheretoplug); 107 /* netwib_err f(netwib_io *pio, netwib_io *piowheretoplug); */ 108 #define netwib_io_plug_read(pio,piowheretoplug) netwib_io_plug(pio,NETWIB_IO_WAYTYPE_READ,piowheretoplug) 109 #define netwib_io_plug_write(pio,piowheretoplug) netwib_io_plug(pio,NETWIB_IO_WAYTYPE_WRITE,piowheretoplug) 110 #define netwib_io_plug_rdwr(pio,piowheretoplug) netwib_io_plug(pio,NETWIB_IO_WAYTYPE_RDWR,piowheretoplug) 111 #define netwib_io_plug_supported(pio,piowheretoplug) netwib_io_plug(pio,NETWIB_IO_WAYTYPE_SUPPORTED,piowheretoplug) 112 113 /*-------------------------------------------------------------*/ 114 /*************************************************************** 115 * There are three ways to unplug : * 116 * ,----. ,----. ,----. ,----. ,----. * 117 * ---> io1 >----> io2 >----> io3 >----> io4 >----> io5 >-- * 118 * `----' `----' `----' `----' `----' * 119 * * 120 * netwib_io_unplug_next with: * 121 * pio = &io1 * 122 * ==> cut between io1 and io2, and put &io2 in pnextio * 123 * * 124 * netwib_io_unplug_before with: * 125 * pio = &io1 * 126 * psearchedio = &io3 * 127 * ==> cut between io2 and io3 * 128 * * 129 * netwib_io_unplug_after with: * 130 * pio = &io1 * 131 * psearchedio = &io3 * 132 * ==> cut between io3 and io4, and put &io4 in pafterio * 133 ***************************************************************/ 134 135 /*-------------------------------------------------------------*/ 136 /* Name : netwib_io_unplug_xyz 137 Description : 138 Separate a chain by unplugging one link/chain from another. 139 Input parameter(s) : 140 typeofplug : type of plug 141 *psearchedio : searched io 142 Input/output parameter(s) : 143 *pio : io chain 144 Output parameter(s) : 145 **ppnextio : next io or NULL if at end 146 **ppafterio : next io or NULL if at end 147 Normal return values : 148 NETWIB_ERR_OK : ok 149 NETWIB_ERR_NOTFOUND : psearchedio was not found 150 */ 151 netwib_err netwib_io_unplug_next(netwib_io *pio, 152 netwib_io_waytype typeofplug, 153 netwib_io **ppnextio); 154 netwib_err netwib_io_unplug_before(netwib_io *pio, 155 netwib_io_waytype typeofplug, 156 netwib_io *psearchedio); 157 netwib_err netwib_io_unplug_after(netwib_io *pio, 158 netwib_io_waytype typeofplug, 159 netwib_io *psearchedio, 160 netwib_io **ppafterio); 161 #define netwib_io_unplug_next_read(pio,ppnextio) netwib_io_unplug_next(pio,NETWIB_IO_WAYTYPE_READ,ppnextio) 162 #define netwib_io_unplug_before_read(pio,psearchedio) netwib_io_unplug_before(pio,NETWIB_IO_WAYTYPE_READ,psearchedio) 163 #define netwib_io_unplug_after_read(pio,psearchedio,ppafterio) netwib_io_unplug_after(pio,NETWIB_IO_WAYTYPE_READ,psearchedio,ppafterio) 164 #define netwib_io_unplug_next_write(pio,ppnextio) netwib_io_unplug_next(pio,NETWIB_IO_WAYTYPE_WRITE,ppnextio) 165 #define netwib_io_unplug_before_write(pio,psearchedio) netwib_io_unplug_before(pio,NETWIB_IO_WAYTYPE_WRITE,psearchedio) 166 #define netwib_io_unplug_after_write(pio,psearchedio,ppafterio) netwib_io_unplug_after(pio,NETWIB_IO_WAYTYPE_WRITE,psearchedio,ppafterio) 167 #define netwib_io_unplug_next_rdwr(pio,ppnextio) netwib_io_unplug_next(pio,NETWIB_IO_WAYTYPE_RDWR,ppnextio) 168 #define netwib_io_unplug_before_rdwr(pio,psearchedio) netwib_io_unplug_before(pio,NETWIB_IO_WAYTYPE_RDWR,psearchedio) 169 #define netwib_io_unplug_after_rdwr(pio,psearchedio,ppafterio) netwib_io_unplug_after(pio,NETWIB_IO_WAYTYPE_RDWR,psearchedio,ppafterio) 170 #define netwib_io_unplug_next_supported(pio,ppnextio) netwib_io_unplug_next(pio,NETWIB_IO_WAYTYPE_SUPPORTED,ppnextio) 171 #define netwib_io_unplug_before_supported(pio,psearchedio) netwib_io_unplug_before(pio,NETWIB_IO_WAYTYPE_SUPPORTED,psearchedio) 172 #define netwib_io_unplug_after_supported(pio,psearchedio,ppafterio) netwib_io_unplug_after(pio,NETWIB_IO_WAYTYPE_SUPPORTED,psearchedio,ppafterio) 173 174 /*-------------------------------------------------------------*/ 175 /* Name : netwib_io_next 176 Description : 177 Obtain the next io in the chain. 178 Input parameter(s) : 179 *pio : io 180 Input/output parameter(s) : 181 **ppionext : io after pio of type typetofollow 182 Output parameter(s) : 183 Normal return values : 184 NETWIB_ERR_OK : ok 185 NETWIB_ERR_DATAEND : there is no more io after 186 */ 187 netwib_err netwib_io_next(netwib_io *pio, 188 netwib_io_waytype typetofollow, 189 netwib_io **ppionext); 190 /* netwib_err f(netwib_io *pio, netwib_io *pionext); */ 191 #define netwib_io_next_read(pio,pionext) netwib_io_next(pio,NETWIB_IO_WAYTYPE_READ,pionext) 192 #define netwib_io_next_write(pio,pionext) netwib_io_next(pio,NETWIB_IO_WAYTYPE_WRITE,pionext) 193 #define netwib_io_next_rdwr(pio,pionext) netwib_io_next(pio,NETWIB_IO_WAYTYPE_RDWR,pionext) 194 #define netwib_io_next_supported(pio,pionext) netwib_io_next(pio,NETWIB_IO_WAYTYPE_SUPPORTED,pionext) 195 196 /*-------------------------------------------------------------*/ 197 /*************************************************************** 198 * Those three functions permits to exchange data through a * 199 * "io chain". * 200 ***************************************************************/ 201 202 /*-------------------------------------------------------------*/ 203 /* Name : netwib_io_write_xyz 204 Description : 205 Write data to a netwib_io. 206 Input parameter(s) : 207 *pbuf : buffer to write 208 Input/output parameter(s) : 209 **pio : netwib_io where to write 210 Output parameter(s) : 211 Normal return values : 212 NETWIB_ERR_OK : ok 213 */ 214 netwib_err netwib_io_write(netwib_io *pio, 215 netwib_constbuf *pbuf); 216 217 /*-------------------------------------------------------------*/ 218 /* Name : netwib_io_read_xyz 219 Description : 220 Read data to a netwib_io. 221 Input parameter(s) : 222 Input/output parameter(s) : 223 **pio : netwib_io where to read 224 *pbuf : buffer storing read data 225 Output parameter(s) : 226 Normal return values : 227 NETWIB_ERR_OK : ok 228 NETWIB_ERR_DATAEND : end of data 229 */ 230 netwib_err netwib_io_read(netwib_io *pio, 231 netwib_buf *pbuf); 232 233 /*-------------------------------------------------------------*/ 234 /* Name : netwib_io_unread 235 Description : 236 Put data back in the read io. 237 Input parameter(s) : 238 Input/output parameter(s) : 239 **pio : netwib_io where to read 240 *pbuf : buffer containing data 241 Output parameter(s) : 242 Normal return values : 243 NETWIB_ERR_OK : ok 244 */ 245 netwib_err netwib_io_unread(netwib_io *pio, 246 netwib_constbuf *pbuf); 247 248 /*-------------------------------------------------------------*/ 249 /*************************************************************** 250 * Those three functions permits to control an "io chain". * 251 ***************************************************************/ 252 253 /*-------------------------------------------------------------*/ 254 /* Name : netwib_io_wait 255 Description : 256 Wait for data in the io. 257 Input parameter(s) : 258 *pabstime : end time. If *pabstime is reached, function 259 returns (*pevent set to NETWIB_FALSE). 260 Input/output parameter(s) : 261 **pio : netwib_io where to wait 262 Output parameter(s) : 263 *pevent : an event occurred 264 Normal return values : 265 NETWIB_ERR_OK : ok 266 */ 267 netwib_err netwib_io_wait(netwib_io *pio, 268 netwib_io_waytype way, 269 netwib_consttime *pabstime, 270 netwib_bool *pevent); 271 /* netwib_err f(netwib_io *pio, netwib_consttime *pabstime, netwib_bool *pevent); */ 272 #define netwib_io_wait_read(pio,pabstime,pevent) netwib_io_wait(pio,NETWIB_IO_WAYTYPE_READ,pabstime,pevent) 273 #define netwib_io_wait_write(pio,pabstime,pevent) netwib_io_wait(pio,NETWIB_IO_WAYTYPE_WRITE,pabstime,pevent) 274 #define netwib_io_wait_rdwr(pio,pabstime,pevent) netwib_io_wait(pio,NETWIB_IO_WAYTYPE_RDWR,pabstime,pevent) 275 #define netwib_io_wait_supported(pio,pabstime,pevent) netwib_io_wait(pio,NETWIB_IO_WAYTYPE_SUPPORTED,pabstime,pevent) 276 277 /*-------------------------------------------------------------*/ 278 /* Explaining those values would be too complicated here. Please 279 refer to the defines using them (which are documented). 280 */ 281 typedef enum { 282 /** values working on current io (they are not recursive) **/ 283 NETWIB_IO_CTLTYPE_SUPPORT = 1, 284 NETWIB_IO_CTLTYPE_NUMUSERS, 285 NETWIB_IO_CTLTYPE_NUMUSERSINC, 286 /** values working on current io (if NETWIB_ERR_OK is returned) or 287 on next io (if NETWIB_ERR_PLEASETRYNEXT is returned) **/ 288 NETWIB_IO_CTLTYPE_RES = 100, 289 NETWIB_IO_CTLTYPE_END, 290 /** values which are specific **/ 291 /* file : 200 */ 292 NETWIB_IO_CTLTYPE_FILE_SEEK_BEGIN = 200, 293 NETWIB_IO_CTLTYPE_FILE_SEEK_CURRENT, 294 NETWIB_IO_CTLTYPE_FILE_SEEK_END, 295 NETWIB_IO_CTLTYPE_FILE_TELL, 296 NETWIB_IO_CTLTYPE_FILE_TRUNCATE, 297 /* fd : 300 */ 298 /* handle : 400 */ 299 /* ipc : 500 */ 300 NETWIB_IO_CTLTYPE_IPC_SIDEREAD = 500, 301 NETWIB_IO_CTLTYPE_IPC_SIDEWRITE, 302 NETWIB_IO_CTLTYPE_IPC_NOTUSED, 303 /* kbd : 600 */ 304 NETWIB_IO_CTLTYPE_KBD_ECHO = 600, 305 NETWIB_IO_CTLTYPE_KBD_LINE, 306 NETWIB_IO_CTLTYPE_KBD_PURGE, 307 /* record : 700 */ 308 /* sock : 800 */ 309 NETWIB_IO_CTLTYPE_SOCK_IP4OPTS = 800, 310 NETWIB_IO_CTLTYPE_SOCK_IP6EXTS, 311 NETWIB_IO_CTLTYPE_SOCK_LOCAL, 312 NETWIB_IO_CTLTYPE_SOCK_REMOTE, 313 NETWIB_IO_CTLTYPE_SOCK_MULTICASTTTL, 314 NETWIB_IO_CTLTYPE_SOCK_SOCKTYPE, 315 /* sockv : 900 */ 316 NETWIB_IO_CTLTYPE_SOCKV_ANSWERALIVE = 900, 317 /* sniff : 1000 */ 318 NETWIB_IO_CTLTYPE_SNIFF_FILTER = 1000, 319 NETWIB_IO_CTLTYPE_SNIFF_DLT, 320 /* spoof : 1100 */ 321 NETWIB_IO_CTLTYPE_SPOOF_DLT= 1100, 322 /** values which are specific to iousual.h **/ 323 /* ioutil : 2000 */ 324 NETWIB_IO_CTLTYPE_DATA_LINE_MSDOS = 2000, 325 NETWIB_IO_CTLTYPE_DATA_CHUNK_MINSIZE, 326 NETWIB_IO_CTLTYPE_DATA_CHUNK_MAXSIZE, 327 NETWIB_IO_CTLTYPE_DATA_FIXED_SIZE, 328 NETWIB_IO_CTLTYPE_DATA_TYPE, 329 NETWIB_IO_CTLTYPE_STORAGE_FLUSH, 330 /** values which are specific to users' utilities **/ 331 /* user defined : start at 10000 */ 332 NETWIB_IO_CTLTYPE_USER_BEGIN = NETWIB_ENUM_USER_BEGIN 333 } netwib_io_ctltype; 334 /* Those functions permit to set/get parameters (pointer and 335 integer) about a netwib_io. It should not be used directly, 336 but by the defines. 337 In function netwib_io_ctl_get, parameter p could be 338 a "netwib_ptr *pp" instead of "netwib_ptr p", but it 339 complicates things for nothing : a pointer can be 340 used for what we want. For example, its easier to use 341 ctl_get(..., &buf, &ui) instead of ("&&buf", &ui). 342 */ 343 netwib_err netwib_io_ctl_set(netwib_io *pio, 344 netwib_io_waytype way, 345 netwib_io_ctltype ctltype, 346 netwib_ptr p, 347 netwib_uint32 ui); 348 netwib_err netwib_io_ctl_get(netwib_io *pio, 349 netwib_io_waytype way, 350 netwib_io_ctltype ctltype, 351 netwib_ptr p, 352 netwib_uint32 *pui); 353 354 /*-------------------------------------------------------------*/ 355 /*************************************************************** 356 * This function permits to close an "io chain". * 357 ***************************************************************/ 358 359 /*-------------------------------------------------------------*/ 360 /* Name : netwib_io_close 361 Description : 362 Close a chain (links are closed only if nobody use them 363 anymore : numusers == 0). 364 Input parameter(s) : 365 Input/output parameter(s) : 366 **ppio : netwib_io to close 367 Output parameter(s) : 368 Normal return values : 369 NETWIB_ERR_OK : ok 370 */ 371 netwib_err netwib_io_close(netwib_io **ppio); 372 373 /*-------------------------------------------------------------*/ 374 /*************************************************************** 375 * Common control defines * 376 ***************************************************************/ 377 378 /*-------------------------------------------------------------*/ 379 typedef enum { 380 NETWIB_IO_RESTYPE_FILE = 1, 381 NETWIB_IO_RESTYPE_FD, 382 NETWIB_IO_RESTYPE_HANDLE, 383 NETWIB_IO_RESTYPE_IPC, 384 NETWIB_IO_RESTYPE_KBD, 385 NETWIB_IO_RESTYPE_SCREEN, 386 NETWIB_IO_RESTYPE_STREAM, 387 NETWIB_IO_RESTYPE_RECORD, 388 NETWIB_IO_RESTYPE_SOCK, 389 NETWIB_IO_RESTYPE_SOCKV, 390 NETWIB_IO_RESTYPE_SNIFF, 391 NETWIB_IO_RESTYPE_SPOOF, 392 NETWIB_IO_RESTYPE_NULL, 393 NETWIB_IO_RESTYPE_MEM, 394 NETWIB_IO_RESTYPE_TLV, 395 NETWIB_IO_RESTYPE_EXEC, 396 NETWIB_IO_RESTYPE_SHELLSERVER, 397 NETWIB_IO_RESTYPE_SHELLCLIENT, 398 NETWIB_IO_RESTYPE_USER_BEGIN = NETWIB_ENUM_USER_BEGIN 399 } netwib_io_restype; 400 /* Obtain the resource type of a netwib_io */ 401 /* netwib_err f(netwib_io *pio, netwib_io_waytype way, netwib_io_restype *pres); */ 402 #define netwib_io_ctl_get_res(pio,way,pres) netwib_io_ctl_get(pio,way,NETWIB_IO_CTLTYPE_RES,NULL,(netwib_uint32*)pres) 403 404 /*-------------------------------------------------------------*/ 405 /* indicate the end of data */ 406 /* netwib_err f(netwib_io *pio, netwib_io_waytype way); */ 407 #define netwib_io_ctl_set_end(pio,way) netwib_io_ctl_set(pio,way,NETWIB_IO_CTLTYPE_END,NULL,0) 408 #define netwib_io_ctl_set_end_write(pio) netwib_io_ctl_set_end(pio,NETWIB_IO_WAYTYPE_WRITE) 409 410 411 /*-------------------------------------------------------------*/ 412 /*************************************************************** 413 * Now, a big example ... * 414 ***************************************************************/ 415 416 /*-------------------------------------------------------------*/ 417 /*-------------------------------------------------------------*/ 418 #if 0 419 /* Complete example : 420 421 We create a module (named m) having one input (i1) and two 422 outputs (o1, o2) : 423 424 ############# m ############# 425 # # 426 # ooooooooo # o1 427 i1 # ,--. o o---------------> 428 >-------->l1 >--o HEART o ,--. # 429 # `--' o o--->l2 >-------> 430 # ooooooooo `--' # o2 431 # # 432 ############################# 433 434 The module contains 2 ios : 435 - l1 : reads line by line 436 - l2 : converts data to base64 437 438 The heart of the module reads data from l1's output. If the 439 data starts by 'A', then it is sent to o1. Else, data goes 440 through l2. 441 442 *** Usage 1 : 443 - i1 is plugged to a file through io l3 444 - o1 is plugged to file2 445 - o2 is plugged to file3 through io l4 446 - l3 reads data and duplicates it (read 'qa', output 'qqaa') 447 - l4 reads data, displays it to screen and sends to output 448 ,------- 449 ##### ,-------> file2 450 -------. ,--. # >------' `------- 451 file1 >----->l3 >------> m # ,--. ,------- 452 -------' `--' # >----->l4 >-----> file3 453 ##### `--' `------- 454 455 *** Usage 2 : 456 - i1 is plugged to socket soc1 457 - o1 is plugged to null (data is junked) 458 - o2 is plugged back to the same socket 459 ##### ,------ 460 ------. # >---------------> null 461 soc1 >-----------------> m # `------ 462 <-------. # >----. 463 ------' \ ##### | 464 `-----------------' 465 466 *** Usage 3 : 467 - i1 is plugged to a socket through io l3 468 - o1 is plugged to null (data is junked) 469 - o2 is plugged back to the same socket through io l4 470 ##### ,------ 471 ,--. # >---------------> null 472 ------. ,-->l3 >------> m # `------ 473 soc1 >--' `--' # >----. 474 <--. ,--. ##### | 475 ------' `--< l4<----------------' 476 `--' 477 478 *** Usage 4 : 479 - l5 is a bi-directional io converting string to uppercase 480 - l5 is plugged to socket soc1 481 - i1 is plugged to l5 482 - o1 is plugged to null (data is junked) 483 - o2 is plugged back to l5 484 ##### ,------ 485 # >---------------> null 486 ------. ,--. ,--> m # `------ 487 soc1 >------>l5 >--' # >----. 488 <------< <--. ##### | 489 ------' `--' `------------' 490 491 *** Usage 5 : 492 - i1 is plugged to file1 through l5 493 - o1 is plugged to null (data is junked) 494 - o2 is plugged to file2 through l5 495 ##### ,------ 496 -------. # >---------------> null 497 file1 >--. ,--. ,--> m # `------ 498 -------' `-->l5 >--' # >----. 499 -------. ,--< <--. ##### | 500 file2 <--' `--' `------------' 501 -------' 502 503 *** Usage 6 : 504 - i1 is plugged to file1 505 - o1 are o2 are both plugged to file2 506 ##### 507 -------. # >------------. ,------- 508 file1 >----------------> m # --> file2 509 -------' # >------------' `------- 510 ##### 511 512 *** Usage 7 : 513 - m2 is a module similar to m except it has 2 inputs 514 and one output 515 - i1 is plugged to file1 516 - i2 is plugged to file1 517 - o1 is plugged to null (data is junked) 518 - o2 is plugged to file2 519 ##### 520 -------. ,-------------> # ,------ 521 file1 >-- # m >---------------> null 522 -------' `-------------> # `------ 523 ##### 524 525 */ 526 527 /*-------------------------------------------------------------*/ 528 /* l1 is netwib_io_init_read_line */ 529 530 /*-------------------------------------------------------------*/ 531 /* l2 : converts data to base64 */ 532 netwib_err l2_write(netwib_io *pio, 533 netwib_constbuf *pbuf); 534 netwib_err l2_write(netwib_io *pio, 535 netwib_constbuf *pbuf) 536 { 537 netwib_buf bufbase64; 538 netwib_io *pionext; 539 netwib_err ret; 540 541 /* obtain the next io in the chain */ 542 netwib_er(netwib_io_next_write(pio, &pionext)); 543 544 /* converts pbuf to base64 */ 545 netwib_er(netwib_buf_init_mallocdefault(&bufbase64)); 546 netwib_er(netwib_buf_encode(pbuf, NETWIB_ENCODETYPE_BASE64, &bufbase64)); 547 548 /* write data to the next io */ 549 ret = netwib_io_write(pionext, &bufbase64); 550 netwib_er(netwib_buf_close(&bufbase64)); 551 552 return(ret); 553 } 554 555 netwib_err l2_init(netwib_io **ppio); 556 netwib_err l2_init(netwib_io **ppio) 557 { 558 netwib_er(netwib_io_init(NETWIB_FALSE, NETWIB_TRUE, NULL, 559 NULL/*read*/, &l2_write, 560 NULL/*wait*/, NULL/*unread*/, 561 NULL/*ctlset*/, NULL/*ctlget*/, 562 NULL/*close*/, ppio)); 563 return(NETWIB_ERR_OK); 564 } 565 566 /*-------------------------------------------------------------*/ 567 /* l3 reads data and duplicates it (read 'qa', output 'qqaa') */ 568 netwib_err l3_dup(netwib_constbuf *pinbuf, 569 netwib_buf *poutbuf); 570 netwib_err l3_dup(netwib_constbuf *pinbuf, 571 netwib_buf *poutbuf) 572 { 573 netwib_data data; 574 netwib_uint32 datasize, i; 575 576 data = netwib__buf_ref_data_ptr(pinbuf); 577 datasize = netwib__buf_ref_data_size(pinbuf); 578 for (i = 0; i < datasize; i++) { 579 netwib_er(netwib_buf_append_byte(data[i], poutbuf)); 580 netwib_er(netwib_buf_append_byte(data[i], poutbuf)); 581 } 582 583 return(NETWIB_ERR_OK); 584 } 585 netwib_err l3_read(netwib_io *pio, 586 netwib_buf *pbuf); 587 netwib_err l3_read(netwib_io *pio, 588 netwib_buf *pbuf) 589 { 590 netwib_buf buf; 591 netwib_io *pionext; 592 593 /* obtain the next io in the chain */ 594 netwib_er(netwib_io_next_read(pio, &pionext)); 595 596 /* read data */ 597 netwib_er(netwib_buf_init_mallocdefault(&buf)); 598 netwib_er(netwib_io_read(pionext, &buf)); 599 600 /* duplicate buf */ 601 netwib_er(l3_dup(&buf, pbuf)); 602 netwib_er(netwib_buf_close(&buf)); 603 604 return(NETWIB_ERR_OK); 605 } 606 netwib_err l3_init(netwib_io **ppio); 607 netwib_err l3_init(netwib_io **ppio) 608 { 609 netwib_er(netwib_io_init(NETWIB_FALSE, NETWIB_TRUE, NULL, 610 &l3_read/*read*/, NULL/*write*/, 611 NULL/*wait*/, NULL/*unread*/, 612 NULL/*ctlset*/, NULL/*ctlget*/, 613 NULL/*close*/, ppio)); 614 615 return(NETWIB_ERR_OK); 616 } 617 618 /*-------------------------------------------------------------*/ 619 /* l4 reads data, displays it to screen and sends to output */ 620 netwib_err l4_write(netwib_io *pio, 621 netwib_constbuf *pbuf); 622 netwib_err l4_write(netwib_io *pio, 623 netwib_constbuf *pbuf) 624 { 625 netwib_buf bufbase64; 626 netwib_io *pionext; 627 netwib_err ret; 628 629 /* obtain the next io in the chain */ 630 netwib_er(netwib_io_next_write(pio, &pionext)); 631 632 /* display it */ 633 netwib_er(netwib_buf_display(pbuf, NETWIB_ENCODETYPE_DUMP)); 634 635 /* write data to the next io */ 636 ret = netwib_io_write(pionext, pbuf); 637 638 return(ret); 639 } 640 641 netwib_err l4_init(netwib_io **ppio); 642 netwib_err l4_init(netwib_io **ppio) 643 { 644 netwib_er(netwib_io_init(NETWIB_FALSE, NETWIB_TRUE, NULL, 645 NULL/*read*/, &l4_write, 646 NULL/*wait*/, NULL/*unread*/, 647 NULL/*ctlset*/, NULL/*ctlget*/, 648 NULL/*close*/, ppio)); 649 650 return(NETWIB_ERR_OK); 651 } 652 653 /*-------------------------------------------------------------*/ 654 /* l5 convert data to uppercase */ 655 netwib_err l5_up(netwib_constbuf *pinbuf, 656 netwib_buf *poutbuf); 657 netwib_err l5_up(netwib_constbuf *pinbuf, 658 netwib_buf *poutbuf) 659 { 660 netwib_data data; 661 netwib_uint32 datasize, i; 662 netwib_byte c; 663 664 data = netwib__buf_ref_data_ptr(pinbuf); 665 datasize = netwib__buf_ref_data_size(pinbuf); 666 for (i = 0; i < datasize; i++) { 667 c = data[i]; 668 netwib_c2_upper(c); 669 netwib_er(netwib_buf_append_byte(c, poutbuf)); 670 } 671 672 return(NETWIB_ERR_OK); 673 } 674 netwib_err l5_read(netwib_io *pio, 675 netwib_buf *pbuf); 676 netwib_err l5_read(netwib_io *pio, 677 netwib_buf *pbuf) 678 { 679 netwib_buf buf; 680 netwib_io *pionext; 681 682 netwib_er(netwib_io_next_read(pio, &pionext)); 683 netwib_er(netwib_buf_init_mallocdefault(&buf)); 684 netwib_er(netwib_io_read(pionext, &buf)); 685 netwib_er(l5_up(&buf, pbuf)); 686 netwib_er(netwib_buf_close(&buf)); 687 688 return(NETWIB_ERR_OK); 689 } 690 netwib_err l5_write(netwib_io *pio, 691 netwib_constbuf *pbuf); 692 netwib_err l5_write(netwib_io *pio, 693 netwib_constbuf *pbuf) 694 { 695 netwib_buf buf; 696 netwib_io *pionext; 697 netwib_err ret; 698 699 netwib_er(netwib_io_next_write(pio, &pionext)); 700 netwib_er(netwib_buf_init_mallocdefault(&buf)); 701 netwib_er(l5_up(pbuf, &buf)); 702 ret = netwib_io_write(pionext, &buf); 703 netwib_er(netwib_buf_close(&buf)); 704 705 return(ret); 706 } 707 netwib_err l5_init(netwib_io **ppio); 708 netwib_err l5_init(netwib_io **ppio) 709 { 710 netwib_er(netwib_io_init(NETWIB_FALSE, NETWIB_TRUE, NULL, 711 &l5_read, &l5_write, 712 NULL/*wait*/, NULL/*unread*/, 713 NULL/*ctlset*/, NULL/*ctlget*/, 714 NULL/*close*/, ppio)); 715 716 return(NETWIB_ERR_OK); 717 } 718 719 /*-------------------------------------------------------------*/ 720 /* module m */ 721 netwib_err m(netwib_io *pi1, 722 netwib_io *po1, 723 netwib_io *po2); 724 netwib_err m(netwib_io *pi1, 725 netwib_io *po1, 726 netwib_io *po2) 727 { 728 netwib_buf buf; 729 netwib_err ret; 730 netwib_io *pl1, *pl2; 731 netwib_data data; 732 netwib_uint32 datasize; 733 734 /* create l1 */ 735 netwib_er(netwib_io_init_line(&pl1)); 736 737 /* create l2 */ 738 netwib_er(l2_init(&pl2)); 739 740 /* add l1 to i1 */ 741 netwib_er(netwib_io_plug_read(pl1, pi1)); 742 743 /* add l2 to o2 */ 744 netwib_er(netwib_io_plug_read(pl2, po2)); 745 746 /* main loop */ 747 netwib_er(netwib_buf_init_mallocdefault(&buf)); 748 while (NETWIB_TRUE) { 749 netwib__buf_reinit(&buf); 750 ret = netwib_io_read(pl1, &buf); 751 if (ret == NETWIB_ERR_DATAEND) { 752 ret = NETWIB_ERR_OK; 753 break; 754 } else if (ret != NETWIB_ERR_OK) { 755 break; 756 } 757 data = netwib__buf_ref_data_ptr(&buf); 758 datasize = netwib__buf_ref_data_size(&buf); 759 if (datasize && data[0] == 'A') { 760 ret = netwib_io_write(po1, &buf); 761 } else { 762 ret = netwib_io_write(pl2, &buf); 763 } 764 if (ret != NETWIB_ERR_OK) { 765 break; 766 } 767 } 768 netwib_er(netwib_buf_close(&buf)); 769 770 /* close only l1 and l2 (not the complete chain) */ 771 netwib_er(netwib_io_close(&pl1)); 772 netwib_er(netwib_io_close(&pl2)); 773 774 return(ret); 775 } 776 777 /*-------------------------------------------------------------*/ 778 /* usage 1 */ 779 netwib_err usage1(void); 780 netwib_err usage1(void) 781 { 782 netwib_err ret; 783 netwib_buf filename; 784 netwib_io *pfile1, *pfile2, *pfile3, *pl3 , *pl4; 785 786 /* open files */ 787 netwib_er(netwib_buf_init_ext_string("file1", &filename)); 788 netwib_er(netwib_io_init_file_read(&filename, &pfile1)); 789 netwib_er(netwib_buf_init_ext_string("file2", &filename)); 790 netwib_er(netwib_io_init_file_write(&filename, &pfile2)); 791 netwib_er(netwib_buf_init_ext_string("file3", &filename)); 792 netwib_er(netwib_io_init_file_write(&filename, &pfile3)); 793 794 /* initialize l3 and l4 */ 795 netwib_er(l3_init(&pl3)); 796 netwib_er(l4_init(&pl4)); 797 798 /* create chains */ 799 netwib_er(netwib_io_plug_read(pl3, pfile1)); 800 netwib_er(netwib_io_plug_write(pl4, pfile3)); 801 802 /* core loop */ 803 ret = m(pl3, pfile2, pl4); 804 805 /* close chains */ 806 netwib_er(netwib_io_close(&pl3)); /* or close_read */ 807 netwib_er(netwib_io_close(&pfile2)); /* or close_write */ 808 netwib_er(netwib_io_close(&pl4)); /* or close_write */ 809 810 return(ret); 811 } 812 813 /*-------------------------------------------------------------*/ 814 /* usage 2 */ 815 netwib_err usage2(void); 816 netwib_err usage2(void) 817 { 818 netwib_err ret; 819 netwib_io *psock, *pnull; 820 netwib_ip ipad; 821 822 /* open socket */ 823 netwib_er(netwib_ip_init_ip4(0x7F000001, &ipad)); 824 netwib_er(netwib_io_init_sock_tcp_cli_easy(&ipad, 1234, &psock)); 825 826 /* open null */ 827 netwib_er(netwib_io_init_null(&pnull)); 828 829 /* core loop */ 830 ret = m(psock, pnull, psock); 831 832 /* close chains */ 833 netwib_er(netwib_io_close(&psock)); 834 netwib_er(netwib_io_close(&pnull)); /* or close_write */ 835 836 return(ret); 837 } 838 839 /*-------------------------------------------------------------*/ 840 /* usage 3 */ 841 netwib_err usage3(void); 842 netwib_err usage3(void) 843 { 844 netwib_err ret; 845 netwib_io *psock, *pnull, *pl3 , *pl4; 846 netwib_ip ipad; 847 848 /* open socket */ 849 netwib_er(netwib_ip_init_ip4(0x7F000001, &ipad)); 850 netwib_er(netwib_io_init_sock_tcp_cli_easy(&ipad, 1234, &psock)); 851 852 /* open null */ 853 netwib_er(netwib_io_init_null(&pnull)); 854 855 /* initialize l3 and l4 */ 856 netwib_er(l3_init(&pl3)); 857 netwib_er(l4_init(&pl4)); 858 859 /* create chains */ 860 netwib_er(netwib_io_plug_read(pl3, psock)); 861 netwib_er(netwib_io_plug_write(pl4, psock)); 862 863 /* core loop */ 864 ret = m(pl3, pnull, pl4); 865 866 /* close chains */ 867 netwib_er(netwib_io_close(&pl3)); /* or close_read */ 868 netwib_er(netwib_io_close(&pnull)); /* or close_write */ 869 netwib_er(netwib_io_close(&pl4)); /* or close_write */ 870 871 return(ret); 872 } 873 874 /*-------------------------------------------------------------*/ 875 /* usage 4 */ 876 netwib_err usage4(void); 877 netwib_err usage4(void) 878 { 879 netwib_err ret; 880 netwib_io *psock, *pnull, *pl5; 881 netwib_ip ipad; 882 883 /* open socket */ 884 netwib_er(netwib_ip_init_ip4(0x7F000001, &ipad)); 885 netwib_er(netwib_io_init_sock_tcp_cli_easy(&ipad, 1234, &psock)); 886 887 /* open null */ 888 netwib_er(netwib_io_init_null(&pnull)); 889 890 /* initialize l5 */ 891 netwib_er(l5_init(&pl5)); 892 893 /* create chains */ 894 netwib_er(netwib_io_plug_read(pl5, psock)); 895 netwib_er(netwib_io_plug_write(pl5, psock)); 896 897 /* core loop */ 898 ret = m(pl5, pnull, pl5); 899 900 /* close chains */ 901 netwib_er(netwib_io_close(&pl5)); 902 netwib_er(netwib_io_close(&pnull)); /* or close_write */ 903 904 return(ret); 905 } 906 907 /*-------------------------------------------------------------*/ 908 /* usage 5 */ 909 netwib_err usage5(void); 910 netwib_err usage5(void) 911 { 912 netwib_err ret; 913 netwib_buf filename; 914 netwib_io *pfile1, *pfile2, *pnull, *pl5; 915 916 /* open files */ 917 netwib_er(netwib_buf_init_ext_string("file1", &filename)); 918 netwib_er(netwib_io_init_file_read(&filename, &pfile1)); 919 netwib_er(netwib_buf_init_ext_string("file2", &filename)); 920 netwib_er(netwib_io_init_file_write(&filename, &pfile2)); 921 922 /* open null */ 923 netwib_er(netwib_io_init_null(&pnull)); 924 925 /* initialize l5 */ 926 netwib_er(l5_init(&pl5)); 927 928 /* create chains */ 929 netwib_er(netwib_io_plug_read(pl5, pfile1)); 930 netwib_er(netwib_io_plug_write(pl5, pfile2)); 931 932 /* core loop */ 933 ret = m(pl5, pnull, pl5); 934 935 /* close chains */ 936 netwib_er(netwib_io_close(&pl5)); 937 netwib_er(netwib_io_close(&pnull)); /* or close_write */ 938 939 return(ret); 940 } 941 942 /*-------------------------------------------------------------*/ 943 /* usage 6 */ 944 netwib_err usage6(void); 945 netwib_err usage6(void) 946 { 947 netwib_err ret; 948 netwib_buf filename; 949 netwib_io *pfile1, *pfile2; 950 951 /* open files */ 952 netwib_er(netwib_buf_init_ext_string("file1", &filename)); 953 netwib_er(netwib_io_init_file_read(&filename, &pfile1)); 954 netwib_er(netwib_buf_init_ext_string("file2", &filename)); 955 netwib_er(netwib_io_init_file_write(&filename, &pfile2)); 956 957 /* core loop */ 958 ret = m(pfile1, pfile2, pfile2); 959 960 /* close chains */ 961 netwib_er(netwib_io_close(&pfile1)); 962 netwib_er(netwib_io_close(&pfile2)); 963 964 return(ret); 965 } 966 967 /*-------------------------------------------------------------*/ 968 /* usage 7 */ 969 netwib_err usage7(void); 970 netwib_err m2(netwib_io *pi1, 971 netwib_io *pi2, 972 netwib_io *po1); 973 netwib_err usage7(void) 974 { 975 netwib_err ret; 976 netwib_buf filename; 977 netwib_io *pfile1, *pnull; 978 979 /* open files */ 980 netwib_er(netwib_buf_init_ext_string("file1", &filename)); 981 netwib_er(netwib_io_init_file_read(&filename, &pfile1)); 982 983 /* open null */ 984 netwib_er(netwib_io_init_null(&pnull)); 985 986 /* core loop */ 987 ret = m2(pfile1, pfile1, pnull); 988 989 /* close chains */ 990 netwib_er(netwib_io_close(&pfile1)); 991 netwib_er(netwib_io_close(&pnull)); 992 993 return(ret); 994 } 995 #endif 996