Cannot get UDP socket to Bind - udp

I have been trying for two weeks to send a character via UDP. So far I have not been able to find an example that actually works using XCode and IOS 7. I am currently stuck as every time I run my code the Bind function returns a -1. I have no clue as to what is wrong or what the solution is. PS. I know my to Address is missing but for now I am just trying to get by the Bind issue. (Examples to use a specific address have failed to compile.)
This is very frustration as I have successfully create UPD programs on Windows, Windows Mobile 6.0, and AS400 without as much effort as I have had to spend on this and so far nothing to show.
Here is my current code
char Buff[256];
strcpy(Buff,"Test MESSAGE");
int handle = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (handle > 0) {
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(311);
inet_pton(AF_INET, "10.121.8.54", &(address.sin_addr));
if (bind(handle,(struct sockaddr *) &address, sizeof(struct sockaddr_in))< 0){
printf("************************ Failed to bind\n");
} else {
send(handle, Buff, sizeof(Buff), 0);
}
} else {
printf("Faile to create socket\n");
}//end if
Here are my imports
#import <sys/socket.h>
#import <netinet/in.h>
#import <sys/types.h>
#import <fcntl.h>
#import <netdb.h>
#import <arpa/inet.h>

Related

Window list from AXUIElementRef always null on High Sierra

After "upgrading" to macOS High Sierra it seems that some code that used to work does no longer. My goal here is just to list out the windows owned by an application. Here is an example:
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <ApplicationServices/ApplicationServices.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
pid_t myPID = 311;
AXUIElementRef appRef = AXUIElementCreateApplication(myPID);
CFArrayRef windowList;
AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute, (CFTypeRef *)&windowList);
}
return 0;
}
The issue here specifically is that windowList does not get contain anything no matter what I do. I have tried multiple PIDs, building/running both debug and release builds, and running them with sudo as well.
Any ideas?

How to create my own modifier key using HID on OSX Sierra

Recently Karabiner (the great OSX remapping tool) stopped working on Sierra.
I just read that it is possible to remap keys with HID and I tried the example code below, which remaps a and b. However it's not clear how to create my own modifier key (say Modifier-X), for example TAB to Modifier-X.
Then create mappings such as TAB+X -> Launch Program X , etc...
Karabiner supported this, now Karabiner does not work, so I am trying to find another way to make this happen.
Any suggestions how can this be implemented with HID ?
#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDEventSystemClient.h>
#import <IOKit/hidsystem/IOHIDServiceClient.h>
#import <IOKit/hid/IOHIDUsageTables.h>
int main(int argc, char *argv[])
{
IOHIDEventSystemClientRef system;
CFArrayRef services;
uint64_t aKey = 0x700000004;
uint64_t bKey = 0x700000005;
NSArray *map = #[
#{#kIOHIDKeyboardModifierMappingSrcKey:#(aKey),
#kIOHIDKeyboardModifierMappingDstKey:#(aKey)},
#{#kIOHIDKeyboardModifierMappingSrcKey:#(bKey),
#kIOHIDKeyboardModifierMappingDstKey:#(bKey)},
];
system = IOHIDEventSystemClientCreateSimpleClient(kCFAllocatorDefault);
services = IOHIDEventSystemClientCopyServices(system);
for(CFIndex i = 0; i < CFArrayGetCount(services); i++) {
IOHIDServiceClientRef service = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(services, i);
if(IOHIDServiceClientConformsTo(service, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) {
IOHIDServiceClientSetProperty(service, CFSTR(kIOHIDUserKeyUsageMapKey), (CFArrayRef)map);
}
}
CFRelease(services);
CFRelease(system);
return 0;
}

How to distinguish MacBook and Mac desktops programmatically?

I'm working on a Mac app that should distinguish MacBook and Mac desktops (iMac/Mac Pro).
I think I can get it done with model number. Then how I can get the model number? And which letter indicates it's a notebook or desktop? Or is there any other easier or better way?
You can use this little program. NSLog the output to test it.
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
+ (NSString *)machineModel
{
size_t length = 0;
sysctlbyname("hw.model", NULL, &length, NULL, 0);
if (length) {
char *m = malloc(length * sizeof(char));
sysctlbyname("hw.model", m, &length, NULL, 0);
NSString *model = [NSString stringWithUTF8String:m];
free(m);
return model;
}
return #"Unknown model";
}
It will provide the same output as entering sysctl hw.model on the terminal.
You haven't specified a language, but from Terminal sysctl hw.model will return with an identifier for the current Mac. For example, on my computer it returns MacBookPro5,5.

