]> git.saurik.com Git - apple/network_cmds.git/commitdiff
network_cmds-356.9.tar.gz mac-os-x-1075 v356.9
authorApple <opensource@apple.com>
Fri, 16 Mar 2012 21:38:31 +0000 (21:38 +0000)
committerApple <opensource@apple.com>
Fri, 16 Mar 2012 21:38:31 +0000 (21:38 +0000)
kdumpd.tproj/kdump.h
kdumpd.tproj/kdumpd.c
kdumpd.tproj/kdumpsubs.c

index 22b732d387bf78fb22d8bff8cdf060e80af32d5d..9536946c0876ead2598a22ce139138752cea2c32 100644 (file)
@@ -56,6 +56,9 @@
 
 #ifndef _KDUMP_H_
 #define        _KDUMP_H_
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
 
 /* Mac OS X kernel core dump server, based on the BSD trivial file
  * transfer protocol server (FreeBSD distribution), with several
@@ -64,7 +67,7 @@
  */
 
 #define        SEGSIZE         512             /* data segment size */
-
+#define MAXIMUM_KDP_PKTSIZE (16384)
 /*
  * Packet types.
  */
@@ -83,7 +86,7 @@ struct        kdumphdr {
                unsigned int tu_code;   /* error code */
                char    tu_stuff[1];    /* request packet stuff */
        } th_u;
-       char    th_data[1];             /* data or error string */
+       char    th_data[0];             /* data or error string */
 }__attribute__((packed));
 
 #define        th_block        th_u.tu_block
@@ -103,4 +106,9 @@ struct      kdumphdr {
 #define        EEXISTS         6               /* file already exists */
 #define        ENOUSER         7               /* no such user */
 
+#define DEBUG 0
+#define WRITE_DEBUG 0
+#define KDUMPD_DEBUG_LEVEL LOG_ALERT
+#define KDP_LARGE_CRASHDUMP_PKT_SIZE (1440 - sizeof(struct udpiphdr))
+
 #endif
index dfbb4bde4ffbad8511a5b806830e2acaafb2b798..4ad72c9a1334eb10dcbe9be5d736ad35a6c8335f 100644 (file)
@@ -55,11 +55,13 @@ static const char copyright[] =
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <sys/mman.h>
 
 #include <netinet/in.h>
 #include "kdump.h"
 #include <arpa/inet.h>
 
+#include <stdint.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -76,15 +78,16 @@ static const char copyright[] =
 
 #include "kdumpsubs.h"
 
-#define        TIMEOUT         5
+#define        TIMEOUT         2
 
 int    peer;
 int    rexmtval = TIMEOUT;
-int    maxtimeout = 10*TIMEOUT;
+int    maxtimeout = 25 * TIMEOUT;
 
 #define        PKTSIZE SEGSIZE+6
-char   buf[PKTSIZE];
-char   ackbuf[PKTSIZE];
+
+char   buf[MAXIMUM_KDP_PKTSIZE];
+char   ackbuf[MAXIMUM_KDP_PKTSIZE];
 struct sockaddr_in from;
 socklen_t fromlen;
 
@@ -109,11 +112,14 @@ static int        ipchroot;
 static char *errtomsg __P((int));
 static void  nak __P((int));
 static char * __P(verifyhost(struct sockaddr_in *));
+uint32_t kdp_crashdump_pkt_size = (SEGSIZE + (sizeof(struct kdumphdr)));
+uint32_t kdp_crashdump_seg_size = SEGSIZE;
 
 #define KDP_FEATURE_MASK_STRING                "features"
-enum   {KDP_FEATURE_LARGE_CRASHDUMPS = 1};
-uint32_t       kdp_crashdump_feature_mask;
-uint32_t       kdp_feature_large_crashdumps;
+enum   {KDP_FEATURE_LARGE_CRASHDUMPS = 1, KDP_FEATURE_LARGE_PKT_SIZE = 2};
+
+uint32_t kdp_crashdump_feature_mask;
+uint32_t kdp_feature_large_crashdumps, kdp_feature_large_packets;
 
 int
 main(argc, argv)
@@ -355,8 +361,15 @@ again:
        if (strncmp(KDP_FEATURE_MASK_STRING, cp, sizeof(KDP_FEATURE_MASK_STRING)) == 0) {
                kdp_crashdump_feature_mask = ntohl(*(uint32_t *) (cp + sizeof(KDP_FEATURE_MASK_STRING)));
                kdp_feature_large_crashdumps = kdp_crashdump_feature_mask & KDP_FEATURE_LARGE_CRASHDUMPS;
-               syslog(LOG_INFO, "Received feature mask %s:%hx", cp, kdp_crashdump_feature_mask);
-       }
+               kdp_feature_large_packets = kdp_crashdump_feature_mask & KDP_FEATURE_LARGE_PKT_SIZE;
+
+               if (kdp_feature_large_packets) {
+                       kdp_crashdump_pkt_size = KDP_LARGE_CRASHDUMP_PKT_SIZE;
+                       kdp_crashdump_seg_size = kdp_crashdump_pkt_size - sizeof(struct kdumphdr);
+               }
+               syslog(KDUMPD_DEBUG_LEVEL, "Received feature mask %s:0x%x", cp, kdp_crashdump_feature_mask);
+       } else
+               syslog(KDUMPD_DEBUG_LEVEL, "Unable to locate feature mask, mode: %s", mode);
        
        for (pf = formats; pf->f_mode; pf++)
                if (strcmp(pf->f_mode, mode) == 0)
