[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 |
Splash - DocumentationSNMP Plus a Lightweight API for SNAP Handlingsnap-1.1-wjdb/src/snap_demux_handler.cGo 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 |