/* Write a record for a packet to a dump file. Returns TRUE on success, FALSE on failure. */ gboolean libpcap_write_enhanced_packet_block(FILE *fp, const struct pcap_pkthdr *phdr, guint32 interface_id, const u_char *pd, long *bytes_written, int *err) { struct epb epb; guint32 block_total_length; guint64 timestamp; const guint32 padding = 0; block_total_length = sizeof(struct epb) + ADD_PADDING(phdr->caplen) + sizeof(guint32); timestamp = (guint64)(phdr->ts.tv_sec) * 1000000 + (guint64)(phdr->ts.tv_usec); epb.block_type = ENHANCED_PACKET_BLOCK_TYPE; epb.block_total_length = block_total_length; epb.interface_id = interface_id; epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff); epb.timestamp_low = (guint32)(timestamp & 0xffffffff); epb.captured_len = phdr->caplen; epb.packet_len = phdr->len; WRITE_DATA(fp, &epb, sizeof(struct epb), *bytes_written, err); WRITE_DATA(fp, pd, phdr->caplen, *bytes_written, err); if (phdr->caplen % 4) { WRITE_DATA(fp, &padding, 4 - phdr->caplen % 4, *bytes_written, err); } WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err); return TRUE; }
int serverPoolAddPoolElement(ServerPool pool, PoolElement newPoolElement) { char buf[POOLHANDLE_SIZE + 5]; size_t poolHandleLen; uint32 peId; if (!newPoolElement) { logDebug("newPoolElement is NULL\n"); return -1; } if (!pool) { logDebug("pool is NULL\n"); return -1; } /* calculate checksum for pool element */ memset(buf, 0, sizeof(buf)); poolHandleLen = strlen(pool->spHandle); if (poolHandleLen < POOLHANDLE_SIZE) { memcpy(buf, pool->spHandle, poolHandleLen); peId = htonl(newPoolElement->peIdentifier); memcpy(buf + ADD_PADDING(poolHandleLen), &peId, 4); newPoolElement->peChecksum = checksumCompute(0, buf, ADD_PADDING(poolHandleLen) + 4); } else { logDebug("pool handle size is too big, can not calculate checksum"); return -1; } /* check if already in peList */ if (serverPoolGetPoolElementById(pool, newPoolElement->peIdentifier) != NULL) { logDebug("pelement with id 0x%08x is already in list, can not add it\n", newPoolElement->peIdentifier); return -1; } newPoolElement->poolPrev = NULL; newPoolElement->poolNext = pool->spPeList; if (pool->spPeList) { pool->spPeList->poolPrev = newPoolElement; } pool->spPeList = newPoolElement; newPoolElement->peServerPool = pool; logDebug("added 0x%08x to pool %s", newPoolElement->peIdentifier, pool->spHandle); return 1; }
static guint32 pcapng_count_string_option(const char *option_value) { if ((option_value != NULL) && (strlen(option_value) > 0) && (strlen(option_value) < G_MAXUINT16)) { /* There's a value to write; get its length */ return (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(option_value))); } return 0; /* nothing to write */ }
static void dissect_error_causes(tvbuff_t *error_causes_tvb, proto_tree *parameter_tree) { guint16 length, total_length; gint offset; tvbuff_t *error_cause_tvb; offset = 0; while(tvb_reported_length_remaining(error_causes_tvb, offset) > 0) { length = tvb_get_ntohs(error_causes_tvb, offset + CAUSE_LENGTH_OFFSET); total_length = ADD_PADDING(length); error_cause_tvb = tvb_new_subset_length(error_causes_tvb, offset , total_length); dissect_error_cause(error_cause_tvb, parameter_tree); offset += total_length; } }
gboolean libpcap_write_session_header_block(FILE *fp, char *appname, long *bytes_written, int *err) { struct shb shb; struct option option; guint32 block_total_length; const guint32 padding = 0; block_total_length = sizeof(struct shb) + sizeof(guint32); if ((strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) { block_total_length += 2 * sizeof(struct option) + (guint16)(ADD_PADDING(strlen(appname) + 1)); } /* write shb header */ shb.block_type = SECTION_HEADER_BLOCK_TYPE; shb.block_total_length = block_total_length; shb.byte_order_magic = PCAPNG_MAGIC; shb.major_version = PCAPNG_MAJOR_VERSION; shb.minor_version = PCAPNG_MINOR_VERSION; shb.section_length = -1; WRITE_DATA(fp, &shb, sizeof(struct shb), *bytes_written, err); if ((strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) { /* write shb_userappl options */ option.type = SHB_USERAPPL; option.value_length = (guint16)(strlen(appname) + 1); WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err); WRITE_DATA(fp, appname, strlen(appname) + 1, *bytes_written, err); if ((strlen(appname) + 1) % 4) { WRITE_DATA(fp, &padding, 4 - (strlen(appname) + 1) % 4, *bytes_written, err); } /* write last option */ option.type = OPT_ENDOFOPT; option.value_length = 0; WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err); } /* write the trailing block total length */ WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err); return TRUE; }
static void dissect_parameters(tvbuff_t *parameters_tvb, proto_tree *tree) { gint offset, length, total_length, remaining_length; tvbuff_t *parameter_tvb; offset = 0; while((remaining_length = tvb_reported_length_remaining(parameters_tvb, offset)) > 0) { length = tvb_get_ntohs(parameters_tvb, offset + PARAMETER_LENGTH_OFFSET); total_length = ADD_PADDING(length); if (remaining_length >= length) total_length = MIN(total_length, remaining_length); /* create a tvb for the parameter including the padding bytes */ parameter_tvb = tvb_new_subset_length(parameters_tvb, offset, total_length); dissect_parameter(parameter_tvb, tree); /* get rid of the handled parameter */ offset += total_length; } }
MMBitmapRef copyMMBitmapFromDisplayInRect(MMRect rect) { #if defined(IS_MACOSX) /* The following is a very modified version of the glGrab code example * given by Apple (as are some of the convenience functions called). */ size_t bytewidth; uint8_t bitsPerPixel, bytesPerPixel; uint8_t *buffer; /* Build OpenGL context of entire screen */ CGDirectDisplayID displayID = CGMainDisplayID(); CGOpenGLDisplayMask mask = CGDisplayIDToOpenGLDisplayMask(displayID); CGLContextObj glContext = createFullScreenCGLContext(mask); if (glContext == NULL) return NULL; /* TODO: CGDisplayBitsPerPixel() is deprecated in Snow Leopard; I'm not * sure of the replacement function. */ bitsPerPixel = (uint8_t)CGDisplayBitsPerPixel(displayID); bytesPerPixel = bitsPerPixel / 8; /* Align width to padding. */ bytewidth = ADD_PADDING(rect.size.width * bytesPerPixel); /* Convert Quartz point to postscript point. */ rect.origin.y = CGDisplayPixelsHigh(displayID) - rect.origin.y - rect.size.height; /* Extract buffer from context */ buffer = createBufferFromCurrentCGLContext((GLint)rect.origin.x, (GLint)rect.origin.y, (GLsizei)rect.size.width, (GLsizei)rect.size.height, bytewidth); /* Reset and release GL context */ destroyFullScreenCGLContext(glContext); if (buffer == NULL) return NULL; /* Convert from OpenGL (origin at bottom left) to Quartz (origin at top * left) coordinate system. */ flipBitmapData(buffer, rect.size.width, rect.size.height, bytewidth); return createMMBitmap(buffer, rect.size.width, rect.size.height, bytewidth, bitsPerPixel, bytesPerPixel); #elif defined(USE_X11) MMBitmapRef bitmap; Display *display = XOpenDisplay(NULL); XImage *image = XGetImage(display, XDefaultRootWindow(display), (int)rect.origin.x, (int)rect.origin.y, (unsigned int)rect.size.width, (unsigned int)rect.size.height, AllPlanes, ZPixmap); XCloseDisplay(display); if (image == NULL) return NULL; bitmap = createMMBitmap((uint8_t *)image->data, rect.size.width, rect.size.height, (size_t)image->bytes_per_line, (uint8_t)image->bits_per_pixel, (uint8_t)image->bits_per_pixel / 8); image->data = NULL; /* Steal ownership of bitmap data so we don't have to * copy it. */ XDestroyImage(image); return bitmap; #elif defined(IS_WINDOWS) MMBitmapRef bitmap; void *data; HDC screen = NULL, screenMem = NULL; HBITMAP dib; BITMAPINFO bi; /* Initialize bitmap info. */ bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = (long)rect.size.width; bi.bmiHeader.biHeight = -(long)rect.size.height; /* Non-cartesian, please */ bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = (DWORD)(4 * rect.size.width * rect.size.height); bi.bmiHeader.biXPelsPerMeter = 0; bi.bmiHeader.biYPelsPerMeter = 0; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; screen = GetDC(NULL); /* Get entire screen */ if (screen == NULL) return NULL; /* Get screen data in display device context. */ dib = CreateDIBSection(screen, &bi, DIB_RGB_COLORS, &data, NULL, 0); /* Copy the data into a bitmap struct. */ if ((screenMem = CreateCompatibleDC(screen)) == NULL || SelectObject(screenMem, dib) == NULL || !BitBlt(screenMem, (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height, screen, 0, 0, SRCCOPY)) { /* Error copying data. */ ReleaseDC(NULL, screen); DeleteObject(dib); if (screenMem != NULL) DeleteDC(screenMem); return NULL; } bitmap = createMMBitmap(NULL, rect.size.width, rect.size.height, 4 * rect.size.width, (uint8_t)bi.bmiHeader.biBitCount, 4); /* Copy the data to our pixel buffer. */ if (bitmap != NULL) { bitmap->imageBuffer = malloc(bitmap->bytewidth * bitmap->height); memcpy(bitmap->imageBuffer, data, bitmap->bytewidth * bitmap->height); } ReleaseDC(NULL, screen); DeleteObject(dib); DeleteDC(screenMem); return bitmap; #endif }
gboolean libpcap_write_interface_description_block(FILE *fp, char *name, char *filter, int link_type, int snap_len, long *bytes_written, int *err) { struct idb idb; struct option option; guint32 block_total_length; const guint32 padding = 0; block_total_length = sizeof(struct idb) + sizeof(guint32); if ((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) { block_total_length += sizeof(struct option) + (guint16)(ADD_PADDING(strlen(name) + 1)); } if ((strlen(filter) > 0) && (strlen(name) < G_MAXUINT16)) { block_total_length += sizeof(struct option) + (guint16)(ADD_PADDING(strlen(filter) + 1)); } if (((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) || ((strlen(filter) > 0) && (strlen(name) < G_MAXUINT16))) { block_total_length += sizeof(struct option); } /* write block header */ idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE; idb.block_total_length = block_total_length; idb.link_type = link_type; idb.reserved = 0; idb.snap_len = snap_len; WRITE_DATA(fp, &idb, sizeof(struct idb), *bytes_written, err); /* write interface name string if applicable */ if ((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) { option.type = IDB_NAME; option.value_length = (guint16)(strlen(name) + 1); WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err); WRITE_DATA(fp, name, strlen(name) + 1, *bytes_written, err); if ((strlen(name) + 1) % 4) { WRITE_DATA(fp, &padding, 4 - (strlen(name) + 1) % 4 , *bytes_written, err); } } /* write filter string if applicable */ if ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) { option.type = IDB_FILTER; option.value_length = (guint16)(strlen(filter) + 1); WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err); WRITE_DATA(fp, filter, strlen(filter) + 1, *bytes_written, err); if ((strlen(filter) + 1) % 4) { WRITE_DATA(fp, &padding, 4 - (strlen(filter) + 1) % 4 , *bytes_written, err); } } /* write endofopt option if there were any options */ if (((strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) || ((strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16))) { option.type = OPT_ENDOFOPT; option.value_length = 0; WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err); } /* write the trailing Block Total Length */ WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err); return TRUE; }
MMBitmapRef newMMBitmapFromPNG(const char *path, MMPNGReadError *err) { FILE *fp; uint8_t header[8]; png_struct *png_ptr = NULL; png_info *info_ptr = NULL; png_byte bit_depth, color_type; uint8_t *row, *bitmapData; uint8_t bytesPerPixel; png_uint_32 width, height, y; uint32_t bytewidth; if ((fp = fopen(path, "rb")) == NULL) { if (err != NULL) *err = kPNGAccessError; return NULL; } /* Initialize error code to generic value. */ if (err != NULL) *err = kPNGGenericError; /* Validate the PNG. */ if (fread(header, 1, sizeof header, fp) == 0) { if (err != NULL) *err = kPNGReadError; goto bail; } else if (!png_check_sig(header, sizeof(header))) { if (err != NULL) *err = kPNGInvalidHeaderError; goto bail; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) goto bail; info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) goto bail; /* Set up error handling. */ if (setjmp(png_jmpbuf(png_ptr))) { goto bail; } png_init_io(png_ptr, fp); /* Skip past the header. */ png_set_sig_bytes(png_ptr, sizeof header); png_read_info(png_ptr, info_ptr); /* Convert different image types to common type to be read. */ bit_depth = png_get_bit_depth(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); /* Convert color palettes to RGB. */ if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); } /* Convert PNG to bit depth of 8. */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { #ifdef PNG_LIBPNG_VER_SONUM #if PNG_LIBPNG_VER_SONUM >= 14 png_set_expand_gray_1_2_4_to_8(png_ptr); #else png_set_gray_1_2_4_to_8(png_ptr); #endif #else png_set_gray_1_2_4_to_8(png_ptr); #endif } else if (bit_depth == 16) { png_set_strip_16(png_ptr); } /* Convert transparency chunk to alpha channel. */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); } /* Convert gray images to RGB. */ if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { png_set_gray_to_rgb(png_ptr); } /* Ignore alpha for now. */ if (color_type & PNG_COLOR_MASK_ALPHA) { png_set_strip_alpha(png_ptr); } /* Get image attributes. */ width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); bytesPerPixel = 3; /* All images decompress to this size. */ bytewidth = ADD_PADDING(width * bytesPerPixel); /* Align width. */ /* Decompress the PNG row by row. */ bitmapData = calloc(1, bytewidth * height); row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); if (bitmapData == NULL || row == NULL) goto bail; for (y = 0; y < height; ++y) { png_uint_32 x; const uint32_t rowOffset = y * bytewidth; uint8_t *rowptr = row; png_read_row(png_ptr, (png_byte *)row, NULL); for (x = 0; x < width; ++x) { const uint32_t colOffset = x * bytesPerPixel; MMRGBColor *color = (MMRGBColor *)(bitmapData + rowOffset + colOffset); color->red = *rowptr++; color->green = *rowptr++; color->blue = *rowptr++; } } free(row); /* Finish reading. */ png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); return createMMBitmap(bitmapData, width, height, bytewidth, bytesPerPixel * 8, bytesPerPixel); bail: png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); return NULL; }
/* Returns pointer to PNGWriteInfo struct containing data ready to be used with * functions such as png_write_png(). * * It is the caller's responsibility to destroy() the returned structure with * destroyPNGWriteInfo(). */ static PNGWriteInfoRef createPNGWriteInfo(MMBitmapRef bitmap) { PNGWriteInfoRef info = malloc(sizeof(PNGWriteInfo)); png_uint_32 y; if (info == NULL) return NULL; info->png_ptr = NULL; info->info_ptr = NULL; info->row_pointers = NULL; assert(bitmap != NULL); /* Initialize the write struct. */ info->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (info->png_ptr == NULL) goto bail; /* Set up error handling. */ if (setjmp(png_jmpbuf(info->png_ptr))) { png_destroy_write_struct(&(info->png_ptr), &(info->info_ptr)); goto bail; } /* Initialize the info struct. */ info->info_ptr = png_create_info_struct(info->png_ptr); if (info->info_ptr == NULL) { png_destroy_write_struct(&(info->png_ptr), NULL); goto bail; } /* Set image attributes. */ png_set_IHDR(info->png_ptr, info->info_ptr, bitmap->width, bitmap->height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); info->row_count = bitmap->height; info->row_pointers = png_malloc(info->png_ptr, sizeof(png_byte *) * info->row_count); if (bitmap->bytesPerPixel == 3) { /* No alpha channel; image data can be copied directly. */ for (y = 0; y < info->row_count; ++y) { info->row_pointers[y] = bitmap->imageBuffer + (bitmap->bytewidth * y); } info->free_row_pointers = false; /* Convert BGR to RGB if necessary. */ if (MMRGB_IS_BGR) { png_set_bgr(info->png_ptr); } } else { /* Ignore alpha channel; copy image data row by row. */ const size_t bytesPerPixel = 3; const size_t bytewidth = ADD_PADDING(bitmap->width * bytesPerPixel); for (y = 0; y < info->row_count; ++y) { png_uint_32 x; png_byte *row_ptr = png_malloc(info->png_ptr, bytewidth); info->row_pointers[y] = row_ptr; for (x = 0; x < bitmap->width; ++x) { MMRGBColor *color = MMRGBColorRefAtPoint(bitmap, x, y); row_ptr[0] = color->red; row_ptr[1] = color->green; row_ptr[2] = color->blue; row_ptr += bytesPerPixel; } } info->free_row_pointers = true; } png_set_rows(info->png_ptr, info->info_ptr, info->row_pointers); return info; bail: if (info != NULL) free(info); return NULL; }
/* Write a record for a packet to a dump file. Returns TRUE on success, FALSE on failure. */ gboolean libpcap_write_enhanced_packet_block(libpcap_write_t write_func, void* write_data_info, const char *comment, time_t sec, guint32 usec, guint32 caplen, guint32 len, guint32 interface_id, guint ts_mul, const guint8 *pd, guint32 flags, guint64 *bytes_written, int *err) { struct epb epb; struct option option; guint32 block_total_length; guint64 timestamp; gboolean have_options = FALSE; const guint32 padding = 0; block_total_length = (guint32)(sizeof(struct epb) + ADD_PADDING(caplen) + sizeof(guint32)); if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(comment))); have_options = TRUE; } if (flags != 0) { block_total_length += (guint32)(sizeof(struct option) + sizeof(guint32)); have_options = TRUE; } /* If we have options add size of end-of-options */ if (have_options) { block_total_length += (guint32)sizeof(struct option); } timestamp = (guint64)sec * ts_mul + (guint64)usec; epb.block_type = ENHANCED_PACKET_BLOCK_TYPE; epb.block_total_length = block_total_length; epb.interface_id = interface_id; epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff); epb.timestamp_low = (guint32)(timestamp & 0xffffffff); epb.captured_len = caplen; epb.packet_len = len; if (!write_func(write_data_info, (const guint8*)&epb, sizeof(struct epb), bytes_written, err)) return FALSE; if (!write_func(write_data_info, pd, caplen, bytes_written, err)) return FALSE; if (caplen % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - caplen % 4, bytes_written, err)) return FALSE; } if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) { option.type = OPT_COMMENT; option.value_length = (guint16)strlen(comment); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)comment, (int) strlen(comment), bytes_written, err)) return FALSE; if (strlen(comment) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(comment) % 4, bytes_written, err)) return FALSE; } } if (flags != 0) { option.type = EPB_FLAGS; option.value_length = sizeof(guint32); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)&flags, sizeof(guint32), bytes_written, err)) return FALSE; option.type = OPT_ENDOFOPT; option.value_length = 0; if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; } return write_func(write_data_info, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err); }
gboolean libpcap_write_interface_description_block(libpcap_write_t write_func, void* write_data_info, const char *comment, /* OPT_COMMENT 1 */ const char *name, /* IDB_NAME 2 */ const char *descr, /* IDB_DESCRIPTION 3 */ const char *filter, /* IDB_FILTER 11 */ const char *os, /* IDB_OS 12 */ int link_type, int snap_len, guint64 *bytes_written, guint64 if_speed, /* IDB_IF_SPEED 8 */ guint8 tsresol, /* IDB_TSRESOL 9 */ int *err) { struct idb idb; struct option option; guint32 block_total_length; const guint32 padding = 0; gboolean have_options = FALSE; block_total_length = (guint32)(sizeof(struct idb) + sizeof(guint32)); /* 01 - OPT_COMMENT */ if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(comment))); have_options = TRUE; } /* 02 - IDB_NAME */ if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(name))); have_options = TRUE; } /* 03 - IDB_DESCRIPTION */ if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(descr))); have_options = TRUE; } /* 08 - IDB_IF_SPEED */ if (if_speed != 0) { block_total_length += (guint32)(sizeof(struct option) + sizeof(guint64)); have_options = TRUE; } /* 09 - IDB_TSRESOL */ if (tsresol != 0) { block_total_length += (guint32)(sizeof(struct option) + sizeof(struct option)); have_options = TRUE; } /* 11 - IDB_FILTER */ if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)(ADD_PADDING(strlen(filter)+ 1))); have_options = TRUE; } /* 12 - IDB_OS */ if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(os))); have_options = TRUE; } /* If we have options add size of end-of-options */ if (have_options) { block_total_length += (guint32)sizeof(struct option); } /* write block header */ idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE; idb.block_total_length = block_total_length; idb.link_type = link_type; idb.reserved = 0; idb.snap_len = snap_len; if (!write_func(write_data_info, (const guint8*)&idb, sizeof(struct idb), bytes_written, err)) return FALSE; /* 01 - OPT_COMMENT - write comment string if applicable */ if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) { option.type = OPT_COMMENT; option.value_length = (guint16)strlen(comment); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)comment, (int) strlen(comment), bytes_written, err)) return FALSE; if (strlen(comment) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(comment) % 4, bytes_written, err)) return FALSE; } } /* 02 - IDB_NAME - write interface name string if applicable */ if ((name != NULL) && (strlen(name) > 0) && (strlen(name) < G_MAXUINT16)) { option.type = IDB_NAME; option.value_length = (guint16)strlen(name); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)name, (int) strlen(name), bytes_written, err)) return FALSE; if (strlen(name) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(name) % 4, bytes_written, err)) return FALSE; } } /* 03 - IDB_DESCRIPTION */ /* write interface description string if applicable */ if ((descr != NULL) && (strlen(descr) > 0) && (strlen(descr) < G_MAXUINT16)) { option.type = IDB_DESCRIPTION; option.value_length = (guint16)strlen(descr); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)descr, (int) strlen(descr), bytes_written, err)) return FALSE; if (strlen(descr) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(descr) % 4, bytes_written, err)) return FALSE; } } /* 08 - IDB_IF_SPEED */ if (if_speed != 0) { option.type = IDB_IF_SPEED; option.value_length = sizeof(guint64); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)&if_speed, sizeof(guint64), bytes_written, err)) return FALSE; } /* 09 - IDB_TSRESOL */ if (tsresol != 0) { option.type = IDB_TSRESOL; option.value_length = sizeof(guint8); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)&tsresol, sizeof(guint8), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)&padding, 3, bytes_written, err)) return FALSE; } /* 11 - IDB_FILTER - write filter string if applicable * We only write version 1 of the filter, libpcap string */ if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) { option.type = IDB_FILTER; option.value_length = (guint16)(strlen(filter) + 1 ); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; /* The first byte of the Option Data keeps a code of the filter used, 0 = lipbpcap filter string */ if (!write_func(write_data_info, (const guint8*)&padding, 1, bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)filter, (int) strlen(filter), bytes_written, err)) return FALSE; if ((strlen(filter) + 1) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - (strlen(filter) + 1) % 4, bytes_written, err)) return FALSE; } } /* 12 - IDB_OS - write os string if applicable */ if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) { option.type = IDB_OS; option.value_length = (guint16)strlen(os); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)os, (int) strlen(os), bytes_written, err)) return FALSE; if (strlen(os) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(os) % 4, bytes_written, err)) return FALSE; } } if (have_options) { /* write end of options */ option.type = OPT_ENDOFOPT; option.value_length = 0; if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; } /* write the trailing Block Total Length */ return write_func(write_data_info, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err); }
gboolean libpcap_write_session_header_block(libpcap_write_t write_func, void* write_data_info, const char *comment, const char *hw, const char *os, const char *appname, guint64 section_length, guint64 *bytes_written, int *err) { struct shb shb; struct option option; guint32 block_total_length; const guint32 padding = 0; gboolean have_options = FALSE; /* Size of base header */ block_total_length = sizeof(struct shb) + sizeof(guint32); if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(comment))); have_options = TRUE; } if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(hw))); have_options = TRUE; } if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(os))); have_options = TRUE; } if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(appname))); have_options = TRUE; } /* If we have options add size of end-of-options */ if (have_options) { block_total_length += (guint32)sizeof(struct option); } /* write shb header */ shb.block_type = SECTION_HEADER_BLOCK_TYPE; shb.block_total_length = block_total_length; shb.byte_order_magic = PCAPNG_MAGIC; shb.major_version = PCAPNG_MAJOR_VERSION; shb.minor_version = PCAPNG_MINOR_VERSION; shb.section_length = section_length; if (!write_func(write_data_info, (const guint8*)&shb, sizeof(struct shb), bytes_written, err)) return FALSE; if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) { /* write opt_comment options */ option.type = OPT_COMMENT; option.value_length = (guint16)strlen(comment); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)comment, (int) strlen(comment), bytes_written, err)) return FALSE; if (strlen(comment) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(comment) % 4, bytes_written, err)) return FALSE; } } if ((hw != NULL) && (strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) { /* write shb_hardware options */ option.type = SHB_HARDWARE; option.value_length = (guint16)strlen(hw); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)hw, (int) strlen(hw), bytes_written, err)) return FALSE; if ((strlen(hw) + 1) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(hw) % 4, bytes_written, err)) return FALSE; } } if ((os != NULL) && (strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) { /* write shb_os options */ option.type = SHB_OS; option.value_length = (guint16)strlen(os); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)os, (int) strlen(os), bytes_written, err)) return FALSE; if (strlen(os) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(os) % 4, bytes_written, err)) return FALSE; } } if ((appname != NULL) && (strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) { /* write shb_userappl options */ option.type = SHB_USERAPPL; option.value_length = (guint16)strlen(appname); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)appname, (int) strlen(appname), bytes_written, err)) return FALSE; if (strlen(appname) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(appname) % 4, bytes_written, err)) return FALSE; } } if (have_options) { /* write end of options */ option.type = OPT_ENDOFOPT; option.value_length = 0; if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; } /* write the trailing block total length */ return write_func(write_data_info, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err); }
MMBitmapRef newMMBitmapFromBMP(const char *path, MMBMPReadError *err) { FILE *fp; struct BITMAP_FILE_HEADER fileHeader = {0}; /* Initialize elements to 0. */ struct BITMAP_INFO_HEADER dibHeader = {0}; uint32_t headerSize = 0; uint8_t bytesPerPixel; size_t bytewidth; uint8_t *imageBuf; if ((fp = fopen(path, "rb")) == NULL) { if (err != NULL) *err = kBMPAccessError; return NULL; } /* Initialize error code to generic value. */ if (err != NULL) *err = kBMPGenericError; if (fread(&fileHeader, sizeof(fileHeader), 1, fp) == 0) goto bail; /* Convert from little-endian if it's not already. */ convertBitmapFileHeader(&fileHeader); /* First two bytes should always be 0x4D42. */ if (fileHeader.magic != BMP_MAGIC) { if (err != NULL) *err = kBMPInvalidKeyError; goto bail; } /* Get header size. */ if (fread(&headerSize, sizeof(headerSize), 1, fp) == 0) goto bail; headerSize = swapLittleAndHost32(headerSize); /* Back up before reading header. */ if (fseek(fp, -(long)sizeof(headerSize), SEEK_CUR) < 0) goto bail; if (headerSize == 12) { /* OS/2 v1 header */ struct BITMAP_CORE_HEADER coreHeader = {0}; if (fread(&coreHeader, sizeof(coreHeader), 1, fp) == 0) goto bail; dibHeader.width = coreHeader.width; dibHeader.height = coreHeader.height; dibHeader.colorPlanes = coreHeader.colorPlanes; dibHeader.bitsPerPixel = coreHeader.bitsPerPixel; } else if (headerSize == 40 || headerSize == 108 || headerSize == 124) { /* Windows v3/v4/v5 header */ /* Read only the common part (v3) and skip over the rest. */ if (fread(&dibHeader, sizeof(dibHeader), 1, fp) == 0) goto bail; } else { if (err != NULL) *err = kBMPUnsupportedHeaderError; goto bail; } convertBitmapInfoHeader(&dibHeader); if (dibHeader.colorPlanes != 1) { if (err != NULL) *err = kBMPInvalidColorPanesError; goto bail; } /* Currently only 24-bit and 32-bit are supported. */ if (dibHeader.bitsPerPixel != 24 && dibHeader.bitsPerPixel != 32) { if (err != NULL) *err = kBMPUnsupportedColorDepthError; goto bail; } if (dibHeader.compression != kBMP_RGB) { if (err != NULL) *err = kBMPUnsupportedCompressionError; goto bail; } /* This can happen because we don't fully parse Windows v4/v5 headers. */ if (ftell(fp) != (long)fileHeader.imageOffset) { fseek(fp, fileHeader.imageOffset, SEEK_SET); } /* Get bytes per row, including padding. */ bytesPerPixel = dibHeader.bitsPerPixel / 8; bytewidth = ADD_PADDING(dibHeader.width * bytesPerPixel); imageBuf = readImageData(fp, dibHeader.width, abs(dibHeader.height), bytesPerPixel, bytewidth); fclose(fp); if (imageBuf == NULL) { if (err != NULL) *err = kBMPInvalidPixelDataError; return NULL; } /* A negative height indicates that the image is flipped. * * We store our bitmaps as "flipped" according to the BMP format; i.e., (0, 0) * is the top left, not bottom left. So we only need to flip the bitmap if * the height is NOT negative. */ if (dibHeader.height < 0) { dibHeader.height = -dibHeader.height; } else { flipBitmapData(imageBuf, dibHeader.width, dibHeader.height, bytewidth); } return createMMBitmap(imageBuf, dibHeader.width, dibHeader.height, bytewidth, (uint8_t)dibHeader.bitsPerPixel, bytesPerPixel); bail: fclose(fp); return NULL; }
/* Write a record for a packet to a dump file. Returns TRUE on success, FALSE on failure. */ gboolean pcapng_write_enhanced_packet_block(FILE* pfile, const char *comment, time_t sec, guint32 usec, guint32 caplen, guint32 len, guint32 interface_id, guint ts_mul, const guint8 *pd, guint32 flags, guint64 *bytes_written, int *err) { struct epb epb; struct option option; guint32 block_total_length; guint64 timestamp; guint32 options_length; const guint32 padding = 0; block_total_length = (guint32)(sizeof(struct epb) + ADD_PADDING(caplen) + sizeof(guint32)); options_length = 0; options_length += pcapng_count_string_option(comment); if (flags != 0) { options_length += (guint32)(sizeof(struct option) + sizeof(guint32)); } /* If we have options add size of end-of-options */ if (options_length != 0) { options_length += (guint32)sizeof(struct option); } block_total_length += options_length; timestamp = (guint64)sec * ts_mul + (guint64)usec; epb.block_type = ENHANCED_PACKET_BLOCK_TYPE; epb.block_total_length = block_total_length; epb.interface_id = interface_id; epb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff); epb.timestamp_low = (guint32)(timestamp & 0xffffffff); epb.captured_len = caplen; epb.packet_len = len; if (!write_to_file(pfile, (const guint8*)&epb, sizeof(struct epb), bytes_written, err)) return FALSE; if (!write_to_file(pfile, pd, caplen, bytes_written, err)) return FALSE; if (caplen % 4) { if (!write_to_file(pfile, (const guint8*)&padding, 4 - caplen % 4, bytes_written, err)) return FALSE; } if (!pcapng_write_string_option(pfile, OPT_COMMENT, comment, bytes_written, err)) return FALSE; if (flags != 0) { option.type = EPB_FLAGS; option.value_length = sizeof(guint32); if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_to_file(pfile, (const guint8*)&flags, sizeof(guint32), bytes_written, err)) return FALSE; } if (options_length != 0) { /* write end of options */ option.type = OPT_ENDOFOPT; option.value_length = 0; if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; } return write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err); }
gboolean pcapng_write_interface_description_block(FILE* pfile, const char *comment, /* OPT_COMMENT 1 */ const char *name, /* IDB_NAME 2 */ const char *descr, /* IDB_DESCRIPTION 3 */ const char *filter, /* IDB_FILTER 11 */ const char *os, /* IDB_OS 12 */ int link_type, int snap_len, guint64 *bytes_written, guint64 if_speed, /* IDB_IF_SPEED 8 */ guint8 tsresol, /* IDB_TSRESOL 9 */ int *err) { struct idb idb; struct option option; guint32 block_total_length; guint32 options_length; const guint32 padding = 0; block_total_length = (guint32)(sizeof(struct idb) + sizeof(guint32)); options_length = 0; /* 01 - OPT_COMMENT */ options_length += pcapng_count_string_option(comment); /* 02 - IDB_NAME */ options_length += pcapng_count_string_option(name); /* 03 - IDB_DESCRIPTION */ options_length += pcapng_count_string_option(descr); /* 08 - IDB_IF_SPEED */ if (if_speed != 0) { options_length += (guint32)(sizeof(struct option) + sizeof(guint64)); } /* 09 - IDB_TSRESOL */ if (tsresol != 0) { options_length += (guint32)(sizeof(struct option) + sizeof(struct option)); } /* 11 - IDB_FILTER */ if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16)) { /* No, this isn't a string, it has an extra type byte */ options_length += (guint32)(sizeof(struct option) + (guint16)(ADD_PADDING(strlen(filter)+ 1))); } /* 12 - IDB_OS */ options_length += pcapng_count_string_option(os); /* If we have options add size of end-of-options */ if (options_length != 0) { options_length += (guint32)sizeof(struct option); } block_total_length += options_length; /* write block header */ idb.block_type = INTERFACE_DESCRIPTION_BLOCK_TYPE; idb.block_total_length = block_total_length; idb.link_type = link_type; idb.reserved = 0; idb.snap_len = snap_len; if (!write_to_file(pfile, (const guint8*)&idb, sizeof(struct idb), bytes_written, err)) return FALSE; /* 01 - OPT_COMMENT - write comment string if applicable */ if (!pcapng_write_string_option(pfile, OPT_COMMENT, comment, bytes_written, err)) return FALSE; /* 02 - IDB_NAME - write interface name string if applicable */ if (!pcapng_write_string_option(pfile, IDB_NAME, name, bytes_written, err)) return FALSE; /* 03 - IDB_DESCRIPTION */ /* write interface description string if applicable */ if (!pcapng_write_string_option(pfile, IDB_DESCRIPTION, descr, bytes_written, err)) return FALSE; /* 08 - IDB_IF_SPEED */ if (if_speed != 0) { option.type = IDB_IF_SPEED; option.value_length = sizeof(guint64); if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_to_file(pfile, (const guint8*)&if_speed, sizeof(guint64), bytes_written, err)) return FALSE; } /* 09 - IDB_TSRESOL */ if (tsresol != 0) { option.type = IDB_TSRESOL; option.value_length = sizeof(guint8); if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_to_file(pfile, (const guint8*)&tsresol, sizeof(guint8), bytes_written, err)) return FALSE; if (!write_to_file(pfile, (const guint8*)&padding, 3, bytes_written, err)) return FALSE; } /* 11 - IDB_FILTER - write filter string if applicable * We only write version 1 of the filter, pcapng string */ if ((filter != NULL) && (strlen(filter) > 0) && (strlen(filter) < G_MAXUINT16 - 1)) { option.type = IDB_FILTER; option.value_length = (guint16)(strlen(filter) + 1 ); if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; /* The first byte of the Option Data keeps a code of the filter used, 0 = lipbpcap filter string */ if (!write_to_file(pfile, (const guint8*)&padding, 1, bytes_written, err)) return FALSE; if (!write_to_file(pfile, (const guint8*)filter, (int) strlen(filter), bytes_written, err)) return FALSE; if ((strlen(filter) + 1) % 4) { if (!write_to_file(pfile, (const guint8*)&padding, 4 - (strlen(filter) + 1) % 4, bytes_written, err)) return FALSE; } } /* 12 - IDB_OS - write os string if applicable */ if (!pcapng_write_string_option(pfile, IDB_OS, os, bytes_written, err)) return FALSE; if (options_length != 0) { /* write end of options */ option.type = OPT_ENDOFOPT; option.value_length = 0; if (!write_to_file(pfile, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; } /* write the trailing Block Total Length */ return write_to_file(pfile, (const guint8*)&block_total_length, sizeof(guint32), bytes_written, err); }
gboolean libpcap_write_interface_statistics_block(libpcap_write_t write_func, void* write_data_info, guint32 interface_id, guint64 *bytes_written, const char *comment, /* OPT_COMMENT 1 */ guint64 isb_starttime, /* ISB_STARTTIME 2 */ guint64 isb_endtime, /* ISB_ENDTIME 3 */ guint64 isb_ifrecv, /* ISB_IFRECV 4 */ guint64 isb_ifdrop, /* ISB_IFDROP 5 */ int *err) { struct isb isb; #ifdef _WIN32 FILETIME now; #else struct timeval now; #endif struct option option; guint32 block_total_length; guint64 timestamp; gboolean have_options = FALSE; const guint32 padding = 0; #ifdef _WIN32 /* * Current time, represented as 100-nanosecond intervals since * January 1, 1601, 00:00:00 UTC. * * I think DWORD might be signed, so cast both parts of "now" * to guint32 so that the sign bit doesn't get treated specially. * * Windows 8 provides GetSystemTimePreciseAsFileTime which we * might want to use instead. */ GetSystemTimeAsFileTime(&now); timestamp = (((guint64)(guint32)now.dwHighDateTime) << 32) + (guint32)now.dwLowDateTime; /* * Convert to same thing but as 1-microsecond, i.e. 1000-nanosecond, * intervals. */ timestamp /= 10; /* * Subtract difference, in microseconds, between January 1, 1601 * 00:00:00 UTC and January 1, 1970, 00:00:00 UTC. */ timestamp -= G_GINT64_CONSTANT(11644473600000000U); #else /* * Current time, represented as seconds and microseconds since * January 1, 1970, 00:00:00 UTC. */ gettimeofday(&now, NULL); /* * Convert to delta in microseconds. */ timestamp = (guint64)(now.tv_sec) * 1000000 + (guint64)(now.tv_usec); #endif block_total_length = (guint32)(sizeof(struct isb) + sizeof(guint32)); if (isb_ifrecv != G_MAXUINT64) { block_total_length += (guint32)(sizeof(struct option) + sizeof(guint64)); have_options = TRUE; } if (isb_ifdrop != G_MAXUINT64) { block_total_length += (guint32)(sizeof(struct option) + sizeof(guint64)); have_options = TRUE; } /* OPT_COMMENT */ if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) { block_total_length += (guint32)(sizeof(struct option) + (guint16)ADD_PADDING(strlen(comment))); have_options = TRUE; } if (isb_starttime !=0) { block_total_length += (guint32)(sizeof(struct option) + sizeof(guint64)); /* ISB_STARTTIME */ have_options = TRUE; } if (isb_endtime !=0) { block_total_length += (guint32)(sizeof(struct option) + sizeof(guint64)); /* ISB_ENDTIME */ have_options = TRUE; } /* If we have options add size of end-of-options */ if (have_options) { block_total_length += (guint32)sizeof(struct option); } isb.block_type = INTERFACE_STATISTICS_BLOCK_TYPE; isb.block_total_length = block_total_length; isb.interface_id = interface_id; isb.timestamp_high = (guint32)((timestamp>>32) & 0xffffffff); isb.timestamp_low = (guint32)(timestamp & 0xffffffff); if (!write_func(write_data_info, (const guint8*)&isb, sizeof(struct isb), bytes_written, err)) return FALSE; /* write comment string if applicable */ if ((comment != NULL) && (strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) { option.type = OPT_COMMENT; option.value_length = (guint16)strlen(comment); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)comment, (int) strlen(comment), bytes_written, err)) return FALSE; if (strlen(comment) % 4) { if (!write_func(write_data_info, (const guint8*)&padding, 4 - strlen(comment) % 4, bytes_written, err)) return FALSE; } } if (isb_starttime !=0) { guint32 high, low; option.type = ISB_STARTTIME; option.value_length = sizeof(guint64); high = (guint32)((isb_starttime>>32) & 0xffffffff); low = (guint32)(isb_starttime & 0xffffffff); if (!write_func(write_data_info, (const guint8*)&option, sizeof(struct option), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)&high, sizeof(guint32), bytes_written, err)) return FALSE; if (!write_func(write_data_info, (const guint8*)&low, sizeof(guint32), bytes_written, err)) return FALSE; }
MMBitmapRef copyMMBitmapFromDisplayInRect(MMRect rect) { #if defined(IS_MACOSX) size_t bytewidth; uint8_t bitsPerPixel, bytesPerPixel; uint8_t *buffer; CGDirectDisplayID displayID = CGMainDisplayID(); //Replacement for CGDisplayBitsPerPixel. CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayID); size_t depth = 0; CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) depth = 32; else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) depth = 16; else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) depth = 8; bitsPerPixel = (uint8_t) depth; bytesPerPixel = bitsPerPixel / 8; /* Align width to padding. */ bytewidth = ADD_PADDING(rect.size.width * bytesPerPixel); /* Convert Quartz point to postscript point. */ rect.origin.y = CGDisplayPixelsHigh(displayID) - rect.origin.y - rect.size.height; CGImageRef image = CGDisplayCreateImageForRect(displayID, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)); // Request access to the raw pixel data via the image's DataProvider. CGDataProviderRef provider = CGImageGetDataProvider(image); CFDataRef data = CGDataProviderCopyData(provider); size_t width, height; width = CGImageGetWidth(image); height = CGImageGetHeight(image); size_t bpp = CGImageGetBitsPerPixel(image) / 8; uint8 *pixels = malloc(width * height * bpp); memcpy(pixels, CFDataGetBytePtr(data), width * height * bpp); CFRelease(data); CGImageRelease(image); return createMMBitmap(pixels, rect.size.width, rect.size.height, bytewidth, bitsPerPixel, bytesPerPixel); #elif defined(USE_X11) MMBitmapRef bitmap; Display *display = XOpenDisplay(NULL); XImage *image = XGetImage(display, XDefaultRootWindow(display), (int)rect.origin.x, (int)rect.origin.y, (unsigned int)rect.size.width, (unsigned int)rect.size.height, AllPlanes, ZPixmap); XCloseDisplay(display); if (image == NULL) return NULL; bitmap = createMMBitmap((uint8_t *)image->data, rect.size.width, rect.size.height, (size_t)image->bytes_per_line, (uint8_t)image->bits_per_pixel, (uint8_t)image->bits_per_pixel / 8); image->data = NULL; /* Steal ownership of bitmap data so we don't have to * copy it. */ XDestroyImage(image); return bitmap; #elif defined(IS_WINDOWS) MMBitmapRef bitmap; void *data; HDC screen = NULL, screenMem = NULL; HBITMAP dib; BITMAPINFO bi; /* Initialize bitmap info. */ bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = (long)rect.size.width; bi.bmiHeader.biHeight = -(long)rect.size.height; /* Non-cartesian, please */ bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = (DWORD)(4 * rect.size.width * rect.size.height); bi.bmiHeader.biXPelsPerMeter = 0; bi.bmiHeader.biYPelsPerMeter = 0; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; screen = GetDC(NULL); /* Get entire screen */ if (screen == NULL) return NULL; /* Get screen data in display device context. */ dib = CreateDIBSection(screen, &bi, DIB_RGB_COLORS, &data, NULL, 0); /* Copy the data into a bitmap struct. */ if ((screenMem = CreateCompatibleDC(screen)) == NULL || SelectObject(screenMem, dib) == NULL || !BitBlt(screenMem, (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height, screen, 0, 0, SRCCOPY)) { /* Error copying data. */ ReleaseDC(NULL, screen); DeleteObject(dib); if (screenMem != NULL) DeleteDC(screenMem); return NULL; } bitmap = createMMBitmap(NULL, rect.size.width, rect.size.height, 4 * rect.size.width, (uint8_t)bi.bmiHeader.biBitCount, 4); /* Copy the data to our pixel buffer. */ if (bitmap != NULL) { bitmap->imageBuffer = malloc(bitmap->bytewidth * bitmap->height); memcpy(bitmap->imageBuffer, data, bitmap->bytewidth * bitmap->height); } ReleaseDC(NULL, screen); DeleteObject(dib); DeleteDC(screenMem); return bitmap; #endif }