1212
1313int (* super_connect )(int sockfd , const struct sockaddr * addr , socklen_t addrlen );
1414
15+ ssize_t (* super_sendto )(int sockfd , const void * buf , size_t len , int flags ,
16+ const struct sockaddr * dest_addr , socklen_t addrlen );
17+
18+ ssize_t (* super_sendmsg )(int sockfd , const struct msghdr * msg , int flags );
19+
20+ ssize_t (* super_recvfrom )(int sockfd , void * buf , size_t len , int flags ,
21+ struct sockaddr * src_addr , socklen_t * addrlen );
22+
23+ ssize_t (* super_recvmsg )(int sockfd , struct msghdr * msg , int flags );
24+
1525typedef struct
1626{
1727 // Port to map from. If "0" or "*" is given, maps from all ports.
@@ -28,10 +38,31 @@ typedef struct
2838
2939} srv_mapping ;
3040
31-
3241srv_mapping * mappings ;
3342unsigned short n_mappings ;
3443
44+
45+ // TODO: attribute hidden
46+ srv_mapping * srv_find_mapping (const struct sockaddr_in * addr_in )
47+ {
48+ for (int i = 0 ; i < n_mappings ; i ++ )
49+ {
50+ if (mappings [i ].addr_from == NULL ||
51+ (* mappings [i ].addr_from ).s_addr == (addr_in -> sin_addr ).s_addr )
52+ {
53+ if (mappings [i ].port_from == 0 ||
54+ mappings [i ].port_from == addr_in -> sin_port )
55+ {
56+ fprintf (stderr , "WE HAVE A MATCH!!!!!!\n" );
57+ return mappings + i ;
58+ }
59+ }
60+ }
61+
62+ return NULL ;
63+ }
64+
65+
3566void _fini (void )
3667{
3768 if (mappings != NULL )
@@ -172,6 +203,30 @@ void _init(void)
172203 fprintf (stderr , "dlsym(connect) failed: %s\n" , err );
173204 exit (42 );
174205 }
206+
207+ super_sendto = dlsym (RTLD_NEXT , "sendto" );
208+ if ((err = dlerror ()) != NULL ) {
209+ fprintf (stderr , "dlsym(sendto) failed: %s\n" , err );
210+ exit (42 );
211+ }
212+
213+ super_sendmsg = dlsym (RTLD_NEXT , "sendmsg" );
214+ if ((err = dlerror ()) != NULL ) {
215+ fprintf (stderr , "dlsym(sendmsg) failed: %s\n" , err );
216+ exit (42 );
217+ }
218+
219+ super_recvmsg = dlsym (RTLD_NEXT , "recvmsg" );
220+ if ((err = dlerror ()) != NULL ) {
221+ fprintf (stderr , "dlsym(recvmsg) failed: %s\n" , err );
222+ exit (42 );
223+ }
224+
225+ super_recvfrom = dlsym (RTLD_NEXT , "recvfrom" );
226+ if ((err = dlerror ()) != NULL ) {
227+ fprintf (stderr , "dlsym(recvfrom) failed: %s\n" , err );
228+ exit (42 );
229+ }
175230}
176231
177232int connect (int sockfd , const struct sockaddr * dest_addr , socklen_t dest_len )
@@ -187,46 +242,224 @@ int connect(int sockfd, const struct sockaddr *dest_addr, socklen_t dest_len)
187242 static struct sockaddr_in * dest_addr_in ;
188243 dest_addr_in = (struct sockaddr_in * )dest_addr ;
189244
190- bool found = false;
191- srv_mapping mapping ;
245+ srv_mapping * mapping = srv_find_mapping (dest_addr_in );
192246
193- for ( int i = 0 ; i < n_mappings ; i ++ )
247+ if ( mapping )
194248 {
195- mapping = mappings [i ];
196- if (mapping .addr_from == NULL ||
197- (* mapping .addr_from ).s_addr == (dest_addr_in -> sin_addr ).s_addr )
249+ static struct sockaddr_storage new_dest_addr ;
250+ memcpy (& new_dest_addr , dest_addr , dest_len );
251+
252+ static struct sockaddr_in * new_dest_addr_in ;
253+ new_dest_addr_in = (struct sockaddr_in * )& new_dest_addr ;
254+ if (mapping -> port_to != 0 )
198255 {
199- if (mapping .port_from == 0 ||
200- mapping .port_from == dest_addr_in -> sin_port )
201- {
202- fprintf (stderr , "WE HAVE A MATCH!!!!!!\n" );
203- found = true;
204- break ;
205- }
256+ new_dest_addr_in -> sin_port = mapping -> port_to ;
206257 }
258+
259+ if (mapping -> addr_to != NULL )
260+ {
261+ new_dest_addr_in -> sin_addr = * mapping -> addr_to ;
262+ }
263+ return super_connect (sockfd , (struct sockaddr * )& new_dest_addr , dest_len );
264+
265+ } else
266+ {
267+ return super_connect (sockfd , dest_addr , dest_len );
268+
207269 }
270+ }
208271
209- if (found )
272+ ssize_t sendto (int sockfd , const void * buf , size_t len , int flags ,
273+ const struct sockaddr * dest_addr , socklen_t addrlen )
274+ {
275+ fprintf (stderr , "Entering sendto(2)\n" );
276+
277+ if (dest_addr -> sa_family != AF_INET ) {
278+ fprintf (stderr , "No AF_INET, skipping\n" );
279+ return super_sendto (sockfd , buf , len , flags , dest_addr , addrlen );
280+ }
281+
282+ static struct sockaddr_in * dest_addr_in ;
283+ dest_addr_in = (struct sockaddr_in * )dest_addr ;
284+
285+ srv_mapping * mapping = srv_find_mapping (dest_addr_in );
286+
287+ if (mapping )
210288 {
211289 static struct sockaddr_storage new_dest_addr ;
212- memcpy (& new_dest_addr , dest_addr , dest_len );
290+ memcpy (& new_dest_addr , dest_addr , addrlen );
213291
214292 static struct sockaddr_in * new_dest_addr_in ;
215293 new_dest_addr_in = (struct sockaddr_in * )& new_dest_addr ;
216- if (mapping . port_to != 0 )
294+ if (mapping -> port_to != 0 )
217295 {
218- new_dest_addr_in -> sin_port = mapping . port_to ;
296+ new_dest_addr_in -> sin_port = mapping -> port_to ;
219297 }
220298
221- if (mapping . addr_to != NULL )
299+ if (mapping -> addr_to != NULL )
222300 {
223- new_dest_addr_in -> sin_addr = * mapping . addr_to ;
301+ new_dest_addr_in -> sin_addr = * mapping -> addr_to ;
224302 }
225- return super_connect (sockfd , (struct sockaddr * )& new_dest_addr , dest_len );
303+ return super_sendto (sockfd , buf , len , flags , (struct sockaddr * )& new_dest_addr , addrlen );
226304
227305 } else
228306 {
229- return super_connect (sockfd , dest_addr , dest_len );
307+ return super_sendto (sockfd , buf , len , flags , dest_addr , addrlen );
308+
309+ }
310+
311+ }
312+
313+ ssize_t sendmsg (int sockfd , const struct msghdr * msg , int flags )
314+ {
315+ fprintf (stderr , "Entering sendmsg(2)\n" );
316+
317+ if (msg -> msg_name == NULL )
318+ {
319+ fprintf (stderr , "No msg_name, skipping\n" );
320+ return super_sendmsg (sockfd , msg , flags );
321+
322+ }
323+
324+ static struct sockaddr_in * dest_addr_in ;
325+ dest_addr_in = (struct sockaddr_in * )msg -> msg_name ;
326+
327+ if (dest_addr_in -> sin_family != AF_INET )
328+ {
329+ fprintf (stderr , "No AF_INET, skipping\n" );
330+ return super_sendmsg (sockfd , msg , flags );
331+ }
332+
333+ srv_mapping * mapping = srv_find_mapping (dest_addr_in );
334+
335+ if (mapping )
336+ {
337+
338+ static struct sockaddr_storage new_dest_addr ;
339+ memcpy (& new_dest_addr , dest_addr_in , msg -> msg_namelen );
340+
341+ static struct sockaddr_in * new_dest_addr_in ;
342+ new_dest_addr_in = (struct sockaddr_in * )& new_dest_addr ;
343+
344+ if (mapping -> port_to != 0 )
345+ {
346+ new_dest_addr_in -> sin_port = mapping -> port_to ;
347+ }
348+
349+ if (mapping -> addr_to != NULL )
350+ {
351+ new_dest_addr_in -> sin_addr = * mapping -> addr_to ;
352+ }
353+
354+ static struct msghdr new_msg ;
355+ memcpy (& new_msg , msg , sizeof (* msg ));
356+
357+ new_msg .msg_name = (void * ) new_dest_addr_in ;
358+
359+ return super_sendmsg (sockfd , & new_msg , flags );
360+
361+
362+ } else
363+ {
364+ return super_sendmsg (sockfd , msg , flags );
365+ }
366+ }
367+
368+ ssize_t recvfrom (int sockfd , void * buf , size_t len , int flags ,
369+ struct sockaddr * src_addr , socklen_t * addrlen )
370+ {
371+ fprintf (stderr , "Entering recvfrom(2)\n" );
372+
373+ if (src_addr -> sa_family != AF_INET ) {
374+ fprintf (stderr , "No AF_INET, skipping\n" );
375+ return super_recvfrom (sockfd , buf , len , flags , src_addr , addrlen );
376+ }
377+
378+ static struct sockaddr_in * src_addr_in ;
379+ src_addr_in = (struct sockaddr_in * )src_addr ;
380+
381+ srv_mapping * mapping = srv_find_mapping (src_addr_in );
382+
383+ if (mapping )
384+ {
385+
386+ in_port_t old_port = src_addr_in -> sin_port ;
387+ struct in_addr old_addr = src_addr_in -> sin_addr ;
388+
389+ if (mapping -> port_to != 0 )
390+ {
391+ src_addr_in -> sin_port = mapping -> port_to ;
392+ }
393+
394+ if (mapping -> addr_to != NULL )
395+ {
396+ src_addr_in -> sin_addr = * mapping -> addr_to ;
397+ }
398+
399+ ssize_t res ;
400+ res = super_recvfrom (sockfd , buf , len , flags , src_addr , addrlen );
401+
402+ src_addr_in -> sin_port = old_port ;
403+ src_addr_in -> sin_addr = old_addr ;
404+
405+ return res ;
406+ } else
407+ {
408+ return super_recvfrom (sockfd , buf , len , flags , src_addr , addrlen );
409+ }
410+ }
230411
412+ ssize_t recvmsg (int sockfd , struct msghdr * msg , int flags )
413+ {
414+ fprintf (stderr , "Entering recvmsg(2)\n" );
415+
416+ if (msg -> msg_name == NULL )
417+ {
418+ fprintf (stderr , "No msg_name, skipping\n" );
419+ return super_sendmsg (sockfd , msg , flags );
231420 }
421+
422+
423+ struct sockaddr_in * src_addr_in = msg -> msg_name ;
424+
425+ fprintf (stderr , "recvmsg: msg_namelen: %d\n" , msg -> msg_namelen );
426+ fprintf (stderr , "recvmsg: AF_INET: %d vs %d\n" , AF_INET , src_addr_in -> sin_family );
427+
428+ if (src_addr_in -> sin_family != AF_INET )
429+ {
430+ fprintf (stderr , "recvmsg: No AF_INET, skipping\n" );
431+ return super_recvmsg (sockfd , msg , flags );
432+ }
433+
434+ srv_mapping * mapping = srv_find_mapping (src_addr_in );
435+
436+ if (mapping )
437+ {
438+ in_port_t old_port = src_addr_in -> sin_port ;
439+ struct in_addr old_addr = src_addr_in -> sin_addr ;
440+
441+ if (mapping -> port_to != 0 )
442+ {
443+ src_addr_in -> sin_port = mapping -> port_to ;
444+ }
445+
446+ if (mapping -> addr_to != NULL )
447+ {
448+ src_addr_in -> sin_addr = * mapping -> addr_to ;
449+ }
450+
451+ ssize_t res ;
452+ res = super_recvmsg (sockfd , msg , flags );
453+
454+ src_addr_in -> sin_port = old_port ;
455+ src_addr_in -> sin_addr = old_addr ;
456+
457+ return res ;
458+
459+
460+ } else
461+ {
462+ return super_recvmsg (sockfd , msg , flags );
463+ }
464+
232465}
0 commit comments