1#include <Python.h> 2#include "pyobjc-api.h" 3#include <sys/socket.h> 4#include <netinet/in.h> 5#include <arpa/inet.h> 6#include <netdb.h> 7 8#import <Foundation/Foundation.h> 9 10@interface PyObjCTestSockAddr : NSObject 11{ 12} 13+(NSObject*)sockAddrToValue:(struct sockaddr*)addr; 14+(void) getIPv4Addr:(struct sockaddr*)buf; 15+(void) getIPv6Addr:(struct sockaddr*)buf; 16@end 17 18static NSString* 19addr2string(void* addr, int addrlen) 20{ 21 char buf[NI_MAXHOST]; 22 int error; 23 24 error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, 25 NI_NUMERICHOST); 26 if (error) { 27 return NULL; 28 } 29 return [NSString stringWithUTF8String:buf]; 30} 31 32 33@implementation PyObjCTestSockAddr 34+(NSObject*)sockAddrToValue:(struct sockaddr*)addr 35{ 36 NSMutableArray* array = [NSMutableArray array]; 37 38 switch (addr->sa_family) { 39 case AF_INET: 40 [array addObject:@"IPv4"]; 41 [array addObject: addr2string(addr, sizeof(struct sockaddr_in))]; 42 [array addObject:[NSNumber numberWithShort:ntohs(((struct sockaddr_in*)addr)->sin_port)]]; 43 return array; 44 break; 45 case AF_INET6: 46 [array addObject:@"IPv6"]; 47 [array addObject: addr2string(addr, sizeof(struct sockaddr_in6))]; 48 [array addObject: [NSNumber numberWithShort:ntohs(((struct sockaddr_in6*)addr)->sin6_port)]]; 49 [array addObject: [NSNumber numberWithUnsignedLong:(((struct sockaddr_in6*)addr)->sin6_flowinfo)]]; 50 [array addObject: [NSNumber numberWithUnsignedLong:(((struct sockaddr_in6*)addr)->sin6_scope_id)]]; 51 return array; 52 break; 53 default: 54 return NULL; 55 } 56} 57 58+(void) getIPv4Addr:(struct sockaddr*)buf 59{ 60 struct sockaddr_in* addr = (struct sockaddr_in*)buf; 61 addr->sin_family = AF_INET; 62 addr->sin_port = htons(80); 63 ascii2addr(AF_INET, "127.0.0.1", &addr->sin_addr); 64} 65 66+(void) getIPv6Addr:(struct sockaddr*)buf 67{ 68 struct sockaddr_in6* addr = (struct sockaddr_in6*)buf; 69 addr->sin6_family = AF_INET6; 70 addr->sin6_port = htons(443); 71 addr->sin6_flowinfo = 2; 72 addr->sin6_scope_id = 3; 73 ((char*)&addr->sin6_addr)[0] = 0; 74 ((char*)&addr->sin6_addr)[1] = 0; 75 ((char*)&addr->sin6_addr)[2] = 0; 76 ((char*)&addr->sin6_addr)[3] = 0; 77 ((char*)&addr->sin6_addr)[4] = 0; 78 ((char*)&addr->sin6_addr)[5] = 0; 79 ((char*)&addr->sin6_addr)[6] = 0; 80 ((char*)&addr->sin6_addr)[7] = 0; 81 ((char*)&addr->sin6_addr)[8] = 0; 82 ((char*)&addr->sin6_addr)[9] = 0; 83 ((char*)&addr->sin6_addr)[10] = 0; 84 ((char*)&addr->sin6_addr)[11] = 0; 85 ((char*)&addr->sin6_addr)[12] = 0; 86 ((char*)&addr->sin6_addr)[13] = 0; 87 ((char*)&addr->sin6_addr)[14] = 0; 88 ((char*)&addr->sin6_addr)[15] = 1; 89} 90@end 91 92static PyMethodDef mod_methods[] = { 93 { 0, 0, 0, 0} 94}; 95 96#if PY_VERSION_HEX >= 0x03000000 97 98static struct PyModuleDef mod_module = { 99 PyModuleDef_HEAD_INIT, 100 "sockaddr", 101 NULL, 102 0, 103 mod_methods, 104 NULL, 105 NULL, 106 NULL, 107 NULL 108}; 109 110#define INITERROR() return NULL 111#define INITDONE() return m 112 113PyObject* PyInit_sockaddr(void); 114 115PyObject* 116PyInit_sockaddr(void) 117 118#else 119 120#define INITERROR() return 121#define INITDONE() return 122 123void initsockaddr(void); 124 125void 126initsockaddr(void) 127#endif 128{ 129 PyObject* m; 130 131#if PY_VERSION_HEX >= 0x03000000 132 m = PyModule_Create(&mod_module); 133#else 134 m = Py_InitModule4("sockaddr", mod_methods, 135 NULL, NULL, PYTHON_API_VERSION); 136#endif 137 if (!m) { 138 INITERROR(); 139 } 140 141 if (PyObjC_ImportAPI(m) < 0) { 142 INITERROR(); 143 } 144 145 if (PyModule_AddObject(m, "PyObjCTestSockAddr", 146 PyObjCClass_New([PyObjCTestSockAddr class])) < 0) { 147 INITERROR(); 148 } 149 150 INITDONE(); 151 152} 153