checkopts.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* include checkopts1 */
  2. /* *INDENT-OFF* */
  3. #include "unp.h"
  4. #include <netinet/tcp.h> /* for TCP_xxx defines */
  5. union val {
  6. int i_val;
  7. long l_val;
  8. struct linger linger_val;
  9. struct timeval timeval_val;
  10. } val;
  11. static char *sock_str_flag(union val *, int);
  12. static char *sock_str_int(union val *, int);
  13. static char *sock_str_linger(union val *, int);
  14. static char *sock_str_timeval(union val *, int);
  15. struct sock_opts {
  16. const char *opt_str;
  17. int opt_level;
  18. int opt_name;
  19. char *(*opt_val_str)(union val *, int);
  20. } sock_opts[] = {
  21. { "SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, sock_str_flag },
  22. { "SO_DEBUG", SOL_SOCKET, SO_DEBUG, sock_str_flag },
  23. { "SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE, sock_str_flag },
  24. { "SO_ERROR", SOL_SOCKET, SO_ERROR, sock_str_int },
  25. { "SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, sock_str_flag },
  26. { "SO_LINGER", SOL_SOCKET, SO_LINGER, sock_str_linger },
  27. { "SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE, sock_str_flag },
  28. { "SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, sock_str_int },
  29. { "SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, sock_str_int },
  30. { "SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, sock_str_int },
  31. { "SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, sock_str_int },
  32. { "SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, sock_str_timeval },
  33. { "SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, sock_str_timeval },
  34. { "SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, sock_str_flag },
  35. #ifdef SO_REUSEPORT
  36. { "SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, sock_str_flag },
  37. #else
  38. { "SO_REUSEPORT", 0, 0, NULL },
  39. #endif
  40. { "SO_TYPE", SOL_SOCKET, SO_TYPE, sock_str_int },
  41. { "SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, sock_str_flag },
  42. { "IP_TOS", IPPROTO_IP, IP_TOS, sock_str_int },
  43. { "IP_TTL", IPPROTO_IP, IP_TTL, sock_str_int },
  44. #ifdef IPV6_DONTFRAG
  45. { "IPV6_DONTFRAG", IPPROTO_IPV6,IPV6_DONTFRAG, sock_str_flag },
  46. #else
  47. { "IPV6_DONTFRAG", 0, 0, NULL },
  48. #endif
  49. #ifdef IPV6_UNICAST_HOPS
  50. { "IPV6_UNICAST_HOPS", IPPROTO_IPV6,IPV6_UNICAST_HOPS,sock_str_int },
  51. #else
  52. { "IPV6_UNICAST_HOPS", 0, 0, NULL },
  53. #endif
  54. #ifdef IPV6_V6ONLY
  55. { "IPV6_V6ONLY", IPPROTO_IPV6,IPV6_V6ONLY, sock_str_flag },
  56. #else
  57. { "IPV6_V6ONLY", 0, 0, NULL },
  58. #endif
  59. { "TCP_MAXSEG", IPPROTO_TCP,TCP_MAXSEG, sock_str_int },
  60. { "TCP_NODELAY", IPPROTO_TCP,TCP_NODELAY, sock_str_flag },
  61. #ifdef SCTP_AUTOCLOSE
  62. { "SCTP_AUTOCLOSE", IPPROTO_SCTP,SCTP_AUTOCLOSE,sock_str_int },
  63. #else
  64. { "SCTP_AUTOCLOSE", 0, 0, NULL },
  65. #endif
  66. #ifdef SCTP_MAXBURST
  67. { "SCTP_MAXBURST", IPPROTO_SCTP,SCTP_MAXBURST, sock_str_int },
  68. #else
  69. { "SCTP_MAXBURST", 0, 0, NULL },
  70. #endif
  71. #ifdef SCTP_MAXSEG
  72. { "SCTP_MAXSEG", IPPROTO_SCTP,SCTP_MAXSEG, sock_str_int },
  73. #else
  74. { "SCTP_MAXSEG", 0, 0, NULL },
  75. #endif
  76. #ifdef SCTP_NODELAY
  77. { "SCTP_NODELAY", IPPROTO_SCTP,SCTP_NODELAY, sock_str_flag },
  78. #else
  79. { "SCTP_NODELAY", 0, 0, NULL },
  80. #endif
  81. { NULL, 0, 0, NULL }
  82. };
  83. /* *INDENT-ON* */
  84. /* end checkopts1 */
  85. /* include checkopts2 */
  86. int
  87. main(int argc, char **argv)
  88. {
  89. int fd;
  90. socklen_t len;
  91. struct sock_opts *ptr;
  92. for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) {
  93. printf("%s: ", ptr->opt_str);
  94. if (ptr->opt_val_str == NULL)
  95. printf("(undefined)\n");
  96. else {
  97. switch(ptr->opt_level) {
  98. case SOL_SOCKET:
  99. case IPPROTO_IP:
  100. case IPPROTO_TCP:
  101. fd = Socket(AF_INET, SOCK_STREAM, 0);
  102. break;
  103. #ifdef IPV6
  104. case IPPROTO_IPV6:
  105. fd = Socket(AF_INET6, SOCK_STREAM, 0);
  106. break;
  107. #endif
  108. #ifdef IPPROTO_SCTP
  109. case IPPROTO_SCTP:
  110. fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
  111. break;
  112. #endif
  113. default:
  114. err_quit("Can't create fd for level %d\n", ptr->opt_level);
  115. }
  116. len = sizeof(val);
  117. if (getsockopt(fd, ptr->opt_level, ptr->opt_name,
  118. &val, &len) == -1) {
  119. err_ret("getsockopt error");
  120. } else {
  121. printf("default = %s\n", (*ptr->opt_val_str)(&val, len));
  122. }
  123. close(fd);
  124. }
  125. }
  126. exit(0);
  127. }
  128. /* end checkopts2 */
  129. /* include checkopts3 */
  130. static char strres[128];
  131. static char *
  132. sock_str_flag(union val *ptr, int len)
  133. {
  134. /* *INDENT-OFF* */
  135. if (len != sizeof(int))
  136. snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
  137. else
  138. snprintf(strres, sizeof(strres),
  139. "%s", (ptr->i_val == 0) ? "off" : "on");
  140. return(strres);
  141. /* *INDENT-ON* */
  142. }
  143. /* end checkopts3 */
  144. static char *
  145. sock_str_int(union val *ptr, int len)
  146. {
  147. if (len != sizeof(int))
  148. snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
  149. else
  150. snprintf(strres, sizeof(strres), "%d", ptr->i_val);
  151. return(strres);
  152. }
  153. static char *
  154. sock_str_linger(union val *ptr, int len)
  155. {
  156. struct linger *lptr = &ptr->linger_val;
  157. if (len != sizeof(struct linger))
  158. snprintf(strres, sizeof(strres),
  159. "size (%d) not sizeof(struct linger)", len);
  160. else
  161. snprintf(strres, sizeof(strres), "l_onoff = %d, l_linger = %d",
  162. lptr->l_onoff, lptr->l_linger);
  163. return(strres);
  164. }
  165. static char *
  166. sock_str_timeval(union val *ptr, int len)
  167. {
  168. struct timeval *tvptr = &ptr->timeval_val;
  169. if (len != sizeof(struct timeval))
  170. snprintf(strres, sizeof(strres),
  171. "size (%d) not sizeof(struct timeval)", len);
  172. else
  173. snprintf(strres, sizeof(strres), "%d sec, %d usec",
  174. tvptr->tv_sec, tvptr->tv_usec);
  175. return(strres);
  176. }