00001
00002
00003
00004
00005
00006
00007 #include "postgres.h"
00008
00009 #include "access/hash.h"
00010 #include "libpq/pqformat.h"
00011 #include "utils/builtins.h"
00012 #include "utils/inet.h"
00013
00014
00015
00016
00017
00018
00019 #define hibits(addr) \
00020 ((unsigned long)(((addr)->a<<16)|((addr)->b<<8)|((addr)->c)))
00021
00022 #define lobits(addr) \
00023 ((unsigned long)(((addr)->d<<16)|((addr)->e<<8)|((addr)->f)))
00024
00025
00026
00027
00028
00029 Datum
00030 macaddr_in(PG_FUNCTION_ARGS)
00031 {
00032 char *str = PG_GETARG_CSTRING(0);
00033 macaddr *result;
00034 int a,
00035 b,
00036 c,
00037 d,
00038 e,
00039 f;
00040 char junk[2];
00041 int count;
00042
00043
00044
00045 count = sscanf(str, "%x:%x:%x:%x:%x:%x%1s",
00046 &a, &b, &c, &d, &e, &f, junk);
00047 if (count != 6)
00048 count = sscanf(str, "%x-%x-%x-%x-%x-%x%1s",
00049 &a, &b, &c, &d, &e, &f, junk);
00050 if (count != 6)
00051 count = sscanf(str, "%2x%2x%2x:%2x%2x%2x%1s",
00052 &a, &b, &c, &d, &e, &f, junk);
00053 if (count != 6)
00054 count = sscanf(str, "%2x%2x%2x-%2x%2x%2x%1s",
00055 &a, &b, &c, &d, &e, &f, junk);
00056 if (count != 6)
00057 count = sscanf(str, "%2x%2x.%2x%2x.%2x%2x%1s",
00058 &a, &b, &c, &d, &e, &f, junk);
00059 if (count != 6)
00060 count = sscanf(str, "%2x%2x%2x%2x%2x%2x%1s",
00061 &a, &b, &c, &d, &e, &f, junk);
00062 if (count != 6)
00063 ereport(ERROR,
00064 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00065 errmsg("invalid input syntax for type macaddr: \"%s\"", str)));
00066
00067 if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
00068 (c < 0) || (c > 255) || (d < 0) || (d > 255) ||
00069 (e < 0) || (e > 255) || (f < 0) || (f > 255))
00070 ereport(ERROR,
00071 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00072 errmsg("invalid octet value in \"macaddr\" value: \"%s\"", str)));
00073
00074 result = (macaddr *) palloc(sizeof(macaddr));
00075
00076 result->a = a;
00077 result->b = b;
00078 result->c = c;
00079 result->d = d;
00080 result->e = e;
00081 result->f = f;
00082
00083 PG_RETURN_MACADDR_P(result);
00084 }
00085
00086
00087
00088
00089
00090 Datum
00091 macaddr_out(PG_FUNCTION_ARGS)
00092 {
00093 macaddr *addr = PG_GETARG_MACADDR_P(0);
00094 char *result;
00095
00096 result = (char *) palloc(32);
00097
00098 snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x",
00099 addr->a, addr->b, addr->c, addr->d, addr->e, addr->f);
00100
00101 PG_RETURN_CSTRING(result);
00102 }
00103
00104
00105
00106
00107
00108
00109 Datum
00110 macaddr_recv(PG_FUNCTION_ARGS)
00111 {
00112 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00113 macaddr *addr;
00114
00115 addr = (macaddr *) palloc(sizeof(macaddr));
00116
00117 addr->a = pq_getmsgbyte(buf);
00118 addr->b = pq_getmsgbyte(buf);
00119 addr->c = pq_getmsgbyte(buf);
00120 addr->d = pq_getmsgbyte(buf);
00121 addr->e = pq_getmsgbyte(buf);
00122 addr->f = pq_getmsgbyte(buf);
00123
00124 PG_RETURN_MACADDR_P(addr);
00125 }
00126
00127
00128
00129
00130 Datum
00131 macaddr_send(PG_FUNCTION_ARGS)
00132 {
00133 macaddr *addr = PG_GETARG_MACADDR_P(0);
00134 StringInfoData buf;
00135
00136 pq_begintypsend(&buf);
00137 pq_sendbyte(&buf, addr->a);
00138 pq_sendbyte(&buf, addr->b);
00139 pq_sendbyte(&buf, addr->c);
00140 pq_sendbyte(&buf, addr->d);
00141 pq_sendbyte(&buf, addr->e);
00142 pq_sendbyte(&buf, addr->f);
00143 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00144 }
00145
00146
00147
00148
00149
00150
00151 static int32
00152 macaddr_cmp_internal(macaddr *a1, macaddr *a2)
00153 {
00154 if (hibits(a1) < hibits(a2))
00155 return -1;
00156 else if (hibits(a1) > hibits(a2))
00157 return 1;
00158 else if (lobits(a1) < lobits(a2))
00159 return -1;
00160 else if (lobits(a1) > lobits(a2))
00161 return 1;
00162 else
00163 return 0;
00164 }
00165
00166 Datum
00167 macaddr_cmp(PG_FUNCTION_ARGS)
00168 {
00169 macaddr *a1 = PG_GETARG_MACADDR_P(0);
00170 macaddr *a2 = PG_GETARG_MACADDR_P(1);
00171
00172 PG_RETURN_INT32(macaddr_cmp_internal(a1, a2));
00173 }
00174
00175
00176
00177
00178
00179 Datum
00180 macaddr_lt(PG_FUNCTION_ARGS)
00181 {
00182 macaddr *a1 = PG_GETARG_MACADDR_P(0);
00183 macaddr *a2 = PG_GETARG_MACADDR_P(1);
00184
00185 PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) < 0);
00186 }
00187
00188 Datum
00189 macaddr_le(PG_FUNCTION_ARGS)
00190 {
00191 macaddr *a1 = PG_GETARG_MACADDR_P(0);
00192 macaddr *a2 = PG_GETARG_MACADDR_P(1);
00193
00194 PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) <= 0);
00195 }
00196
00197 Datum
00198 macaddr_eq(PG_FUNCTION_ARGS)
00199 {
00200 macaddr *a1 = PG_GETARG_MACADDR_P(0);
00201 macaddr *a2 = PG_GETARG_MACADDR_P(1);
00202
00203 PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) == 0);
00204 }
00205
00206 Datum
00207 macaddr_ge(PG_FUNCTION_ARGS)
00208 {
00209 macaddr *a1 = PG_GETARG_MACADDR_P(0);
00210 macaddr *a2 = PG_GETARG_MACADDR_P(1);
00211
00212 PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) >= 0);
00213 }
00214
00215 Datum
00216 macaddr_gt(PG_FUNCTION_ARGS)
00217 {
00218 macaddr *a1 = PG_GETARG_MACADDR_P(0);
00219 macaddr *a2 = PG_GETARG_MACADDR_P(1);
00220
00221 PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) > 0);
00222 }
00223
00224 Datum
00225 macaddr_ne(PG_FUNCTION_ARGS)
00226 {
00227 macaddr *a1 = PG_GETARG_MACADDR_P(0);
00228 macaddr *a2 = PG_GETARG_MACADDR_P(1);
00229
00230 PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) != 0);
00231 }
00232
00233
00234
00235
00236 Datum
00237 hashmacaddr(PG_FUNCTION_ARGS)
00238 {
00239 macaddr *key = PG_GETARG_MACADDR_P(0);
00240
00241 return hash_any((unsigned char *) key, sizeof(macaddr));
00242 }
00243
00244
00245
00246
00247 Datum
00248 macaddr_not(PG_FUNCTION_ARGS)
00249 {
00250 macaddr *addr = PG_GETARG_MACADDR_P(0);
00251 macaddr *result;
00252
00253 result = (macaddr *) palloc(sizeof(macaddr));
00254 result->a = ~addr->a;
00255 result->b = ~addr->b;
00256 result->c = ~addr->c;
00257 result->d = ~addr->d;
00258 result->e = ~addr->e;
00259 result->f = ~addr->f;
00260 PG_RETURN_MACADDR_P(result);
00261 }
00262
00263 Datum
00264 macaddr_and(PG_FUNCTION_ARGS)
00265 {
00266 macaddr *addr1 = PG_GETARG_MACADDR_P(0);
00267 macaddr *addr2 = PG_GETARG_MACADDR_P(1);
00268 macaddr *result;
00269
00270 result = (macaddr *) palloc(sizeof(macaddr));
00271 result->a = addr1->a & addr2->a;
00272 result->b = addr1->b & addr2->b;
00273 result->c = addr1->c & addr2->c;
00274 result->d = addr1->d & addr2->d;
00275 result->e = addr1->e & addr2->e;
00276 result->f = addr1->f & addr2->f;
00277 PG_RETURN_MACADDR_P(result);
00278 }
00279
00280 Datum
00281 macaddr_or(PG_FUNCTION_ARGS)
00282 {
00283 macaddr *addr1 = PG_GETARG_MACADDR_P(0);
00284 macaddr *addr2 = PG_GETARG_MACADDR_P(1);
00285 macaddr *result;
00286
00287 result = (macaddr *) palloc(sizeof(macaddr));
00288 result->a = addr1->a | addr2->a;
00289 result->b = addr1->b | addr2->b;
00290 result->c = addr1->c | addr2->c;
00291 result->d = addr1->d | addr2->d;
00292 result->e = addr1->e | addr2->e;
00293 result->f = addr1->f | addr2->f;
00294 PG_RETURN_MACADDR_P(result);
00295 }
00296
00297
00298
00299
00300
00301 Datum
00302 macaddr_trunc(PG_FUNCTION_ARGS)
00303 {
00304 macaddr *addr = PG_GETARG_MACADDR_P(0);
00305 macaddr *result;
00306
00307 result = (macaddr *) palloc(sizeof(macaddr));
00308
00309 result->a = addr->a;
00310 result->b = addr->b;
00311 result->c = addr->c;
00312 result->d = 0;
00313 result->e = 0;
00314 result->f = 0;
00315
00316 PG_RETURN_MACADDR_P(result);
00317 }