[insert project logo here (125x200px max)]

Navigator

Mailinglists

Please report any errors or ommissions you find to our `Help' mailinglist, or post a message in the Forums.

Copyright and Licensing Information

Snap is (c) Jonathan T. Moore, 1999-2002 and licensed under the GNU General Public License (GPL).

All other parts of Splash are (c) Willem de Bruijn, 2002-2003 and licensed under the BSD Open Source License.

All sourcecode is made publicly available.

Acknowledgement

Splash and the Splash website are hosted by SourceForge.net

SourceForge.net Logo

osi-open source certified logo

Splash - Documentation

SNMP Plus a Lightweight API for SNAP Handling

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

snap-1.1-wjdb/src/snap_demux_handler.c

Go to the documentation of this file.
00001  /*
00002  * snap_demux_handler.c : functions for retrieving DEMUXed data
00003  */
00004 
00005 #include <netinet/ip.h>
00006 #include <unistd.h>
00007 #include <sys/socket.h>
00008 #include <sys/un.h>
00009 #include <ctype.h> /* for isprint(..) call */
00010 #include "../lib/d_printf.h"
00011 #include "../lib/io.h"
00012 
00013 #include "snap_demux_handler.h"
00014 
00015 int socket_unix = -1;
00016 int socket_rawip = -1;
00017 int socket_udp = -1;
00018 
00019 int protocols_internal = 0;
00020 int max_filedes = -1;
00021 fd_set fdset;
00022 
00023 /*
00024     UNIX socket specific code
00025 */
00026 
00027 void snap_demux_close_unix(){
00028     char filename[PATH_MAX];
00029 
00030     /* close the file descriptor*/
00031     close(socket_unix);
00032 
00033     /* remove the accompanying file */
00034     sprintf(filename, "/tmp/snap%d",receiveport);
00035     remove(filename);
00036 
00037     socket_unix = -1;
00038 }
00039 
00040 int snap_demux_init_unix(){
00041     struct sockaddr_un laddr;
00042 
00043     if ((socket_unix = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) {
00044         perror("demux_init_unix: socket()");
00045         return 1;
00046     }
00047 
00048     laddr.sun_family = AF_UNIX;
00049     sprintf(laddr.sun_path, "/tmp/snap%d",receiveport);
00050 
00051 
00052     if (bind(socket_unix, (struct sockaddr *) &laddr, sizeof(laddr)) < 0){
00053             perror("receivesock bind()");
00054             snap_demux_close_unix ();
00055             return 1;
00056     }
00057 
00058     return 0;
00059 }
00060 
00061 /*
00062     RAW IP socket specific code
00063 */
00064 
00065 void snap_demux_close_rawip(){
00066 
00067     /* close the file descriptor*/
00068     close(socket_rawip);
00069 
00070     socket_rawip = -1;
00071 }
00072 
00073 int snap_demux_init_rawip(){
00074     struct sockaddr_in bindaddr;
00075 
00076     if ((socket_rawip = socket(AF_INET, SOCK_RAW, IPPROTO_SNAP)) < 0) {
00077         perror("snap_demux_init_rawip: socket()");
00078         return 1;
00079     }
00080 
00081     memset(&bindaddr, 0, sizeof(bindaddr));
00082     bindaddr.sin_family = AF_INET;
00083     bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
00084 
00085     if (bind(socket_rawip, (struct sockaddr *)&bindaddr,sizeof(bindaddr)) < 0) {
00086         perror("snap_demux_init_rawip: bind()");
00087         snap_demux_close_rawip();
00088         return 1;
00089     }
00090 
00091     return 0;
00092 }
00093 
00094 /*
00095     UDP socket specific code
00096 */
00097 
00098 void snap_demux_close_udp(){
00099 
00100     /* close the file descriptor*/
00101     close(socket_udp);
00102 
00103     socket_udp = -1;
00104 }
00105 
00106 int snap_demux_init_udp(){
00107     struct sockaddr_in bindaddr;
00108 
00109     if ((socket_udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00110         perror("snap_demux_init_udp: socket()");
00111         return 1;
00112     }
00113 
00114     memset(&bindaddr, 0, sizeof(bindaddr));
00115     bindaddr.sin_family = AF_INET;
00116     bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
00117     bindaddr.sin_port = htons(receiveport);
00118 
00119     if (bind(socket_udp, (struct sockaddr *)&bindaddr,sizeof(bindaddr)) < 0) {
00120         perror("snap_demux_init_udp: bind()");
00121         snap_demux_close_udp();
00122         return 1;
00123     }
00124 
00125     return 0;
00126 }
00127 
00128 /*
00129     buffer handlers
00130 */
00131 
00132 void snap_demux_buffer_noop(char* pbuf){
00133 }
00134 
00135 void snap_demux_buffer_print_unsafe(char* pbuf){
00136     fprintf(stdout,"DEMUX output = [%s]\n",pbuf);
00137 }
00138 
00139 void snap_demux_buffer_print(char* pbuf){
00140     int i;
00141 
00142     fprintf(stderr,"DEMUX output = [");
00143     for(i=0; i<strlen(pbuf); i++) {
00144         if (pbuf[i] == '\0') {
00145             break;
00146         }
00147         switch(pbuf[i]) {
00148             case '"': fprintf(stderr,"\\\""); break;
00149             case '\\': fprintf(stderr,"\\"); break;
00150             case '\n': fprintf(stderr,"\\n"); break;
00151             case '\b': fprintf(stderr,"\\b"); break;
00152             case '\r': fprintf(stderr,"\\r"); break;
00153             case '\t': fprintf(stderr,"\\t"); break;
00154             default:
00155             if (isprint(pbuf[i])) {
00156                 fprintf(stderr,"%c",pbuf[i]);
00157             } else {
00158                 fprintf(stderr,"\\%03o",pbuf[i]);
00159             }
00160             break;
00161         }
00162     }
00163     fprintf(stderr,"] \n");
00164 }
00165 
00166 /*
00167     general code
00168 */
00169 
00170 void snap_demux_close(){
00171     if (protocols_internal & SNAP_UNIX)
00172         snap_demux_close_unix();
00173 
00174     if (protocols_internal & SNAP_RAWIP)
00175         snap_demux_close_rawip();
00176 
00177     if (protocols_internal & SNAP_UDP)
00178         snap_demux_close_udp();
00179 
00180     /* extend in identical fashion for new protocols */
00181 
00182     /* reset vars */
00183     protocols_internal = 0;
00184     max_filedes = -1;
00185 
00186 }
00187 
00188 int snap_demux_init(int protocols){
00189 
00190     /* safety check */
00191     if (protocols_internal){
00192         d_printf(10,"snap_demux_init : WARNING : initializing open connections\n");
00193         snap_demux_close();
00194     }
00195 
00196     /* initialize vars */
00197     FD_ZERO(&fdset);
00198 
00199     /* call protocol specfic initilization routines */
00200     if (protocols & SNAP_UNIX)
00201         if (!snap_demux_init_unix())
00202             protocols_internal |= SNAP_UNIX;
00203 
00204     if (protocols & SNAP_RAWIP)
00205         if (!snap_demux_init_rawip())
00206             protocols_internal |= SNAP_RAWIP;
00207 
00208     if (protocols & SNAP_UDP)
00209         if (!snap_demux_init_udp())
00210             protocols_internal |= SNAP_UDP;
00211     /* extend in identical fashion for new protocols */
00212 
00213     /* calculate the maximum filedescriptor that has to be read */
00214     max_filedes = (socket_unix > socket_rawip ? socket_unix : socket_rawip) + 1;
00215     max_filedes = (socket_udp >= max_filedes ? socket_udp + 1 : max_filedes);
00216 
00217     d_printf(80,"fds: unix:%d raw:%d udp:%d max:%d\n",socket_unix,socket_rawip,socket_udp,max_filedes);
00218 
00219     return protocols_internal;
00220 }
00221 
00222 int snap_demux_receivefrom(int socket_waiting, buffer_handler active_handler){
00223     int length;
00224     /*int i;*/
00225     char pbuf[SNAP_BUFLEN];
00226 
00227     memset(&pbuf, 0, sizeof(char) * SNAP_BUFLEN);
00228     length = recvfrom(socket_waiting, pbuf, sizeof(pbuf), 0, NULL, NULL);
00229 
00230     /* DEBUG_START */
00231     d_printf_timed(7,"snap_demux_receive : received packet\n"); 
00232     d_printf(100,"snap_demux_receive: packet is %d bytes, received from filedes %u\n",sizeof(char) * length,(unsigned int) socket_waiting);
00233 /*  d_printf(100,"snap_demux_receive : received bincode = [");
00234     for (i = 0; i< length ; i++)
00235         d_printf(100,"%u ",pbuf[i]);
00236     d_printf(100,"] \n");
00237 */  /* DEBUG_END */
00238 
00239     if (length < 0){
00240         perror("recvfrom");
00241         return 0;
00242     }
00243     else{
00244         if (active_handler)
00245             active_handler(pbuf);
00246         d_printf_timed(7,"snap_demux_receive : received and handled a message\n");
00247         return length;
00248     }
00249 }
00250 
00251 int snap_demux_receive(buffer_handler active_handler){
00252     int returnvalue = 0;
00253 
00254     /* handle messages */
00255     if (protocols_internal & SNAP_UNIX && FD_ISSET(socket_unix,&fdset))
00256         returnvalue += snap_demux_receivefrom(socket_unix, active_handler);
00257     if (protocols_internal & SNAP_RAWIP && FD_ISSET(socket_rawip,&fdset))
00258         returnvalue += snap_demux_receivefrom(socket_rawip, active_handler);
00259     if (protocols_internal & SNAP_UDP && FD_ISSET(socket_udp,&fdset))
00260         returnvalue += snap_demux_receivefrom(socket_udp, active_handler);
00261 
00262     if (!returnvalue)
00263         d_printf_timed(5,"snap_demux_receive : unable to handle message\n");
00264 
00265     /* extend in identical fashion for new protocols */
00266     return returnvalue;
00267 }
00268 
00269 int snap_demux_select(){
00270     struct timeval timeout;
00271 
00272     d_printf_timed(7,"snap_demux_select : waiting for message\n");
00273 
00274     /* initialize the select() vars */
00275     FD_ZERO(&fdset);
00276     timeout.tv_sec = 3; /* timeout in 3 secs */
00277     timeout.tv_usec = 0;
00278 
00279 
00280     if (protocols_internal & SNAP_UNIX)
00281         FD_SET(socket_unix, &fdset);
00282     if (protocols_internal & SNAP_RAWIP)
00283         FD_SET(socket_rawip, &fdset);
00284     if (protocols_internal & SNAP_UDP)
00285         FD_SET(socket_udp, &fdset);
00286     /* extend in identical fashion for new protocols */
00287 
00288     /* wait for messages */
00289     if (select(max_filedes, &fdset, NULL, NULL, &timeout) < 0) {
00290         perror("select");
00291         return 1;
00292     }
00293 
00294     return 0;
00295 }
00296 
00297 int snap_demux_handler(buffer_handler active_handler){
00298 
00299     if (!snap_demux_select())
00300         return snap_demux_receive(active_handler);
00301     else
00302         return 0;
00303 }
00304