mirror of
https://github.com/Karmaz95/Snake_Apple.git
synced 2026-08-13 21:30:18 +02:00
Adding example Mach IPC client-server with and without MIG
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
# Makefile for Mach IPC example with MIG
|
||||||
|
|
||||||
|
# Compiler settings
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -Wall -Werror
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
all: server client
|
||||||
|
|
||||||
|
# Generate MIG files from definition
|
||||||
|
mig_files: message.defs
|
||||||
|
mig message.defs
|
||||||
|
|
||||||
|
# Build server with MIG-generated files
|
||||||
|
server: mig_files server.c messageServer.c
|
||||||
|
$(CC) $(CFLAGS) server.c messageServer.c -o server
|
||||||
|
|
||||||
|
# Build client with MIG-generated files
|
||||||
|
client: mig_files client.c messageUser.c
|
||||||
|
$(CC) $(CFLAGS) client.c messageUser.c -o client
|
||||||
|
|
||||||
|
# Clean generated files and executables
|
||||||
|
clean:
|
||||||
|
rm -f server client message.h messageUser.c messageServer.c
|
||||||
|
|
||||||
|
.PHONY: all clean mig_files
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// client.c - MIG version
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <servers/bootstrap.h>
|
||||||
|
#include "message.h" // MIG-generated header
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
// Validate command line arguments
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s <message>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get bootstrap port for service lookup
|
||||||
|
mach_port_t port;
|
||||||
|
kern_return_t kr = bootstrap_look_up(bootstrap_port,
|
||||||
|
"xyz.hacktricks.mig",
|
||||||
|
&port);
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
printf("Service not found\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use MIG-generated function to send message
|
||||||
|
// This handles all the message structure creation internally
|
||||||
|
USER_send_message(port, (pointer_t)argv[1], strlen(argv[1]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// message.defs - MIG Interface Definition
|
||||||
|
subsystem message 400; // Define subsystem name and ID
|
||||||
|
|
||||||
|
// Prefix for generated client and server function names
|
||||||
|
userprefix USER_;
|
||||||
|
serverprefix SERVER_;
|
||||||
|
|
||||||
|
// Include necessary Mach type definitions
|
||||||
|
#include <mach/mach_types.defs>
|
||||||
|
#include <mach/std_types.defs>
|
||||||
|
|
||||||
|
// Define our message passing routine
|
||||||
|
// 'simpleroutine' means one-way communication (no reply expected)
|
||||||
|
// pointer_t is used for variable-length data
|
||||||
|
simpleroutine send_message(
|
||||||
|
server_port : mach_port_t; // Port to send message to
|
||||||
|
message : pointer_t); // Message data
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// server.c - MIG version
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <servers/bootstrap.h>
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
// Function prototype for MIG-generated server function
|
||||||
|
extern boolean_t message_server(
|
||||||
|
mach_msg_header_t *InHeadP,
|
||||||
|
mach_msg_header_t *OutHeadP);
|
||||||
|
|
||||||
|
// Implementation of our message handling function
|
||||||
|
// This is called by MIG-generated code when a message arrives
|
||||||
|
kern_return_t SERVER_send_message(
|
||||||
|
mach_port_t server_port,
|
||||||
|
vm_offset_t message,
|
||||||
|
mach_msg_type_number_t messageCnt)
|
||||||
|
{
|
||||||
|
// Simply print the received message
|
||||||
|
printf("Received message: %s\n", (char*)message);
|
||||||
|
return KERN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
mach_port_t port;
|
||||||
|
kern_return_t kr;
|
||||||
|
|
||||||
|
// Register our service with the bootstrap server
|
||||||
|
kr = bootstrap_check_in(bootstrap_port, "xyz.hacktricks.mig", &port);
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
printf("bootstrap_check_in() failed with code 0x%x\n", kr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start message handling loop using MIG-generated server function
|
||||||
|
// 4096 is the maximum message size
|
||||||
|
mach_msg_server(message_server, 4096, port, MACH_MSG_TIMEOUT_NONE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Makefile for Mach IPC example without MIG
|
||||||
|
|
||||||
|
# Compiler settings
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -Wall -Werror
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
all: server client
|
||||||
|
|
||||||
|
# Build server
|
||||||
|
server: server.c
|
||||||
|
$(CC) $(CFLAGS) server.c -o server
|
||||||
|
|
||||||
|
# Build client
|
||||||
|
client: client.c
|
||||||
|
$(CC) $(CFLAGS) client.c -o client
|
||||||
|
|
||||||
|
# Clean generated files and executables
|
||||||
|
clean:
|
||||||
|
rm -f server client
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
// client.c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <servers/bootstrap.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Message structure for IPC communication
|
||||||
|
* Consists of two parts:
|
||||||
|
* 1. mach_msg_header_t h - Standard Mach message header required for all IPC
|
||||||
|
* 2. char d[1024] - Data buffer for the actual message content
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
mach_msg_header_t h; // Header must be first member
|
||||||
|
char d[1024]; // Data buffer follows immediately after header
|
||||||
|
} msg_t;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
// Validate command line arguments
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s <message>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: Get the bootstrap port
|
||||||
|
// Bootstrap server is the central name server in Mach IPC
|
||||||
|
mach_port_t bootstrap_port;
|
||||||
|
task_get_special_port(mach_task_self(),
|
||||||
|
TASK_BOOTSTRAP_PORT,
|
||||||
|
&bootstrap_port);
|
||||||
|
|
||||||
|
// Step 2: Look up the service port using bootstrap server
|
||||||
|
// This finds our server process using the registered name
|
||||||
|
mach_port_t service_port;
|
||||||
|
kern_return_t kr = bootstrap_look_up(bootstrap_port,
|
||||||
|
"com.crimson.message_service",
|
||||||
|
&service_port);
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
printf("Service not found\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Prepare the message structure
|
||||||
|
// Initialize message structure to zero
|
||||||
|
msg_t message = {0};
|
||||||
|
|
||||||
|
// Configure message header
|
||||||
|
message.h.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND); // Set message type to copy-send
|
||||||
|
message.h.msgh_size = sizeof(msg_t); // Total size of message struct
|
||||||
|
message.h.msgh_remote_port = service_port; // Destination port
|
||||||
|
message.h.msgh_local_port = MACH_PORT_NULL; // No reply port needed
|
||||||
|
message.h.msgh_id = 0; // Message ID (unused in this case)
|
||||||
|
|
||||||
|
// Copy the user's message into data buffer
|
||||||
|
// Using strncpy to prevent buffer overflow
|
||||||
|
strncpy(message.d, argv[1], sizeof(message.d) - 1);
|
||||||
|
message.d[sizeof(message.d) - 1] = '\0'; // Ensure null termination
|
||||||
|
|
||||||
|
// Step 4: Send the message
|
||||||
|
kr = mach_msg(
|
||||||
|
&message.h, // Message header pointer
|
||||||
|
MACH_SEND_MSG, // Send-only operation
|
||||||
|
sizeof(msg_t), // Size of entire message
|
||||||
|
0, // Maximum receive size (unused for send)
|
||||||
|
MACH_PORT_NULL, // Destination port (unused for send)
|
||||||
|
MACH_MSG_TIMEOUT_NONE,// No timeout
|
||||||
|
MACH_PORT_NULL // No notify port
|
||||||
|
);
|
||||||
|
|
||||||
|
// Step 5: Check for errors and return status
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
printf("Failed to send message\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// server.c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <servers/bootstrap.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// Step 1: Get the bootstrap port
|
||||||
|
mach_port_t bootstrap_port;
|
||||||
|
task_get_special_port(mach_task_self(),
|
||||||
|
TASK_BOOTSTRAP_PORT,
|
||||||
|
&bootstrap_port);
|
||||||
|
|
||||||
|
// Step 2: Register our service with the bootstrap server
|
||||||
|
// This allows clients to find us using the service name
|
||||||
|
mach_port_t service_port;
|
||||||
|
kern_return_t kr = bootstrap_check_in(bootstrap_port,
|
||||||
|
"com.crimson.message_service",
|
||||||
|
&service_port);
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
printf("Failed to register service\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Server running...\n");
|
||||||
|
|
||||||
|
// Allocate buffer for receiving messages
|
||||||
|
// Buffer must be large enough for header + maximum message size
|
||||||
|
char buffer[2048];
|
||||||
|
mach_msg_header_t *msg = (mach_msg_header_t*)buffer;
|
||||||
|
|
||||||
|
// Main message receive loop
|
||||||
|
while (1) {
|
||||||
|
// Receive message
|
||||||
|
kr = mach_msg(
|
||||||
|
msg, // Buffer to receive message
|
||||||
|
MACH_RCV_MSG, // Receive-only operation
|
||||||
|
0, // Send size (unused for receive)
|
||||||
|
sizeof(buffer), // Maximum receive size
|
||||||
|
service_port, // Port to receive on
|
||||||
|
MACH_MSG_TIMEOUT_NONE, // No timeout
|
||||||
|
MACH_PORT_NULL // No notify port
|
||||||
|
);
|
||||||
|
|
||||||
|
// Process received message
|
||||||
|
if (kr == KERN_SUCCESS) {
|
||||||
|
// Message data follows immediately after header
|
||||||
|
char *data = (char*)(msg + 1);
|
||||||
|
printf("Received: %s\n", data);
|
||||||
|
} else {
|
||||||
|
printf("Error receiving message\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // Never reached in this example
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user