cidr: Implement simplified IPv6 formats
* include/mailutils/cidr.h (MU_CIDR_FMT_SIMPLIFY): New format flag. * libmailutils/cidr/tostr.c (format_ipv6_bytes): Take additional argument, indicating whether to simplify the output. (format_ipv6_bytes_normal) (format_ipv6_bytes_simplified): New static functions. (mu_cidr_to_string): Select appropriate ipv6 printer depending on the MU_CIDR_FMT_SIMPLIFY bit. * libmailutils/tests/cidr.c (main): New options -s and -S
Showing
3 changed files
with
100 additions
and
16 deletions
... | @@ -42,6 +42,7 @@ int mu_cidr_from_sockaddr (struct mu_cidr *cp, const struct sockaddr *sa); | ... | @@ -42,6 +42,7 @@ int mu_cidr_from_sockaddr (struct mu_cidr *cp, const struct sockaddr *sa); |
42 | int mu_cidr_from_string (struct mu_cidr *cp, const char *str); | 42 | int mu_cidr_from_string (struct mu_cidr *cp, const char *str); |
43 | 43 | ||
44 | #define MU_CIDR_FMT_ADDRONLY 0x01 | 44 | #define MU_CIDR_FMT_ADDRONLY 0x01 |
45 | #define MU_CIDR_FMT_SIMPLIFY 0x02 | ||
45 | 46 | ||
46 | int mu_cidr_to_string (struct mu_cidr *cidr, int flags, char *buf, size_t size, | 47 | int mu_cidr_to_string (struct mu_cidr *cidr, int flags, char *buf, size_t size, |
47 | size_t *pret); | 48 | size_t *pret); | ... | ... |
... | @@ -34,33 +34,102 @@ to_xdig (unsigned char b) | ... | @@ -34,33 +34,102 @@ to_xdig (unsigned char b) |
34 | 34 | ||
35 | static size_t | 35 | static size_t |
36 | format_ipv6_bytes (const unsigned char *bytes, int len, | 36 | format_ipv6_bytes (const unsigned char *bytes, int len, |
37 | char *buf, size_t size) | 37 | char *buf, size_t size, int simplify) |
38 | { | 38 | { |
39 | size_t total = 0; | 39 | size_t total = 0; |
40 | int i; | 40 | int i; |
41 | int run_count = 0; | ||
42 | char *p; | ||
41 | 43 | ||
42 | for (i = 0; i < len; i += 2) | 44 | for (i = 0; i < len; i += 2) |
43 | { | 45 | { |
44 | if (i) | 46 | if (bytes[0] == 0 && bytes[1] == 0) |
47 | { | ||
48 | if (simplify) | ||
49 | run_count++; | ||
50 | else | ||
51 | { | ||
52 | if (i && total++ < size) | ||
53 | *buf++ = ':'; | ||
54 | if (total++ < size) | ||
55 | *buf++ = '0'; | ||
56 | } | ||
57 | bytes += 2; | ||
58 | } | ||
59 | else | ||
60 | { | ||
61 | if (run_count) | ||
62 | { | ||
63 | if (run_count == 1) | ||
64 | { | ||
65 | if (i && total++ < size) | ||
66 | *buf++ = ':'; | ||
67 | if (total++ < size) | ||
68 | *buf++ = '0'; | ||
69 | } | ||
70 | else | ||
71 | { | ||
72 | if (total++ < size) | ||
73 | *buf++ = ':'; | ||
74 | simplify = 0; | ||
75 | } | ||
76 | run_count = 0; | ||
77 | } | ||
78 | |||
79 | if (i && total++ < size) | ||
80 | *buf++ = ':'; | ||
81 | |||
82 | p = buf; | ||
83 | if ((*bytes & 0xf0) && total++ < size) | ||
84 | *buf++ = to_xdig (*bytes >> 4); | ||
85 | if ((buf > p || (*bytes & 0xf)) && total++ < size) | ||
86 | *buf++ = to_xdig (*bytes & 0xf); | ||
87 | bytes++; | ||
88 | if ((buf > p || (*bytes & 0xf0)) && total++ < size) | ||
89 | *buf++ = to_xdig (*bytes >> 4); | ||
90 | if ((buf > p || (*bytes & 0xf)) && total++ < size) | ||
91 | *buf++ = to_xdig (*bytes & 0xf); | ||
92 | bytes++; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | if (run_count) | ||
97 | { | ||
98 | if (run_count == 1) | ||
99 | { | ||
100 | if (i && total++ < size) | ||
101 | *buf++ = ':'; | ||
102 | if (total++ < size) | ||
103 | *buf++ = '0'; | ||
104 | } | ||
105 | else | ||
45 | { | 106 | { |
46 | if (total++ < size) | 107 | if (total++ < size) |
47 | *buf++ = ':'; | 108 | *buf++ = ':'; |
109 | if (total++ < size) | ||
110 | *buf++ = ':'; | ||
48 | } | 111 | } |
49 | if (total++ < size) | ||
50 | *buf++ = to_xdig (*bytes >> 4); | ||
51 | if (total++ < size) | ||
52 | *buf++ = to_xdig (*bytes & 0xf); | ||
53 | bytes++; | ||
54 | if (total++ < size) | ||
55 | *buf++ = to_xdig (*bytes >> 4); | ||
56 | if (total++ < size) | ||
57 | *buf++ = to_xdig (*bytes & 0xf); | ||
58 | bytes++; | ||
59 | } | 112 | } |
113 | |||
60 | return total; | 114 | return total; |
61 | } | 115 | } |
62 | 116 | ||
63 | static size_t | 117 | static size_t |
118 | format_ipv6_bytes_normal (const unsigned char *bytes, int len, | ||
119 | char *buf, size_t size) | ||
120 | { | ||
121 | return format_ipv6_bytes (bytes, len, buf, size, 0); | ||
122 | } | ||
123 | |||
124 | static size_t | ||
125 | format_ipv6_bytes_simplified (const unsigned char *bytes, int len, | ||
126 | char *buf, size_t size) | ||
127 | { | ||
128 | return format_ipv6_bytes (bytes, len, buf, size, 1); | ||
129 | } | ||
130 | |||
131 | |||
132 | static size_t | ||
64 | format_ipv4_bytes (const unsigned char *bytes, int len, | 133 | format_ipv4_bytes (const unsigned char *bytes, int len, |
65 | char *buf, size_t size) | 134 | char *buf, size_t size) |
66 | { | 135 | { |
... | @@ -114,7 +183,8 @@ mu_cidr_to_string (struct mu_cidr *cidr, int flags, | ... | @@ -114,7 +183,8 @@ mu_cidr_to_string (struct mu_cidr *cidr, int flags, |
114 | 183 | ||
115 | #ifdef MAILUTILS_IPV6 | 184 | #ifdef MAILUTILS_IPV6 |
116 | case AF_INET6: | 185 | case AF_INET6: |
117 | fmt = format_ipv6_bytes; | 186 | fmt = (flags & MU_CIDR_FMT_SIMPLIFY) ? |
187 | format_ipv6_bytes_simplified : format_ipv6_bytes_normal; | ||
118 | break; | 188 | break; |
119 | #endif | 189 | #endif |
120 | 190 | ... | ... |
... | @@ -33,10 +33,12 @@ print_bytes (unsigned char *b, size_t l) | ... | @@ -33,10 +33,12 @@ print_bytes (unsigned char *b, size_t l) |
33 | int | 33 | int |
34 | main (int argc, char **argv) | 34 | main (int argc, char **argv) |
35 | { | 35 | { |
36 | int flags = 0; | ||
37 | |||
36 | mu_set_program_name (argv[0]); | 38 | mu_set_program_name (argv[0]); |
37 | if (argc < 2) | 39 | if (argc < 2) |
38 | { | 40 | { |
39 | mu_error ("usage: %s CIDR [CIDR...]", argv[0]); | 41 | mu_error ("usage: %s [-sS] CIDR [CIDR...]", argv[0]); |
40 | return 1; | 42 | return 1; |
41 | } | 43 | } |
42 | 44 | ||
... | @@ -46,7 +48,18 @@ main (int argc, char **argv) | ... | @@ -46,7 +48,18 @@ main (int argc, char **argv) |
46 | struct mu_cidr cidr; | 48 | struct mu_cidr cidr; |
47 | int rc; | 49 | int rc; |
48 | char *str; | 50 | char *str; |
49 | 51 | ||
52 | if (strcmp (arg, "-s") == 0) | ||
53 | { | ||
54 | flags |= MU_CIDR_FMT_SIMPLIFY; | ||
55 | continue; | ||
56 | } | ||
57 | else if (strcmp (arg, "-S") == 0) | ||
58 | { | ||
59 | flags &= ~MU_CIDR_FMT_SIMPLIFY; | ||
60 | continue; | ||
61 | } | ||
62 | |||
50 | rc = mu_cidr_from_string (&cidr, arg); | 63 | rc = mu_cidr_from_string (&cidr, arg); |
51 | if (rc) | 64 | if (rc) |
52 | { | 65 | { |
... | @@ -61,7 +74,7 @@ main (int argc, char **argv) | ... | @@ -61,7 +74,7 @@ main (int argc, char **argv) |
61 | print_bytes (cidr.address, cidr.len); | 74 | print_bytes (cidr.address, cidr.len); |
62 | printf ("netmask ="); | 75 | printf ("netmask ="); |
63 | print_bytes (cidr.netmask, cidr.len); | 76 | print_bytes (cidr.netmask, cidr.len); |
64 | rc = mu_cidr_format (&cidr, 0, &str); | 77 | rc = mu_cidr_format (&cidr, flags, &str); |
65 | if (rc) | 78 | if (rc) |
66 | { | 79 | { |
67 | mu_error ("cannot covert to string: %s", mu_strerror (rc)); | 80 | mu_error ("cannot covert to string: %s", mu_strerror (rc)); | ... | ... |
-
Please register or sign in to post a comment