packetsrv.c

Go to the documentation of this file.
00001 /*
00002  ** Copyright (C) 2002-2008 INL
00003  ** Written by Eric Leblond <eric@regit.org>
00004  **            Vincent Deffontaines <vincent@gryzor.com>
00005  ** INL http://www.inl.fr/
00006  **
00007  ** $Id: packetsrv.c 5286 2008-11-21 16:09:21Z pollux $
00008  **
00009  ** This program is free software; you can redistribute it and/or modify
00010  ** it under the terms of the GNU General Public License as published by
00011  ** the Free Software Foundation, version 3 of the License.
00012  **
00013  ** This program is distributed in the hope that it will be useful,
00014  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  ** GNU General Public License for more details.
00017  **
00018  ** You should have received a copy of the GNU General Public License
00019  ** along with this program; if not, write to the Free Software
00020  ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 #include "nufw.h"
00024 
00025 #include <nubase.h>
00026 
00027 #ifdef HAVE_NFQ_INDEV_NAME
00028 #  include "iface.h"
00029 #endif
00030 
00051 int look_for_tcp_flags(unsigned char *dgram, unsigned int datalen)
00052 {
00053         struct iphdr *iphdrs = (struct iphdr *) dgram;
00054         /* check need some data */
00055         if (datalen < sizeof(struct iphdr) + sizeof(struct tcphdr)) {
00056                 log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_VERBOSE_DEBUG,
00057                                 "Incorrect packet data length");
00058                 return 0;
00059         }
00060         /* check IP version */
00061         if (iphdrs->version == 4) {
00062                 if (iphdrs->protocol == IPPROTO_TCP) {
00063                         struct tcphdr *tcphdrs =
00064                             (struct tcphdr *) (dgram + 4 * iphdrs->ihl);
00065                         if (tcphdrs->fin || tcphdrs->ack || tcphdrs->rst) {
00066                                 RETURN_NO_LOG 1;
00067                         }
00068                 }
00069         }
00070         return 0;
00071 }
00072 
00073 #ifdef USE_NFQUEUE
00074 
00087 static int treat_packet(struct nfq_handle *qh, struct nfgenmsg *nfmsg,
00088                         struct nfq_data *nfa, void *data)
00089 {
00090         packet_idl *current;
00091         struct queued_pckt q_pckt;
00092         struct nfqnl_msg_packet_hdr *ph;
00093         struct timeval timestamp;
00094         int ret;
00095 #ifdef HAVE_NFQ_INDEV_NAME
00096         struct nlif_handle *nlif_handle = (struct nlif_handle *) data;
00097 #endif
00098 
00099         debug_log_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_VERBOSE_DEBUG,
00100                          "(*) New packet");
00101 
00102         q_pckt.payload_len = nfq_get_payload(nfa, &(q_pckt.payload));
00103         if (q_pckt.payload_len == -1) {
00104                 log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_INFO,
00105                                 "Unable to get payload");
00106                 return 0;
00107         }
00108 
00109         q_pckt.mark = nfq_get_nfmark(nfa);
00110 
00111 #ifdef HAVE_NFQ_INDEV_NAME
00112         if (!get_interface_information(nlif_handle, &q_pckt, nfa)) {
00113                 log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_INFO,
00114                                 "Can not get interfaces information for message");
00115                 return 0;
00116         }
00117 #else
00118         snprintf(q_pckt.indev, sizeof(q_pckt.indev), "*");
00119         snprintf(q_pckt.physindev, sizeof(q_pckt.physindev), "*");
00120         snprintf(q_pckt.outdev, sizeof(q_pckt.outdev), "*");
00121         snprintf(q_pckt.physoutdev, sizeof(q_pckt.physoutdev), "*");
00122 #endif
00123 
00124         ret = nfq_get_timestamp(nfa, &timestamp);
00125         if (ret == 0) {
00126                 q_pckt.timestamp = timestamp.tv_sec;
00127         } else {
00128                 q_pckt.timestamp = time(NULL);
00129         }
00130 
00131         if (look_for_tcp_flags
00132             ((unsigned char *) q_pckt.payload, q_pckt.payload_len)) {
00133                 ph = nfq_get_msg_packet_hdr(nfa);
00134                 if (ph) {
00135                         q_pckt.packet_id = ntohl(ph->packet_id);
00136                         auth_request_send(AUTH_CONTROL, &q_pckt);
00137                         IPQ_SET_VERDICT(q_pckt.packet_id, NF_ACCEPT);
00138                         RETURN_NO_LOG 1;
00139                 } else {
00140                         log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_VERBOSE_DEBUG,
00141                                         "Can not get the packet headers");
00142                         return 0;
00143                 }
00144         }
00145         current = calloc(1, sizeof(packet_idl));
00146         current->nfmark = q_pckt.mark;
00147         current->timestamp = q_pckt.timestamp ;
00148         current->id = 0;
00149         if (current == NULL) {
00150                 log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_MESSAGE,
00151                                 "Can not allocate packet_id");
00152                 return 0;
00153         }
00154 #ifdef PERF_DISPLAY_ENABLE
00155         gettimeofday(&(current->arrival_time), NULL);
00156 #endif
00157         /* Get unique identifier of packet in queue */
00158         ph = nfq_get_msg_packet_hdr(nfa);
00159         if (ph) {
00160                 current->id = ntohl(ph->packet_id);
00161         } else {
00162                 free(current);
00163                 log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_INFO,
00164                                 "Can not get id for message");
00165                 return 0;
00166         }
00167 
00168         /* Try to add the packet to the list */
00169         pthread_mutex_lock(&packets_list.mutex);
00170         q_pckt.packet_id = padd(current);
00171         pthread_mutex_unlock(&packets_list.mutex);
00172 
00173         if (q_pckt.packet_id) {
00174                 /* send an auth request packet */
00175                 if (!auth_request_send(AUTH_REQUEST, &q_pckt)) {
00176                         int sandf = 0;
00177                         /* send failure dropping packet */
00178                         IPQ_SET_VERDICT(q_pckt.packet_id, NF_DROP);
00179                         /* we fail to send the packet so we free packet related to current */
00180                         pthread_mutex_lock(&packets_list.mutex);
00181                         /* search and destroy packet by packet_id */
00182                         sandf =
00183                             psearch_and_destroy(q_pckt.packet_id,
00184                                                 &(q_pckt.mark));
00185                         pthread_mutex_unlock(&packets_list.mutex);
00186 
00187                         if (!sandf) {
00188                                 log_area_printf(DEBUG_AREA_MAIN,
00189                                                 DEBUG_LEVEL_WARNING,
00190                                                 "Packet could not be removed: %u",
00191                                                 q_pckt.packet_id);
00192                         }
00193                 }
00194         }
00195         return 1;
00196 }
00197 
00198 
00202 int packetsrv_open(void *data)
00203 {
00204         struct nfnl_handle *nh;
00205 
00206         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG,
00207                         "Opening netfilter queue socket");
00208         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG,
00209                         "[!] Don't forget to load kernel modules nfnetlink and nfnetlink_queue (using modprobe command)");
00210 
00211         /* opening library handle */
00212         h = nfq_open();
00213         if (!h) {
00214                 log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00215                                 "[!] Error during nfq_open()");
00216                 return -1;
00217         }
00218 
00219         /* unbinding existing nf_queue handler for AF_INET (if any) */
00220         /* ignoring return, see http://www.spinics.net/lists/netfilter/msg42063.html */
00221         nfq_unbind_pf(h, AF_INET);
00222 
00223         /* binding nfnetlink_queue as nf_queue handler for AF_INET */
00224         if (nfq_bind_pf(h, AF_INET) < 0) {
00225                 log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00226                                 "[!] Error during nfq_bind_pf()");
00227                 return -1;
00228         }
00229 
00230         if (!nufw_no_ipv6) {
00231                 /* unbinding existing nf_queue handler for AF_INET6 (if any) */
00232                 nfq_unbind_pf(h, AF_INET6);
00233 
00234                 /* binding nfnetlink_queue as nf_queue handler for AF_INET6 */
00235                 if (nfq_bind_pf(h, AF_INET6) < 0) {
00236                         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00237                                         "[!] Error during nfq_bind_pf()");
00238                         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00239                                         "Maybe you need to compile NF_NETLINK* kernel options as modules (not built in the kernel!)");
00240                         return -1;
00241                 }
00242         }
00243 
00244         /* binding this socket to queue number ::nfqueue_num
00245          * and install our packet handler */
00246         hndl = nfq_create_queue(h, nfqueue_num,
00247                              (nfq_callback *) & treat_packet, data);
00248         if (!hndl) {
00249                 log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00250                                 "[!] Error during nfq_create_queue() (queue %d busy ?)",
00251                                 nfqueue_num);
00252                 return -1;
00253         }
00254 
00255         /* setting copy_packet mode */
00256         if (nfq_set_mode(hndl, NFQNL_COPY_PACKET, 0xffff) < 0) {
00257                 log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00258                                 "[!] Can't set packet_copy mode");
00259                 return -1;
00260         }
00261 #ifdef HAVE_NFQ_SET_QUEUE_MAXLEN
00262         /* setting queue length */
00263         if (queue_maxlen) {
00264                 if (nfq_set_queue_maxlen(hndl, queue_maxlen) < 0) {
00265                         if (nufw_set_mark) {
00266                                 log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00267                                                 "[!] Can't set queue length, and mark will be set, leaving !");
00268                                 exit(EXIT_FAILURE);
00269                         } else {
00270                                 log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00271                                                 "[!] Can't set queue length, continuing anyway");
00272                         }
00273                 }
00274         }
00275 #endif
00276 
00277         nh = nfq_nfnlh(h);
00278         return nfnl_fd(nh);
00279 }
00280 
00281 void packetsrv_close(int smart)
00282 {
00283         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_SERIOUS_MESSAGE,
00284                         "Destroy netfilter queue socket");
00285         if (smart)
00286                 nfq_destroy_queue(hndl);
00287         nfq_close(h);
00288 }
00289 
00290 #else                           /* USE_NFQUEUE */
00291 
00296 void packetsrv_ipq_process(unsigned char *buffer)
00297 {
00298         ipq_packet_msg_t *msg_p = NULL;
00299         packet_idl *current;
00300         struct queued_pckt q_pckt;
00301         uint32_t pcktid;
00302 
00303         pckt_rx++;
00304         /* printf("Working on IP packet\n"); */
00305         msg_p = ipq_get_packet(buffer);
00306         q_pckt.packet_id = msg_p->packet_id;
00307         q_pckt.payload = (char *) msg_p->payload;
00308         q_pckt.payload_len = msg_p->data_len;
00309         /* need to parse to see if it's an end connection packet */
00310         if (look_for_tcp_flags(msg_p->payload, msg_p->data_len)) {
00311                 auth_request_send(AUTH_CONTROL, &q_pckt);
00312                 IPQ_SET_VERDICT(msg_p->packet_id, NF_ACCEPT);
00313                 RETURN_NO_LOG;
00314         }
00315 
00316         /* Create packet */
00317         current = calloc(1, sizeof(packet_idl));
00318         if (current == NULL) {
00319                 /* no more memory: drop packet and exit */
00320                 IPQ_SET_VERDICT(msg_p->packet_id, NF_DROP);
00321                 log_area_printf(DEBUG_AREA_MAIN | DEBUG_AREA_PACKET,
00322                                 DEBUG_LEVEL_SERIOUS_WARNING,
00323                                 "[+] Can not allocate packet_id (drop packet)");
00324                 return;
00325         }
00326         current->id = msg_p->packet_id;
00327         current->timestamp = msg_p->timestamp_sec;
00328 #ifdef HAVE_LIBIPQ_MARK
00329         current->nfmark = msg_p->mark;
00330 #endif
00331 
00332         /* Adding packet to list */
00333         pthread_mutex_lock(&packets_list.mutex);
00334         pcktid = padd(current);
00335         pthread_mutex_unlock(&packets_list.mutex);
00336         if (!pcktid) {
00337                 log_area_printf(DEBUG_AREA_MAIN | DEBUG_AREA_PACKET,
00338                                 DEBUG_LEVEL_VERBOSE_DEBUG,
00339                                 "Can not add packet to packet list (so already dropped): exit");
00340                 return;
00341         }
00342 
00343         /* send an auth request packet */
00344         if (!auth_request_send(AUTH_REQUEST, &q_pckt)) {
00345                 int sandf = 0;
00346                 /* we fail to send the packet so we free packet related to current */
00347                 pthread_mutex_lock(&packets_list.mutex);
00348                 /* search and destroy packet by packet_id */
00349                 sandf =
00350                     psearch_and_destroy(msg_p->packet_id,
00351                                         (uint32_t *) & msg_p->mark);
00352                 pthread_mutex_unlock(&packets_list.mutex);
00353 
00354                 if (!sandf) {
00355                         log_area_printf(DEBUG_AREA_MAIN,
00356                                         DEBUG_LEVEL_WARNING,
00357                                         "Packet could not be removed: %lu",
00358                                         msg_p->packet_id);
00359                 }
00360         }
00361 }
00362 #endif                          /* USE_NFQUEUE */
00363 
00376 void *packetsrv(void *void_arg)
00377 {
00378         struct nufw_threadargument *thread_arg = void_arg;
00379         struct nufw_threadtype *this = thread_arg->thread;
00380         int fatal_error = 0;
00381 #ifdef USE_NFQUEUE
00382         unsigned char buffer[BUFSIZ];
00383         struct timeval tv;
00384         int fd;
00385 #ifdef HAVE_NFQ_INDEV_NAME
00386         struct nlif_handle *nlif_handle;
00387         int if_fd;
00388 #endif
00389         int rv;
00390         int select_result;
00391         int max_fd;
00392         fd_set wk_set;
00393 
00394 #ifdef HAVE_NFQ_INDEV_NAME
00395         nlif_handle = iface_table_open();
00396 
00397         if (!nlif_handle)
00398                 exit(EXIT_FAILURE);
00399 
00400         if_fd = nlif_fd(nlif_handle);
00401         if (if_fd < 0) {
00402                 exit(EXIT_FAILURE);
00403         }
00404 
00405         fd = packetsrv_open((void *) nlif_handle);
00406 #else
00407         fd = packetsrv_open(NULL);
00408 #endif
00409 
00410         if (fd < 0) {
00411                 exit(EXIT_FAILURE);
00412         }
00413 
00414         log_area_printf(DEBUG_AREA_MAIN | DEBUG_AREA_PACKET, DEBUG_LEVEL_DEBUG,
00415                         "[+] Packet server started");
00416 
00417         /* loop until main process ask to stop */
00418         while (pthread_mutex_trylock(&this->mutex) == 0) {
00419                 pthread_mutex_unlock(&this->mutex);
00420 
00421                 /* Set timeout: one second */
00422                 tv.tv_sec = 1;
00423                 tv.tv_usec = 0;
00424 
00425                 /* wait new event on socket */
00426                 FD_ZERO(&wk_set);
00427                 FD_SET(fd, &wk_set);
00428 #ifdef HAVE_NFQ_INDEV_NAME
00429                 FD_SET(if_fd, &wk_set);
00430 
00431                 if (fd >= if_fd) {
00432                         max_fd = fd + 1;
00433                 } else {
00434                         max_fd = if_fd + 1;
00435                 }
00436 #else
00437                 max_fd = fd + 1;
00438 #endif
00439 
00440                 select_result = select(max_fd, &wk_set, NULL, NULL, &tv);
00441                 if (select_result == -1) {
00442                         int err = errno;
00443                         if (err == EINTR) {
00444                                 continue;
00445                         }
00446 
00447                         if (err == EBADF) {
00448                                 struct stat s;
00449 #ifdef HAVE_NFQ_INDEV_NAME
00450                                 if ((fstat(if_fd, &s)<0)) {
00451                                         iface_table_close(nlif_handle);
00452 
00453                                         nlif_handle = iface_table_open();
00454                                         if (!nlif_handle)
00455                                                 exit(EXIT_FAILURE);
00456 
00457                                         if_fd = nlif_fd(nlif_handle);
00458                                         if (if_fd < 0) {
00459                                                 exit(EXIT_FAILURE);
00460                                         }
00461                                 }
00462 #endif
00463                                 if ((fstat(fd, &s)<0)) {
00464                                         packetsrv_close(0);
00465 #ifdef HAVE_NFQ_INDEV_NAME
00466                                         fd = packetsrv_open(nlif_handle);
00467 #else
00468                                         fd = packetsrv_open(NULL);
00469 #endif
00470                                 }
00471                                 continue;
00472                         }
00473                         log_area_printf(DEBUG_AREA_MAIN,
00474                                         DEBUG_LEVEL_CRITICAL,
00475                                         "[!] FATAL ERROR: Error of select() in netfilter queue thread (code %i)!",
00476                                         err);
00477                         fatal_error = 1;
00478                         break;
00479                 }
00480 
00481                 /* catch timeout */
00482                 if (select_result == 0) {
00483                         /* timeout! */
00484                         continue;
00485                 }
00486 #ifdef HAVE_NFQ_INDEV_NAME
00487                 if (FD_ISSET(if_fd, &wk_set)) {
00488                         iface_treat_message(nlif_handle);
00489                         continue;
00490                 }
00491 #endif
00492                 /* read one packet */
00493                 rv = recv(fd, buffer, sizeof(buffer), 0);
00494                 if (rv < 0) {
00495                         log_area_printf(DEBUG_AREA_MAIN,
00496                                         DEBUG_LEVEL_WARNING,
00497                                         "[!] Error of read on netfilter queue socket (code %i)!",
00498                                         rv);
00499                         log_area_printf(DEBUG_AREA_MAIN,
00500                                         DEBUG_LEVEL_SERIOUS_MESSAGE,
00501                                         "Reopen netlink connection.");
00502                         packetsrv_close(0);
00503 #ifdef HAVE_NFQ_INDEV_NAME
00504                         fd = packetsrv_open(nlif_handle);
00505 #else
00506                         fd = packetsrv_open(NULL);
00507 #endif
00508                         if (fd < 0) {
00509                                 log_area_printf(DEBUG_AREA_MAIN,
00510                                                 DEBUG_LEVEL_CRITICAL,
00511                                                 "[!] FATAL ERROR: Fail to reopen netlink connection!");
00512                                 fatal_error = 1;
00513                                 break;
00514                         }
00515                         continue;
00516                 }
00517 
00518                 /* process the packet */
00519                 nfq_handle_packet(h, (char *) buffer, rv);
00520                 pckt_rx++;
00521         }
00522 
00523 #ifdef HAVE_NFQ_INDEV_NAME
00524         iface_table_close(nlif_handle);
00525 #endif
00526 
00527 
00528         packetsrv_close(!fatal_error);
00529 #else                           /* USE_NFQUEUE */
00530         unsigned char buffer[BUFSIZ];
00531         int size;
00532 
00533         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_MESSAGE,
00534                         "Try to connect to netlink (IPQ)");
00535         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_SERIOUS_WARNING,
00536                         "Don't forget to load Linux kernel module ip_queue (using modprobe command)");
00537 
00538         /* init netlink connection */
00539         hndl = ipq_create_handle(0, PF_INET);
00540         if (!hndl) {
00541                 log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL,
00542                                 "[!] FATAL ERROR: Could not create ipq handle!");
00543                 kill(thread_arg->parent_pid, SIGTERM);
00544                 pthread_exit(NULL);
00545         }
00546 
00547         ipq_set_mode(hndl, IPQ_COPY_PACKET, BUFSIZ);
00548 
00549         log_area_printf(DEBUG_AREA_MAIN | DEBUG_AREA_PACKET, DEBUG_LEVEL_FATAL,
00550                         "[+] Packet server started");
00551 
00552         /* loop until main process ask this thread to stop using its mutex */
00553         while (pthread_mutex_trylock(&this->mutex) != EBUSY) {
00554                 pthread_mutex_unlock(&this->mutex);
00555 
00556                 /* wait netfilter event with a timeout of one second */
00557                 size = ipq_read(hndl, buffer, sizeof(buffer), 1000000);
00558 
00559                 /* is timeout recheaded */
00560                 if (size == 0) {
00561                         continue;
00562                 }
00563 
00564                 /* Check buffer size */
00565                 if (size == -1) {
00566                         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG,
00567                                         "BUFSIZ too small (size == %d)",
00568                                         size);
00569                         continue;
00570                 }
00571                 if (BUFSIZ <= size) {
00572                         log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG,
00573                                         "BUFSIZ too small (size == %d)",
00574                                         size);
00575                         continue;
00576                 }
00577 
00578                 /* skip message different than packets */
00579                 if (ipq_message_type(buffer) != IPQM_PACKET) {
00580                         /* if it's an error, display it and stop NuFW !!! */
00581                         if (ipq_message_type(buffer) == NLMSG_ERROR) {
00582                                 log_area_printf(DEBUG_AREA_MAIN,
00583                                                 DEBUG_LEVEL_CRITICAL,
00584                                                 "[!] FATAL ERROR: libipq error (code %d)!",
00585                                                 ipq_get_msgerr(buffer));
00586                                 fatal_error = 1;
00587                                 break;
00588                         }
00589                         continue;
00590                 }
00591 
00592                 /* process packet */
00593                 packetsrv_ipq_process(buffer);
00594         }
00595         ipq_destroy_handle(hndl);
00596 #endif
00597         log_area_printf(DEBUG_AREA_MAIN | DEBUG_AREA_PACKET,
00598                         DEBUG_LEVEL_WARNING,
00599                         "[+] Leave packet server thread");
00600         if (fatal_error) {
00601                 kill(thread_arg->parent_pid, SIGTERM);
00602         }
00603         pthread_exit(NULL);
00604 }
00605 
00609 void shutdown_tls()
00610 {
00611         if(!tls.auth_server_running)
00612                 return;
00613 
00614         log_area_printf(DEBUG_AREA_GW, DEBUG_LEVEL_CRITICAL,
00615                         "tls send failure when sending request");
00616 
00617         pthread_cancel(tls.auth_server);
00618 
00619         close_tls_session();
00620 
00621         /* put auth_server_running to 0 because this is this thread which has
00622          * just killed auth_server */
00623         tls.auth_server_running = 0;
00624 }
00625 
00639 int auth_request_send(uint8_t type, struct queued_pckt *pckt_datas)
00640 {
00641         unsigned char datas[512];
00642         nuv4_nufw_to_nuauth_auth_message_t *msg_header =
00643             (nuv4_nufw_to_nuauth_auth_message_t *) & datas;
00644         unsigned char *msg_content =
00645             datas + sizeof(nuv4_nufw_to_nuauth_auth_message_t);
00646         int msg_length;
00647 
00648         /* Drop non-IPv(4|6) packet */
00649         if ((((struct iphdr *) (pckt_datas->payload))->version != 4)
00650             && (((struct iphdr *) (pckt_datas->payload))->version != 6)) {
00651                 log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_DEBUG,
00652                                  "Dropping non-IPv4/non-IPv6 packet (version %u)",
00653                                  ((struct iphdr *) (pckt_datas->payload))->
00654                                  version);
00655                 return 0;
00656         }
00657 
00658         /* Truncate packet content if needed */
00659         if (sizeof(datas) <
00660             sizeof(nuv4_nufw_to_nuauth_auth_message_t) +
00661             pckt_datas->payload_len) {
00662                 debug_log_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_DEBUG,
00663                                  "Very long packet: truncating!");
00664                 pckt_datas->payload_len =
00665                     sizeof(datas) -
00666                     sizeof(nuv4_nufw_to_nuauth_auth_message_t);
00667         }
00668         msg_length =
00669             sizeof(nuv4_nufw_to_nuauth_auth_message_t) +
00670             pckt_datas->payload_len;
00671 
00672         /* Fill message header */
00673         msg_header->protocol_version = PROTO_NUFW_VERSION;
00674         msg_header->msg_type = type;
00675         msg_header->msg_length = htons(msg_length);
00676         msg_header->packet_id = htonl(pckt_datas->packet_id);
00677         msg_header->timestamp = htonl(pckt_datas->timestamp);
00678 
00679         /* Add info about interfaces */
00680         msg_header->mark = pckt_datas->mark;
00681         memcpy(msg_header->indev, pckt_datas->indev,
00682                IFNAMSIZ * sizeof(char));
00683         memcpy(msg_header->outdev, pckt_datas->outdev,
00684                IFNAMSIZ * sizeof(char));
00685         memcpy(msg_header->physindev, pckt_datas->physindev,
00686                IFNAMSIZ * sizeof(char));
00687         memcpy(msg_header->physoutdev, pckt_datas->physoutdev,
00688                IFNAMSIZ * sizeof(char));
00689 
00690         /* Copy (maybe truncated) packet content */
00691         memcpy(msg_content, pckt_datas->payload, pckt_datas->payload_len);
00692 
00693         /* Display message */
00694         log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_DEBUG,
00695                         "Sending request for %lu", (long)pckt_datas->packet_id);
00696 
00697         /* cleaning up current session : auth_server has detected a problem */
00698         pthread_mutex_lock(&tls.mutex);
00699         if ((tls.auth_server_running == 0) && tls.session != NULL) {
00700                 close_tls_session();
00701         }
00702 
00703         pthread_mutex_unlock(&tls.mutex);
00704 
00705         /* negotiate TLS connection if needed */
00706         if (!tls.session) {
00707                 log_area_printf(DEBUG_AREA_GW, DEBUG_LEVEL_INFO,
00708                                 "Not connected, trying TLS connection");
00709                 tls_connect();
00710 
00711                 if (tls.session) {
00712                         log_area_printf(DEBUG_AREA_GW,
00713                                         DEBUG_LEVEL_WARNING,
00714                                         "[+] TLS connection to nuauth restored (%s:%d)",
00715                                         authreq_addr, authreq_port);
00716 
00717                 } else {
00718                         log_area_printf(DEBUG_AREA_GW,
00719                                         DEBUG_LEVEL_WARNING,
00720                                         "[!] TLS connection to nuauth can NOT be restored (%s:%d)",
00721                                         authreq_addr, authreq_port);
00722                         return 0;
00723                 }
00724         }
00725 
00726         /* send packet */
00727         pthread_mutex_lock(&tls.mutex);
00728 
00729         if (nussl_write(tls.session, (char*)datas, msg_length) < 0) {
00730                 debug_log_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG,
00731                                  "Error during nussl_write (auth_request_send).");
00732                 shutdown_tls();
00733                 pthread_mutex_unlock(&tls.mutex);
00734                 log_area_printf(DEBUG_AREA_GW,
00735                                 DEBUG_LEVEL_WARNING,
00736                                 "[!] TLS send failure");
00737                 return 0;
00738         }
00739         pthread_mutex_unlock(&tls.mutex);
00740         return 1;
00741 }
00742 

Generated on Sat Nov 22 04:00:38 2008 for NuFW by  doxygen 1.4.7