@@ -367,7 +380,7 @@ again:
        }
        ecode = (*pf->f_validate)(&filename, tp->th_opcode);
        if (logging) {
-               syslog(LOG_INFO, "%s: %s request for %s: %s", verifyhost(&from),
+               syslog(KDUMPD_DEBUG_LEVEL, "%s: %s request for %s: %s", verifyhost(&from),
                        tp->th_opcode == WRQ ? "write" : "read",
                        filename, errtomsg(ecode));
        }
@@ -420,7 +433,7 @@ validate_access(char **filep, int mode)
     return (errno);
 
 
-  fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC);
+  fd = open(filename, O_RDWR|O_CREAT|O_TRUNC , S_IRUSR | S_IWUSR);
 
   if (fd < 0)
     return (errno + 100);
@@ -456,7 +469,6 @@ justquit()
        exit(0);
 }
 
-
 /*
  * Receive a file.
  */
@@ -477,7 +489,7 @@ recvfile(pf)
        do {
 send_seek_ack: timeout = 0;
                if (block == 0)
-                       ap->th_opcode = htons((u_short)ACK | (kdp_feature_large_crashdumps << 8));
+                       ap->th_opcode = htons((u_short)ACK | ((kdp_feature_large_crashdumps | kdp_feature_large_packets)  << 8));
                else
                        ap->th_opcode = htons((u_short)ACK);
                ap->th_block = htonl((unsigned int)block);
@@ -496,7 +508,7 @@ send_ack:
                write_behind(file, pf->f_convert);
                for ( ; ; ) {
                        alarm(rexmtval);
-                       n = recv(peer, dp, PKTSIZE, 0);
+                       n = recv(peer, dp, kdp_crashdump_pkt_size, 0);
                        alarm(0);
                        if (n < 0) {            /* really? */
                                syslog(LOG_ERR, "read: %m");
@@ -504,8 +516,13 @@ send_ack:
                        }
                        dp->th_opcode = ntohs((u_short)dp->th_opcode);
                        dp->th_block = ntohl((unsigned int)dp->th_block);
+#if    DEBUG
+                       syslog(KDUMPD_DEBUG_LEVEL, "Received packet type %u, block %u\n", (unsigned)dp->th_opcode, (unsigned)dp->th_block);
+#endif
+                       
                        if (dp->th_opcode == ERROR)
                                goto abort;
+                       
                        if (dp->th_opcode == KDP_EOF)
                          {
                            syslog (LOG_ERR, "Received last panic dump packet");
@@ -520,16 +537,14 @@ send_ack:
 
                                if (kdp_feature_large_crashdumps) {
                                        crashdump_offset = OSSwapBigToHostInt64((*(uint64_t *)dp->th_data));
-#if    DEBUG                                   
-                                       syslog(LOG_INFO, "Large offset");
-#endif                                 
                                }
                                else {
                                bcopy (dp->th_data, &tempoff, sizeof(unsigned int));
                                crashdump_offset = ntohl(tempoff);
                                }
+
 #if    DEBUG
-                               syslog(LOG_INFO, "Seeking to offset 0x%llx\n", crashdump_offset);
+                               syslog(KDUMPD_DEBUG_LEVEL, "Seeking to offset 0x%llx\n", crashdump_offset);
 #endif
                                errno = 0;
                                lseek(fileno (file), crashdump_offset, SEEK_SET);
@@ -540,11 +555,11 @@ send_ack:
                              }
                            (void) synchnet(peer);
                            if (dp->th_block == (block-1))
-                             {
-                               syslog (LOG_DAEMON|LOG_ERR, "Retransmitting seek ack - current block %hu, received block %hu", block, dp->th_block);
-                               goto send_ack;          /* rexmit */
-                             }
-                         }
+                           {
+                                   syslog (LOG_DAEMON|LOG_ERR, "Retransmitting seek ack - current block %u, received block %u", block, dp->th_block);
+                                   goto send_ack;          /* rexmit */
+                           }
+                       }
 
                        if (dp->th_opcode == DATA) {
                                if (dp->th_block == block) {
@@ -554,14 +569,16 @@ send_ack:
                                (void) synchnet(peer);
                                if (dp->th_block == (block-1))
                                  {
-                                   syslog (LOG_DAEMON|LOG_ERR, "Retransmitting ack - current block %hu, received block %hu", block, dp->th_block);
+                                   syslog (LOG_DAEMON|LOG_ERR, "Retransmitting ack - current block %u, received block %u", block, dp->th_block);
                                    goto send_ack;          /* rexmit */
                                  }
                                else
-                                 syslog (LOG_DAEMON|LOG_ERR, "Not retransmitting ack - current block %hu, received block %hu", block, dp->th_block);
+                                 syslog (LOG_DAEMON|LOG_ERR, "Not retransmitting ack - current block %u, received block %u", block, dp->th_block);
                        }
                }
