From fa34b6f5f32f696bb2fe92a877dfaec960fcd850 Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 28 Sep 2015 21:10:05 +0000 Subject: [PATCH 1/1] network_cmds-481.20.1.tar.gz --- ecnprobe/capture.c | 4 +- ecnprobe/ecn.c | 231 ++++++++++++++++++++++++- ecnprobe/ecn.h | 2 + ecnprobe/ecn_probe.c | 21 ++- ecnprobe/inet.c | 10 +- ecnprobe/inet.h | 13 ++ ifconfig.tproj/ifconfig.c | 30 +++- network_cmds.xcodeproj/project.pbxproj | 9 +- unbound/doc/README.svn | 17 ++ 9 files changed, 313 insertions(+), 24 deletions(-) create mode 100644 unbound/doc/README.svn diff --git a/ecnprobe/capture.c b/ecnprobe/capture.c index 494fc21..34ed9ec 100644 --- a/ecnprobe/capture.c +++ b/ecnprobe/capture.c @@ -136,8 +136,8 @@ void CaptureInit(u_int32_t sourceIP, u_int16_t sourcePort, /* Setup initial filter */ sprintf(filtercmds, - "host %s and host %s and port %d\n", - source, target, targetPort); + "(host %s && host %s && port %d) || icmp\n", + source, target, targetPort); if (captureDebug) { printf("datalinkOffset = %d\n", datalinkOffset); diff --git a/ecnprobe/ecn.c b/ecnprobe/ecn.c index 82ebc01..f09282d 100644 --- a/ecnprobe/ecn.c +++ b/ecnprobe/ecn.c @@ -72,7 +72,6 @@ int EstablishTcpConnection(u_int8_t syn_flags, u_int8_t ip_tos) int tcpoptlen = 4; /* For negotiating MSS */ u_int8_t *opt = NULL; struct IPPacket *p = NULL; - u_int16_t nmss; /* allocate the syn packet -- Changed for new IPPacket structure */ synPacket = AllocateIPPacket(0, tcpoptlen, 0, "ECN (SYN)"); @@ -325,7 +324,6 @@ void DataPkt (char *filename, u_int8_t iptos, u_int8_t tcp_flags) /* Check if we have received any packets */ if ((read_packet =(char *)CaptureGetPacket(&pi)) != NULL) { - p = (struct IPPacket *)FindHeaderBoundaries(read_packet); /* @@ -535,7 +533,8 @@ void ECNAckData (struct IPPacket *p) SendSessionPacket(datapkt, ipsz, TCPFLAGS_PSH | TCPFLAGS_ACK | TCPFLAGS_CWR, 0, 0, 2); - + + session.snd_nxt += (datalen + 1); send_cwr = 1; FreeIPPacket(&datapkt); } @@ -722,3 +721,229 @@ void checkECN () } return; } + +void DataPktPathCheck(char *filename, u_int8_t iptos, u_int8_t tcp_flags) +{ + struct IPPacket *p, *datapkt; + struct pcap_pkthdr pi; + char *read_packet; + int i ; + int sendflag = 1 ; + u_int16_t lastSeqSent = session.snd_nxt; + double startTime = 0; + char *dataptr; + char data[MAXREQUESTLEN]; + int datalen; + int ipsz; + unsigned int init_ttl; + + datalen = PrepareRequest (data, filename); + + datapkt = AllocateIPPacket(0, 0, datalen + 1, "ECN (datapkt)"); + + dataptr = (char *)datapkt->tcp + sizeof(struct TcpHeader); + memcpy((void *)dataptr,(void *)data, datalen); + + ipsz = sizeof(struct IpHeader) + sizeof(struct TcpHeader) + datalen + 1; + /* send the data packet + * we try to "achieve" reliability by + * sending the packet upto 5 times, wating for + * 2 seconds between packets + * BAD busy-wait loop + */ + + i = 0 ; + init_ttl = 1; + while(1) { + + if (sendflag == 1) { + session.curr_ttl = ++init_ttl; + if (init_ttl > 64) /* reached the max */ + break; + SendSessionPacket(datapkt, ipsz, + TCPFLAGS_PSH | TCPFLAGS_ACK | tcp_flags, 0, 0, 0x3); + + startTime = GetTime(); + sendflag = 0; + i++ ; + } + + /* Check if we have received any packets */ + if ((read_packet =(char *)CaptureGetPacket(&pi)) != NULL) { + + p = (struct IPPacket *)FindHeaderBoundaries(read_packet); + + /* + * packet that we sent? + */ + + if (INSESSION(p,session.src, session.sport, + session.dst,session.dport) && + (p->tcp->tcp_flags == (TCPFLAGS_PSH | TCPFLAGS_ACK)) && + SEQ_GT(ntohl(p->tcp->tcp_seq), lastSeqSent) && + SEQ_LEQ(ntohl(p->tcp->tcp_ack), session.rcv_nxt)) { + lastSeqSent = ntohl(p->tcp->tcp_seq); + if (session.debug >= SESSION_DEBUG_LOW) { + printf("xmit %d\n", i); + PrintTcpPacket(p); + } + StorePacket(p); + session.snd_nxt += datalen + 1; + session.totSeenSent ++ ; + continue ; + } + + /* + * from them? + */ + if (INSESSION(p, session.dst, session.dport, session.src, + session.sport) && (p->tcp->tcp_flags & TCPFLAGS_ACK) && + (ntohl(p->tcp->tcp_seq) == session.rcv_nxt) && + ntohl(p->tcp->tcp_ack) == session.snd_nxt) { + session.snd_una = ntohl(p->tcp->tcp_ack); + session.snd_nxt = session.snd_una; + if (p->ip->ip_ttl != session.ttl) { + session.ttl = p->ip->ip_ttl; + } + if (session.debug >= SESSION_DEBUG_LOW) { + printf("rcvd %d\n", i); + PrintTcpPacket(p); + } + StorePacket(p); + session.totRcvd ++; + break ; + } + /* + * ICMP ttl exceeded + */ + if (p->ip->ip_p == IPPROTOCOL_ICMP) { + uint16_t ip_hl; + struct IcmpHeader *icmp; + ip_hl = (p->ip->ip_vhl & 0x0f) << 2; + void *nexthdr; + + icmp = (struct IcmpHeader *)((char *)p->ip + ip_hl); + nexthdr = (void *)icmp; + if (icmp->icmp_type == ICMP_TIMXCEED) { + struct IpHeader off_ip; + struct TcpHeader off_tcp; + + bzero(&off_ip, sizeof(struct IpHeader)); + nexthdr = nexthdr + sizeof(struct IcmpHeader); + memcpy((void *)&off_ip, nexthdr, + sizeof(struct IpHeader)); + nexthdr += sizeof(struct IpHeader); + + bzero(&off_tcp, sizeof(struct TcpHeader)); + memcpy(&off_tcp, nexthdr, 4); + if (session.src == off_ip.ip_src && + session.dst == off_ip.ip_dst) { + printf("Received ICMP TTL exceeded from %s:" + "ttl used %u ip_tos 0x%x sport %u dport %u\n", + InetAddress(p->ip->ip_src), init_ttl, off_ip.ip_tos, + ntohs(off_tcp.tcp_sport), ntohs(off_tcp.tcp_dport)); + } + } + } + /* + * otherwise, this is a bad packet + * we must quit + */ + //processBadPacket(p); + } + if ((GetTime() - startTime >= 1) && (sendflag == 0)) { + sendflag = 1; + session.snd_nxt = session.snd_una; + } + } + + FreeIPPacket(&datapkt); +} +void ECNPathCheckTest(u_int32_t sourceAddress, u_int16_t sourcePort, + u_int32_t targetAddress, u_int16_t targetPort, int mss) +{ + int rawSocket, rc, flag; + + arc4random_stir(); + + session.src = sourceAddress; + session.sport = sourcePort; + session.dst = targetAddress; + session.dport = targetPort; + session.rcv_wnd = 5*mss; + session.snd_nxt = arc4random(); + session.iss = session.snd_nxt; + session.rcv_nxt = 0; + session.irs = 0; + session.mss = mss; + session.maxseqseen = 0; + session.epochTime = GetTime(); + session.maxpkts = 1000; + session.debug = 0; + + if ((session.dataRcvd = (u_int8_t *)calloc(sizeof(u_int8_t), + mss * session.maxpkts)) == NULL) { + printf("no memory to store data, error: %d \n", ERR_MEM_ALLOC); + Quit(ERR_MEM_ALLOC); + } + + if ((rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { + perror("ERROR: couldn't open socket:"); + Quit(ERR_SOCKET_OPEN); + } + + flag = 1; + if (setsockopt(rawSocket, IPPROTO_IP, IP_HDRINCL, + (char *)&flag, sizeof(flag)) < 0) { + perror("ERROR: couldn't set raw socket options:"); + Quit(ERR_SOCKOPT); + } + + session.socket = rawSocket; + + /* Establish a TCP connections with ECN bits */ + rc = EstablishTcpConnection(TCPFLAGS_ECN_ECHO | TCPFLAGS_CWR, 0); + switch (rc) { + case ESTABLISH_FAILURE_EARLY_RST: + { + /* Received a RST when ECN bits are used. Try again without ECN */ + rc = EstablishTcpConnection(0, 0); + if (rc == ESTABLISH_FAILURE_EARLY_RST) { + printf("Received RST with or without ECN negotiation\n"); + printf("The server might not be listening on this port\n"); + Quit(EARLY_RST); + } else if (rc == ESTABLISH_SUCCESS) { + printf("Received RST with ECN.\n"); + printf("Connection established successfully without ECN\n"); + Quit(ECN_SYN_DROP); + } else if (rc == ESTABLISH_FAILURE_NO_REPLY) { + printf("Received RST with ECN\n"); + printf("Exceed max SYN retransmits without ECN\n"); + Quit(NO_CONNECTION); + } + break; + } + case ESTABLISH_FAILURE_NO_REPLY: + { + /* No reply after retring, try again without ECN */ + rc = EstablishTcpConnection(0, 0); + if (rc == ESTABLISH_FAILURE_EARLY_RST) { + printf("Exceeded max SYN retransmits with ECN\n"); + printf("Received RST without ECN\n"); + Quit(NO_CONNECTION); + } else if (rc == ESTABLISH_FAILURE_NO_REPLY) { + printf("Exceeded max SYN retransmits with ECN\n"); + printf("Exceeded max SYN retransmits without ECN\n"); + Quit(NO_CONNECTION); + } else { + printf("Exceeded max SYN retransmits with ECN\n"); + printf("Connection established successfully without ECN\n"); + Quit(ECN_SYN_DROP); + } + break; + } + } + + DataPktPathCheck(session.filename, 3, 0); + return; +} diff --git a/ecnprobe/ecn.h b/ecnprobe/ecn.h index b0fdbdc..adf8260 100644 --- a/ecnprobe/ecn.h +++ b/ecnprobe/ecn.h @@ -44,3 +44,5 @@ void ECNTest (u_int32_t sourceIpAddress, u_int16_t sourcePort, u_int32_t targetI void ECNAckData (struct IPPacket *p); void DataPkt (char *filename, u_int8_t iptos, u_int8_t tcp_flags); void checkECN (); +void ECNPathCheckTest(u_int32_t sourceIpAddress, u_int16_t surcePort, + u_int32_t targetIpAddress, u_int16_t targetPort, int mss); diff --git a/ecnprobe/ecn_probe.c b/ecnprobe/ecn_probe.c index 36e0967..9ff6193 100644 --- a/ecnprobe/ecn_probe.c +++ b/ecnprobe/ecn_probe.c @@ -78,6 +78,7 @@ void usage(char *name) printf("\t-s \n"); printf("\t-f \n"); printf("\t-d \n"); + printf("\t-C for CE path check\n"); return; } @@ -250,15 +251,13 @@ int main(int argc, char **argv) u_int32_t sourceIpAddress = 0; int mss = DEFAULT_MSS; int mtu = DEFAULT_MTU; - int fd; - int opt; - int usedev = 0, rc = 0; + int fd, opt, usedev = 0, rc = 0, path_check = 0; struct sockaddr_in saddr; char dev[11]; /* device name for pcap init */ struct ifaddrs *ifap, *tmp; bzero(&session, sizeof(session)); - while ((opt = getopt(argc, argv, "n:p:w:m:M:s:d:f:")) != -1) { + while ((opt = getopt(argc, argv, "n:p:w:m:M:s:d:f:-C")) != -1) { switch (opt) { case 'n': if (strlen(optarg) > (MAXHOSTNAMELEN - 1)) { @@ -306,6 +305,9 @@ int main(int argc, char **argv) printf("Invalid file name \n"); } break; + case 'C': + path_check = 1; + break; default: usage(argv[0]); exit(1); @@ -391,9 +393,14 @@ int main(int argc, char **argv) SetupFirewall(targetIpAddress, targetPort, dev); printf("Starting ECN test\n"); - ECNTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss); - - Cleanup(); + if (path_check) { + ECNPathCheckTest(sourceIpAddress, sourcePort, targetIpAddress, + targetPort, mss); + } else { + ECNTest(sourceIpAddress, sourcePort, targetIpAddress, + targetPort, mss); + } + Quit(SUCCESS); close(session.socket); return (0); } diff --git a/ecnprobe/inet.c b/ecnprobe/inet.c index e1c1d43..723101a 100644 --- a/ecnprobe/inet.c +++ b/ecnprobe/inet.c @@ -222,8 +222,8 @@ void ReadIPPacket(struct IPPacket *p, uint16 tcp_hl; /* XXX do checksum check? */ - if (ip->ip_p != IPPROTOCOL_TCP) { - printf("Error: not a TCP packet\n"); + if (ip->ip_p != IPPROTOCOL_TCP && ip->ip_p != IPPROTOCOL_ICMP) { + printf("Unexpected protocol packet: %u\n", ip->ip_p); Quit(ERR_CHECKSUM); } @@ -426,15 +426,15 @@ struct IPPacket *FindHeaderBoundaries(char *p) { packet->ip = (struct IpHeader *)p; - if (packet->ip->ip_p != IPPROTOCOL_TCP) { - printf("Error: not a TCP packet\n"); + if (packet->ip->ip_p != IPPROTOCOL_TCP && + packet->ip->ip_p != IPPROTOCOL_ICMP) { + printf("Error: Unexpected protocol packet: %u \n", packet->ip->ip_p); Quit(ERR_CHECKSUM); } ip_hl = (packet->ip->ip_vhl & 0x0f) << 2; packet->tcp = (struct TcpHeader *)((char *)p + ip_hl); - return packet; } diff --git a/ecnprobe/inet.h b/ecnprobe/inet.h index 0185be3..8d1ccff 100644 --- a/ecnprobe/inet.h +++ b/ecnprobe/inet.h @@ -55,6 +55,9 @@ typedef unsigned int uint32; #define IPPROTOCOL_UDP 17 #define IP_DF 0x4000 +/* ICMP type */ +#define ICMP_TIMXCEED 11 + /* TCP Flags */ #define TCPFLAGS_FIN 0x01 #define TCPFLAGS_SYN 0x02 @@ -154,6 +157,16 @@ struct ICMPUnreachableErrorPacket { uint32 tcp_seqno; }; +struct ICMPTimeExceededErrorPacket { + struct IpHeader ip; + struct IcmpHeader icmp; + struct IpHeader off_ip; + /* 8-first bytes of Tcpheader */ + uint16 tcp_sport; + uint16 tcp_dport; + uint32 tcp_seqno; +}; + char *InetAddress(uint32 addr); uint16 InetChecksum(uint16 *ip_addr, uint16 *tcp_addr, uint16 ip_len, uint16 tcp_len); diff --git a/ifconfig.tproj/ifconfig.c b/ifconfig.tproj/ifconfig.c index 4f01a15..1a708da 100644 --- a/ifconfig.tproj/ifconfig.c +++ b/ifconfig.tproj/ifconfig.c @@ -982,6 +982,33 @@ setexpensive(const char *vname, int value, int s, const struct afswtch *afp) } +void +setecnmode(const char *val, int dummy __unused, int s, + const struct afswtch *afp) +{ + char *cp; + + if (strcmp(val, "default") == 0) + ifr.ifr_ifru.ifru_ecn_mode = IFRTYPE_ECN_DEFAULT; + else if (strcmp(val, "enable") == 0) + ifr.ifr_ifru.ifru_ecn_mode = IFRTYPE_ECN_ENABLE; + else if (strcmp(val, "disable") == 0) + ifr.ifr_ifru.ifru_ecn_mode = IFRTYPE_ECN_DISABLE; + else { + ifr.ifr_ifru.ifru_ecn_mode = strtold(val, &cp); + if (val == cp || errno != 0) { + warn("Invalid ECN mode value '%s'", val); + return; + } + } + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + + if (ioctl(s, SIOCSECNMODE, (caddr_t)&ifr) < 0) + Perror("ioctl(SIOCSECNMODE)"); +} + + #define IFFBITS \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \ "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ @@ -991,7 +1018,7 @@ setexpensive(const char *vname, int value, int s, const struct afswtch *afp) "\020\1AUTOCONFIGURING\6IPV6_DISABLED\7ACCEPT_RTADV\10TXSTART\11RXPOLL" \ "\12VLAN\13BOND\14ARPLL\15NOWINDOWSCALE\16NOAUTOIPV6LL\17EXPENSIVE\20ROUTER4" \ "\21ROUTER6\22LOCALNET_PRIVATE\23ND6ALT\24RESTRICTED_RECV\25AWDL\26NOACKPRI" \ -"\27AWDL_RESTRICTED\30CL2K\35SENDLIST\36DIRECTLINK\40UPDOWNCHANGE" +"\27AWDL_RESTRICTED\30CL2K\31ECN_ENABLE\32ECN_DISABLE\35SENDLIST\36DIRECTLINK\40UPDOWNCHANGE" #define IFCAPBITS \ "\020\1RXCSUM\2TXCSUM\3VLAN_MTU\4VLAN_HWTAGGING\5JUMBO_MTU" \ @@ -1688,6 +1715,7 @@ static struct cmd basic_cmds[] = { DEF_CMD("-cl2k", 0, setcl2k), DEF_CMD("expensive", 1, setexpensive), DEF_CMD("-expensive", 0, setexpensive), + DEF_CMD_ARG("ecn", setecnmode), }; static __constructor void diff --git a/network_cmds.xcodeproj/project.pbxproj b/network_cmds.xcodeproj/project.pbxproj index 265f732..d7b9d4c 100755 --- a/network_cmds.xcodeproj/project.pbxproj +++ b/network_cmds.xcodeproj/project.pbxproj @@ -4420,7 +4420,7 @@ INSTALL_PATH = /usr/libexec; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = ""; + SDKROOT = macosx.internal; SUPPORTED_PLATFORMS = macosx; "USER_HEADER_SEARCH_PATHS[arch=*]" = unbound/; VALID_ARCHS = "x86_64 x86_64h"; @@ -4453,7 +4453,7 @@ INSTALL_PATH = /usr/libexec; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = ""; + SDKROOT = macosx.internal; SUPPORTED_PLATFORMS = macosx; "USER_HEADER_SEARCH_PATHS[arch=*]" = unbound; VALID_ARCHS = "x86_64 x86_64h"; @@ -4486,7 +4486,7 @@ INSTALL_PATH = /usr/libexec; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = ""; + SDKROOT = macosx.internal; SUPPORTED_PLATFORMS = macosx; VALID_ARCHS = "x86_64 x86_64h"; }; @@ -5478,7 +5478,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos.internal; }; name = Debug; }; @@ -5514,7 +5513,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos.internal; }; name = Release; }; @@ -5550,7 +5548,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos.internal; }; name = "Ignore Me"; }; diff --git a/unbound/doc/README.svn b/unbound/doc/README.svn new file mode 100644 index 0000000..b887e30 --- /dev/null +++ b/unbound/doc/README.svn @@ -0,0 +1,17 @@ +README.svn + +For a svn checkout: +* configure script, aclocal.m4, as well as yacc/lex output files are + committed to the repository. +* use --enable-debug flag for configure to enable dependency tracking and + assertions, otherwise, use make clean; make after svn update. + +* Note changes in the Changelog. +* Every check-in a postcommit hook is run + (the postcommit hook is in the svn/unbound/hooks directory). + * generates commit email with your changes and comment. + * compiles and runs the tests (with testcode/do-tests.sh). + * If build errors or test errors happen + * Please fix your errors and commit again. + +* Use gnu make to compile, make or 'gmake'. -- 2.45.2