00001
00002 #ifdef GIDS
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <pcap.h>
00006 #include <dnet.h>
00007
00008 #include "snort.h"
00009 #include "decode.h"
00010 #include "inline.h"
00011 #include "rules.h"
00012 #include "checksum.h"
00013 #include "bounds.h"
00014 #include "util.h"
00015 #include "mstring.h"
00016 #include "stream.h"
00017 #define PKT_BUFSIZE 70000
00018
00019
00020
00021
00022
00023
00024 ip_t *rawdev;
00025 eth_t *ethdev;
00026 rand_t *randh;
00027
00028 static void *tcp_pkt = NULL;
00029 static void *icmp_pkt = NULL;
00030
00031 static u_int8_t link_offset;
00032 static u_int8_t alignment;
00033
00034 static INLINE u_int8_t CalcOriginalTTL(Packet *p);
00035 Packet *tmpP;
00036 extern Stream4Data s4data;
00037
00038 #ifdef NFNETLINKQ
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 struct my_ipq_packet_msg {
00058 unsigned long packet_id;
00059 unsigned long mark;
00060 long timestamp_sec;
00061 long timestamp_usec;
00062 unsigned int hook;
00063 char indev_name[IFNAMSIZ];
00064 char outdev_name[IFNAMSIZ];
00065 unsigned short hw_protocol;
00066 unsigned short hw_type;
00067 unsigned char hw_addrlen;
00068 unsigned char hw_addr[8];
00069 size_t data_len;
00070 unsigned char payload[PKT_BUFSIZE];
00071 } ipq_pkt;
00072 unsigned char buf[PKT_BUFSIZE];
00073 unsigned int glid;
00074 char ifnames[32][IF_NAMESIZE];
00075 int nl_fd, rv;
00076 struct nfq_handle *nfqh;
00077 struct nfq_q_handle *qhndl;
00078 struct nfnl_handle *nh;
00079 int rcvstatus, done;
00080
00081 #endif
00082
00083 #ifndef IPFW
00084 ipq_packet_msg_t *g_m = NULL;
00085 #endif
00086
00087
00088 #ifndef IPFW
00089 void HandlePacket(ipq_packet_msg_t *);
00090 void TranslateToPcap(ipq_packet_msg_t *, struct pcap_pkthdr *);
00091 #else
00092 void HandlePacket();
00093 void TranslateToPcap(struct pcap_pkthdr *phdr, ssize_t len);
00094 #endif
00095 void ResetIV(void);
00096
00097
00098
00099
00100
00101
00102
00103 int InlineMode()
00104 {
00105 if (pv.inline_flag)
00106 return 1;
00107
00108 return 0;
00109 }
00110
00111
00112 #ifndef IPFW
00113 void TranslateToPcap(ipq_packet_msg_t *m, struct pcap_pkthdr *phdr)
00114 {
00115 static struct timeval t;
00116 if (!m->timestamp_sec)
00117 {
00118 memset (&t, 0, sizeof(struct timeval));
00119 gettimeofday(&t, NULL);
00120 phdr->ts.tv_sec = t.tv_sec;
00121 phdr->ts.tv_usec = t.tv_usec;
00122 }
00123 else
00124 {
00125 phdr->ts.tv_sec = m->timestamp_sec;
00126 phdr->ts.tv_usec = m->timestamp_usec;
00127 }
00128 phdr->caplen = m->data_len;
00129 phdr->len = m->data_len;
00130 }
00131 #else
00132 void TranslateToPcap(struct pcap_pkthdr *phdr, ssize_t len)
00133 {
00134 static struct timeval t;
00135 memset (&t, 0, sizeof(struct timeval));
00136 gettimeofday(&t, NULL);
00137 phdr->ts.tv_sec = t.tv_sec;
00138 phdr->ts.tv_usec = t.tv_usec;
00139 phdr->caplen = len;
00140 phdr->len = len;
00141
00142 }
00143 #endif
00144
00145 static INLINE u_int8_t CalcOriginalTTL(Packet *p)
00146 {
00147 switch (tmpP->iph->ip_ttl / 64)
00148 {
00149 case 3:
00150 return 255;
00151 case 2:
00152 return 192;
00153 case 1:
00154 return 128;
00155 default:
00156 return 64;
00157 }
00158 }
00159
00160 void RejectFuRestart()
00161 {
00162
00163
00164 if (rawdev != NULL)
00165 rawdev = ip_close(rawdev);
00166 if (ethdev != NULL)
00167 ethdev = eth_close(ethdev);
00168
00169
00170
00171 if (tcp_pkt != NULL)
00172 {
00173 tcp_pkt -= alignment;
00174 free(tcp_pkt);
00175 tcp_pkt = NULL;
00176 }
00177 if (icmp_pkt != NULL)
00178 {
00179 icmp_pkt -= alignment;
00180 free(icmp_pkt);
00181 icmp_pkt = NULL;
00182 }
00183
00184
00185 if (randh != NULL)
00186 randh = rand_close(randh);
00187
00188 return;
00189 }
00190
00191 void ResetIV()
00192 {
00193 iv.drop = 0;
00194 iv.rejectsrc = 0;
00195 iv.rejectdst = 0;
00196 iv.reinject = 0;
00197 iv.replace = 0;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 void InitInlinePostConfig(void)
00211 {
00212
00213 printf("InitInline stage 2: InitInlinePostConfig starting...\n");
00214
00215
00216
00217
00218 #ifndef IPFW
00219 if(pv.layer2_resets)
00220 {
00221 link_offset = ETH_HDR_LEN;
00222 alignment = 2;
00223 if ((randh = rand_open()) == NULL)
00224 {
00225 printf("could no open random handle\n");
00226 }
00227
00228 }
00229 else
00230 {
00231 #ifdef DEBUG_GIDS
00232 printf("opening raw socket in IP-mode\n");
00233 #endif
00234 link_offset = 0;
00235 alignment = 0;
00236
00237 if ((rawdev = ip_open()) == NULL)
00238 {
00239 printf("InitInline: Unable to open raw socket for dnet.\n");
00240 }
00241
00242 }
00243 #else
00244 link_offset = 0;
00245 alignment = 0;
00246
00247 if ((rawdev = ip_open()) == NULL)
00248 {
00249 printf("InitInline: Unable to open raw socket for dnet.\n");
00250 }
00251
00252 #endif
00253 tcp_pkt = SnortAlloc(alignment + link_offset + IP_HDR_LEN + TCP_HDR_LEN);
00254 tcp_pkt += alignment;
00255 icmp_pkt = SnortAlloc(alignment + link_offset + IP_HDR_LEN + ICMP_LEN_MIN + 68);
00256 icmp_pkt += alignment;
00257 }
00258
00259 #ifdef NFNETLINKQ
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
00270 struct nfq_data *nfa, void *data)
00271 {
00272 int iret;
00273 u_int32_t ifi;
00274 char *junkdata;
00275 struct nfqnl_msg_packet_timestamp ts;
00276
00277 ipq_pkt.data_len = nfq_get_payload(nfa, &junkdata);
00278
00279 memcpy(ipq_pkt.payload, junkdata, ipq_pkt.data_len);
00280
00281 struct nfqnl_msg_packet_hdr *ph =
00282 nfq_get_msg_packet_hdr(nfa);
00283 glid = ntohl(ph->packet_id);
00284 ipq_pkt.packet_id = glid;
00285 ipq_pkt.hw_protocol = ntohs(ph->hw_protocol);
00286 ipq_pkt.hook = ph->hook;
00287 ipq_pkt.mark = nfq_get_nfmark(nfa);
00288
00289 ifi = nfq_get_indev(nfa);
00290 strncpy(ipq_pkt.indev_name, ifnames[ifi], 16);
00291
00292 ifi = nfq_get_outdev(nfa);
00293 strncpy(ipq_pkt.outdev_name, ifnames[ifi], 16);
00294
00295
00296 struct nfqnl_msg_packet_hw *hw = nfq_get_packet_hw(nfa);
00297 if(hw){
00298 ipq_pkt.hw_addrlen = ntohs(hw->hw_addrlen);
00299
00300 memcpy(ipq_pkt.hw_addr, hw->hw_addr, ipq_pkt.hw_addrlen);
00301 }
00302
00303 iret = nfq_get_timestamp(nfa, &ts);
00304 if(iret){
00305 ipq_pkt.timestamp_sec = (long)(ts.sec);
00306 ipq_pkt.timestamp_usec = (long)(ts.usec);
00307 }
00308
00309 return(0);
00310 }
00311
00312 #endif
00313
00314
00315
00316 int InitInline()
00317 {
00318 #ifndef IPFW
00319 int status;
00320 #endif
00321
00322 #ifdef DEBUG_GIDS
00323 printf("Initializing Inline mode \n");
00324 #endif
00325
00326 printf("Initializing Inline mode \n");
00327
00328 #ifndef IPFW
00329
00330 #ifdef NFNETLINKQ
00331
00332
00333 struct if_nameindex *if_nameindex(void);
00334 struct if_nameindex *blah;
00335 int i,j;
00336
00337 for (j = 0; j < 32; j++)
00338 for(i = 0; i < IF_NAMESIZE; i++)ifnames[j][i] = 0;
00339
00340 blah = if_nameindex();
00341 for(i = 0; i < 32; i++){
00342
00343 if(blah[i].if_index == 0)break;
00344 strlcpy(ifnames[blah[i].if_index], blah[i].if_name, IF_NAMESIZE);
00345
00346 }
00347 if_freenameindex(blah);
00348 #else
00349
00350 ipqh = ipq_create_handle(0, PF_INET);
00351 if (!ipqh)
00352 {
00353 ipq_perror("InlineInit: ");
00354 ipq_destroy_handle(ipqh);
00355 exit(1);
00356 }
00357
00358 status = ipq_set_mode(ipqh, IPQ_COPY_PACKET, PKT_BUFSIZE);
00359 if (status < 0)
00360 {
00361 ipq_perror("InitInline: ");
00362 ipq_destroy_handle(ipqh);
00363 exit(1);
00364 }
00365
00366
00367
00368
00369
00370 #endif
00371 #endif
00372
00373 ResetIV();
00374
00375
00376
00377
00378 pd = pcap_open_dead(DLT_RAW, SNAPLEN);
00379
00380 return 0;
00381 }
00382
00383 #ifndef IPFW
00384 #ifndef NFNETLINKQ
00385 void IpqLoop()
00386 {
00387 int status = 0;
00388 struct pcap_pkthdr PHdr;
00389 unsigned char buf[PKT_BUFSIZE];
00390 static ipq_packet_msg_t *m;
00391
00392 #ifdef DEBUG_GIDS
00393 printf("Reading Packets from ipq handle \n");
00394 #endif
00395
00396
00397 while(1)
00398 {
00399 ResetIV();
00400 status = ipq_read(ipqh, buf, PKT_BUFSIZE, 0);
00401 if (status < 0)
00402 {
00403 ipq_perror("IpqLoop: ");
00404 }
00405 else
00406 {
00407 switch(ipq_message_type(buf))
00408 {
00409 case NLMSG_ERROR:
00410 fprintf(stderr, "Received error message %d\n",
00411 ipq_get_msgerr(buf));
00412 break;
00413
00414 case IPQM_PACKET:
00415 m = ipq_get_packet(buf);
00416 g_m = m;
00417 #ifdef DEBUG_INLINE
00418 printf("%02X:%02X:%02X:%02X:%02X:%02X\n", m->hw_addr[0], m->hw_addr[1],
00419 m->hw_addr[2], m->hw_addr[3], m->hw_addr[4], m->hw_addr[5]);
00420 #endif
00421
00422 TranslateToPcap(m, &PHdr);
00423 PcapProcessPacket(NULL, &PHdr, (u_char *)m->payload);
00424 HandlePacket(m);
00425 break;
00426 }
00427 }
00428 }
00429 }
00430 #endif
00431 #endif
00432
00433
00434 #ifndef IPFW
00435 #ifdef NFNETLINKQ
00436 void NfnetlinkQLoop()
00437 {
00438 int status = 0;
00439 struct pcap_pkthdr PHdr;
00440 static ipq_packet_msg_t *m;
00441
00442
00443 #ifdef DEBUG_GIDS
00444 printf("Reading Packets from ipq handle \n");
00445 #endif
00446
00447 m = &ipq_pkt;
00448 g_m = m;
00449
00450
00451
00452
00453
00454
00455 nfqh = nfq_open();
00456 if (!nfqh) {
00457 printf("[%d] error during nfq_open()\n",getpid());
00458 exit(1);
00459 }
00460
00461 if (nfq_unbind_pf(nfqh, AF_INET) < 0) {
00462 printf("[%d] error during nfq_unbind_pf()\n",getpid());
00463 exit(1);
00464 }
00465
00466 if (nfq_bind_pf(nfqh, AF_INET) < 0) {
00467 printf("[%d] error during nfq_bind_pf()\n",getpid());
00468 exit(1);
00469 }
00470
00471 qhndl = nfq_create_queue(nfqh, nfqueue_num, &cb, NULL);
00472 if (!qhndl) {
00473 printf("[%d] error during nfq_create_queue() (queue %d busy ?)\n",
00474 getpid(),nfqueue_num);
00475 exit(1);
00476 }
00477
00478 if (nfq_set_mode(qhndl, NFQNL_COPY_PACKET, 0xffff) < 0) {
00479 printf("[%d] can't set packet_copy mode\n",getpid());
00480 exit(1);
00481 }
00482
00483 nh = nfq_nfnlh(nfqh);
00484 nl_fd = nfnl_fd(nh);
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 while(1)
00503 {
00504 done = 0;
00505 ResetIV();
00506
00507
00508
00509 memset(buf, 0, sizeof(buf));
00510 rcvstatus = recv(nl_fd, buf, PKT_BUFSIZE, 0);
00511
00512 if (rcvstatus < 0)
00513 {
00514 printf("[%d] packet recv contents failure\n",getpid());
00515 }
00516 else
00517 {
00518 TranslateToPcap(m, &PHdr);
00519 ProcessPacket(NULL, &PHdr, (u_char *)m->payload, NULL);
00520 HandlePacket(m);
00521 if(!done){
00522 status = nfq_set_verdict(qhndl, glid, NF_ACCEPT, 0, NULL);
00523 if (status < 0)
00524 {
00525 fprintf(stderr,"NF_ACCEPT: ");
00526 }
00527 nfq_handle_packet(nfqh, buf, rcvstatus);
00528 }
00529 }
00530
00531 }
00532 }
00533 #endif
00534 #endif
00535
00536
00537 #ifdef IPFW
00538
00539
00540
00541
00542 void IpfwLoop()
00543 {
00544 char pkt[IP_MAXPACKET];
00545 struct pcap_pkthdr PHdr;
00546 ssize_t pktlen;
00547 struct sockaddr_in sin;
00548 socklen_t sinlen;
00549 int rtsock;
00550 int ifindex;
00551 fd_set fdset;
00552 ifindex = 0;
00553 rtsock = -1;
00554
00555 #ifdef DEBUG_GIDS
00556 printf("Reading Packets from ipfw divert socket \n");
00557 #endif
00558
00559
00560 if ((divert_socket = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1)
00561 {
00562 perror("IpfwLoop: can't create divert socket");
00563 exit(-1);
00564 }
00565
00566
00567 bzero(&sin, sizeof(sin));
00568 sin.sin_family = PF_INET;
00569 sin.sin_addr.s_addr = INADDR_ANY;
00570 sin.sin_port = htons(pv.divert_port);
00571
00572
00573 if (bind(divert_socket, (struct sockaddr *)&sin, sizeof(sin)) == -1)
00574 {
00575 perror("IpfwLoop: can't bind divert socket");
00576 exit(-1);
00577 }
00578
00579
00580 while (1)
00581 {
00582 ResetIV();
00583 FD_ZERO(&fdset);
00584 FD_SET(divert_socket, &fdset);
00585 if (rtsock != -1)
00586 {
00587 FD_SET(rtsock, &fdset);
00588 }
00589
00590 if (select(32, &fdset, (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)NULL) == -1)
00591 {
00592 printf("select failed");
00593 continue;
00594 }
00595
00596 if (FD_ISSET(divert_socket, &fdset))
00597 {
00598 sinlen = sizeof(sin);
00599
00600 if ((pktlen = recvfrom(divert_socket, pkt, sizeof(pkt), 0,(struct sockaddr *)&sin, &sinlen)) == -1)
00601 {
00602 if (errno != EINTR)
00603 {
00604 printf("IpfwLoop: read from divert socket failed");
00605 continue;
00606 }
00607 }
00608
00609 TranslateToPcap(&PHdr,pktlen);
00610 PcapProcessPacket(NULL, &PHdr, pkt);
00611 HandlePacket();
00612
00613
00614
00615
00616 if (! iv.drop && ! iv.rejectsrc)
00617 {
00618 if (iv.reinject)
00619 {
00620 if (pv.ipfw_reinject_rule)
00621 {
00622 if (pv.ipfw_reinject_rule < sin.sin_port)
00623 {
00624 printf("IpfwLoop: reinjection loop: start=%d,end=%d\n",sin.sin_port,pv.ipfw_reinject_rule);
00625 continue;
00626 }
00627
00628 sin.sin_port=pv.ipfw_reinject_rule;
00629 }
00630 }
00631
00632 if (sendto(divert_socket, pkt, pktlen, 0,(struct sockaddr *)&sin, sinlen) == -1)
00633 {
00634 printf("IpfwLoop: write to divert socket failed");
00635 }
00636 }
00637 }
00638
00639 }
00640 }
00641 #endif
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 #ifndef IPFW
00656 static void
00657 RejectFu(ipq_packet_msg_t *m, int mode)
00658 #else
00659 static void
00660 RejectFu(int mode)
00661 #endif
00662 {
00663 if(tmpP->iph == NULL)return;
00664 int proto = tmpP->iph->ip_proto;
00665 int noreverse = 0;
00666 IPHdr *iph;
00667 #ifndef IPFW
00668 int i = 0;
00669 char **macbytes;
00670 int num_macbytes;
00671 EtherHdr *eh;
00672
00673 #endif
00674
00675 if(mode == 1)
00676 {
00677 noreverse = 1;
00678 }
00679 #ifndef IPFW
00680 char *device;
00681 eth_addr_t srclinkaddr;
00682 u_char enet_src[6];
00683
00684 if(s4data.stream4inline_mode && opdsize)
00685 {
00686 tmpP->dsize = opdsize;
00687 }
00688 if(link_offset)
00689 {
00690
00691
00692 if(noreverse)
00693 {
00694 printf("layer2 resets don't work for non reversed packets\n");
00695 return;
00696 }
00697
00698
00699 if(m->indev_name[0] != '\0')
00700 device = m->indev_name;
00701 else
00702 device = m->outdev_name;
00703
00704 if ((ethdev = eth_open(device)) != NULL)
00705 {
00706 if (eth_get(ethdev, &srclinkaddr)< 0)
00707 {
00708 #ifdef DEBUG_GIDS
00709 printf("failed to get macaddy\n");
00710 #endif
00711 }
00712 else
00713 {
00714 #ifdef DEBUG_GIDS
00715 printf("mac addy of src int is %s\n",eth_ntoa(&srclinkaddr));
00716 #endif
00717 }
00718 }
00719
00720
00721
00722 if(pv.enet_src[0] == 0 && pv.enet_src[1] == 0 && pv.enet_src[2] == 0 && pv.enet_src[3] == 0 && pv.enet_src[4] == 0 && pv.enet_src[5] == 0)
00723 {
00724
00725 macbytes = mSplit(eth_ntoa(&srclinkaddr), ":", 6, &num_macbytes, '\\');
00726
00727 if (num_macbytes < 6)
00728 {
00729 #ifdef DEBUG_GIDS
00730 printf("That is one crazy mac addy");
00731 #endif
00732 }
00733 else
00734 {
00735 for (i = 0; i < 6; i++)
00736 enet_src[i] = (u_int8_t) strtoul(macbytes[i], NULL, 16);
00737 }
00738 mSplitFree(&macbytes, num_macbytes);
00739 }
00740 else
00741 {
00742 for(i = 0; i < 6; i++)
00743 enet_src[i] = pv.enet_src[i];
00744
00745 }
00746
00747 }
00748 #endif
00749 switch(proto)
00750 {
00751 case IPPROTO_TCP:
00752 if (!tmpP->frag_flag)
00753 {
00754 TCPHdr *tcp;
00755 size_t sz = IP_HDR_LEN + TCP_HDR_LEN;
00756 ssize_t n;
00757 u_int32_t i, ack, seq;
00758 u_int16_t window, dsize;
00759 iph = (IPHdr *)(tcp_pkt + link_offset);
00760 tcp = (TCPHdr *)(tcp_pkt + IP_HDR_LEN + link_offset);
00761 #ifndef IPFW
00762 if(link_offset)
00763 {
00764 eh = (EtherHdr *)tcp_pkt;
00765 eh->ether_type = htons(ETH_TYPE_IP);
00766 memcpy(eh->ether_src, enet_src, 6);
00767 memcpy(eh->ether_dst, m->hw_addr, 6);
00768 }
00769 #endif
00770 SET_IP_VER(iph, 4);
00771 SET_IP_HLEN(iph, (IP_HDR_LEN >> 2));
00772 iph->ip_proto = IPPROTO_TCP;
00773
00774
00775 tcp = (TCPHdr *)(tcp_pkt + IP_HDR_LEN + link_offset);
00776 tcp->th_flags = TH_RST|TH_ACK;
00777 SET_TCP_OFFSET(tcp, (TCP_HDR_LEN >> 2));
00778
00779
00780 dsize = tmpP->dsize;
00781 if(noreverse)
00782 {
00783
00784 iph->ip_src.s_addr = tmpP->iph->ip_src.s_addr;
00785 iph->ip_dst.s_addr = tmpP->iph->ip_dst.s_addr;
00786
00787 if(tmpP->tcph == NULL)return;
00788 tcp->th_sport = tmpP->tcph->th_sport;
00789 tcp->th_dport = tmpP->tcph->th_dport;
00790 seq = ntohl(tmpP->tcph->th_seq);
00791 ack = ntohl(tmpP->tcph->th_ack);
00792 iph->ip_ttl = CalcOriginalTTL(tmpP);
00793 tcp->th_win = tmpP->tcph->th_win;
00794
00795
00796 window = ntohs(tcp->th_win);
00797 }
00798
00799 else
00800 {
00801
00802 iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr;
00803 iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr;
00804
00805 if(tmpP->tcph == NULL)return;
00806 tcp->th_sport = tmpP->tcph->th_dport;
00807 tcp->th_dport = tmpP->tcph->th_sport;
00808 seq = ntohl(tmpP->tcph->th_ack);
00809 ack = ntohl(tmpP->tcph->th_seq) + tmpP->dsize;
00810 iph->ip_ttl = CalcOriginalTTL(tmpP);
00811 tcp->th_win = tmpP->tcph->th_win;
00812
00813
00814 window = ntohs(tcp->th_win);
00815 }
00816
00817
00818 for (i = 0; i < 4; i++)
00819 {
00820 if (link_offset)
00821 {
00822 iph->ip_id = rand_uint16(randh);
00823 }
00824 switch (i)
00825 {
00826 case 0:
00827 break;
00828 case 1:
00829 seq += dsize;
00830 break;
00831 case 2:
00832 seq += (dsize << 1);
00833 ack += (dsize << 1);
00834 break;
00835 case 3:
00836 seq += (dsize << 1);
00837 ack += (dsize << 1);
00838 break;
00839 case 4:
00840 seq += (dsize << 2);
00841 ack += (dsize << 2);
00842 break;
00843 default:
00844 seq += (window >> 1);
00845 ack += (window >> 1);
00846 break;
00847 }
00848
00849 #ifndef IPFW
00850 tcp->th_seq = htonl(seq);
00851 tcp->th_ack = htonl(ack);
00852
00853 #else
00854
00855 tcp->th_ack = htonl(ack + 1);
00856 #endif
00857
00858 iph->ip_len = htons(sz);
00859 ip_checksum(tcp_pkt + link_offset, sz);
00860
00861
00862 if (link_offset)
00863 n = eth_send(ethdev, tcp_pkt, sz + link_offset);
00864 else
00865 n = ip_send(rawdev, tcp_pkt, sz);
00866
00867 if (n < sz)
00868 printf("failed to send reset\n");
00869 }
00870 }
00871 break;
00872
00873 case IPPROTO_UDP:
00874 if (!tmpP->frag_flag)
00875 {
00876 ICMPHdr *icmph;
00877 u_int16_t payload_len;
00878 size_t sz;
00879 ssize_t n;
00880
00881
00882 if (tmpP->iph->ip_proto == IPPROTO_ICMP && tmpP->icmph->code == ICMP_UNREACH_PORT)
00883 {
00884 #ifdef DEBUG_GIDS
00885 printf("ignoring icmp_port set on ICMP packet.\n");
00886 #endif
00887 return;
00888 }
00889
00890 iph = (IPHdr *)(icmp_pkt + link_offset);
00891 icmph = (ICMPHdr *)(icmp_pkt + IP_HDR_LEN + link_offset);
00892
00893
00894 iph = (IPHdr *)(icmp_pkt + link_offset);
00895 SET_IP_VER(iph, 4);
00896 SET_IP_HLEN(iph, (IP_HDR_LEN >> 2));
00897 iph->ip_proto = IPPROTO_ICMP;
00898
00899
00900 icmph = (ICMPHdr *)(icmp_pkt + IP_HDR_LEN + link_offset);
00901 icmph->type = ICMP_UNREACH;
00902
00903 if(noreverse)
00904 {
00905 iph->ip_src.s_addr = tmpP->iph->ip_src.s_addr;
00906 iph->ip_dst.s_addr = tmpP->iph->ip_dst.s_addr;
00907 }
00908 else
00909 {
00910 iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr;
00911 iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr;
00912 }
00913
00914 iph->ip_ttl = CalcOriginalTTL(tmpP);
00915
00916 icmph->code = ICMP_UNREACH_PORT;
00917 #ifndef IPFW
00918 if(link_offset)
00919 {
00920
00921 eh = (EtherHdr *)icmp_pkt;
00922 eh->ether_type = htons(ETH_TYPE_IP);
00923 if(noreverse)
00924 {
00925 memcpy(eh->ether_src, m->hw_addr, 6);
00926 memcpy(eh->ether_dst, enet_src, 6);
00927 }
00928 else
00929 {
00930 memcpy(eh->ether_src, enet_src, 6);
00931 memcpy(eh->ether_dst, m->hw_addr, 6);
00932 }
00933 iph->ip_id = rand_uint16(randh);
00934 }
00935 #endif
00936 if ((payload_len = ntohs(tmpP->iph->ip_len) - (IP_HLEN(tmpP->iph) << 2)) > 8)
00937 payload_len = 8;
00938
00939 memcpy((char *)icmph + ICMP_LEN_MIN, tmpP->iph, (IP_HLEN(tmpP->iph) << 2)
00940 + payload_len);
00941 sz = IP_HDR_LEN + ICMP_LEN_MIN + (IP_HLEN(tmpP->iph) << 2) + payload_len;
00942
00943 iph->ip_len = htons(sz);
00944 ip_checksum(icmp_pkt + link_offset, sz);
00945 sz += link_offset;
00946
00947 if (link_offset)
00948 n = eth_send(ethdev, icmp_pkt, sz);
00949 else
00950 n = ip_send(rawdev, icmp_pkt, sz);
00951
00952 if (n < sz)
00953 printf("failed to send icmp reset");
00954 }
00955 break;
00956 }
00957 if(link_offset)
00958 {
00959 eth_close(ethdev);
00960 }
00961 }
00962
00963
00964 #ifndef IPFW
00965 void HandlePacket(ipq_packet_msg_t *m)
00966 #else
00967 void HandlePacket()
00968 #endif
00969 {
00970 #ifndef IPFW
00971 int status;
00972 #endif
00973 if (iv.drop)
00974 {
00975 #ifndef IPFW
00976 #ifdef NFNETLINKQ
00977 status = nfq_set_verdict(qhndl, glid, NF_DROP, 0, NULL);
00978 if (status < 0)
00979 {
00980 fprintf(stderr,"NF_DROP: ");
00981 }
00982
00983 #else
00984 status = ipq_set_verdict(ipqh, m->packet_id, NF_DROP, 0, NULL);
00985 if (status < 0)
00986 {
00987 ipq_perror("NF_DROP: ");
00988 }
00989 #endif
00990 #endif
00991 if (iv.rejectsrc)
00992 {
00993 #ifndef IPFW
00994 RejectFu(m,0);
00995 #else
00996 RejectFu(0);
00997 #endif
00998 }
00999 if (iv.rejectdst)
01000 {
01001 #ifndef IPFW
01002 RejectFu(m,1);
01003 #else
01004 RejectFu(1);
01005 #endif
01006 }
01007
01008 }
01009 #ifndef IPFW
01010
01011 else if (!iv.replace)
01012 {
01013 #ifdef NFNETLINKQ
01014 if(!done)
01015 {
01016 status = nfq_set_verdict(qhndl, glid, NF_ACCEPT, 0, NULL);
01017 if (status < 0)
01018 {
01019 fprintf(stderr, "NF_ACCEPT: ");
01020 }
01021
01022 }
01023 #else
01024 status = ipq_set_verdict(ipqh, m->packet_id, NF_ACCEPT, 0, NULL);
01025 if (status < 0)
01026 {
01027 ipq_perror("NF_ACCEPT: ");
01028 }
01029 #endif
01030 }
01031 else
01032 {
01033 #ifdef NFNETLINKQ
01034 if(!done)
01035 {
01036 status = nfq_set_verdict(qhndl, glid, NF_ACCEPT, m->data_len, m->payload);
01037 if (status < 0)
01038 {
01039 fprintf(stderr,"NF_ACCEPT: ");
01040 }
01041 nfq_handle_packet(nfqh, buf, rcvstatus);
01042 done = 1;
01043 }
01044 #else
01045 status = ipq_set_verdict(ipqh, m->packet_id, NF_ACCEPT,
01046 m->data_len, m->payload);
01047 if (status < 0)
01048 {
01049 ipq_perror("NF_ACCEPT: ");
01050 }
01051 #endif
01052 }
01053 #ifdef NFNETLINKQ
01054 nfq_handle_packet(nfqh, buf, rcvstatus);
01055 done = 1;
01056 #endif
01057
01058 #endif
01059 }
01060
01061
01062 int InlineDrop()
01063 {
01064 iv.drop = 1;
01065 return 0;
01066 }
01067
01068 int InlineReject(Packet *p)
01069 {
01070 iv.rejectsrc = 1;
01071 iv.drop = 1;
01072 tmpP = p;
01073 return 0;
01074 }
01075
01076 int InlineRejectBoth(Packet *p)
01077 {
01078 iv.rejectsrc = 1;
01079 iv.rejectdst = 1;
01080 iv.drop = 1;
01081 tmpP = p;
01082 return 0;
01083 }
01084
01085 int InlineRejectSrc(Packet *p)
01086 {
01087 iv.rejectsrc = 1;
01088 iv.drop = 1;
01089 tmpP = p;
01090 return 0;
01091 }
01092
01093 int InlineRejectDst(Packet *p)
01094 {
01095 iv.rejectdst = 1;
01096 iv.drop = 1;
01097 tmpP = p;
01098 return 0;
01099 }
01100
01101 #ifdef IPFW
01102 int InlineReinject(Packet *p)
01103 {
01104 iv.rejectsrc = 0;
01105 iv.rejectdst = 0;
01106 iv.drop = 0;
01107 iv.reinject = 1;
01108 tmpP = p;
01109 return 0;
01110 }
01111 #endif
01112
01113 int InlineAccept()
01114 {
01115 iv.drop = 0;
01116 return 0;
01117 }
01118
01119 int InlineReplace()
01120 {
01121 iv.replace = 1;
01122 return 0;
01123 }
01124
01125 #else
01126
01127 #include "snort.h"
01128
01129 extern int g_drop_pkt;
01130 extern PV pv;
01131
01132
01133
01134
01135 int InlineMode()
01136 {
01137 if (pv.inline_flag)
01138 return 1;
01139
01140 return 0;
01141 }
01142
01143 int InlineDrop()
01144 {
01145 g_drop_pkt = 1;
01146
01147 return 0;
01148 }
01149 #endif
01150