-
+#if DEBUG
+               syslog(KDUMPD_DEBUG_LEVEL, "Writing block sized %u, current offset 0x%llx\n", n - 6, ftello(file));
+#endif
                size = writeit(file, &dp, n - 6, pf->f_convert);
                if (size != (n-6)) {                    /* ahem */
                        if (size < 0) nak(errno + 100);
index 1f37ce83286676a1d3f20df9bdde478e22d5bd51..283ca62c4abae4d840fe329c6f89a69f83607908 100644 (file)
@@ -53,6 +53,7 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <syslog.h>
 
 #include "kdumpsubs.h"
 
@@ -60,7 +61,7 @@
 
 struct bf {
        int counter;            /* size of data in buffer, or flag */
-       char buf[PKTSIZE];      /* room for data packet */
+       char buf[MAXIMUM_KDP_PKTSIZE];      /* room for data packet */
 } bfs[2];
 
                                /* Values for bf.counter  */
@@ -80,6 +81,9 @@ static struct kdumphdr *rw_init __P ((int));
 struct kdumphdr *w_init() { return rw_init(0); }         /* write-behind */
 struct kdumphdr *r_init() { return rw_init(1); }         /* read-ahead */
 
+extern uint32_t kdp_crashdump_pkt_size;
+extern uint32_t kdp_crashdump_seg_size;
+
 /* init for either read-ahead or write-behind */
 /* zero for write-behind, one for read-head */
 static struct kdumphdr *
@@ -140,12 +144,12 @@ read_ahead(FILE *file, int convert)
        dp = (struct kdumphdr *)b->buf;
 
        if (convert == 0) {
-               b->counter = read(fileno(file), dp->th_data, SEGSIZE);
+               b->counter = read(fileno(file), dp->th_data, kdp_crashdump_seg_size);
                return;
        }
 
        p = dp->th_data;
-       for (i = 0 ; i < SEGSIZE; i++) {
+       for (i = 0 ; i < kdp_crashdump_seg_size; i++) {
                if (newline) {
                        if (prevchar == '\n')
                                c = '\n';       /* lf to cr,lf */
@@ -182,6 +186,7 @@ writeit(FILE *file, struct kdumphdr **dpp, int ct, int convert)
        return ct;                      /* this is a lie of course */
 }
 
+
 /*
  * Output a buffer to a file, converting from netascii if requested.
  * CR,NUL -> CR  and CR,LF => LF.
@@ -250,7 +255,7 @@ int
 synchnet(int f)
 {
        int i, j = 0;
-       char rbuf[PKTSIZE];
+       char rbuf[kdp_crashdump_pkt_size];
        struct sockaddr_in from;
        socklen_t fromlen;