1
1
/*
2
2
* PostgreSQL type definitions for the INET and CIDR types.
3
3
*
4
- * $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.63 2006/02/07 17:04:04 momjian Exp $
4
+ * $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.64 2006/02/11 03:32:39 momjian Exp $
5
5
*
6
6
* Jon Postel RIP 16 Oct 1998
7
7
*/
@@ -27,6 +27,7 @@ static int32 network_cmp_internal(inet *a1, inet *a2);
27
27
static int bitncmp (void * l , void * r , int n );
28
28
static bool addressOK (unsigned char * a , int bits , int family );
29
29
static int ip_addrsize (inet * inetptr );
30
+ static Datum internal_inetpl (inet * ip , int64 iarg );
30
31
31
32
/*
32
33
* Access macros.
@@ -1250,3 +1251,208 @@ inet_server_port(PG_FUNCTION_ARGS)
1250
1251
1251
1252
PG_RETURN_DATUM (DirectFunctionCall1 (int4in , CStringGetDatum (local_port )));
1252
1253
}
1254
+
1255
+
1256
+ Datum
1257
+ inetnot (PG_FUNCTION_ARGS )
1258
+ {
1259
+ inet * ip = PG_GETARG_INET_P (0 );
1260
+ inet * dst ;
1261
+
1262
+ dst = (inet * ) palloc0 (VARHDRSZ + sizeof (inet_struct ));
1263
+
1264
+ {
1265
+ int nb = ip_addrsize (ip );
1266
+ unsigned char * pip = ip_addr (ip );
1267
+ unsigned char * pdst = ip_addr (dst );
1268
+
1269
+ while (nb -- > 0 )
1270
+ pdst [nb ] = ~pip [nb ];
1271
+ }
1272
+ ip_bits (dst ) = ip_bits (ip );
1273
+
1274
+ ip_family (dst ) = ip_family (ip );
1275
+ VARATT_SIZEP (dst ) = VARHDRSZ +
1276
+ ((char * ) ip_addr (dst ) - (char * ) VARDATA (dst )) +
1277
+ ip_addrsize (dst );
1278
+
1279
+ PG_RETURN_INET_P (dst );
1280
+ }
1281
+
1282
+
1283
+ Datum
1284
+ inetand (PG_FUNCTION_ARGS )
1285
+ {
1286
+ inet * ip = PG_GETARG_INET_P (0 );
1287
+ inet * ip2 = PG_GETARG_INET_P (1 );
1288
+ inet * dst ;
1289
+
1290
+ dst = (inet * ) palloc0 (VARHDRSZ + sizeof (inet_struct ));
1291
+
1292
+ if (ip_family (ip ) != ip_family (ip2 ))
1293
+ ereport (ERROR ,
1294
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1295
+ errmsg ("mismatch in address family (%d) != (%d)" ,
1296
+ ip_family (ip ), ip_family (ip2 ))));
1297
+ else
1298
+ {
1299
+ int nb = ip_addrsize (ip );
1300
+ unsigned char * pip = ip_addr (ip );
1301
+ unsigned char * pip2 = ip_addr (ip2 );
1302
+ unsigned char * pdst = ip_addr (dst );
1303
+
1304
+ while (nb -- > 0 )
1305
+ pdst [nb ] = pip [nb ] & pip2 [nb ];
1306
+ }
1307
+ ip_bits (dst ) = Max (ip_bits (ip ), ip_bits (ip2 ));
1308
+
1309
+ ip_family (dst ) = ip_family (ip );
1310
+ VARATT_SIZEP (dst ) = VARHDRSZ +
1311
+ ((char * ) ip_addr (dst ) - (char * ) VARDATA (dst )) +
1312
+ ip_addrsize (dst );
1313
+
1314
+ PG_RETURN_INET_P (dst );
1315
+ }
1316
+
1317
+
1318
+ Datum
1319
+ inetor (PG_FUNCTION_ARGS )
1320
+ {
1321
+ inet * ip = PG_GETARG_INET_P (0 );
1322
+ inet * ip2 = PG_GETARG_INET_P (1 );
1323
+ inet * dst ;
1324
+
1325
+ dst = (inet * ) palloc0 (VARHDRSZ + sizeof (inet_struct ));
1326
+
1327
+ if (ip_family (ip ) != ip_family (ip2 ))
1328
+ ereport (ERROR ,
1329
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1330
+ errmsg ("mismatch in address family (%d) != (%d)" ,
1331
+ ip_family (ip ), ip_family (ip2 ))));
1332
+ else
1333
+ {
1334
+ int nb = ip_addrsize (ip );
1335
+ unsigned char * pip = ip_addr (ip );
1336
+ unsigned char * pip2 = ip_addr (ip2 );
1337
+ unsigned char * pdst = ip_addr (dst );
1338
+
1339
+ while (nb -- > 0 )
1340
+ pdst [nb ] = pip [nb ] | pip2 [nb ];
1341
+ }
1342
+ ip_bits (dst ) = Max (ip_bits (ip ), ip_bits (ip2 ));
1343
+
1344
+ ip_family (dst ) = ip_family (ip );
1345
+ VARATT_SIZEP (dst ) = VARHDRSZ +
1346
+ ((char * ) ip_addr (dst ) - (char * ) VARDATA (dst )) +
1347
+ ip_addrsize (dst );
1348
+
1349
+ PG_RETURN_INET_P (dst );
1350
+ }
1351
+
1352
+
1353
+ static Datum
1354
+ internal_inetpl (inet * ip , int64 plus )
1355
+ {
1356
+ inet * dst ;
1357
+
1358
+ dst = (inet * ) palloc0 (VARHDRSZ + sizeof (inet_struct ));
1359
+
1360
+ {
1361
+ int nb = ip_addrsize (ip );
1362
+ unsigned char * pip = ip_addr (ip );
1363
+ unsigned char * pdst = ip_addr (dst );
1364
+ int carry = 0 ;
1365
+
1366
+ while (nb -- > 0 )
1367
+ {
1368
+ pdst [nb ] = carry = pip [nb ] + plus + carry ;
1369
+ plus /= 0x100 ; /* process next byte */
1370
+ carry /= 0x100 ; /* remove low byte */
1371
+ /* Overflow on high byte? */
1372
+ if (nb == 0 && (plus != 0 || carry != 0 ))
1373
+ ereport (ERROR ,
1374
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
1375
+ errmsg ("result out of range" )));
1376
+ }
1377
+ }
1378
+ ip_bits (dst ) = ip_bits (ip );
1379
+
1380
+ ip_family (dst ) = ip_family (ip );
1381
+ VARATT_SIZEP (dst ) = VARHDRSZ +
1382
+ ((char * ) ip_addr (dst ) - (char * ) VARDATA (dst )) +
1383
+ ip_addrsize (dst );
1384
+
1385
+ PG_RETURN_INET_P (dst );
1386
+ }
1387
+
1388
+
1389
+ Datum
1390
+ inetpl (PG_FUNCTION_ARGS )
1391
+ {
1392
+ inet * ip = PG_GETARG_INET_P (0 );
1393
+ int64 plus = PG_GETARG_INT64 (1 );
1394
+
1395
+ return internal_inetpl (ip , plus );
1396
+ }
1397
+
1398
+
1399
+ Datum
1400
+ inetmi_int8 (PG_FUNCTION_ARGS )
1401
+ {
1402
+ inet * ip = PG_GETARG_INET_P (0 );
1403
+ int64 plus = PG_GETARG_INT64 (1 );
1404
+
1405
+ return internal_inetpl (ip , - plus );
1406
+ }
1407
+
1408
+
1409
+ Datum
1410
+ inetmi (PG_FUNCTION_ARGS )
1411
+ {
1412
+ inet * ip = PG_GETARG_INET_P (0 );
1413
+ inet * ip2 = PG_GETARG_INET_P (1 );
1414
+ int64 res = 0 ;
1415
+
1416
+ if (ip_family (ip ) != ip_family (ip2 ))
1417
+ ereport (ERROR ,
1418
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1419
+ errmsg ("mismatch in address family (%d) != (%d)" ,
1420
+ ip_family (ip ), ip_family (ip2 ))));
1421
+ else
1422
+ {
1423
+ int nb = ip_addrsize (ip );
1424
+ int byte = 0 ;
1425
+ unsigned char * pip = ip_addr (ip );
1426
+ unsigned char * pip2 = ip_addr (ip2 );
1427
+
1428
+ while (nb -- > 0 )
1429
+ {
1430
+ /*
1431
+ * Error if overflow on last byte. This test is tricky
1432
+ * because if the subtraction == 128 and res is negative, or
1433
+ * if subtraction == -128 and res is positive, the result
1434
+ * would still fit in int64.
1435
+ */
1436
+ if (byte + 1 == sizeof (int64 ) &&
1437
+ (pip [nb ] - pip2 [nb ] >= 128 + (res < 0 ) ||
1438
+ pip [nb ] - pip2 [nb ] <= -128 - (res > 0 )))
1439
+ ereport (ERROR ,
1440
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
1441
+ errmsg ("result out of range" )));
1442
+ if (byte >= sizeof (int64 ))
1443
+ {
1444
+ /* Error if bytes beyond int64 length differ. */
1445
+ if (pip [nb ] != pip2 [nb ])
1446
+ ereport (ERROR ,
1447
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
1448
+ errmsg ("result out of range" )));
1449
+ }
1450
+ else
1451
+ res += (int64 )(pip [nb ] - pip2 [nb ]) << (byte * 8 );
1452
+
1453
+ byte ++ ;
1454
+ }
1455
+ }
1456
+
1457
+ PG_RETURN_INT64 (res );
1458
+ }
0 commit comments