56
56
#include <sys/vnode.h>
57
57
58
58
#include <as400_protos.h>
59
+ #include <as400_types.h>
59
60
60
61
61
62
typedef struct {
@@ -98,24 +99,91 @@ typedef struct {
98
99
} SSTS0200 ;
99
100
100
101
102
+ typedef struct {
103
+ char header [208 ];
104
+ unsigned char loca_adapter_address [12 ];
105
+ } LIND0500 ;
106
+
107
+
108
+ typedef struct {
109
+ int bytes_provided ;
110
+ int bytes_available ;
111
+ char msgid [7 ];
112
+ } errcode_s ;
113
+
114
+
115
+ static const unsigned char e2a [256 ] = {
116
+ 0 , 1 , 2 , 3 , 156 , 9 , 134 , 127 , 151 , 141 , 142 , 11 , 12 , 13 , 14 , 15 ,
117
+ 16 , 17 , 18 , 19 , 157 , 133 , 8 , 135 , 24 , 25 , 146 , 143 , 28 , 29 , 30 , 31 ,
118
+ 128 , 129 , 130 , 131 , 132 , 10 , 23 , 27 , 136 , 137 , 138 , 139 , 140 , 5 , 6 , 7 ,
119
+ 144 , 145 , 22 , 147 , 148 , 149 , 150 , 4 , 152 , 153 , 154 , 155 , 20 , 21 , 158 , 26 ,
120
+ 32 , 160 , 161 , 162 , 163 , 164 , 165 , 166 , 167 , 168 , 91 , 46 , 60 , 40 , 43 , 33 ,
121
+ 38 , 169 , 170 , 171 , 172 , 173 , 174 , 175 , 176 , 177 , 93 , 36 , 42 , 41 , 59 , 94 ,
122
+ 45 , 47 , 178 , 179 , 180 , 181 , 182 , 183 , 184 , 185 , 124 , 44 , 37 , 95 , 62 , 63 ,
123
+ 186 , 187 , 188 , 189 , 190 , 191 , 192 , 193 , 194 , 96 , 58 , 35 , 64 , 39 , 61 , 34 ,
124
+ 195 , 97 , 98 , 99 , 100 , 101 , 102 , 103 , 104 , 105 , 196 , 197 , 198 , 199 , 200 , 201 ,
125
+ 202 , 106 , 107 , 108 , 109 , 110 , 111 , 112 , 113 , 114 , 203 , 204 , 205 , 206 , 207 , 208 ,
126
+ 209 , 126 , 115 , 116 , 117 , 118 , 119 , 120 , 121 , 122 , 210 , 211 , 212 , 213 , 214 , 215 ,
127
+ 216 , 217 , 218 , 219 , 220 , 221 , 222 , 223 , 224 , 225 , 226 , 227 , 228 , 229 , 230 , 231 ,
128
+ 123 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 232 , 233 , 234 , 235 , 236 , 237 ,
129
+ 125 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , 238 , 239 , 240 , 241 , 242 , 243 ,
130
+ 92 , 159 , 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 244 , 245 , 246 , 247 , 248 , 249 ,
131
+ 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 250 , 251 , 252 , 253 , 254 , 255 };
132
+
133
+
134
+ static const unsigned char a2e [256 ] = {
135
+ 0 , 1 , 2 , 3 , 55 , 45 , 46 , 47 , 22 , 5 , 37 , 11 , 12 , 13 , 14 , 15 ,
136
+ 16 , 17 , 18 , 19 , 60 , 61 , 50 , 38 , 24 , 25 , 63 , 39 , 28 , 29 , 30 , 31 ,
137
+ 64 , 79 , 127 , 123 , 91 , 108 , 80 , 125 , 77 , 93 , 92 , 78 , 107 , 96 , 75 , 97 ,
138
+ 240 , 241 , 242 , 243 , 244 , 245 , 246 , 247 , 248 , 249 , 122 , 94 , 76 , 126 , 110 , 111 ,
139
+ 124 , 193 , 194 , 195 , 196 , 197 , 198 , 199 , 200 , 201 , 209 , 210 , 211 , 212 , 213 , 214 ,
140
+ 215 , 216 , 217 , 226 , 227 , 228 , 229 , 230 , 231 , 232 , 233 , 74 , 224 , 90 , 95 , 109 ,
141
+ 121 , 129 , 130 , 131 , 132 , 133 , 134 , 135 , 136 , 137 , 145 , 146 , 147 , 148 , 149 , 150 ,
142
+ 151 , 152 , 153 , 162 , 163 , 164 , 165 , 166 , 167 , 168 , 169 , 192 , 106 , 208 , 161 , 7 ,
143
+ 32 , 33 , 34 , 35 , 36 , 21 , 6 , 23 , 40 , 41 , 42 , 43 , 44 , 9 , 10 , 27 ,
144
+ 48 , 49 , 26 , 51 , 52 , 53 , 54 , 8 , 56 , 57 , 58 , 59 , 4 , 20 , 62 , 225 ,
145
+ 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 81 , 82 , 83 , 84 , 85 , 86 , 87 ,
146
+ 88 , 89 , 98 , 99 , 100 , 101 , 102 , 103 , 104 , 105 , 112 , 113 , 114 , 115 , 116 , 117 ,
147
+ 118 , 119 , 120 , 128 , 138 , 139 , 140 , 141 , 142 , 143 , 144 , 154 , 155 , 156 , 157 , 158 ,
148
+ 159 , 160 , 170 , 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183 ,
149
+ 184 , 185 , 186 , 187 , 188 , 189 , 190 , 191 , 202 , 203 , 204 , 205 , 206 , 207 , 218 , 219 ,
150
+ 220 , 221 , 222 , 223 , 234 , 235 , 236 , 237 , 238 , 239 , 250 , 251 , 252 , 253 , 254 , 255 };
151
+
152
+
153
+ static void iconv_e2a (unsigned char src [], unsigned char dst [], size_t length ) {
154
+ size_t i ;
155
+ for (i = 0 ; i < length ; i ++ )
156
+ dst [i ] = e2a [src [i ]];
157
+ }
158
+
159
+
160
+ static void iconv_a2e (const char * src , unsigned char dst [], size_t length ) {
161
+ size_t srclen ;
162
+ size_t i ;
163
+
164
+ srclen = strlen (src );
165
+ if (srclen > length )
166
+ abort ();
167
+ for (i = 0 ; i < srclen ; i ++ )
168
+ dst [i ] = a2e [src [i ]];
169
+ /* padding the remaining part with spaces */
170
+ for (; i < length ; i ++ )
171
+ dst [i ] = a2e [' ' ];
172
+ }
173
+
174
+
101
175
static int get_ibmi_system_status (SSTS0200 * rcvr ) {
102
176
/* rcvrlen is input parameter 2 to QWCRSSTS */
103
177
unsigned int rcvrlen = sizeof (* rcvr );
178
+ unsigned char format [8 ], reset_status [10 ];
104
179
105
- /* format is input parameter 3 to QWCRSSTS ("SSTS0200" in EBCDIC) */
106
- unsigned char format [] = {0xE2 , 0xE2 , 0xE3 , 0xE2 , 0xF0 , 0xF2 , 0xF0 , 0xF0 };
107
-
108
- /* reset_status is input parameter 4 to QWCRSSTS ("*NO " in EBCDIC) */
109
- unsigned char reset_status [] = {
110
- 0x5C , 0xD5 , 0xD6 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40
111
- };
180
+ /* format is input parameter 3 to QWCRSSTS */
181
+ iconv_a2e ("SSTS0200" , format , sizeof (format ));
182
+ /* reset_status is input parameter 4 */
183
+ iconv_a2e ("*NO" , reset_status , sizeof (reset_status ));
112
184
113
185
/* errcode is input parameter 5 to QWCRSSTS */
114
- struct _errcode {
115
- int bytes_provided ;
116
- int bytes_available ;
117
- char msgid [7 ];
118
- } errcode ;
186
+ errcode_s errcode ;
119
187
120
188
/* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */
121
189
ILEpointer __attribute__((aligned (16 ))) qwcrssts_pointer ;
@@ -145,7 +213,7 @@ static int get_ibmi_system_status(SSTS0200* rcvr) {
145
213
qwcrssts_argv [5 ] = NULL ;
146
214
147
215
/* Call the IBM i QWCRSSTS API from PASE */
148
- rc = _PGMCALL (& qwcrssts_pointer , ( void * * ) & qwcrssts_argv , 0 );
216
+ rc = _PGMCALL (& qwcrssts_pointer , qwcrssts_argv , 0 );
149
217
150
218
return rc ;
151
219
}
@@ -166,10 +234,13 @@ uint64_t uv_get_free_memory(void) {
166
234
uint64_t current_unprotected_storage_used =
167
235
rcvr .current_unprotected_storage_used * 1024ULL ;
168
236
169
- uint64_t free_storage_size =
170
- (main_storage_size - current_unprotected_storage_used ) * 1024ULL ;
237
+ /* Current unprotected storage includes the storage used for memory
238
+ * and disks so it is possible to exceed the amount of main storage.
239
+ */
240
+ if (main_storage_size <= current_unprotected_storage_used )
241
+ return 0ULL ;
171
242
172
- return free_storage_size < 0 ? 0 : free_storage_size ;
243
+ return ( main_storage_size - current_unprotected_storage_used ) * 1024ULL ;
173
244
}
174
245
175
246
@@ -247,3 +318,159 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
247
318
248
319
return 0 ;
249
320
}
321
+
322
+
323
+ static int get_ibmi_physical_address (const char * line , char (* phys_addr )[6 ]) {
324
+ LIND0500 rcvr ;
325
+ /* rcvrlen is input parameter 2 to QDCRLIND */
326
+ unsigned int rcvrlen = sizeof (rcvr );
327
+ unsigned char format [8 ], line_name [10 ];
328
+ unsigned char mac_addr [sizeof (rcvr .loca_adapter_address )];
329
+ int c [6 ];
330
+
331
+ /* format is input parameter 3 to QDCRLIND */
332
+ iconv_a2e ("LIND0500" , format , sizeof (format ));
333
+
334
+ /* line_name is input parameter 4 to QDCRLIND */
335
+ iconv_a2e (line , line_name , sizeof (line_name ));
336
+
337
+ /* err is input parameter 5 to QDCRLIND */
338
+ errcode_s err ;
339
+
340
+ /* qwcrssts_pointer is the 16-byte tagged system pointer to QDCRLIND */
341
+ ILEpointer __attribute__((aligned (16 ))) qdcrlind_pointer ;
342
+
343
+ /* qwcrssts_argv is the array of argument pointers to QDCRLIND */
344
+ void * qdcrlind_argv [6 ];
345
+
346
+ /* Set the IBM i pointer to the QSYS/QDCRLIND *PGM object */
347
+ int rc = _RSLOBJ2 (& qdcrlind_pointer , RSLOBJ_TS_PGM , "QDCRLIND" , "QSYS" );
348
+
349
+ if (rc != 0 )
350
+ return rc ;
351
+
352
+ /* initialize the QDCRLIND returned info structure */
353
+ memset (& rcvr , 0 , sizeof (rcvr ));
354
+
355
+ /* initialize the QDCRLIND error code structure */
356
+ memset (& err , 0 , sizeof (err ));
357
+ err .bytes_provided = sizeof (err );
358
+
359
+ /* initialize the array of argument pointers for the QDCRLIND API */
360
+ qdcrlind_argv [0 ] = & rcvr ;
361
+ qdcrlind_argv [1 ] = & rcvrlen ;
362
+ qdcrlind_argv [2 ] = & format ;
363
+ qdcrlind_argv [3 ] = & line_name ;
364
+ qdcrlind_argv [4 ] = & err ;
365
+ qdcrlind_argv [5 ] = NULL ;
366
+
367
+ /* Call the IBM i QDCRLIND API from PASE */
368
+ rc = _PGMCALL (& qdcrlind_pointer , qdcrlind_argv , 0 );
369
+ if (rc != 0 )
370
+ return rc ;
371
+
372
+ /* convert ebcdic loca_adapter_address to ascii first */
373
+ iconv_e2a (rcvr .loca_adapter_address , mac_addr ,
374
+ sizeof (rcvr .loca_adapter_address ));
375
+
376
+ /* convert loca_adapter_address(char[12]) to phys_addr(char[6]) */
377
+ int r = sscanf (mac_addr , "%02x%02x%02x%02x%02x%02x" ,
378
+ & c [0 ], & c [1 ], & c [2 ], & c [3 ], & c [4 ], & c [5 ]);
379
+
380
+ if (r == ARRAY_SIZE (c )) {
381
+ (* phys_addr )[0 ] = c [0 ];
382
+ (* phys_addr )[1 ] = c [1 ];
383
+ (* phys_addr )[2 ] = c [2 ];
384
+ (* phys_addr )[3 ] = c [3 ];
385
+ (* phys_addr )[4 ] = c [4 ];
386
+ (* phys_addr )[5 ] = c [5 ];
387
+ } else {
388
+ memset (* phys_addr , 0 , sizeof (* phys_addr ));
389
+ rc = -1 ;
390
+ }
391
+ return rc ;
392
+ }
393
+
394
+
395
+ int uv_interface_addresses (uv_interface_address_t * * addresses , int * count ) {
396
+ uv_interface_address_t * address ;
397
+ struct ifaddrs_pase * ifap = NULL , * cur ;
398
+ int inet6 , r = 0 ;
399
+
400
+ * count = 0 ;
401
+ * addresses = NULL ;
402
+
403
+ if (Qp2getifaddrs (& ifap ))
404
+ return UV_ENOSYS ;
405
+
406
+ /* The first loop to get the size of the array to be allocated */
407
+ for (cur = ifap ; cur ; cur = cur -> ifa_next ) {
408
+ if (!(cur -> ifa_addr -> sa_family == AF_INET6 ||
409
+ cur -> ifa_addr -> sa_family == AF_INET ))
410
+ continue ;
411
+
412
+ if (!(cur -> ifa_flags & IFF_UP && cur -> ifa_flags & IFF_RUNNING ))
413
+ continue ;
414
+
415
+ (* count )++ ;
416
+ }
417
+
418
+ if (* count == 0 ) {
419
+ Qp2freeifaddrs (ifap );
420
+ return 0 ;
421
+ }
422
+
423
+ /* Alloc the return interface structs */
424
+ * addresses = uv__calloc (* count , sizeof (* * addresses ));
425
+ if (* addresses == NULL ) {
426
+ Qp2freeifaddrs (ifap );
427
+ return UV_ENOMEM ;
428
+ }
429
+ address = * addresses ;
430
+
431
+ /* The second loop to fill in the array */
432
+ for (cur = ifap ; cur ; cur = cur -> ifa_next ) {
433
+ if (!(cur -> ifa_addr -> sa_family == AF_INET6 ||
434
+ cur -> ifa_addr -> sa_family == AF_INET ))
435
+ continue ;
436
+
437
+ if (!(cur -> ifa_flags & IFF_UP && cur -> ifa_flags & IFF_RUNNING ))
438
+ continue ;
439
+
440
+ address -> name = uv__strdup (cur -> ifa_name );
441
+
442
+ inet6 = (cur -> ifa_addr -> sa_family == AF_INET6 );
443
+
444
+ if (inet6 ) {
445
+ address -> address .address6 = * ((struct sockaddr_in6 * )cur -> ifa_addr );
446
+ address -> netmask .netmask6 = * ((struct sockaddr_in6 * )cur -> ifa_netmask );
447
+ address -> netmask .netmask6 .sin6_family = AF_INET6 ;
448
+ } else {
449
+ address -> address .address4 = * ((struct sockaddr_in * )cur -> ifa_addr );
450
+ address -> netmask .netmask4 = * ((struct sockaddr_in * )cur -> ifa_netmask );
451
+ address -> netmask .netmask4 .sin_family = AF_INET ;
452
+ }
453
+ address -> is_internal = cur -> ifa_flags & IFF_LOOPBACK ? 1 : 0 ;
454
+ if (!address -> is_internal ) {
455
+ int rc = get_ibmi_physical_address (address -> name , & address -> phys_addr );
456
+ if (rc != 0 )
457
+ r = rc ;
458
+ }
459
+
460
+ address ++ ;
461
+ }
462
+
463
+ Qp2freeifaddrs (ifap );
464
+ return r ;
465
+ }
466
+
467
+
468
+ void uv_free_interface_addresses (uv_interface_address_t * addresses , int count ) {
469
+ int i ;
470
+
471
+ for (i = 0 ; i < count ; ++ i ) {
472
+ uv__free (addresses [i ].name );
473
+ }
474
+
475
+ uv__free (addresses );
476
+ }
0 commit comments