⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpip.cc

📁 Ubuntu packages of security software。 相当不错的源码
💻 CC
📖 第 1 页 / 共 5 页
字号:
  assert(source);  assert(ipoptlen%4==0);    /* Time to live */  if (ttl == -1) {    myttl = (get_random_uint() % 23) + 37;  } else {    myttl = ttl;  }    udp->uh_sport = htons(sport);  udp->uh_dport = htons(dport);  udp->uh_sum   = 0;  udp->uh_ulen  = htons(sizeof(udphdr_bsd) + datalen);    /* We should probably copy the data over too */  if (data)    memcpy((u8*)udp + sizeof(udphdr_bsd), data, datalen);    /* Now the pseudo header for checksuming */  pseudo->source.s_addr = source->s_addr;  pseudo->dest.s_addr = victim->s_addr;  pseudo->zer0  = 0;  pseudo->proto = IPPROTO_UDP;  pseudo->length = htons(sizeof(udphdr_bsd) + datalen);    /* OK, now we should be able to compute a valid checksum */#if STUPID_SOLARIS_CHECKSUM_BUG  udp->uh_sum = sizeof(udphdr_bsd) + datalen;#else  udp->uh_sum = in_cksum((unsigned short *)pseudo, 20 /* pseudo + UDP headers */ + datalen);#endif    if ( o.badsum )    --udp->uh_sum;    fill_ip_raw(ip, packetlen, ipopt, ipoptlen,	tos, ipid, df?IP_DF:0, myttl, IPPROTO_UDP,	source, victim);    *outpacketlen = packetlen;  return packet;}int send_udp_raw( int sd, struct eth_nfo *eth,		  struct in_addr *source, const struct in_addr *victim, 		  int ttl, u16 ipid, 		  u8* ipopt, int ipoptlen, 		  u16 sport, u16 dport, 		  char *data, u16 datalen) {  unsigned int packetlen;  int res = -1;  u8 *packet = build_udp_raw(source, victim,  			     ttl, ipid, IP_TOS_DEFAULT, false,  			     ipopt, ipoptlen,  			     sport, dport,  			     data, datalen, &packetlen);  if (!packet) return -1;  res = send_ip_packet(sd, eth, packet, packetlen);  free(packet);  return res;}/* Builds an IP packet (including an IP header) by packing the fields   with the given information.  It allocates a new buffer to store the   packet contents, and then returns that buffer.  The packet is not   actually sent by this function.  Caller must delete the buffer when   finished with the packet.  The packet length is returned in   packetlen, which must be a valid int pointer. */u8 *build_ip_raw(const struct in_addr *source, const struct in_addr *victim, 		 u8 proto,		 int ttl, u16 ipid, u8 tos, bool df,		 u8 *ipopt, int ipoptlen,		 char *data, u16 datalen, 		 u32 *outpacketlen) {int packetlen = sizeof(struct ip) + ipoptlen + datalen;u8 *packet = (u8 *) safe_malloc(packetlen);struct ip *ip = (struct ip *) packet;static int myttl = 0;/* check that required fields are there and not too silly */assert(source);assert(victim);assert(ipoptlen%4==0);/* Time to live */if (ttl == -1) {	        myttl = (get_random_uint() % 23) + 37;} else {	        myttl = ttl;}  fill_ip_raw(ip, packetlen, ipopt, ipoptlen,	tos, ipid, df?IP_DF:0, myttl, proto,	source, victim); /* We should probably copy the data over too */ if (data)    memcpy((u8*)ip + sizeof(struct ip) + ipoptlen, data, datalen);  *outpacketlen = packetlen; return packet;}/* You need to call sethdrinclude(sd) on the sending sd before calling this */int send_ip_raw( int sd, struct eth_nfo *eth,		 struct in_addr *source, const struct in_addr *victim,		 u8 proto, int ttl,		 u8* ipopt, int ipoptlen,		 		 char *data, u16 datalen) {  unsigned int packetlen;  int res = -1;  u8 *packet = build_ip_raw(source, victim,    			    proto,  			    ttl, get_random_u16(), IP_TOS_DEFAULT, false,  			    ipopt, ipoptlen,  			    data, datalen, &packetlen);  if (!packet) return -1;  res = send_ip_packet(sd, eth, packet, packetlen);  free(packet);  return res;}int unblock_socket(int sd) {#ifdef WIN32u_long one = 1;if(sd != 501) // Hack related to WinIP Raw Socket support  ioctlsocket (sd, FIONBIO, &one);#elseint options;/*Unblock our socket to prevent recvfrom from blocking forever  on certain target ports. */options = O_NONBLOCK | fcntl(sd, F_GETFL);fcntl(sd, F_SETFL, options);#endif //WIN32return 1;}/* Read an IP packet using libpcap .  We return the packet and take   a pcap descripter and a pointer to the packet length (which we set   in the function. If you want a maximum length returned, you   should specify that in pcap_open_live() *//* to_usec is the timeout period in microseconds -- use 0 to skip the   test and -1 to block forever.  Note that we don't interrupt pcap, so   low values (and 0) degenerate to the timeout specified    in pcap_open_live() *//* If rcvdtime is non-null and a packet is returned, rcvd will be   filled with the time that packet was captured from the wire by   pcap.  If linknfo is not NULL, linknfo->headerlen and   linknfo->header will be filled with the appropriate values. */char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec, 		  struct timeval *rcvdtime, struct link_header *linknfo) {unsigned int offset = 0;struct pcap_pkthdr head;char *p;int datalink;int pcap_descriptor=-1; // -1 means we CANNOT select()int timedout = 0;struct timeval tv_start, tv_end;static char *alignedbuf = NULL;static unsigned int alignedbufsz=0;static int warning = 0;if (linknfo) { memset(linknfo, 0, sizeof(*linknfo)); }if (!pd) fatal("NULL packet device passed to readip_pcap"); if (to_usec < 0) {   if (!warning) {     warning = 1;     error("WARNING: Negative timeout value (%lu) passed to readip_pcap() -- using 0", to_usec);   }   to_usec = 0; }/* New packet capture device, need to recompute offset */ if ( (datalink = pcap_datalink(pd)) < 0)   fatal("Cannot obtain datalink information: %s", pcap_geterr(pd)); /* NOTE: IF A NEW OFFSET EVER EXCEEDS THE CURRENT MAX (24), ADJUST    MAX_LINK_HEADERSZ in tcpip.h */ switch(datalink) { case DLT_EN10MB: offset = 14; break; case DLT_IEEE802: offset = 22; break;#ifdef __amigaos__ case DLT_MIAMI: offset = 16; break;#endif#ifdef DLT_LOOP case DLT_LOOP:#endif case DLT_NULL: offset = 4; break; case DLT_SLIP:#ifdef DLT_SLIP_BSDOS case DLT_SLIP_BSDOS:#endif#if (FREEBSD || OPENBSD || NETBSD || BSDI || MACOSX)   offset = 16;#else   offset = 24; /* Anyone use this??? */#endif   break; case DLT_PPP: #ifdef DLT_PPP_BSDOS case DLT_PPP_BSDOS:#endif#ifdef DLT_PPP_SERIAL case DLT_PPP_SERIAL:#endif#ifdef DLT_PPP_ETHER case DLT_PPP_ETHER:#endif#if (FREEBSD || OPENBSD || NETBSD || BSDI || MACOSX)   offset = 4;#else#ifdef SOLARIS   offset = 8;#else   offset = 24; /* Anyone use this? */#endif /* ifdef solaris */#endif /* if freebsd || openbsd || netbsd || bsdi */   break; case DLT_RAW: offset = 0; break; case DLT_FDDI: offset = 21; break;#ifdef DLT_ENC case DLT_ENC: offset = 12; break;#endif /* DLT_ENC */#ifdef DLT_LINUX_SLL case DLT_LINUX_SLL: offset = 16; break;#endif default:   p = (char *) pcap_next(pd, &head);   if (head.caplen == 0) {     /* Lets sleep a brief time and try again to increase the chance of seeing	a real packet ... */     usleep(500000);     p = (char *) pcap_next(pd, &head);   }   if (head.caplen > 100000) {     fatal("FATAL: readip_pcap: bogus caplen from libpcap (%d) on interface type %d", head.caplen, datalink);   }    error("FATAL:  Unknown datalink type (%d). Caplen: %d; Packet:\n", datalink, head.caplen);   lamont_hdump(p, head.caplen);   exit(1); } if (to_usec > 0) {   gettimeofday(&tv_start, NULL); } pcap_descriptor = -1; if (pcap_selectable_fd_valid())     pcap_descriptor = my_pcap_get_selectable_fd(pd); do {#ifdef WIN32   gettimeofday(&tv_end, NULL);   long to_left = MAX(1, (to_usec - TIMEVAL_SUBTRACT(tv_end, tv_start)) / 1000);   // Set the timeout (BUGBUG: this is cheating)   PacketSetReadTimeout(pd->adapter, to_left);#endif   p = NULL;   if (pcap_descriptor != -1) {     fd_set rfds;     struct timeval sel_tv;     int rv=0;     FD_ZERO(&rfds);     FD_SET(pcap_descriptor, &rfds);     sel_tv.tv_sec = to_usec/1000000;     sel_tv.tv_usec = to_usec%1000000;     rv = select(pcap_descriptor+1, &rfds, NULL, NULL, to_usec ? &sel_tv : NULL);     if (rv == -1) {       fatal("Your system does not support select()ing on pcap devices (%s). PLEASE REPORT THIS ALONG WITH DETAILED SYSTEM INFORMATION TO THE nmap-dev MAILING LIST!", strerror(errno));     } else if (rv == 0) {       timedout = 1;     } else {       p = (char *) pcap_next(pd, &head);     }   } else {     // THIS CALL CAN BLOCK INAPPROPRIATLEY! (ie, will block until it sees another     // packet - to_usec notwithstanding) Use the select() code if possible.     p = (char *) pcap_next(pd, &head);   }   if (p) {     if (head.caplen <= offset) {       *len = 0;       return NULL;     }     if (offset && linknfo) {       linknfo->datalinktype = datalink;       linknfo->headerlen = offset;       assert(offset < MAX_LINK_HEADERSZ);       memcpy(linknfo->header, p, MIN(sizeof(linknfo->header), offset));     }     p += offset;   }   if (!p || (*p & 0x40) != 0x40) {     /* Should we timeout? */     if (to_usec == 0) {       timedout = 1;     } else if (to_usec > 0) {       gettimeofday(&tv_end, NULL);       if (TIMEVAL_SUBTRACT(tv_end, tv_start) >= to_usec) {	 timedout = 1;            }     }   } } while(!timedout && (!p || (*p & 0x40) != 0x40)); /* Go until we get IPv4 packet */ if (timedout) {   *len = 0;   return NULL; } *len = head.caplen - offset; if (*len > alignedbufsz) {   alignedbuf = (char *) realloc(alignedbuf, *len);   if (!alignedbuf) {     fatal("Unable to realloc %d bytes of mem", *len);   }   alignedbufsz = *len; } memcpy(alignedbuf, p, *len); // printf("Just got a packet at %li,%li\n", head.ts.tv_sec, head.ts.tv_usec); if (rcvdtime) {   // FIXME: I eventually need to figure out why Windows head.ts time is sometimes BEFORE the time I   // sent the packet (which is according to gettimeofday() in nbase).  For now, I will sadly have to   // use gettimeofday() for Windows in this case   // Actually I now allow .05 discrepancy.   So maybe this isn't needed.  I'll comment out for now.   // Nope: it is still needed at least for Windows.  Sometimes the time from he pcap header is a    // COUPLE SECONDS before the gettimeofday() results :(.#if defined(WIN32) || defined(__amigaos__)   gettimeofday(&tv_end, NULL);   *rcvdtime = tv_end;#else   rcvdtime->tv_sec = head.ts.tv_sec;   rcvdtime->tv_usec = head.ts.tv_usec;   assert(head.ts.tv_sec);#endif } if (rcvdtime)   PacketTrace::trace(PacketTrace::RCVD, (u8 *) alignedbuf, *len, rcvdtime); else PacketTrace::trace(PacketTrace::RCVD, (u8 *) alignedbuf, *len); return alignedbuf;}// Returns whether the system supports pcap_get_selectable_fd() properlybool pcap_selectable_fd_valid() {#if defined(WIN32) || defined(MACOSX)  return false;#endif  return true;}/* Call this instead of pcap_get_selectable_fd directly (or your code   won't compile on Windows).  On systems which don't seem to support   the pcap_get_selectable_fd() function properly, returns -1,   otherwise simply calls pcap_selectable_fd and returns the   results.  If you just want to test whether the function is supported,   use pcap_selectable_fd_valid() instead. */int my_pcap_get_selectable_fd(pcap_t *p) {#if defined(WIN32) || defined(MACOSX)  return -1;#else  assert(pcap_selectable_fd_valid());  return pcap_get_selectable_fd(p);#endif} // Returns whether the packet receive time value obtained from libpcap// (and thus by readip_pcap()) should be considered valid.  When// invalid (Windows and Amiga), readip_pcap returns the time you called it.bool pcap_recv_timeval_valid() {#if defined(WIN32) || defined(__amigaos__)  return false;#else  return

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -