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 ---