]> git.saurik.com Git - apple/network_cmds.git/commitdiff
network_cmds-481.20.1.tar.gz os-x-10112 os-x-10113 os-x-10114 os-x-10115 os-x-10116 v481.20.1
authorApple <opensource@apple.com>
Mon, 28 Sep 2015 21:10:05 +0000 (21:10 +0000)
committerApple <opensource@apple.com>
Mon, 28 Sep 2015 21:10:05 +0000 (21:10 +0000)
ecnprobe/capture.c
ecnprobe/ecn.c
ecnprobe/ecn.h
ecnprobe/ecn_probe.c
ecnprobe/inet.c
ecnprobe/inet.h
ifconfig.tproj/ifconfig.c
network_cmds.xcodeproj/project.pbxproj
unbound/doc/README.svn [new file with mode: 0644]

index 494fc2197c9f3802396d001442529ef526e75225..34ed9ece68e414a58cd2b9e41e0aebdfe072ceb1 100644 (file)
@@ -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);
index 82ebc0197897ee88b2b50490b319f94bf18bcb6e..f09282d7e3faeededd48a22ccaacd6fcfb0f2cbf 100644 (file)
@@ -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;
+}
index b0fdbdcfe1fad7609e78cdfa0e9b9b5a2c50688b..adf826004b9ca376966a3b9c2fb07c5a4422bb45 100644 (file)
@@ -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);
index 36e0967f02a8ca1e1c0855a8d106bfee4da585b9..9ff6193b1b3f6c1de988c7aea7062ebd884ec3db 100644 (file)
@@ -78,6 +78,7 @@ void usage(char *name)
        printf("\t-s <source hostname or ip address>\n");
        printf("\t-f <file-name to get>\n");
        printf("\t-d <interface name>\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);
 }
index e1c1d4363b5f01110c81a3d4f2bd1121fe60ce27..723101a9e0e4c5650943ed184d6b8fd626e99177 100644 (file)
@@ -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;
 
 }
index 0185be3716420519ab7b0a73d59983dc30bc9b88..8d1ccff84f659c56d8025c529ef5f4b4c5cdc664 100644 (file)
@@ -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);
index 4f01a15b9d54b4864db6f5138f72397a60bb47d5..1a708da087ed54f47bd612e910b3d98d417a8b3a 100644 (file)
@@ -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
index 265f7329a189569239bd1ad9ebfaed0fe1c4d73a..d7b9d4c1753aeba5f1fc6b5df6dc43b1e7abb8b6 100755 (executable)
                                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";
                                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";
                                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";
                        };
                                MACOSX_DEPLOYMENT_TARGET = 10.11;
                                MTL_ENABLE_DEBUG_INFO = YES;
                                PRODUCT_NAME = "$(TARGET_NAME)";
-                               SDKROOT = iphoneos.internal;
                        };
                        name = Debug;
                };
                                MACOSX_DEPLOYMENT_TARGET = 10.11;
                                MTL_ENABLE_DEBUG_INFO = NO;
                                PRODUCT_NAME = "$(TARGET_NAME)";
-                               SDKROOT = iphoneos.internal;
                        };
                        name = Release;
                };
                                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 (file)
index 0000000..b887e30
--- /dev/null
@@ -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'.