linux_socket.c (3106d6704b59fa0ce9132ccdad18361aedcbda4b) | linux_socket.c (b6f96462ba817862b0b4a07284389b544e1271cd) |
---|---|
1/*- 2 * Copyright (c) 1995 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 67 unchanged lines hidden (view full) --- 76 77/* 78 * Reads a linux sockaddr and does any necessary translation. 79 * Linux sockaddrs don't have a length field, only a family. 80 * Copy the osockaddr structure pointed to by osa to kernel, adjust 81 * family and convert to sockaddr. 82 */ 83static int | 1/*- 2 * Copyright (c) 1995 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 67 unchanged lines hidden (view full) --- 76 77/* 78 * Reads a linux sockaddr and does any necessary translation. 79 * Linux sockaddrs don't have a length field, only a family. 80 * Copy the osockaddr structure pointed to by osa to kernel, adjust 81 * family and convert to sockaddr. 82 */ 83static int |
84linux_getsockaddr(struct sockaddr **sap, const struct osockaddr *osa, int osalen) | 84linux_getsockaddr(struct sockaddr **sap, const struct osockaddr *osa, int salen) |
85{ 86 struct sockaddr *sa; 87 struct osockaddr *kosa; 88#ifdef INET6 89 struct sockaddr_in6 *sin6; 90 int oldv6size; 91#endif 92 char *name; | 85{ 86 struct sockaddr *sa; 87 struct osockaddr *kosa; 88#ifdef INET6 89 struct sockaddr_in6 *sin6; 90 int oldv6size; 91#endif 92 char *name; |
93 int alloclen, bdom, error, hdrlen, namelen; | 93 int bdom, error, hdrlen, namelen; |
94 | 94 |
95 if (osalen < 2 || osalen > UCHAR_MAX || !osa) | 95 if (salen < 2 || salen > UCHAR_MAX || !osa) |
96 return (EINVAL); 97 | 96 return (EINVAL); 97 |
98 alloclen = osalen; | |
99#ifdef INET6 100 oldv6size = 0; 101 /* 102 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it 103 * if it's a v4-mapped address, so reserve the proper space 104 * for it. 105 */ | 98#ifdef INET6 99 oldv6size = 0; 100 /* 101 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it 102 * if it's a v4-mapped address, so reserve the proper space 103 * for it. 104 */ |
106 if (alloclen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) { 107 alloclen = sizeof(struct sockaddr_in6); | 105 if (salen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) { 106 salen += sizeof(uint32_t); |
108 oldv6size = 1; 109 } 110#endif 111 | 107 oldv6size = 1; 108 } 109#endif 110 |
112 kosa = malloc(alloclen, M_SONAME, M_WAITOK); | 111 kosa = malloc(salen, M_SONAME, M_WAITOK); |
113 | 112 |
114 if ((error = copyin(osa, kosa, osalen))) | 113 if ((error = copyin(osa, kosa, salen))) |
115 goto out; 116 117 bdom = linux_to_bsd_domain(kosa->sa_family); 118 if (bdom == -1) { 119 error = EAFNOSUPPORT; 120 goto out; 121 } 122 --- 17 unchanged lines hidden (view full) --- 140 sin6->sin6_scope_id = 0; 141 } else { 142 log(LOG_DEBUG, 143 "obsolete pre-RFC2553 sockaddr_in6 rejected\n"); 144 error = EINVAL; 145 goto out; 146 } 147 } else | 114 goto out; 115 116 bdom = linux_to_bsd_domain(kosa->sa_family); 117 if (bdom == -1) { 118 error = EAFNOSUPPORT; 119 goto out; 120 } 121 --- 17 unchanged lines hidden (view full) --- 139 sin6->sin6_scope_id = 0; 140 } else { 141 log(LOG_DEBUG, 142 "obsolete pre-RFC2553 sockaddr_in6 rejected\n"); 143 error = EINVAL; 144 goto out; 145 } 146 } else |
148 alloclen -= sizeof(uint32_t); | 147 salen -= sizeof(uint32_t); |
149 } 150#endif 151 if (bdom == AF_INET) { | 148 } 149#endif 150 if (bdom == AF_INET) { |
152 alloclen = sizeof(struct sockaddr_in); 153 if (osalen < alloclen) { | 151 if (salen < sizeof(struct sockaddr_in)) { |
154 error = EINVAL; 155 goto out; 156 } | 152 error = EINVAL; 153 goto out; 154 } |
155 salen = sizeof(struct sockaddr_in); |
|
157 } 158 | 156 } 157 |
159 if (bdom == AF_LOCAL && osalen > sizeof(struct sockaddr_un)) { | 158 if (bdom == AF_LOCAL && salen > sizeof(struct sockaddr_un)) { |
160 hdrlen = offsetof(struct sockaddr_un, sun_path); 161 name = ((struct sockaddr_un *)kosa)->sun_path; 162 if (*name == '\0') { 163 /* 164 * Linux abstract namespace starts with a NULL byte. 165 * XXX We do not support abstract namespace yet. 166 */ | 159 hdrlen = offsetof(struct sockaddr_un, sun_path); 160 name = ((struct sockaddr_un *)kosa)->sun_path; 161 if (*name == '\0') { 162 /* 163 * Linux abstract namespace starts with a NULL byte. 164 * XXX We do not support abstract namespace yet. 165 */ |
167 namelen = strnlen(name + 1, osalen - hdrlen - 1) + 1; | 166 namelen = strnlen(name + 1, salen - hdrlen - 1) + 1; |
168 } else | 167 } else |
169 namelen = strnlen(name, osalen - hdrlen); | 168 namelen = strnlen(name, salen - hdrlen); |
170 if (hdrlen + namelen > sizeof(struct sockaddr_un)) { 171 error = ENAMETOOLONG; 172 goto out; 173 } | 169 if (hdrlen + namelen > sizeof(struct sockaddr_un)) { 170 error = ENAMETOOLONG; 171 goto out; 172 } |
174 alloclen = sizeof(struct sockaddr_un); | 173 salen = sizeof(struct sockaddr_un); |
175 } 176 177 sa = (struct sockaddr *)kosa; 178 sa->sa_family = bdom; | 174 } 175 176 sa = (struct sockaddr *)kosa; 177 sa->sa_family = bdom; |
179 sa->sa_len = alloclen; | 178 sa->sa_len = salen; |
180 181 *sap = sa; 182 return (0); 183 184out: 185 free(kosa, M_SONAME); 186 return (error); 187} --- 1505 unchanged lines hidden --- | 179 180 *sap = sa; 181 return (0); 182 183out: 184 free(kosa, M_SONAME); 185 return (error); 186} --- 1505 unchanged lines hidden --- |