Sending UDP packets in Objective C: packet arriving without any data

I'm trying to send UDP packets in objective C. More specifically, building with xcode targeting the iphone 6.1 simulator.
I can't seem to actually receive the data I send. Weirdly, I do get a data event... the data's just been truncated to length 0.
I've cut it down as much as I can, to make a dead simple test I think should pass.
#import "UdpSocketTest.h"
#include <arpa/inet.h>
#import <CoreFoundation/CFSocket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#implementation UdpSocketTest
static int receivedByteCount = 0;
void onReceive(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info);
void onReceive(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
// this gets called once, but CFDataGetLength(data) == 0
receivedByteCount += CFDataGetLength(data);
}
-(void) testUdpSocket {
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(5000); // <-- doesn't really matter, not sending from receiver
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
CFSocketContext socketContext = { 0, (__bridge void*)self, CFRetain, CFRelease, NULL };
// prepare receiver
CFSocketRef receiver = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_DGRAM, IPPROTO_UDP ,kCFSocketDataCallBack, (CFSocketCallBack)onReceive, &socketContext);
CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(NULL, receiver, 0), kCFRunLoopCommonModes);
CFSocketConnectToAddress(receiver, CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr)), -1);
// point sender at receiver
CFSocketRef sender = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketDataCallBack, (CFSocketCallBack)onReceive, &socketContext);
CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(NULL, sender, 0), kCFRunLoopCommonModes);
CFSocketConnectToAddress(sender, CFSocketCopyAddress(receiver), -1);
// send data of sixty zeroes, allow processing to occur
CFSocketSendData(sender, NULL, (__bridge CFDataRef)[NSMutableData dataWithLength:60], 2.0);
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
// did the data arrive?
STAssertTrue(receivedByteCount > 0, #"");
// nope
}
#end
What am I doing wrong? I know it's something obvious, but I can't see it.
I'm surprised you're getting any callbacks at all—you're never actually binding your receiver to your local port. You're creating two sockets and telling both of them "I went to send data to 127.0.0.1:5000", but nowhere are you saying "I want to receive data on 127.0.0.1:5000.
In order to do that, you should be calling CFSocketSetAddress on the receiver socket, not CFSocketConnectToAddress. This is equivalent to calling the bind(2) system call on the underlying native BSD socket.

Get a list of all available network interfaces (en0, en1, en2, etc) with Cocoa?

In my Cocoa application I want to show the user a list of available network interfaces, like Wireshark does:
What is the best way of getting such a list? Does Apple provide a framework for this, or must I use a C API from the standard library or another library?
Better than wrapping ifconfig you shall check the reference of SCNetworkConfiguration which is part of Core Foundation.
Check SCNetworkInterfaceXxx functions for details.
related answer:
Using Cocoa / Objective-C, get currently connected network's security type in Mac OS X
The following code will get all the interfaces from OS X through System Configuration, then use standard C functions to get the IP addresses (where available).
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define IFT_ETHER 0x6
#include <SystemConfiguration/SCDynamicStore.h>
+(void)getInterfaces
{
SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)#"FindCurrentInterfaceIpMac", NULL, NULL);
CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Interface"));
id primaryInterface = [(__bridge NSDictionary *)global valueForKey:#"Interfaces"];
for (NSString* item in primaryInterface)
{
if(get_iface_address([item UTF8String]))
{
NSString *ip = [NSString stringWithUTF8String:get_iface_address([item UTF8String])];
NSLog(#"interface: %# - %#",item,ip);
} else
NSLog(#"interface: %#",item);
}
}
static char * get_iface_address (char *interface)
{
int sock;
uint32_t ip;
struct ifreq ifr;
char *val;
if (!interface)
return NULL;
/* determine UDN according to MAC address */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket");
return NULL;
}
strcpy (ifr.ifr_name, interface);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl (sock, SIOCGIFADDR, &ifr) < 0)
{
perror ("ioctl");
close (sock);
return NULL;
}
val = (char *) malloc (16 * sizeof (char));
ip = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
ip = ntohl (ip);
sprintf (val, "%d.%d.%d.%d",
(ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF);
close (sock);
return val;
}
#include <SystemConfiguration/SCDynamicStore.h>
SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)#"FindCurrentInterfaceIpMac", NULL, NULL);
CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Interface"));
id primaryInterface = [(__bridge NSDictionary *)global valueForKey:#"Interfaces"];
for (NSString* item in primaryInterface)
{
NSLog(#"%#", item);
}
Your quickest and best bet is to write a wrapper for ifconfig command.