1 | #include "mruby.h"
|
---|
2 | #include <sys/types.h>
|
---|
3 | #include <sys/socket.h>
|
---|
4 | #include <netinet/in.h>
|
---|
5 | #include <arpa/inet.h>
|
---|
6 | #include <string.h>
|
---|
7 | #include "mruby/string.h"
|
---|
8 |
|
---|
9 | static mrb_value
|
---|
10 | mrb_ipaddr_ntop(mrb_state *mrb, mrb_value klass)
|
---|
11 | {
|
---|
12 | mrb_int af, n;
|
---|
13 | char *addr, buf[50];
|
---|
14 |
|
---|
15 | mrb_get_args(mrb, "s", &addr, &n);
|
---|
16 | if (n == 4) {
|
---|
17 | af = AF_INET;
|
---|
18 | } else if (n == 16) {
|
---|
19 | af = AF_INET6;
|
---|
20 | } else {
|
---|
21 | mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
|
---|
22 | }
|
---|
23 | if (inet_ntop(af, addr, buf, sizeof(buf)) == NULL)
|
---|
24 | mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
|
---|
25 | return mrb_str_new_cstr(mrb, buf);
|
---|
26 | }
|
---|
27 |
|
---|
28 | static mrb_value
|
---|
29 | mrb_ipaddr_pton(mrb_state *mrb, mrb_value klass)
|
---|
30 | {
|
---|
31 | mrb_int af, n;
|
---|
32 | mrb_value s;
|
---|
33 | char *bp, buf[50];
|
---|
34 |
|
---|
35 | mrb_get_args(mrb, "is", &af, &bp, &n);
|
---|
36 | if (n > sizeof(buf) - 1)
|
---|
37 | mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
|
---|
38 | memcpy(buf, bp, n);
|
---|
39 | buf[n] = '\0';
|
---|
40 |
|
---|
41 | if (af == AF_INET) {
|
---|
42 | struct in_addr in;
|
---|
43 | if (inet_pton(AF_INET, buf, (void *)&in.s_addr) != 1) {
|
---|
44 | mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
|
---|
45 | }
|
---|
46 | s = mrb_str_new(mrb, (char *)&in.s_addr, 4);
|
---|
47 | } else if (af == AF_INET6) {
|
---|
48 | struct in6_addr in6;
|
---|
49 | if (inet_pton(AF_INET6, buf, (void *)&in6.s6_addr) != 1) {
|
---|
50 | mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
|
---|
51 | }
|
---|
52 | s = mrb_str_new(mrb, (char *)&in6.s6_addr, 16);
|
---|
53 | } else
|
---|
54 | mrb_raise(mrb, E_ARGUMENT_ERROR, "unsupported address family");
|
---|
55 |
|
---|
56 | return s;
|
---|
57 | }
|
---|
58 |
|
---|
59 | void
|
---|
60 | mrb_mruby_ipaddr_gem_init(mrb_state *mrb)
|
---|
61 | {
|
---|
62 | struct RClass *c;
|
---|
63 |
|
---|
64 | c = mrb_define_class(mrb, "IPAddr", mrb->object_class);
|
---|
65 | mrb_define_class_method(mrb, c, "_pton", mrb_ipaddr_pton, MRB_ARGS_REQ(1));
|
---|
66 | mrb_define_class_method(mrb, c, "ntop", mrb_ipaddr_ntop, MRB_ARGS_REQ(1));
|
---|
67 | }
|
---|
68 |
|
---|
69 | void
|
---|
70 | mrb_mruby_ipaddr_gem_final(mrb_state *mrb)
|
---|
71 | {
|
---|
72 | }
|
---|